Dan*_*Lip 2 c# unity-game-engine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
using System.Linq;
public class CamerasInfo : MonoBehaviour
{
public List<CinemachineFreeLook> FreeLook;
public List<CinemachineVirtualCamera> Virtual;
public List<Camera> AllCameras;
public List<string> currentActiveCameras;
// Start is called before the first frame update
void Start()
{
Cameras();
}
// Update is called once per frame
void Update()
{
}
public void Cameras()
{
FreeLook = FindObjectsOfType<CinemachineFreeLook>().ToList();
Virtual = FindObjectsOfType<CinemachineVirtualCamera>().ToList();
for(int i = 0; i < Virtual.Count; i++)
{
if (!Virtual[i].name.StartsWith("CM"))
Virtual.RemoveAt(i);
}
AllCameras = Camera.allCameras.ToList();
foreach (CinemachineFreeLook freelook in FreeLook)
{
if (freelook.isActiveAndEnabled)
currentActiveCameras.Add(freelook.Name);
}
foreach (CinemachineVirtualCamera vir in Virtual)
{
if (vir.isActiveAndEnabled)
currentActiveCameras.Add(vir.Name);
}
for(int i = 0; i < AllCameras.Count; i++)
{
if (AllCameras[i].isActiveAndEnabled)
currentActiveCameras.Add(AllCameras[i].name);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,这部分有 8 个摄像头在虚拟监听:
for(int i = 0; i < Virtual.Count; i++)
{
if (!Virtual[i].name.StartsWith("CM"))
Virtual.RemoveAt(i);
}
Run Code Online (Sandbox Code Playgroud)
但它只删除了 3 个摄像头而不是 6 个。最后我应该只留下两个以 CM 开头的摄像头,但在编辑器中有 5 个摄像头:
它不会删除底部顶部和中间:
问题是您正在遍历列表,同时还从中删除项目。
让我们举个例子
0 1 2
[TopRig, TopRig, CM]
Run Code Online (Sandbox Code Playgroud)
我们进入for循环,i = 0。我们查看元素 0,即TopRig,因此我们调用.RemoveAt(0)。我们的名单现在是:
0 1
[TopRig, CM]
Run Code Online (Sandbox Code Playgroud)
我们现在进入for循环的下一次迭代,并且i增量为 1。我们查看(修改后的)列表的元素 1,并看到它是CM。
看到问题了吗?我们直接跳过了第二个TopRig,因为我们从列表中删除了一个元素(导致所有后续元素向后移动),并且还 increment i。我们需要确保我们只递增i,如果我们不从列表中删除一个项目:
for (int i = 0; i < Virtual.Count; /* no increment */)
{
if (!Virtual[i].name.StartsWith("CM"))
Virtual.RemoveAt(i);
else
i++;
}
Run Code Online (Sandbox Code Playgroud)
或考虑到它会增加的事实:
for (int i = 0; i < Virtual.Count; i++)
{
if (!Virtual[i].name.StartsWith("CM"))
{
Virtual.RemoveAt(i);
i--;
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以向后遍历列表,从而回避问题:
for (int i = Virtual.Count - 1; i >= 0; i--)
{
if (!Virtual[i].name.StartsWith("CM"))
Virtual.RemoveAt(i);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50 次 |
| 最近记录: |