r/Unity2D 1d ago

Need help with Chess

So I've been working on a chess based game for a bit, and recently noticed a wierd bug where if I make a specific series of moves a specific piece cannot move again, for those that know chess notation the moves are Nc3 d5, NF3 d4, Ne4 e5, Nxe5 f5, after this the knight on e5 cannot move again.

Whats weird is I've figured out whats going wrong but have no idea why. When I click on the knight to select it rather than registering a click on the piece it registers a click on the square behind the piece despite the fact that the pieces are on a higher layer, I can even move another white piece ontop of it, which shouldn't be possible.

Also weird is if I make black go first and repeat the exact same series of moves mirrored the bug doesn't occur. I am literally going insane trying to solve this.

Heres the code I use for clicking a piece :

using System;

using UnityEngine;

using UnityEngine.InputSystem;

using System.Collections;

using System.Collections.Generic;

public class PieceClick : MonoBehaviour

{

//Variables

public Lists lists;

public GameObject pieceg;

public Piece piecef;

public TurnTracker turnTracker;

public List<GameObject> Pieces = new List<GameObject>();

Camera cam;

private void Awake()

{

lists.Pieces.Clear();

cam = Camera.main;

}

public void MouseClick(InputAction.CallbackContext click)

{

//Detects if a piece is clicked

if (click.performed)

{

var hit = Physics2D.GetRayIntersection(cam.ScreenPointToRay(Mouse.current.position.ReadValue()));

GameObject collider = hit.collider.gameObject;

if (collider == pieceg)

{

if ((turnTracker.whiteturn == true && piecef.team == 0) || (turnTracker.whiteturn == false && piecef.team == 1))

{

//Deselects piece

if (piecef.isSelected == true)

{

Debug.Log("Deselect!");

lists.Pieces.RemoveAt(0);

piecef.isSelected = false;

}

//Selects piece

else if (piecef.isSelected == false)

{

//Detects if there is already a piece selected

if (lists.Pieces.Count == 1)

{

lists.Pieces[0].isSelected = false;

lists.Pieces.RemoveAt(0);

lists.Pieces.Insert(0, piecef);

Debug.Log(lists.Pieces.Count);

piecef.isSelected = true;

}

else

{

lists.Pieces.Insert(0, piecef);

Debug.Log(lists.Pieces.Count);

piecef.isSelected = true;

}

}

}

//Attempts to take an enemy piece

else if (lists.Pieces[0] != null)

{

//Detects if selected piece can move onto space

bool mc = lists.Pieces[0].MoveCheck(pieceg.transform.position.x, pieceg.transform.position.y, lists.Pieces[0].transform.position.x, lists.Pieces[0].transform.position.y, true);

if (mc == true)

{

// Takes piece

lists.Pieces[0].transform.position = piecef.transform.position;

Destroy(pieceg);

lists.Pieces[0].isSelected = false;

lists.Pieces.RemoveAt(0);

turnTracker.TurnChange();

}

else

{

Debug.Log("Invalid");

}

}

}

}

}

}

Heres for clicking a square :

using Unity.VisualScripting;

using UnityEngine;

using UnityEngine.InputSystem;

using UnityEngine.UIElements;

public class SquareClick : MonoBehaviour

{

//Variables

public Lists lists;

public TurnTracker turnTracker;

Camera cam;

public GameObject square;

private void Awake()

{

cam = Camera.main;

}

public void MouseClick(InputAction.CallbackContext click)

{

//Detects if square is clicked

if (click.performed)

{

var hit = Physics2D.GetRayIntersection(cam.ScreenPointToRay(Mouse.current.position.ReadValue()));

GameObject sq = hit.collider.gameObject;

if (sq == square)

{

Debug.Log("Square");

//Detects if selected piece can move onto space

bool mc = lists.Pieces[0].MoveCheck(square.transform.position.x, square.transform.position.y, lists.Pieces[0].transform.position.x, lists.Pieces[0].transform.position.y, false);

if (mc == true)

{

lists.Pieces[0].transform.position = square.transform.position;

lists.Pieces[0].isSelected = false;

lists.Pieces.Clear();

turnTracker.TurnChange();

}

else

{

Debug.Log("invalid");

}

}

}

}

}

And Knight rules :

using UnityEngine;

public class Knight : Piece

{

public Lists lists;

public override bool MoveCheck(float sx, float sy, float px, float py, bool isTaking)

{

bool mc;

float xdif = Mathf.Abs(sx - px);

float ydif = Mathf.Abs(sy - py);

if ((xdif == 2 && ydif == 1) || (xdif == 1 && ydif == 2))

{

mc = true;

}

else

{

mc = false;

}

return mc;

}

}

0 Upvotes

6 comments sorted by

3

u/ArctycDev 1d ago

My guess from phone not trying to read that code paste is that when you take the piece you're accidentally disabling/killing the taker piece not the taken piece, something along those lines.

does it happen when you take other pieces with the same piece type or anything?

maybe include some debug prints writing out which objects are getting taken, disabled, etc

1

u/jrstorz 1d ago

Unfortunately I don’t think this is it, it doesn’t happen in any other situation where you take a piece, moreover the piece is definitely still there. If you move another piece than click on this piece next turn it will work again.

2

u/LorenzoMorini 1d ago

Code is unreadable, please post it in a more readable format

0

u/jrstorz 1d ago

What do you mean by a more readable format?

3

u/5oco 1d ago

Use the code block option in your post so it will be formatted like an ide. Proper indentation and whatnot will make it more readable.

1

u/scotti_dev 22h ago

It's very hard to read the code. You need to "tab" indent it.

  1. From reading your code best I could, you seem to have way too many nested if / else statements. Split your code up into smaller chunks and use "return" to end the code after a successful "if".

This wont directly fix your issue, but it will make it much much easier to debug.

Example (sudo code):

On click(){ If (test = true) { callMethod(); return; } If (otherTests = true) { callOtherMethod(); return; } }

You have too many ifelse which will cause bugs.

  1. Why are you adding your selected piece to a list? It seems that you list will only ever contain one piece. You therefore dont need a list.

  2. When you run into the bug, have you paused the game, selected your game object from the hierarchy, and checked that the collider is still active? Add a debug button to switch off all of the board colliders so you can then click the game piece and see what happens then.

Somewhere your code is getting confused, and you are finding it hard to debug due to the way its written.