首页 > 解决方案 > 是否可以从字符串中调用 ac# 函数?

问题描述

我有一个 inv 系统,您可以在其中创建项目并为它们提供脚本以在满足某些条件时执行。问题是我尝试使用 UnityEvents,但我对项目使用了 Scriptable 对象,所以我不能只调用运行时函数。然后,我尝试使用一个空的游戏对象来保存所有项目脚本,基本上,如果你给出项目脚本的名称,inv 系统将调用项目脚本上的一个函数。但问题是我不能只将字符串转换为可以调用函数的类。

所以经过很长时间我想出了这个

try
{
  // scriptHolder = the gameobject where all the item scripts are
  Type type = scriptHolder.GetComponent(ondrop[i]).GetType();
  object instance = Activator.CreateInstance(type);
  type.GetMethod("onDropInv").Invoke(instance, null);
}
catch { }

但问题是我需要在统一使用的脚本的当前实例上调用该函数。所以我尝试了最后 24 小时,现在我放弃了。我只是想不出任何解决方案或替代方案。

标签: c#unity3d

解决方案


不停!

您正在创建一个新实例,Activator只是使用它来调用一个方法?

使用 ! 后,您已经有了组件的实例GetComponent

此外,“不允许”(您仍然可以这样做,但会收到警告和意外行为)创建MonoBehaviour/ ComponentusingnewActivator!的新实例


UnityEvent我不完全了解您的用例,或者如果您愿意这样做,为什么您不能使用。

但是您看起来(至少)有以下两个选项:

利用GameObject.SendMessage

调用此游戏对象methodName中每个命名的方法。MonoBehaviour

像例如

// scriptHolder = the gameobject where all the item scripts are
scriptHolder.SendMessage("onDropInv");

但是,这仅在方法名称实际上是动态的并且您事先不知道时才有意义。

接口或基类

在您的情况下,您似乎无论如何都对方法名称进行了硬编码,因此只需确保所有相应的组件都实现了该接口,例如

public interface IOnDropInv
{
    public void onDropInv();
}

像例如

public ExampleDropInv : MonoBehaviour, IOnDropInv
{
    public void onDropInv ()
    {
        Debug.Log("Hello there!");
    }
}

然后简单地做

scriptHolder.GetComponent<IOnDropInv>().onDropInv();

或者它们都继承自某个基类,例如

public abstract class BaseDropInv : MonoBehaviour
{
    public abstract void onDropInv ();
}

喜欢

public class ExampleDropInv : BaseDropInv
{
    public override void onDropInv ()
    {
        Debug.Log("Hello there!");
    }
}

然后做

scriptHolder.GetComponent<BaseDropInv>().onDropInv();

推荐阅读