我在 Unity 中練習 C# 串列,但遇到了問題。我的測驗腳本實體化了 5 個添加到游戲物件串列中的預制件。然后我撰寫了一個生成隨機整數的代碼,并從該數字移動使用該索引(indexof)實體化的預制件。一切正常,但移動和洗掉預制件的方法對場景中的所有游戲物件重復,其索引高于所選的一個。我附上這兩個腳本以更好地解釋問題。(我只需要執行一次 unlist 方法。
如何解決此問題并一次從串列中洗掉一項?(每次按下按鈕時,都不是現在這樣。謝謝)
腳本:
- NpcController:在每個實體化的預制件中添加
- ListCOntroller:添加到場景中。
public class ListCOntroller : MonoBehaviour
{
public GameObject cubePrefab;
private GameObject cubeInstance;
public static List<GameObject> cubeList = new List<GameObject> ();
public TextMeshProUGUI checkText;
public static event Action chooseNpc;
public static int randNpcValue;
int rand;
private void Start()
{
for(int i =0; i < 5; i )
{
cubeInstance = Instantiate(cubePrefab, new Vector3(i, -2, 0), Quaternion.identity);
cubeList.Add(cubeInstance);
}
}
public void CheckListText()
{
checkText.text = "Npc in list: " cubeList.Count.ToString();
}
public static void SelectRandomCube()
{
randNpcValue = Random.Range(0, cubeList.Count);
chooseNpc?.Invoke();
}
}
公共類 NpcController : MonoBehaviour {
void Start()
{
ListCOntroller.chooseNpc = NpcEvent;
}
private void NpcEvent()
{
if (ListCOntroller.cubeList.IndexOf(gameObject) == ListCOntroller.randNpcValue)
{
transform.localPosition = new Vector3(transform.position.x, 2, 0);
DeleteFromList();
}
}
private void DeleteFromList()
{
ListCOntroller.cubeList.RemoveAt(ListCOntroller.randNpcValue);
Debug.Log($"Delete from list: {ListCOntroller.randNpcValue}");
}
}
附圖中生成的 int 亂數為:2


uj5u.com熱心網友回復:
因為事件是一個接一個地執行的。
假設您有 3 個 NPC:NPC0, NPC1, NPC2
現在您選擇的亂數為 1,當 NPC1NpcEvent運行時,ListCOntroller.cubeList.IndexOf(gameObject)為 1 等于randNpcValue,然后 NPC1 將從串列中洗掉。
請注意,現在串列還剩下 2 個專案:NPC0, NPC2. Next NPC2 的NpcEventruns 依次運行,此時ListCOntroller.cubeList.IndexOf(gameObject)仍然為1,因為串列中只有2 個專案,所以NPC2 也從串列中洗掉。
一個解決方案是您可以在randNpcValue移除 NPC 時將其更改為無效值。
if (ListCOntroller.cubeList.IndexOf(gameObject) == ListCOntroller.randNpcValue)
{
transform.localPosition = new Vector3(transform.position.x, 2, 0);
DeleteFromList();
ListCOntroller.randNpcValue = -2;
}
uj5u.com熱心網友回復:
除了這個答案之外,我并沒有真正看到將邏輯混合到兩個不同腳本中的目的。
您有一個用于存盤串列并引發事件,而另一個用于偵聽事件并操作存盤的串列->這聽起來不對。
您也可以簡單地做`為什么不首先將相應的物件傳遞給事件,而是做類似的事情
public class ListCOntroller : MonoBehaviour
{
// Singleton instance
private static ListCOntroller _instance;
// Read-only getter
public static ListCOntroller Instance => _instance;
// pass in the target object reference instead of doing things index based
public event Action<GameObject> chooseNpc;
public GameObject cubePrefab;
// THIS is the list controller -> nobody else should be able to manipulate this list
private readonly List<GameObject> cubeList = new ();
public TextMeshProUGUI checkText;
private void Awake()
{
if(_instance && _instance != this)
{
Destroy(this);
return;
}
_instance = this;
}
private void Start()
{
for(int i =0; i < 5; i )
{
cubeInstance = Instantiate(cubePrefab, new Vector3(i, -2, 0), Quaternion.identity);
cubeList.Add(cubeInstance);
}
}
public static void SelectRandomCube()
{
if(cubeList.Count == 0)
{
Debug.LogWarning("Trying to pick item from empty list");
return;
}
var randomIndex = Random.Range(0, cubeList.Count);
var randomItem = cubeList[randomIndex];
// remove from the list yourself instead of relying on others to work correctly
cubeList.RemoveAt(randomIndex);
// pass along the target object
chooseNpc?.Invoke(randomItem);
}
}
接著
public class NpcController : MonoBehaviour
{
void Start()
{
ListCOntroller.Instance.chooseNpc = NpcEvent;
}
private void NpcEvent(GameObject target)
{
// check if you are the target object
if (target == gameObject))
{
// adjust your position - you don't care about other NPCs or the existence of a list
transform.localPosition = new Vector3(transform.position.x, 2, 0);
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/533280.html
標籤:C#unity3d
下一篇:多個碰撞同時發生
