在编辑模式统一中不会调用协程功能

问题描述 投票:0回答:1

我有一个生成自定义复合网格的脚本。但是当用户编辑生成复合网格的脚本的属性时,我想删除先前创建的网格。我必须按照脚本来完成这个:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class BasicVoidVisualizationProperties : MonoBehaviour {

    public Vector3 Dimensions;
    public float Thickness;
    public float Spacing;

    private GameObject[] Corners = new GameObject[8];
    private EdgeBuilder[] Edges = new EdgeBuilder[12];

    // Use this for initialization
    void Start () {
        for (int i = 0; i < Corners.Length; i++)
        {
            Corners[i] = Instantiate(Resources.Load("cube") as GameObject);
            Corners[i].transform.SetParent(this.transform);
        }
        RebuildCorners(Corners, Dimensions, Thickness);
        for (int i = 0; i < Edges.Length; i++)
        {
            Edges[i] = new EdgeBuilder(this.transform);
        }
        RebuildEdges(Edges, Corners);
    }

    // Update is called once per frame
    void Update () {

    }

    private void RebuildCorners(GameObject[] Corners, Vector3 Dimensions, float Thickness)
    {
        Corners[0].transform.localScale = new Vector3(Thickness, Thickness, Thickness);
        Corners[0].transform.position = this.transform.position + new Vector3(Thickness/2, Thickness /2, Thickness/2);
        Corners[1].transform.localScale = new Vector3(Thickness, Thickness, Thickness);
        Corners[1].transform.position = this.transform.position + new Vector3(Dimensions.x - Thickness /2, Thickness /2, Thickness/2);
        Corners[2].transform.localScale = new Vector3(Thickness, Thickness, Thickness);
        Corners[2].transform.position = this.transform.position + new Vector3(Dimensions.x - Thickness /2, Thickness/2, Dimensions.z - Thickness /2);
        Corners[3].transform.localScale = new Vector3(Thickness, Thickness, Thickness);
        Corners[3].transform.position = this.transform.position + new Vector3(Thickness/2, Thickness/2, Dimensions.z - Thickness /2);
        Corners[4].transform.localScale = new Vector3(Thickness, Thickness, Thickness);
        Corners[4].transform.position = this.transform.position + new Vector3(Thickness/2, Dimensions.y - Thickness/2, Thickness/2);
        Corners[5].transform.localScale = new Vector3(Thickness, Thickness, Thickness);
        Corners[5].transform.position = this.transform.position + new Vector3(Dimensions.x - Thickness /2, Dimensions.y - Thickness/2, Thickness/2);
        Corners[6].transform.localScale = new Vector3(Thickness, Thickness, Thickness);
        Corners[6].transform.position = this.transform.position + new Vector3(Dimensions.x - Thickness /2, Dimensions.y - Thickness/2, Dimensions.z - Thickness /2);
        Corners[7].transform.localScale = new Vector3(Thickness, Thickness, Thickness);
        Corners[7].transform.position = this.transform.position + new Vector3(Thickness/2, Dimensions.y - Thickness/2, Dimensions.z - Thickness /2);
    }

    private void RebuildEdges(EdgeBuilder[] Edges, GameObject[] Corners)
    {
        Edges[0].RebuildEdge(Corners[0].transform.position, Corners[1].transform.position, Thickness, Spacing, Direction.right);
        Edges[1].RebuildEdge(Corners[3].transform.position, Corners[2].transform.position, Thickness, Spacing, Direction.right);
        Edges[2].RebuildEdge(Corners[4].transform.position, Corners[5].transform.position, Thickness, Spacing, Direction.right);
        Edges[3].RebuildEdge(Corners[7].transform.position, Corners[6].transform.position, Thickness, Spacing, Direction.right);

        Edges[4].RebuildEdge(Corners[0].transform.position, Corners[4].transform.position, Thickness, Spacing, Direction.up);
        Edges[5].RebuildEdge(Corners[1].transform.position, Corners[5].transform.position, Thickness, Spacing, Direction.up);
        Edges[6].RebuildEdge(Corners[2].transform.position, Corners[6].transform.position, Thickness, Spacing, Direction.up);
        Edges[7].RebuildEdge(Corners[3].transform.position, Corners[7].transform.position, Thickness, Spacing, Direction.up);

        Edges[8].RebuildEdge(Corners[0].transform.position, Corners[3].transform.position, Thickness, Spacing, Direction.forward);
        Edges[9].RebuildEdge(Corners[1].transform.position, Corners[2].transform.position, Thickness, Spacing, Direction.forward);
        Edges[10].RebuildEdge(Corners[4].transform.position, Corners[7].transform.position, Thickness, Spacing, Direction.forward);
        Edges[11].RebuildEdge(Corners[5].transform.position, Corners[6].transform.position, Thickness, Spacing, Direction.forward);
    }

    void OnValidate()
    {
        if(Corners[0] != null) RebuildCorners(Corners, Dimensions, Thickness);
        if(Corners[0] != null && Edges[0] != null)
        {
            foreach (var edge in Edges)
            {
                foreach (var eb in edge.EdgeBlocks)
                {
                    StartCoroutine(DestroyEdgeElement(eb));
                }
            }
            RebuildEdges(Edges, Corners);
        }
    }

    private IEnumerator DestroyEdgeElement(GameObject go)
    {
        yield return new WaitForEndOfFrame();
        Debug.Log("DESTROYED");           // IS NEVER CALLED (never logs to console)
        DestroyImmediate(go);
    }

    private class EdgeBuilder
    {
        private Transform Parent;
        public List<GameObject> EdgeBlocks = new List<GameObject>();

        public EdgeBuilder(Transform parent)
        {
            Parent = parent;
        }

        private List<GameObject> CalculateEdgeBlocks(Vector3 origin, Vector3 end, float thickness, float spacing)
        {
            List<GameObject> elements = new List<GameObject>();
            var dist = Vector3.Distance(origin, end) - thickness;
            var blocks = (int)Mathf.Round((dist - (thickness + spacing * 2)) / (thickness + spacing));
            for (int i = 0; i < blocks; i++)
            {
                var el = Instantiate(Resources.Load("cube") as GameObject);
                el.transform.localScale = new Vector3(thickness, thickness, thickness);
                el.transform.SetParent(Parent);
                elements.Add(el);
            }

            return elements;
        }

        public void RebuildEdge(Vector3 origin, Vector3 end, float thickness, float spacing, Direction dir)
        {
            // if(EdgeBlocks.Count > 0) ClearEdge(); 
            EdgeBlocks = CalculateEdgeBlocks(origin, end, thickness, spacing);

            if (dir == Direction.up)
            {
                var firstEl = new Vector3(origin.x, origin.y + thickness + spacing, origin.z);
                foreach (var el in EdgeBlocks)
                {
                    el.transform.position = firstEl;
                    firstEl += new Vector3(0, thickness + spacing, 0);
                }
            }
            else if(dir == Direction.right)
            {
                var firstEl = new Vector3(origin.x + thickness + spacing, origin.y, origin.z);
                foreach (var el in EdgeBlocks)
                {
                    el.transform.position = firstEl;
                    firstEl += new Vector3(thickness + spacing, 0, 0);
                }
            }
            else if(dir == Direction.forward)
            {
                var firstEl = new Vector3(origin.x, origin.y, origin.z + thickness + spacing);
                foreach (var el in EdgeBlocks)
                {
                    el.transform.position = firstEl;
                    firstEl += new Vector3(0, 0, thickness + spacing);
                }
            }
        }

        // private void ClearEdge()
        // {
        //  foreach (var eb in EdgeBlocks)
        //  {
        //      DestroyImmediate(eb, true);
        //  }
        //  EdgeBlocks.Clear();
        // }
    }

    private enum Direction
    {
        up,
        right,
        forward 
    }
}

我一直存在的问题是从未调用过Debug.log("Destroyed");(我没看到Debug.log执行)。为什么会这样?

为什么使用你可能会问的协程,请参阅下面的链接,了解我使用协程的原因:Coroutine to destroy object from editor event

如果需要更多信息,请告诉我,以便我澄清!

c# oop unity3d coroutine
1个回答
1
投票

问题来自WaitForEndOfFrame。对于原因并不完全有信心,但似乎在编辑器模式下此操作不会返回,而不是处于播放模式。

如果你改用yield return null,它应该达到同样的效果。

答案可能对执行顺序图表中的其他人显而易见:https://docs.unity3d.com/uploads/Main/monobehaviour_flowchart.svg

© www.soinside.com 2019 - 2024. All rights reserved.