GameObject API

思考并回答以下问题:

  • 如何在脚本中获取自身所在的GameObject?
  • Debug.Log的第2个参数有什么作用?
  • 如何通过物体名字查找物体?
  • GameObject.Find()有什么缺点?是深度遍历还是广度遍历?如何解决?
  • 如何修改物体的active状态?
  • activeInHierarchy和active有什么区别?
  • 如何用代码创建空物体?
  • 如何用代码创建内置几何体?
  • 怎么得到游戏对象的layer,tag和所在场景名?
  • 如何给游戏对象添加组件?

GameObject本身没有功能,它是组件的容器,很多时候我们需要在脚本中操作GameObject。

如何在脚本中获取自身所在的GameObject?

我们知道脚本必须挂在一个GameObject上面才能执行,那么如何知道当前脚本所挂载的GameObject是哪一个呢?

这就需要用到gameObject属性了。

gameObject属性可以在所有继承MonoBehaviour的类中获取到,因为脚本必须要挂载到一个物体上才能执行,这个gameObject就是脚本挂到的物体。

1
2
3
4
5
6
7
8
9
using UnityEngine;

public class Test : MonoBehaviour
{
void Start ()
{
Debug.Log(gameObject.name, gameObject);
}
}

上面的代码就会打印出脚本所挂物体的名字。

注意这里Debug.Log传入了两个参数,这是为什么呢?

遇到这种问题,我们首先查一下Unity的文档。

为什么要查Unity的文档呢?

从图中可以看到,将光标移到Debug上面时,显示Debug类是属于UnityEngine这个命名空间的,也就是Unity提供的API。

Debug.Log有两种形式:

1
2
public static void Log(object message);
public static void Log(object message, Object context);

第二种形式中可以传入一个Object类型的参数,传入这个参数时,在Console中显示的log会与脚本所在的物体关联。点击Console中这条信息时,会在Hierarchy中高亮这一个物体。

Log关联GameObject

如何通过物体名字查找物体?

GameObject类中有一个静态(static)方法Find,用于通过名字查找场景中的物体。

什么是静态方法

静态方法是标记为static的方法。静态方法独立于实例对象存在。即使没有类的实例,仍然可以通过类名.静态方法调用。静态方法中不能访问实例成员,可以访问其他静态成员。

静态方法在定义时需要在返回值类型前面加上static修饰符,比如:

1
2
3
4
static void Walk()
{
Debug.Log("Walking");
}

访问时,可以直接通过类名.方法名调用。比如查找物体的方法就是GameObject.Find(“cat”)。

查找的名称字符串中可以包含“/”,比如GameObject.Find(“animals/cat”)就只会查到父物体名字为animals的cat物体。如果“/”字符在字符串中最开始的位置,那么会在根节点开始找,比如GameObject.Find(“/animals/cat”)就只会查到根节点为animals物体的子物体cat。

查找过后,一定要判断一下是否为空,因为Find有可能找不到你想找的物体。

特别注意1

这个方法的效率比较低,不要在Update中调用此方法,否则可能会造成游戏卡顿。一般的做法是,在Awake或Start方法中通过Find找到,然后保存到成员变量中。

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
using UnityEngine;

public class Test : MonoBehaviour
{
private GameObject cat;

void Start()
{
cat = GameObject.Find("cat");
if(cat != null)
Debug.Log("找到了cat物体", cat);
}
}

特别注意2

这个方法无法找到active为false的物体。

那么如何查找active为false的物体呢?

1、不要使用Find,直接在代码中通过public的变量关联物体。

2、不要设置物体的active为false,先在游戏最开始时通过代码找到物体,然后通过代码设为false。

3、通过transform.Find。

如何修改物体的active状态?

修改物体的active状态是一个快速隐藏/显示物体的方法。物体的active是false时,物体上所有的组件都不会执行,相当于将物体隐藏了。

1
gameObject.SetActive(false);

特别注意

这个方法只会改变物体自身的active属性。如果该物体有子物体,那么子物体也会被隐藏,但是active属性不会变。如果该物体的父物体的active是false,即使将该物体的active设置为true,该物体也不会显示出来。

物体的active可以通过两个属性来判断:

activeInHierarchy 物体是否在Hierarchy中是激活状态。这个属性为true时,则可知该物体及其所有父物体的active都为true。

activeSelf 物体自身的active属性是否为true,即使该物体的父物体的active可能为false。

如何通过tag查找物体?

除了通过物体的name查找物体,通过物体的tag也可以查找。Tag即在Inspector上设置的一个标签,如下图所示:

一个物体只能有一个Tag,但是一个Tag可以被多个物体使用。

通过tag查找有两个方法:

1
public static GameObject FindWithTag(string tag);

返回第一个查找到的标签为tag的active为true的物体(以字母排序),如果没有找到则返回null。

