【问题标题】:Gameobject destroy fails inside destructor游戏对象销毁在析构函数内失败
【发布时间】:2020-10-24 09:28:00
【问题描述】:

我有一个对象,其中包含一个游戏对象列表。我希望在其析构函数中销毁所有这些游戏对象。

但是,当我尝试从析构函数内部调用 GameObject.Destroy() 时,它似乎停止执行(GameObject.Destroy() 之后的行从不执行,但它之前的行执行)

如果我将完全相同的代码复制并粘贴到一个名为 not_a_destructor() 的函数中并调用它,它会完美运行。是什么赋予了?我已经让它工作了,但我真的很想了解发生了什么。

析构函数和 not_a_destructor() 代码:

    // Destructor DOES NOT work
    ~MoveAction(){
        for(int i = 0; i < arrows.Count; i++){
            Debug.Log("wasd");
            GameObject.Destroy(arrows[i]);
            Debug.Log("asdf");
        }
    }

    // Identical code, calling not_a_destructor() works perfectly
    public void not_a_destructor(){
        for(int i = 0; i < arrows.Count; i++){
            Debug.Log("PRETEND DESTRUCTOR!");
            GameObject.Destroy(arrows[i]);
            Debug.Log("GameObject destroyed successfully");
        }
    }

根据 cmets 的要求,该类的完整副本:

public class Action
{
    public int type;
    public string debug_string;
    public GameObject ui_pill; // Only present for Actions created on the client
}

public class MoveAction : Action
{
    public int type = ActionType.MOVE;
    public MapHex origin;
    public List<MapHex> route; // Intermediate hexes travelled through during the move (includes target_hex)
    public Fleet fleet;
    private List<GameObject> arrows = new List<GameObject>(); // Arrows for the graphical representation of the pending move on the tactical map

    public MapHex target_hex {
        get {
            return route[route.Count - 1];
        }
    }
    public string debug_string {
        get {
            return "MOVE ACTION WITH FLEET: " + fleet.name;
        }
    }
    public MoveAction(Fleet _fleet, List<MapHex> _route){
        fleet = _fleet;
        route = _route;
        origin = fleet.planned_position;
        update_arrows_from_route();
    }

    public void update_arrows_from_route(){
        Material default_material = new Material(Shader.Find("Sprites/Default"));
        // Create one arrow for every hex we will pass through.
        MapHex last = fleet.planned_position;
        foreach (MapHex hex in route){
            // Create arrow from last to hex
            GameObject arrow_gameobj = new GameObject();
            arrow_gameobj.name = "move_order_arrow";
            LineRenderer line_renderer = arrow_gameobj.AddComponent<LineRenderer>();
            line_renderer.material = default_material;
            line_renderer.SetColors(fleet.owner.color, fleet.owner.color);
            line_renderer.positionCount = 2;
            arrow_gameobj.layer = layers.tactical_map;

            Vector3[] line_points = new Vector3[]{last.position, hex.position};
            line_renderer.SetPositions(line_points);
            line_renderer.startWidth = 0.1f;
            line_renderer.endWidth = 0.1f;
            arrows.Add(arrow_gameobj);

            last = hex;
        }
    }

    public void not_a_destructor(){
        for(int i = 0; i < arrows.Count; i++){
            Debug.Log("PRETEND DESTRUCTOR!");
            GameObject.Destroy(arrows[i]);
            Debug.Log("GameObject destroyed successfully");
        }
    }

    ~MoveAction(){
        for(int i = 0; i < arrows.Count; i++){
            Debug.Log("wasd");
            GameObject.Destroy(arrows[i]);
            Debug.Log("asdf");
        }
    }

【问题讨论】:

  • 你的 ~MoveAction() 析构函数缺少一个结束的 '}`,这只是一个复制粘贴问题吗?
  • 很好,但是是的,只是复制+粘贴问题。我已经更新了问题
  • GameObject.Destroy() 有什么作用?我相信终结器/析构函数是单线程的,可能是死锁..
  • 它似乎只是停止,没有错误或任何东西。所以死锁符合症状,但它是我正在破坏的非常简单的游戏对象。它只包含一个 LineRenderer,我不知道如何破坏它会导致死锁。
  • 一般来说,除非绝对必要,否则应避免在 C# 中使用终结器。除了不知道它们何时运行之外,它们还可能导致性能下降,因为垃圾收集器必须以不同于常规对象的方式处理具有终结器的对象(有关更多要点,请参阅类似这样的文章:viva64.com/en/b/0437

标签: c# unity3d destructor


【解决方案1】:

使用更多的 Unity 和更少的 C# 可能是最好的,有一个称为 OnDestroy() 的很好的回调,它将是销毁所有箭头的好地方。如果你的统一代码的执行依赖于对某个东西运行终结器,这是一种非常强烈的代码气味。

除非您以需要在终结器中执行操作的方式使用 IO(可能是诸如释放 IO 资源之类的事情),否则最好将它们留空,并将 Unity 代码放入 Unity 回调中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    • 2012-12-06
    相关资源
    最近更新 更多