unity 获取对象上得脚本

2015年01月14日 10:39 0 点赞 0 评论 更新于 2025-11-21 14:20

在Unity开发中,我们常常需要获取对象上的脚本。在深入探讨获取脚本的方法之前,先来了解一下Unity里的TransformGameObject。这两个类就像是一对紧密相连的“双胞胎兄弟”,它们之间可以相互访问。很多开发者喜欢在类中保存GameObject对象,以解决GameObject.Find()无法获取天生active = false对象的问题。

不过,建议大家保存Transform对象而非GameObject。因为Transform类提供的方法比GameObject更多,使用频率也更高。以下是保存Transform对象的示例代码:

private Transform root;

这里有一个疑问:为什么Unity不把GameObjectTransform合并成一个对象呢?

接下来,详细介绍两种常用的获取游戏对象的方法。

1. GameObject.Find()

GameObject.Find()方法允许我们通过场景中的名称或者路径直接获取游戏对象。示例代码如下:

GameObject root = GameObject.Find("GameObject");

如果游戏对象不在最上层,建议使用路径的方式进行查找,因为场景中可能存在重名的游戏对象,路径使用“/”符号分隔。示例如下:

GameObject root = GameObject.Find("GameObject/Cube");

GameObject.Find()使用起来非常方便,但它存在一个明显的缺陷。如果游戏对象天生active = false,那么使用GameObject.Find()将永远无法获取该对象。一旦对象无法获取,其身上的脚本和组件也就无法获取,这个对象对于我们来说就失去了意义。对于这个问题,查阅了很多资料也未能找到通用的解决方案。不过,可以采用一个巧妙的办法来解决(后续会详细讲解),或者提前将所有游戏对象保存在内存中。

需要注意的是,GameObject.Find()方法在游戏中的使用频率很高,但它比较消耗性能。其原理很可能是采用类似递归的方式实现的,因此应尽量减少调用该方法的次数。可以将获取到的游戏对象保存在内存中,这是一个不错的选择。尤其要注意,不要在Update方法中调用Find()方法来查找游戏对象。

2. Transform.Find()

前面提到GameObject.Find()无法获取天生active = false的游戏对象,而Transform.Find()可以很好地解决这个问题。另外,Unity还提供了一个Transform.FindChild()方法,但该方法未来会被弃用,建议使用Transform.Find()来替代。

以下代码展示了如何使用Transform.Find()方法:

// 先获取顶级对象root
Transform root = ...;
// 接着用Find()去找它的子节点"xxxx"的对象,无论"xxxx"对象是否active = true 都可以直接找到
Transform child = root.Find("xxxx");

通过以上两种方法,我们可以在Unity中更灵活地获取游戏对象,进而获取对象上的脚本。在实际开发中,应根据具体需求选择合适的方法,以提高开发效率和性能。