tag必须在TagManager中设置过,否则会抛出异常。异常内容是:UnityException: Tag: cat is not defined.含义是:标签:cat 没有定义。

1
public static GameObject[] FindGameObjectsWithTag(string tag);

由于一个Tag可以被多个物体使用,所以这个方法可以找到所有使用该标签的active为true的物体,并返回对应的数组。如果没有找到,会返回一个空数组(长度为0的数组)。

tag必须在TagManager中设置过,否则会抛出异常。异常内容是:UnityException: Tag: xxx is not defined.含义是:标签:xxx 没有定义。

如何用代码创建空物体?

有时候为了组织Hierarchy的结构,需要动态创建空物体作为文件夹使用。

创建空物体可以使用如下代码:

1
2
3
GameObject go = new GameObject();
go.name = "EmptyGameObject";
GameObject dog = new GameObject("Puppy");

new的时候可以传入一个字符串作为GameObject的名字。也可以不传,默认名字是New Game Object。也可以创建后再修改空物体的名字。

如何用代码创建内置几何体?

通过代码也很容易创建Unity中的几种默认几何体。

1
public static GameObject CreatePrimitive(PrimitiveType type);

其中PrimitiveType是一个枚举(enum)类型,包括的类型有:Sphere、Capsule、Cylinder、Cube、Plane、Quad。

具体的用法如下:

1
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);

上面的代码可以创建一个Cube,和通过菜单栏GameObject › 3D Object › Cube创建出来的Cube一致。

什么是枚举?

枚举是一组命名整型常量。枚举类型是使用enum关键字声明的。

C#枚举是值类型。换句话说,枚举包含自己的值,且不能继承或传递继承。

声明枚举的一般语法:

1
2
3
4
enum ‹enum_name›
{
enumeration list
};

其中,

enum_name 指定枚举的类型名称。

enumeration list 是一个用逗号分隔的标识符列表。

枚举列表中的每个符号代表一个整数值,一个比它前面的符号大的整数值。默认情况下,第一个枚举符号的值是0。例如:

1
enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat };

使用时,可以使用Days.Sun来表示星期日。

官方文档

class in UnityEngine / Inherits from:Object / Implemented in:UnityEngine.CoreModule

Description
Base class for all entities(实体) in Unity Scenes.

Properties

属性 作用
activeInHierarchy Defines whether the GameObject is active in the Scene.
activeSelf The local active state of this GameObject. (Read Only)
isStatic Editor only API that specifies if a game object is static.
layer The layer the game object is in. 返回数字
scene Scene that the GameObject is part of.返回UnityEngine.SceneManagement.Scene,obj.scene.name可得到场景名
tag The tag of this game object.
transform The Transform attached to this GameObject.

Constructors

名称 作用
GameObject Creates a new game object, named name.

Public Methods

名称 作用
AddComponent Adds a component class named className to the game object.
BroadcastMessage Calls the method named methodName on every MonoBehaviour in this game object or any of its children.
CompareTag Is this game object tagged with tag ?
GetComponent Returns the component of Type type if the game object has one attached, null if it doesn’t.
GetComponentInChildren Returns the component of Type type in the GameObject or any of its children using depth first search.
GetComponentInParent Returns the component of Type type in the GameObject or any of its parents.
GetComponents Returns all components of Type type in the GameObject.
GetComponentsInChildren Returns all components of Type type in the GameObject or any of its children.
GetComponentsInParent Returns all components of Type type in the GameObject or any of its parents.
SendMessage Calls the method named methodName on every MonoBehaviour in this game object.
SendMessageUpwards Calls the method named methodName on every MonoBehaviour in this game object and on every ancestor(祖先) of the behaviour.
SetActive Activates/Deactivates the GameObject, depending on the given true or false value.

Static Methods

名称 作用
CreatePrimitive Creates a game object with a primitive mesh renderer and appropriate collider.
Find Finds a GameObject by name and returns it.
FindGameObjectsWithTag Returns a list of active GameObjects tagged tag. Returns empty array if no GameObject was found.
FindWithTag Returns one active GameObject tagged tag. Returns null if no GameObject was found.

Inherited Members

Properties

名称 作用
hideFlags Should the object be hidden, saved with the Scene or modifiable by the user?
name The name of the object.

Public Methods

名称 作用
GetInstanceID Returns the instance id of the object.
ToString Returns the name of the GameObject.

Static Methods

名称 作用
Destroy Removes a gameobject, component or asset.
DestroyImmediate Destroys the object obj immediately. You are strongly recommended to use Destroy instead.
DontDestroyOnLoad Do not destroy the target Object when loading a new Scene.
FindObjectOfType Returns the first active loaded object of Type type.
FindObjectsOfType Returns a list of all active loaded objects of Type type.
Instantiate Clones the object original and returns the clone.

Operators

名称 作用
bool Does the object exist?
operator!= Compares if two objects refer to a different object.
operator== Compares two object references to see if they refer to the same object.
0%