英文:
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");
}
}
要在检视器中选择回调,有两种情况:
-
如果有与回调相关联的资源/实例,例如在
Attack
类中定义了它,那么脚本化对象的实例就是资源,您可以直接从检视器中选择回调。 -
如果没有资源/实例,您需要将检视器切换到调试模式并手动填充回调,参见第二张截图。请注意以下字段:
Target Assembly
、Method Name
、Mode
、Call State
。如果回调需要参数,您还应该填写一个Arguments
字段中的参数。
现在,如果一切正常,当您调用 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:
-
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. -
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 theArguments
field.
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();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论