Unity 查找游戏对象以及游戏组件

2022年4月25日 6555点热度 8人点赞 0条评论

前言

Unity 引擎中十分重要的两个类,GameObject 与Component。

游戏场景中的几乎所有的东西都可以使用GameObject来表示,而GameObject可以看作是一个Component的容器,大部分功能都由Component来实现。GameObejct需要某个功能时就将对应的Component添加,不需要时就移除,十分的方便。

需要注意的是,C#脚本在添加进GameObject中,也是被一个Component调用的。

游戏对象

GameObject 是 Unity 中场景的构建块,可充当用于确定 GameObject 外观以及 GameObject 作用的功能组件的容器。

在脚本编写中,GameObject 类提供了允许在代码中使用的方法的集合,包括查找、建立连接和在 GameObject 之间发送消息,以及添加或移除附加到 GameObject 的组件和设置与其在场景中的状态相关的值。

GameObject

在Inspector Window可以查看GameObject 的一些属性和组件属性,所有的GameObject都有上图的这几种固定属性,分别是Name,Tag,Layer。Name旁边的复选框代表GameObject的可用状态,如果为不可用,那么这个对象不会触发仍和回调或者事件,包括它拥有的组件也是。

Name和Tag都是用于标记对象,通过这些标记,可以在全局去查找这些对象,一个Tag可以多个对象公用,貌似name也是可以重复的,暂时不理解。

Layer属性决定了GameObject的显示层级以及碰撞层级,只用相同层级的对象才能触发碰撞检测。

操作游戏对象

在脚本编写中,常常需要对GameObject对象进行操作,读取数据,修改数据等。虽然可以通过Component.gameObejct获取组件当前所在的对象,但这还远远不够,因为常常还需要在对象脚本中操作别的GameObject.

一个简单的办法

public GameObject obj;

在脚本中声明一个public成员,然后在Inspector Window中把需要连接的游戏对象拖拽过去,这部分可以参考Unity C#脚本的基本使用方法。然后就可以在脚本中对obj进行操作了。

这种方法适用于单一连接的固定对象,必须要在游戏场景建立时就知道我们要操作的时哪个对象,然后将对象绑定,所以Unity 提供了使用Name和Tag查找游戏对象的方法。

使用Name查找
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
    public GameObject hand;

    void Example()
    {
        //  返回名称为 Hand的游戏对象
        hand = GameObject.Find("Hand");

        //  返回名称为 Hand的游戏对象
        //  这个对象必须是在Hierarchy Window的顶层
        hand = GameObject.Find("/Hand");

        //  返回名称为 Hand的游戏对象
        //  Hand必须是Arm的子对象 且Arm必须是MOnster的子对象
        //  Monseter必须是在Hierarchy Window的顶层
        hand = GameObject.Find("/Monster/Arm/Hand");

        //  返回名称为 Hand的游戏对象
        //  Hand必须是Arm的子对象 且Arm必须是MOnster的子对象
        hand = GameObject.Find("Monster/Arm/Hand");
    }
}

这里主要使用了GameObject.Find()函数,它是一个静态成员函数,所以可以直接被调用,参数是name,也可以按照路径的格式出入对象的父子关系,可以根据负责关系去查找对象。

这个查找方式是全局的,只要是在Hierarchy Window中的对象都会是被筛选对象。

注意:这个函数很消耗性能,所以要避免在update()这种频率比较高的事件中调用,比较好的做法是在Start()函数中查找,然后到update()中去操作。

使用Tag查找
public static GameObject[] FindGameObjectsWithTag (string tag);
public static GameObject FindWithTag (string tag);

这个两个成员函数都在GameObject中被声明,使用时只需要传入Tag作为参数就可以了。

使用时需要注意的是FindWithTag()函数,因为一个Tag下可能由多个GameObject,它只返回找到的第一个,而具体的查找顺序是不知道的,这种情况最好是使用FindGameObjectsWithTag()将所有的GameObject都返回。

另外,这个函数的性能消耗是要比Find()函数小的。

注意 :查找函数找不到对象是都会返回null

游戏组件

游戏组件用于确定GameObejct的外观,行为。Unity 引擎提供了许多默认的组件,如Transform,Sprite Renderer,Animator等等,包括使用C#编写的脚本,也是以组件的形式被调用的。

GameObject1

在Inspector Window 中点击Add Component 按钮就可以为精灵添加一个组件,移除也只需要在组件上方右键,点击remove Component即可。

脚本中也可以做到这样的事情。

添加组件
public Component AddComponent (string className);//已弃用
public Component AddComponent (Type componentType);
public T AddComponent();

AddComponent()有三种声明,第一种以字符串作为参数的已经被弃用了,现在只能用后两种。

示例:

ComponentName cp = gameObject.AddComponent(typeof(ComponentName)) as ComponentName;
ComponentName cp = gameObject.AddComponent<ComponentName>();
移除组件

GameObject没有提供RmoveComponent()函数,需要用户将组件释放调,才能移除组件。

在Unity中释放对象使用:

public static void Destroy (Object obj, float t= 0.0F);

这个成员函数被声明在object类中,obj为需要释放掉的对象,t是代码它在t秒之后会被释放,是一个可选的参数。

需要先获取到组件,才能释放掉,所以还需要:

public Component GetComponent (Type type);
public T GetComponent ();
public Component GetComponent (string type);
public Component[] GetComponents (Type type);
public T[] GetComponents ();

这些成员函数被声明在GameObject中,使用方法参考AddComponent。

大脸猫

这个人虽然很勤快,但什么也没有留下!

文章评论