[组件笔记]2.UnityEngine.Object

如果System.Object是.Net所有的类型根,那么UnityEngine.Object就是我们Unity中的所有对象的类型根,当然UnityEngine.Object的类型根也是System.Object。

  • Object 派生的任何公共变量都将在 Inspector 中显示为放置目标, 让我们能够从 GUI 设置其值。
    public class Point:UnityEngine.Object
    {
        public int x;
        public int y;
    }
    
    当我们的Point继承UnityEngine.Object就换变为一个Unity内置对象
  • UnityEngine.Object 是所有 Unity 内置对象的基类。
  • 虽然 Object 是一个类,但其本意不是为了在脚本中广泛使用。更多的是做为资源或者实体对象进行使用。我们在 Resources 类中使用了Object作为资源对象的返回值。
    public static Object Load(string path);
    public static T[] LoadAll<T>(string path) where T : Object;

公共变量

hideFlags

public HideFlags hideFlags { get; set; }

该变量是通过BitMask方式控制此Object可见性的一种标识状态。其字段类型是HideFlags枚举类型,每个枚举类型代表不同的处理方式。

HideFlags枚举

DontSave,DontSaveInEditor,DontUnloadUnusedAsset,HideAndDontSave如果你不十分了解的情况下慎用。如果使用,一定要进行内存回收,否则他们将会常驻在你的内存里,如果是编辑器模式下,他们依旧不会被清理掉。也不会随着编译脚本,切换场景此类操作而进行释放。可以通过Resources.FindObjectsOfTypeAll获取对应对象数组。

  • None=0 :默认的类型,Unity会按照默认的处理机制对此对象进行处理。
  • HideInHierarchy=1:在层级试图隐藏,如果是此状态 ,我们的对象将仅仅不再Hierarchy视图中显示,并且层级视图下也搜索不到,但是不会影响GameObject.Find或者GameObject.FindObjectOfType此类方法,OnEnableOnDisable依然会按照正常流程进行回调,这里需要多加注意。
    在Awake中加入gameObject.hideFlags = HideFlags.HideInHierarchy;测试下效果吧。
  • HideInInspector=2:上面的是在层级试图隐藏,这个便是在属性视图进行隐藏。在这里如果你设置的是gameobject将会隐藏所有组件,如果你设置的是组件,这个组件会被隐藏,当然你的脚本也算在组件。
    在Awake中分别加入gameObject.hideFlags = HideFlags.HideInInspector;this.hideFlags = HideFlags.HideInInspector;,测试效果吧。
  • NotEditable=8:在属性视图不可编辑。在这里如果你设置的是gameobject将会禁止编辑所有组件,如果你设置的是组件,这个组件会被禁止编辑,当然你的脚本也算在组件。
  • DontSaveInEditor=4:你的作用对象将不存在于场景中。加载新场景时,也不会销毁它。须使用 DestroyImmediate 从内存中手动清除该对象以避免内存泄漏。此实体对象脱离于场景的生命周期管理。须使用 DestroyImmediate 从内存中手动清除该对象以避免内存泄漏。
  • GameObject.FindObjectOfType搜索对象将会失效,使用Resources.FindObjectsOfTypeAll有效,但是不影响GameObject.Find或者GameObject.FindGameObjectsWithTag此类方法。
  • 使用后在跳转场景后,层级视图将不对其显示,但是不影响GameObject.Find或者GameObject.FindGameObjectsWithTag此类方法获取目标对象。
  • DontSaveInBuild=16:在播放器building 中,不对对象进行保存,这里仅在编辑环境下设置此属性有效。必须使用 DestroyImmediate 从内存中手动清除该对象以避免内存泄漏。
  • DontUnloadUnusedAsset=32:使用Resources.UnloadUnusedAssets 不会卸载该对象。必须使用 DestroyImmediate 从内存中手动清除该对象以避免内存泄漏。
  • DontSave4+16+32:此对象将不会保存在场景中,也不会被Resources.UnloadUnusedAssets 卸载掉,也不会再building中对此对象进行保存。
    • 此枚举值是HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor | HideFlags.DontUnloadUnusedAsset与运算结果。
  • HideAndDontSave=1+4+8+16+32:该 GameObject 不显示在层级视图中、不保存到场景、也不会被 Resources.UnloadUnusedAssets 卸载。必须使用 DestroyImmediate 从内存中手动清除该对象以避免内存泄漏。

