呆呆敲代码的小Y头像
关注
【100个 Unity实用技巧】☀️ | Unity常用属性底层开销速查 + gameObject.name完整原理封面图

【100个 Unity实用技巧】☀️ | Unity常用属性底层开销速查 + gameObject.name完整原理

请添加图片描述


Unity 小知识 大智慧

  • 🎬 博客主页:https://xiaoy.blog.csdn.net

  • 🎥 本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉

  • 🎄 学习专栏推荐:Unity系统学习专栏

  • 🌲 游戏制作专栏推荐:游戏制作

  • 🌲Unity实战100例专栏推荐:Unity 实战100例 教程

  • 🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

  • 📆 未来很长,值得我们全力奔赴更美好的生活✨

  • ------------------❤️分割线❤️-------------------------

请添加图片描述


Unity 实用技巧学习

Unity常用属性底层开销速查 + gameObject.name完整原理笔记

说明:MonoBehaviour下直接写name等价gameObject.name;transform.position是高频踩坑点。
跨桥:C#托管 ↔ Unity C++原生引擎;GC分配=托管堆产生对象,会给GC带来压力,移动端敏感。

一、常见属性底层开销对比速查表

属性底层实现跨桥调用GC Alloc(get读取)注意要点
gameObject.nameC#是包装属性,真实字符串存储在C++GameObject;每次get:跨桥拷贝C++字符串,新建C# string对象✅每次访问都跨桥✅每次读取都分配string GCUpdate/循环严禁频繁读取;运行时不变就Awake缓存成员变量;无原生无GC对比接口
gameObject.tagtag字符串存C++;get同样跨桥生成新string✅每次访问都跨桥✅每次读取分配string GC判断标签不要用 ==,使用gameObject.CompareTag("xxx")无GC
transform.position属性,get:跨桥读取C++变换矩阵,计算世界坐标返回新Vector3结构体✅每次访问都跨桥❌无GC(struct值类型)频繁读写有CPU开销;Update大量物体反复读写会耗CPU;不要多次重复get,优先缓存局部变量
transform.localPosition属性,get:跨桥读取C++本地变换,返回新Vector3✅每次访问都跨桥❌无GC(struct值类型)同上;set同样跨桥;连续多次读写建议先缓存到局部Vector3
transform.rotation跨桥读取四元数,返回新Quaternion✅每次访问都跨桥❌无GC值类型无堆分配,但跨桥CPU开销存在
transform.localRotation跨桥读取本地四元数✅每次访问都跨桥❌无GC同上
transform.localScale跨桥读取缩放Vector3✅每次访问都跨桥❌无GC同上
gameObject.GetInstanceID()跨桥返回int数字✅跨桥❌无GC适合运行时区分对象,不要用name做对象身份判断
gameObject.activeSelf跨桥读取激活状态bool✅跨桥❌无GC仅bool返回,开销很小,可适度频繁调用

重要区分:

  1. Vector3/Quaternion是struct值类型:每次get返回新副本,CPU跨桥开销,没有GC堆分配;
  2. name/tag返回string引用类型:每次get都会在托管堆新建字符串,既有跨桥CPU开销,又产生GC垃圾,危害更大。

二、Unity组件访问 gameObject.name 底层原理完整笔记

1.底层执行流程(每一次get读取都会完整走一遍)

gameObject.name是C#层Native属性,C# GameObject只是薄包装句柄(存实例指针/InstanceID),C#侧不存储名字字符串,真正名字保存在C++原生GameObject。

  1. C#访问gameObject.name,触发托管→原生跨桥marshalling;
  2. 引擎C++根据句柄找到原生GameObject实例,取出char*名字;
  3. 将C++字符串拷贝,在C#托管堆创建全新string对象返回;
  4. C#拿到字符串,若无引用很快变为GC垃圾。

简写this.name(MonoBehaviour直接写name)完全等价gameObject.name,底层开销一模一样。

set赋值 gameObject.name="xxx":C#字符串封送拷贝到C++修改原生名字;C#依然不缓存,下一次读取依旧重新生成新string。

