【发布时间】:2021-12-30 09:42:16
【问题描述】:
在我的应用程序中,用户可以将对象放入场景中。每个对象都有一个背景网格,将由程序计算和添加。因此放置的对象被存储为一个元组列表:
public List<Tuple<GameObject, GameObject>> PlacedObjects;
用户还可以得到一个“清除”按钮来删除对象,如下所示:
foreach (var placedObject in PlacedObjects)
{
Destroy(placedObject.Item1);
Destroy(placedObject.Item2);
}
PlacedObjects.Clear();
由于某种原因,Item1 被删除,但 Item2 在场景中仍然可见。我想,一定有一些泄漏或引用阻止了数据被破坏?
无论如何要获得全貌,以下是数据的生成方式。首先,用户可以放置一个项目(从下拉选择中克隆),操作如下:
public void OnPlaceHereButtonPressed()
{
var clone = Instantiate(currentlySelectedObject);
clone.GetComponentInChildren<MeshFilter>().mesh = Instantiate(currentlySelectedObject.GetComponentInChildren<MeshFilter>().mesh);
// Clone the material for each item
Material cloneMat = new Material(currentlySelectedObject.GetComponentInChildren<Renderer>().material);
if (currentlySelectedObject.tag.Equals(paramSphere)) // Spheres get random colors after placing
cloneMat.SetColor("_BaseColor", Random.ColorHSV());
clone.GetComponentInChildren<Renderer>().material = cloneMat;
PlacedObjects.Add(new Tuple<GameObject, GameObject>(clone, null));
SendVirtualObjectsToServer(clone);
SetCameraBackgroundShader(true);
}
Item2 有点复杂,因为它来自服务器的结果数据。其中大部分只是将传入的数据流转换为网格数据:
// this is done for each of the placed objects after getting the result
if (hasReconstrucedData)
{
var reconstructed = new GameObject("Reconstructed Mesh " + i.ToString(), typeof(MeshFilter), typeof(MeshRenderer));
reconstructed.transform.position = new Vector3(0, 0, 0);
reconstructed.transform.localScale = new Vector3(1, -1, 1);
reconstructed.isStatic = true;
Mesh mesh = new Mesh();
// vertices
int vertexBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset += sizeof(int);
mesh.vertices = nativeBuffer.GetSubArray(bufferOffset, vertexBufferSize).Reinterpret<Vector3>(vertexBufferSize / 12).ToArray();
bufferOffset += vertexBufferSize;
// normals
int vertexNormalsBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset += sizeof(int);
mesh.normals = nativeBuffer.GetSubArray(bufferOffset, vertexNormalsBufferSize).Reinterpret<Vector3>(vertexNormalsBufferSize / 12).ToArray();
bufferOffset += vertexNormalsBufferSize;
// colors
int vertexColorsBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset += sizeof(int);
mesh.colors = nativeBuffer.GetSubArray(bufferOffset, vertexColorsBufferSize).Reinterpret<Color>(vertexNormalsBufferSize / 16).ToArray();
bufferOffset += vertexColorsBufferSize;
// triangles
int trianglesBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset += sizeof(int);
mesh.triangles = nativeBuffer.GetSubArray(bufferOffset, trianglesBufferSize).Reinterpret<int>(trianglesBufferSize / 4).ToArray();
bufferOffset += trianglesBufferSize;
// sh probes
int reconstructedProbeBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset += sizeof(int);
// set material and probe texture for reconstructed mesh
Material reconstructedMat = new Material(Shader.Find("Custom/Differential"));
rows = (int)Math.Ceiling((float)reconstructedProbeBufferSize / (float)cols);
recbuffer = new NativeArray<float>(cols * rows, Allocator.TempJob);
// only needed to fill up the complete texture
recbuffer.CopyFrom(nativeBuffer.GetSubArray(bufferOffset, reconstructedProbeBufferSize).Reinterpret<float>(reconstructedProbeBufferSize / 4));
bufferOffset += reconstructedProbeBufferSize;
Texture2D shEnvTexture = new Texture2D(cols, rows, TextureFormat.RFloat, false);
shEnvTexture.LoadRawTextureData(recbuffer);
shEnvTexture.filterMode = FilterMode.Point;
shEnvTexture.wrapMode = TextureWrapMode.Clamp;
shEnvTexture.Apply(updateMipmaps: false);
reconstructedMat.SetTexture("_SHTexture", shEnvTexture);
float[] objectPos = new float[3]
{
PlacedObjects[i].Item1.transform.position.x,
PlacedObjects[i].Item1.transform.position.y,
PlacedObjects[i].Item1.transform.position.z
};
reconstructedMat.SetFloatArray("_ObjectPosition", objectPos);
reconstructedMat.SetFloat("_ObjectScale",
(PlacedObjects[i].Item1.transform.localScale * differentialShaderScaleFactor).magnitude);
reconstructed.GetComponentInChildren<Renderer>().material = reconstructedMat;
reconstructed.GetComponent<MeshFilter>().mesh = mesh;
PlacedObjects[i] = Tuple.Create(PlacedObjects[i].Item1, reconstructed);
}
这些是在列表中添加或删除数据的所有位置。为什么Destroy() 函数对第二项不起作用?
【问题讨论】:
-
@rustyBucketBay 描述中说,强烈建议使用
Destroy()而不是DestroyImmediat()。我会测试一下,但是正常的Destroy()不工作的原因我猜可能会导致一些未来的问题? -
尽管如此,我还是测试了
DestroyImmediat(),但也没有用。也没有将这两个项目分开List<GameObjects>