name

public string name { get; set; }

对象的名称。

  • 组件与游戏对象及所有附加组件使用相同的名称。
  • 如果一个类派生自 MonoBehaviour,它将从 MonoBehaviour 继承“name”字段。
  • 如果也将该类附加到 GameObject,则“name”字段将设置为该 GameObject 的名称。

公共函数

Equals

public override bool Equals(object other);

重写了Equals ,比较两个对象是否为同一对象。

GetHashCode

public override int GetHashCode();

重写了GetHashCode,获取哈希码。

  • 返回值是GetInstanceID()的值。

GetInstanceID

public int GetInstanceID();

获取对象实例ID

  • 对象的实例ID当前场景下具有唯一性。
  • 当返回正数时为原始对象,负数时为实例对象
  • 此数值会在游戏运行时和编辑器会话之间发生改变,所以你不能从保存的文件中加载这个对象时用它作为一个标识。
  • 切换场景后或者重启Unity后,此数值会发生改变。

ToString

public override string ToString();

返回对象的字符串表示

  • 重写了基类,返回对象的名称。

静态函数

Destroy

public static void Destroy(Object obj, [DefaultValue("0.0F")] float t);
public static void Destroy(Object obj);

用于移除 GameObject对象、组件或资源。

  • 可以设置延时时间,进行延时销毁。
  • 如果 obj 是 Component,则此方法会从 GameObject 移除该组件并将它销毁。
  • 如果 obj 是 GameObject,则会销毁该 GameObject、其所有组件以及该 GameObject 的所有子项。
  • 实际的对象销毁操作始终延迟到当前更新循环结束,渲染前完成。
  • 销毁脚本时,在删除脚本之前会调用OnDisableOnDestroy

DestroyImmediate

public static void DestroyImmediate(Object obj);
public static void DestroyImmediate(Object obj, [DefaultValue("false")] bool allowDestroyingAssets);

立刻销毁 GameObject对象、组件或资源。

  • 设置allowDestroyingAssets为ture 将会允许销毁资源。
  • 推荐只在编写 Editor 代码时使用,因为在编辑模式下, 永远不会调用延迟销毁。游戏中使用Destroy方法。
  • 使用该函数时要务必小心,因为它可以永久销毁资源!
  • 循环访问数组并销毁正在迭代的元素,这会导致异常的问题。可以采用:
    for(int i=list.count; i>=0 ;i--)

DontDestroyOnLoad

public static void DontDestroyOnLoad([NotNull("NullExceptionObject")] Object target);

在加载新的 Scene 时,请勿销毁此Object。

  • 加载新场景会销毁所有当前场景对象。DontDestroyOnLoad声明在场景加载期间保留对象。
  • 如果目标对象是组件或GameObject,Unity也会保留GameObject所有子对象。
  • 如果目标对象是组件,则会保留对应的GameObject。
  • 当保留对象存在于场景中,跳转回所在场景会增加这个保留对象,这里需要注意下。

FindObjectOfType

public static T FindObjectOfType<T>() where T : Object;
public static T FindObjectOfType<T>(bool includeInactive) where T : Object;
public static Object FindObjectOfType(Type type);
public static Object FindObjectOfType(Type type, bool includeInactive);

用于查找场景中第一个活跃或者通过设置includeInactive为true非活跃的对应类型对象,如果没有找到返回null

  • 无法查找资源类对象,如Meshes, Textures, Prefabs。
  • 无法查找hideFlags设置为HideFlags.DontSave的对象。
  • 此方法效率较低,不建议每帧调用。

FindObjectsOfType

public static T[] FindObjectsOfType<T>() where T : Object;
public static Object[] FindObjectsOfType(Type type, bool includeInactive);
public static T[] FindObjectsOfType<T>(bool includeInactive) where T : Object;
public static Object[] FindObjectsOfType(Type type);

