如何在Unity检视器中引用静态函数

huangapple go评论82阅读模式
英文:

How to reference static functions in Unity inspector

问题

我有一个可编写脚本的对象类 Attack,并从中创建了一些资产。

在 Attack 资产检视器中,我想能够引用其他类的静态函数,以便在发生某些事件时,可以获取 Attack 中引用的该静态函数并执行它。

这是否可能?


我尝试过一个名为 UltEvents 的资产(声称可以完成此任务),但似乎在最新的 Unity LTS 版本中无法正常工作。

英文:

I have a scriptable object class Attack and created some assets from it.

In the Attack asset inspector, I want to be able to reference static functions from other classes, so when something happens, I can grab this static function referenced in Attack and execute it.

Is that possible?


I tried an asset called UltEvents (which claims to get this task done) but it didn't seem work in the newest Unity LTS.

答案1

得分: 1

UnityEvent 应该可以工作,以下是一个示例。

像往常一样添加一个 UnityEvent 属性。静态的 RunTest 方法是回调,TestCallback 用于调用事件。

[CreateAssetMenu(menuName = "Attack")]
public class Attack : ScriptableObject
{
    public UnityEvent callback;

    public static void RunTest()
    {
        Debug.Log("Run Test");
    }

    public void TestCallback()
    {
        callback?.Invoke();
        Debug.Log("TestCallback");
    }
}

要在检视器中选择回调,有两种情况:

  1. 如果有与回调相关联的资源/实例,例如在 Attack 类中定义了它,那么脚本化对象的实例就是资源,您可以直接从检视器中选择回调。

    如何在Unity检视器中引用静态函数

  2. 如果没有资源/实例,您需要将检视器切换到调试模式并手动填充回调,参见第二张截图。请注意以下字段:Target AssemblyMethod NameModeCall State。如果回调需要参数,您还应该填写一个 Arguments 字段中的参数。

    如何在Unity检视器中引用静态函数

现在,如果一切正常,当您调用 TestCallback 时,您应该在控制台中看到 "Run Test"。


备选方案1

第二种解决方案似乎有点巧妙,您可以以自定义的方式模仿它:

[Serializable]
public class MyStaticCallback
{
    public string TypeName, MethodName;
    private Action _callback;

    public void Invoke()
    {
        _callback ??= (Action)Delegate.CreateDelegate(typeof(Action),
            Type.GetType(TypeName), MethodName);
        _callback?.Invoke();
    }
}

public class Attack : ScriptableObject
{
    public MyStaticCallback callback;
}

备选方案2

由于回调是静态的,您可以通过为每种回调类型定义派生类来以静态方式解决此问题。

public class Attack1 : Attack
{
    public override void RunCallback() => AnyType.AnyStaticMethod();
}
英文:

UnityEvent should work, here's an example.

Add a UnityEvent property as usual. The static RunTest method is the callback, the TestCallback is used to invoke the event.

[CreateAssetMenu(menuName = "Attack")]
public class Attack : ScriptableObject
{
	public UnityEvent callback;

	public static void RunTest()
	{
		Debug.Log("Run Test");
	}

	public void TestCallback()
	{
		callback?.Invoke();
		Debug.Log("TestCallback");
	}
}

To select the callback in the inspector, there are 2 situations:

  1. You have an asset/instance associated with the callback, in this example because I define it in the Attack class, the instantiated scriptable object is the asset, you can directly select the callback from the inspector.

    如何在Unity检视器中引用静态函数

  2. You don't have an asset/instance, you need to switch the inspector to the debug mode and manually populate the callback, see the 2nd screenshot. Pay attention to these fields: Target Assembly, Method Name, Mode, Call State. If the callback needs an argument, you should also fill in one of the Arguments field.

    如何在Unity检视器中引用静态函数

Now if everything is OK, you can see "Run Test" in the console when you call TestCallback.


Alternative 1

The 2nd solution seems like a trick, you can imitate it in a customized way:

[Serializable]
public class MyStaticCallback
{
	public string TypeName, MethodName;
	private Action _callback;

	public void Invoke()
	{
		_callback ??= (Action)Delegate.CreateDelegate(typeof(Action),
			Type.GetType(TypeName), MethodName);
		_callback?.Invoke();
	}
}

public class Attack : ScriptableObject
{
	public MyStaticCallback callback;
}

Alternative 2

Since the callback is static, you can solve this problem in a static way by defining derived classes for each kind of callbacks.

public class Attack1 : Attack
{
    public override void RunCallback() => AnyType.AnyStaticMethod();
}

huangapple
  • 本文由 发表于 2023年6月22日 13:58:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76528945.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定