我正在Unity中制作一个TicTacToe游戏,但是现在我需要在单击按钮时重新启动它。
public class GlobalCtrl : MonoBehaviour
{
#region variables
/// <summary>
/// the prefab of playerMarkA
/// </summary>
public GameObject playerMarkA;
/// <summary>
/// the prefab of playerMarkB
/// </summary>
public GameObject playerMarkB;
public Camera mainCamera;
public List<GameObject> list = new List<GameObject>();
private int[,] boardStatus = new int[3, 3];
private Vector3[,] boardPos = new Vector3[3, 3];
private Vector3 a;
private Vector3 b;
private Vector3 c;
private Vector3 d;
bool playerChange = true;
bool playerA = false;
bool playerB = false;
bool gameOver = false;
bool tie = false;
public Button m_button;
public Text m_text;
#endregion
/// <summary>
/// Start is called before the first
/// </summary>
void Start()
{
boardPos[0, 0] = new Vector3(-10 / 3, -10 / 3, 0);
boardPos[0, 1] = new Vector3(0, -10 / 3, 0);
boardPos[0, 2] = new Vector3(10 / 3, -10 / 3, 0);
boardPos[1, 0] = new Vector3(-10 / 3, 0, 0);
boardPos[1, 1] = new Vector3(0, 0, 0);
boardPos[1, 2] = new Vector3(10 / 3, 0, 0);
boardPos[2, 0] = new Vector3(-10 / 3, 10 / 3, 0);
boardPos[2, 1] = new Vector3(0, 10 / 3, 0);
boardPos[2, 2] = new Vector3(10 / 3, 10 / 3, 0);
a = new Vector3(-10 / 6, 10 / 6, 0);
b = new Vector3(10 / 6, 10 / 6, 0);
c = new Vector3(-10 / 6, -10 / 6, 0);
d = new Vector3(10 / 6, -10 / 6, 0);
boardStatus[0, 0] = boardStatus[0, 1] = boardStatus[0, 2] =
boardStatus[1, 0] = boardStatus[1, 1] = boardStatus[1, 2] =
boardStatus[2, 0] = boardStatus[1, 0] = boardStatus[0, 0] = 0;
}
// Update is called once per frame
void Update()
{
if(gameOver == false) {
if (Input.GetMouseButtonDown(0))
{
Debug.Log(Input.mousePosition);
Ray _ray = mainCamera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit1;
if (Physics.Raycast(_ray, out hit1))
{
int m = 0;
int n = 0;
if (hit1.point.x < a.x)//left
{
m = 0;
}
else if (hit1.point.x > b.x)//right
{
m = 2;
}
else//middle
{
m = 1;
}
if (hit1.point.y > a.y)//top
{
n = 2;
}
else if (hit1.point.y < c.y)//bottom
{
n = 0;
}
else//middle
{
n = 1;
}
if (playerChange)
{
if (boardStatus[n, m] == 0)
{
list.Add(Instantiate(playerMarkA, transform.position = boardPos[n, m], Quaternion.identity));
boardStatus[n, m] = -1;
playerChange = false;
Debug.Log(boardStatus[n, m]);
winner();
}
}
else
{
if (boardStatus[n, m] == 0)
{
list.Add(Instantiate(playerMarkB, transform.position = boardPos[n, m], Quaternion.identity));
boardStatus[n, m] = 1;
playerChange = true;
Debug.Log(boardStatus[n, m]);
winner();
}
}
}
}
}
}
void winner()
{
if(gameOver)
{
}
if ((boardStatus[0, 0] == -1 && boardStatus[0, 1] == -1 && boardStatus[0, 2] == -1) ||
(boardStatus[1, 0] == -1 && boardStatus[1, 1] == -1 && boardStatus[1, 2] == -1) ||
(boardStatus[2, 0] == -1 && boardStatus[2, 1] == -1 && boardStatus[2, 2] == -1) ||
(boardStatus[2, 0] == -1 && boardStatus[1, 0] == -1 && boardStatus[0, 0] == -1) ||
(boardStatus[2, 1] == -1 && boardStatus[1, 1] == -1 && boardStatus[0, 1] == -1) ||
(boardStatus[2, 2] == -1 && boardStatus[1, 2] == -1 && boardStatus[0, 2] == -1) ||
(boardStatus[2, 0] == -1 && boardStatus[1, 1] == -1 && boardStatus[0, 2] == -1) ||
(boardStatus[2, 2] == -1 && boardStatus[1, 1] == -1 && boardStatus[0, 0] == -1))
{
playerA = true;
}
else if ((boardStatus[0, 0] == 1 && boardStatus[0, 1] == 1 && boardStatus[0, 2] == 1) ||
(boardStatus[1, 0] == 1 && boardStatus[1, 1] == 1 && boardStatus[1, 2] == 1) ||
(boardStatus[2, 0] == 1 && boardStatus[2, 1] == 1 && boardStatus[2, 2] == 1) ||
(boardStatus[2, 0] == 1 && boardStatus[1, 0] == 1 && boardStatus[0, 0] == 1) ||
(boardStatus[2, 1] == 1 && boardStatus[1, 1] == 1 && boardStatus[0, 1] == 1) ||
(boardStatus[2, 2] == 1 && boardStatus[1, 2] == 1 && boardStatus[0, 2] == 1) ||
(boardStatus[2, 0] == 1 && boardStatus[1, 1] == 1 && boardStatus[0, 2] == 1) ||
(boardStatus[2, 2] == 1 && boardStatus[1, 1] == 1 && boardStatus[0, 0] == 1))
{
playerB = true;
}
else
{
tie = true;
}
if (playerA)
{
m_text.text = "Player A wins!";
gameOver = true;
}
else if (playerB)
{
m_text.text = "Player B wins!";
gameOver = true;
}
else if (tie)
{
m_text.text = "Nobody won :(";
//gameOver = true;
}
}
}
然后,我只需要添加功能即可删除游戏对象。我的意思是,当我重新启动游戏时,只应删除游戏对象,但游戏板应保持原样:
所以我尝试了
public void button()
{
for(int i = 0; i < list.Count - 1; i++)
{
var last = list[list.Count - 1];
list.Remove(last);
Destroy(last);
}
}
但是它似乎无法正常工作,因为当我单击以将对象添加到面板中时,该面板不再存在,但是在层次结构窗口中仍然存在添加的对象(在游戏/场景)。
非常感谢您阅读一些答案,谢谢!
答案 0 :(得分:3)
在for
循环中执行此操作很不好,因为您从循环内更改了Count
对象,这或早或晚会使您的迭代索引i
无效。
您宁愿简单地做
// destroy all items
foreach(var item in list)
{
Destroy(item);
}
// then in one call remove all elements from the list
list.Clear();
注意:您的列表为public
。因此,为了确保没有任何因Inspector意外引用而在第一次重置时被删除的内容,您应该在一次清除该列表中
private void Awake()
{
list.Clear();
}
但是,正如已经提到的,简单地重新加载整个场景通常也是一个很好的解决方案。这样,您就不必进行任何重置操作
SceneManager.LoadSceneAsync(SceneManager.GetActiveScene().buildIndex);
顺便说一句,您的示例行可能应该看起来像
Instantiate(playerMarkA, boardPos[n, m], Quaternion.identity);
Instantiate(playerMarkB, boardPos[n, m], Quaternion.identity);