用于查找场景中所有活跃或者通过设置includeInactive为true非活跃的对应类型对象数组。

  • 无法查找资源类对象,如Meshes, Textures, Prefabs。
  • 无法查找hideFlags设置为HideFlags.DontSave的对象。
  • 使用 Resources.FindObjectsOfTypeAll 可避免这些限制。
  • 在编辑器中,这在默认情况下会搜索 Scene 视图。如果要在预制件阶段查找对象,可使用StageUtility API。
  • 此方法效率较低,不建议每帧调用。

Instantiate

public static T Instantiate<T>(T original, Transform parent) where T : Object;
public static Object Instantiate(Object original, Vector3 position, Quaternion rotation);
public static T Instantiate<T>(T original, Transform parent, bool worldPositionStays) where T : Object;
public static Object Instantiate(Object original);
public static Object Instantiate(Object original, Vector3 position, Quaternion rotation, Transform parent);
public static Object Instantiate(Object original, Transform parent, bool instantiateInWorldSpace);
public static T Instantiate<T>(T original) where T : Object;
public static T Instantiate<T>(T original, Vector3 position, Quaternion rotation) where T : Object;
public static T Instantiate<T>(T original, Vector3 position, Quaternion rotation, Transform parent) where T : Object;
public static Object Instantiate(Object original, Transform parent);

original要复制的原始对象。
position新对象的位置。
rotation新的对象的旋转量
parent新对象的父节点
instantiateInWorldSpace指定父节点时,如果为true以在世界空间中设定新对象的位置和旋转量。如果为false以设置对象相对于其父节点的位置和旋转量。

克隆 original 对象并返回克隆对象。

  • 此函数会通过与编辑器中的复制命令类似的方式创建对象的副本。
  • 如果要克隆 GameObject,则可以指定其位置和旋转量(否则,这些默认为原始 GameObject 的位置和旋转)。
  • 如果要克隆 Component,则也会克隆它所属的 GameObject(同样可指定可选的位置和旋转)。
  • 克隆 GameObject 或 Component 时,也将克隆所有子对象和组件,它们的属性设置与原始对象相同。
  • 此方法克隆子对象时,也会克隆子对象自己的子对象。为了防止堆栈溢出,Unity限制这种嵌套克隆。如果超过堆栈大小的一半以上,Unity会抛出一个InsufficientExecutionStackException
  • 默认情况下,新对象的父对象 为 null;它与原始对象不"同级”"。但是,仍可以使用transform.SetParent(parent);设置父对象。
  • 如果指定了父对象但未指定位置和旋转,则使用原始对象的位置和旋转作为克隆对象的本地位置和旋转或是其世界位置和旋转。可以通过参数instantiateInWorldSpace指定世界空间还是父节点相对空间。
  • 克隆的GameObject 的活动状态会和原始对象保持一致,因此,如果原始对象处于非活动状态,则克隆对象也会在非活动状态下创建。
  • 对于层级视图中的对象和所有子对象,其每个 Monobehaviour 和 Component 都会仅当它们在层级视图中处于活动状态时,才会调用其 Awake 和 OnEnable 方法。
  • 这些方法不会创建与新实例化对象的预制件连接。可以使用 PrefabUtility.InstantiatePrefab 创建具有预制件连接的对象。这里的PrefabUtility是Editor代码,此处表述的是如果你在编辑器下创建实例对象,如果需要带有预制件连接的需求使用PrefabUtility

运算符

bool

public static implicit operator bool(Object exists);

该对象是否存在?

  • if (GetComponent<Rigidbody>()) 等同于:
    • if (GetComponent<Rigidbody>() == true)
    • if (GetComponent<Rigidbody>() != null)

operator !=

public static bool operator !=(Object x, Object y);

比较两个对象是否引用不同的对象。

operator ==

public static bool operator ==(Object x, Object y);

比较两个对象引用,判断它们是否引用同一个对象。

  • 实例化 GameObject 会将其添加到场景中,因此它已完全初始化 (!destroyed)。实例化一个简单的 UnityEngine.Object 则没有这样的语义,因此它将保持“destroyed”状态,这将导致语句变成 true 与 null 进行比较为true。Debug.Log(new Object()== null); // 返回trueDebug.Log(new GameObject()== null); // 返回false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值