Unity - 通过编辑器引用传递脚本,在运行时将其实例化为对象

时间:2018-06-06 20:51:08

标签: c# unity3d

所以基本上我想结束几个游戏对象,每个对象都有很少的.cs脚本和monobehaviour。 (每个对象上的不同脚本集)

拥有技能的角色派对

每个角色的脚本可能会随时间而变化

字符学习新技能/放弃旧

因此,当游戏开始时,我想在运行时动态地将脚本附加到对象

基于技能树中的玩家决策

如果不使用反射,我怎么能这样做?

编辑:我似乎找到了如何让它在没有反射的情况下工作的解决方案

public class TestSkill : MonoBehaviour {}

public class TestFireball : TestSkill {}
public class TestMeleeAttack : TestSkill {}

public class TestSkillBook : MonoBehaviour {

    public MonoScript script;

    void Start () {

        System.Type t = script.GetClass();

        TestSkill skill = gameObject.AddComponent(t) as TestSkill;

    }

}

2 个答案:

答案 0 :(得分:2)

  

我想在运行时动态地将脚本附加到对象。

AddComponent函数用于将脚本附加到GameObjects。

你的对象

public GameObject yourgameObject;

将脚本附加到它:

yourgameObject.AddComponent<YourScript>();

修改

  

问题是,我不知道它是MyScript1还是MyScript2。一世   不希望它被硬编码,但可以通过编辑器/游戏UI进行修改。

我认为您正在寻找可以AddComponent作为参数的string。 曾经有一个像this

public Component AddComponent(string className);

但几年前它被弃用了。我去年创建了一个名为AddComponentExt的新扩展方法,你可以得到它here。它可以像这样使用:

yourgameObject.AddComponentExt<"YourScript">();

即使脚本尚不存在,您也可以添加脚本。在这种情况下,您将获得运行时错误而不是编译时错误。

  

如果不使用反射,我怎么能这样做呢?

,如果没有反射就不能这样做,因为它还不存在。这就是反射的用途。

答案 1 :(得分:0)

因为这不符合程序员回答的评论,一些例子并澄清你能做什么/必须做什么:

// The component to add
public class B : MonoBehaviour
{
    public void TestCall()
    {
        Debug.Log("Success");
    }
}




public class A : MonoBehaviour
{
    public string ToAddName = "B";

    private void Start()
    {
        System.Type t = System.Type.GetType(ToAddName);
        AddComponent(t);    // This does successfully add the component (assuming it exists)

        Debug.Log(t.GetType());    // This will give out "System.MonoType"

        // This doesn't work since it is not known that this is actually "B", not "MonoScript"
        GetComponent(t).TestCall();

        // What is possible is this, requires hardcoding the method name though:
        System.Reflection.MethodInfo mI = t.GetMethod("TestCall");
        var c = GetComponent(t);
        mI.Invoke(c, null);    // null because "TestCall" doesn't take params
    }
}

这并不是一个真正的解决方案,我宁愿说可能有一种(更好的)方法来设置整个构造,以便你根本没有这个问题。