Reputation:
I am making a TicTacToe game in Unity, but now I need to restart it when a button is clicked.
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;
}
}
}
Then I just need to add the function to delete the game objects. I mean when I restart the game, ontly the game objects should be deleted, but the board should stay there as it is:
So I tried this
public void button()
{
for(int i = 0; i < list.Count - 1; i++)
{
var last = list[list.Count - 1];
list.Remove(last);
Destroy(last);
}
}
But it doesn't seem to work properly, because when I click to add an object into the board, the board ceases to exist, but there is still the added objects in the hierarchy window (it's nowhere to be seen in the game/scene).
I'd be really happy to read some of your answers, thanks in advance!
Upvotes: 1
Views: 342
Reputation: 90659
Doing this in a for
loop is bad since you change the Count
of objects from within the loop which sooner or later makes your iteration index i
invalid.
You should rather do simply
// destroy all items
foreach(var item in list)
{
Destroy(item);
}
// then in one call remove all elements from the list
list.Clear();
Note: Your list is public
. So in order to be sure there is nothing referenced by accident from the Inspector which would get deleted on the first reset you should clear the list once in
private void Awake()
{
list.Clear();
}
However as already mentioned it is often also a good solution to simply reload the entire scene. This way you don't have to take care of any resetting yourself
SceneManager.LoadSceneAsync(SceneManager.GetActiveScene().buildIndex);
btw your instantion lines should probably simply look like
Instantiate(playerMarkA, boardPos[n, m], Quaternion.identity);
Instantiate(playerMarkB, boardPos[n, m], Quaternion.identity);
Upvotes: 2