我有一个脚本来生成一个定制的复合网格。但是,当用户编辑生成复合网格的脚本的属性时,我想删除前面创建的网格。为了实现这一点,我必须遵循以下脚本:
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:用于从编辑器事件中销毁对象的协同机制。
如果需要更多的信息,让我知道,以便我可以澄清!
发布于 2018-11-24 16:19:07
这个问题来自于WaitForEndOfFrame。不完全确定为什么,但似乎此操作在编辑器模式下不会返回,而不是在播放模式中。
如果你用yield return null代替,它应该达到同样的效果。
对于执行顺序图中的其他人来说,答案可能是显而易见的:flowchart.svg
https://stackoverflow.com/questions/53459658
复制相似问题