Unity:获取或添加组件的通用方法

时间:2016-08-10 21:32:29

标签: c# generics unity3d

每次我在Unity中创建一个新脚本时,我总是会对我的脚本所依赖的任何组件进行一系列检查,例如:

SpriteRenderer sr = gameObject.GetComponent<SpriteRenderer>();

if(sr == null)
      sr = gameObject.AddComponent<SpriteRenderer>() as SpriteRenderer;

所以我决定使用任何Component来制作一个通用方法,然后我想出了以下代码,我只是添加到我自己的新脚本中。

  T GetOrAddComponent<T>() where T : Component
    {
        T component = gameObject.GetComponent<T>();

        if (component == null)     
            component = gameObject.AddComponent<T>() as T;

        return component;

    }

我已经尝试了,功能运行良好,但我想知道这种方法是否有任何重大缺点,或者是否有其他更好的方法来完成相同的任务,可能使用现有方法我是不知道或以其他方式创建方法。

4 个答案:

答案 0 :(得分:2)

GetComponent方法实际上对系统非常重要。如果您正在开发移动设备,其中太多可能会导致加载时间明显滞后。

我个人使用RequireComponent方法。然后,脚本会在添加到GameObject时自动添加组件。然后,我将手动将组件的名称拖到检查器中脚本对象上的字段中。

示例:

using UnityEngine;

// PlayerScript requires the GameObject to have a RigidBody component
[RequireComponent (typeof (RigidBody))]
public class PlayerScript : MonoBehavior {
    [SerializeField]
    private RigidBody rb;
...
}

答案 1 :(得分:0)

首先,我建议您使用“ RequireComponent”:

[RequireComponent(typeof(SpriteRenderer))]
[RequireComponent(typeof(AnotherComponent))]
public class NetworkService : MonoBehaviour
{ 
   private SpriteRenderer _sRenderer;

   //strong way to never get a null reference.
   #if UNITY_EDITOR
   private void OnValidate()
   {
       if (null == _sRenderer)
           _sRenderer = GetComponent<_sRenderer>();
   }

   #endif

每次在编辑器中更改参数值或加载脚本/组件时,将执行“ OnValidate” method

答案 2 :(得分:0)

public static void GetOrAddComponent<T>(this GameObject model, Action<T> onSucess) where T: Component {
    onSucess(model.GetComponent<T>() ?? model.AddComponent<T> () as T);
}

答案 3 :(得分:-1)

如果您愿意,可以在一个if语句中完成所有操作:

SpriteRenderer sr;

if(gameObject.GetComponent<SpriteRenderer>())
    sr = gameObject.GetComponent<SpriteRenderer>();
else
    sr = gameObject.AddComponent<SpriteRenderer>() as SpriteRenderer;

您可能会进行两次GetComponent调用,但如果您更喜欢代码结构,那就这样吧。我个人认为你这样做的方式最好。

虽然更简洁,但您可以直接返回组件,而不必将其存储在变量component

public T GetOrAddComponent<T>() where T : Component
{
    if (gameObject.GetComponent<T>())
        return gameObject.GetComponent<T>();
    else     
        return gameObject.AddComponent<T>() as T;
}

只要您在场景加载或start功能中执行此操作,就不会有任何性能差异。