2.两大性能开销

  1. CPU开销:C#与C++跨边界调用
    单次开销很小,Update、循环、大量实体频繁访问会累积CPU耗时。
  2. GC堆分配(最主要危害)
    string是不可变引用类型,每读取一次就分配一次托管堆内存。Update每帧读取会持续产生GC Alloc,移动端容易出现GC卡顿。

Profiler → GC Allocated 面板可以直接观测到字节分配。

⚠️tag同理;但是tag提供CompareTag(),直接在C++对比内部标识,零GC;name没有官方无GC替代接口。

3.代码示例:好坏写法对比

❌错误:Update每帧读取,持续GC分配

void Update()
{
    Debug.Log(gameObject.name); //每帧跨桥+新建string,持续产生垃圾
}

误区:赋值给局部变量并不能消除分配

void Update()
{
    string temp = gameObject.name; //get依旧执行,依然分配GC,只是临时接收结果
}

✅正确:Awake/Start一次性缓存成员字段(名字运行时不变)

private string _cachedObjName;
void Awake()
{
    _cachedObjName = gameObject.name; //仅执行一次跨桥、一次分配
}

void Update()
{
    Debug.Log(_cachedObjName); //读取本地变量:0跨桥、0GC
}

如果运行时代码会修改gameObject.name,修改之后同步更新缓存变量。

✅业务身份判断不要用name字符串对比

❌不推荐:if(gameObject.name == "Enemy") 每次访问name带来GC
✅推荐方案:

  1. gameObject.CompareTag("Enemy")
  2. 自定义标记MonoBehaviour组件
  3. gameObject.GetInstanceID()(int无GC,区分对象实例)
  4. 枚举ID配置

4.允许 / 严禁使用场景

✅安全场景:Awake、Start、OnEnable、只执行一次初始化逻辑、编辑器脚本,偶尔访问无压力。
❌禁止场景:Update / FixedUpdate / LateUpdate、for/while循环、OnTriggerStay、大量怪物/子弹等实体每帧读取name。

5.常见误区澄清

  1. IL2CPP打包不会消除name读取的字符串堆分配,只是编译方式改变,C++字符串封送拷贝逻辑保留。
  2. transform.name底层转发gameObject.name,开销完全相同。
  3. =只是局部变量接收返回值,不能消除getter内部的跨桥和内存分配;只有提前缓存到成员字段才生效。

补充小知识点

  • gameObject.tag判断标签务必用CompareTag(),不要gameObject.tag == "xxx";后者每次读取tag产生string GC。
  • position/localPosition虽然没有GC,但大量循环重复读取会累积CPU开销,建议缓存局部变量:
Vector3 pos = transform.position;
pos.x += 1;
transform.position = pos;

面试背诵精简版

  1. gameObject.name字符串存在C++层,C#只是包装句柄;每次get触发跨桥,拷贝生成全新C# string,产生GC。
  2. 不要在Update频繁读name;名字不变就在Awake缓存成员变量。
  3. name没有无GC对比API;tag判断优先CompareTag。
  4. transform.position等值类型属性:跨桥CPU开销,无GC;多次读写缓存局部变量优化。

资料白嫖,技术互助

学习路线指引(点击解锁)知识定位人群定位
🧡 Unity系统学习专栏 入门级本专栏从Unity入门开始学习,快速达到Unity的入门水平
💛 Unity实战类项目 进阶级计划制作Unity的 100个实战案例!助你进入Unity世界,争取做最全的Unity原创博客大全。
❤️ 游戏制作专栏 难度偏高分享学习一些Unity成品的游戏Demo和其他语言的小游戏!
💚 游戏爱好者万人社区 互助/吹水数万人游戏爱好者社区,聊天互助,白嫖奖品
💙 Unity100个实用技能 Unity查漏补缺针对一些Unity中经常用到的一些小知识和技能进行学习介绍,核心目的就是让我们能够快速学习Unity的知识以达到查漏补缺

在这里插入图片描述

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/zhangay1998/article/details/164450376

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--