gpt4 book ai didi

c# - 调用虚拟方法而不是覆盖

转载 作者:太空宇宙 更新时间:2023-11-03 12:10:18 26 4
gpt4 key购买 nike

我有四个类(class),EventAction它们都是基类,然后我有两个子类 Create : EventMoveTo : Action .

Event包含 Action 的列表实例,以及何时Trigger()在 child 里叫Create它叫Event.Trigger() ,循环遍历操作列表,并调用 Action.Run()在调用 Called() 的每个操作上.

我遇到的问题是 virtual正在调用方法而不是 override MoveTo 内部的方法.

[Serializable]
public abstract class Event : MonoBehaviour {
[SerializeField] public List<Action> actions = new List<Action>();

protected void Trigger() {
foreach (Action action in actions) {
action.Run();
}
}
}

事件

public class Create : Event {
void Start() {
Trigger();
}
}

Action

[Serializable]
public class Action {
public virtual void Called() {
Debug.Log("Virtual");
}

public void Run() {
Called();
}
}

移动到

public class MoveTo : Action {
public override void Called() {
Debug.Log("Called");
}
}

我正在添加 MoveTo将 Unity 编辑器中的事件列表操作添加到预制件上。我不确定 unity 如何在运行时处理这些,是在初始化它们还是我呢?我不确定。这可能是导致我的问题的原因......

private Event GetCurrentEvent(){}

void AddActionCallback(Type actionType) {
// actionType is MoveTo
var prefab = GetCurrentPrefabItem().Value;
var evt = GetCurrentEvent();
evt.actions.Add((Action)Activator.CreateInstance(actionType));
Undo.RecordObject(prefab.gameObject, "Added actions");
PrefabUtility.RecordPrefabInstancePropertyModifications(prefab.gameObject);
}

这是我运行游戏之前的样子。它显示MoveTo , 红色列中的按钮显示使用 action.GetType().Name 的操作.这是我运行游戏之前的名字:

before

运行游戏后,按钮现在看起来像这样:

after

运行时:

evt.actions.Add((Action)Activator.CreateInstance(actionType));

编辑器显示类型不匹配,即使 actionType 的输出也是如此和 Activator.CreateInstance(actionType)MoveTo :

type mismatch

最佳答案

Unity does not support built-in polymorphic serialization .

当您保存预制件时,它会将 List 序列化为纯 Action 的列表。 s,并删除所有只有子类的信息 MoveTo有。

来自 Unity docs on serialization :

No support for polymorphism

If you have a public Animal[] animals and you put in an instance of aDog, a Cat and a Giraffe, after serialization, you have three instances of Animal.

One way to deal with this limitation is to realize that it only applies to custom classes, which get serialized inline. References to other UnityEngine.Objects get serialized as actual references, and for those, polymorphism does actually work. You would make a ScriptableObject derived class or another MonoBehaviour derived class, and reference that. The downside of this is that you need to store that Monobehaviour or scriptable object somewhere, and that you cannot serialize it inline efficiently.

The reason for these limitations is that one of the core foundations of the serialization system is that the layout of the datastream for an object is known ahead of time; it depends on the types of the fields of the class, rather than what happens to be stored inside the fields.

这就是为什么它的类显示为 Action 的原因.

但是,它不能序列化为 Action because :

How to ensure a custom class can be serialized

Ensure it:

  • Has the Serializable attribute

  • Is not abstract

  • Is not static

  • Is not generic, though it may inherit from a generic class

Action是一个抽象类,所以它甚至不会正确地部分序列化。我认为这是 Type Mismatch 的根本原因问题,因为 Unity 正在努力反序列化不受支持的内容。

简而言之,如果要序列化MoveTo中的数据, 你需要有一个 [SerializeField] List<MoveTo>为了不丢失信息,或者你可以让 Action 继承自 ScriptableObject ,这带来了自己的问题。

关于c# - 调用虚拟方法而不是覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52653400/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com