首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在编辑模式下不调用协同函数

在编辑模式下不调用协同函数
EN

Stack Overflow用户
提问于 2018-11-24 15:29:38
回答 1查看 523关注 0票数 1

我有一个脚本来生成一个定制的复合网格。但是,当用户编辑生成复合网格的脚本的属性时,我想删除前面创建的网格。为了实现这一点,我必须遵循以下脚本:

代码语言:javascript
复制
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,您可能会问,请参阅下面的链接,以了解为什么我使用coroutine:用于从编辑器事件中销毁对象的协同机制

如果需要更多的信息,让我知道,以便我可以澄清!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-24 16:19:07

这个问题来自于WaitForEndOfFrame。不完全确定为什么,但似乎此操作在编辑器模式下不会返回,而不是在播放模式中。

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

对于执行顺序图中的其他人来说,答案可能是显而易见的:flowchart.svg

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53459658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档