Example:
Width = 200 and Height = 100. It will always be this size unless resized explicitly.Example:
200x100 button with Scale (2,2,1) will appear as 400x200 visually, but the RectTransform’s Width and Height values remain at 200x100.삭제나 캐슬링 같은 경우 여러 개의 기물을 옮겨야 하고
턴이 끝나는 타이밍도 맞춰야 하기 때문에
커맨드 패턴과 큐를 이용하여 이동 제어
나중에 플레이어측 이동은 InvisibleCommand를 활용할 예정
삭제하는 경우의 수
기존 DestoryPieceAt()에 현재 턴에 따라 누가 지울지 결정
public class RoboticArmCommand : ICommand
{
private RoboticArm roboticArm;
private GameObject piece;
private Vector3 targetPos;
private float time;
public RoboticArmCommand(GameObject piece, Vector3 targetPos, float time, RoboticArm roboticArm)
{
this.piece = piece;
this.targetPos = targetPos;
this.time = time;
this.roboticArm = roboticArm;
}
public void Execute()
{
roboticArm.MovePieceToPos(piece, targetPos, time);
}
}
move commmand를 만들고
public class PieceCommandManager : MonoBehaviour
{
private Queue<ICommand> moveQueue = new Queue<ICommand>();
[SerializeField] private RoboticArm roboticArm;
private GameManager gameManager;
private bool isWorking = false;
void Start()
{
GameObject serviceLocator = GameObject.FindGameObjectWithTag("ServiceLocator");
gameManager = serviceLocator.GetComponentInChildren<GameManager>();
}
/// <summary>
/// 각 명령이 끝나면 호출되어 다음 명령을 실행하는 함수
/// </summary>
public void ExecuteNextCommand()
{
if (isWorking) return;
if (moveQueue.Count > 0)
{
moveQueue.Dequeue().Execute();
isWorking = true;
}
else
{
gameManager.EndTurn();
}
}
public void CompleteCommand()
{
isWorking = false;
ExecuteNextCommand();
}
public void EnQueueRoboticArmMove(GameObject piece, Vector3 targetPos, float time)
{
moveQueue.Enqueue(new RoboticArmCommand(piece, targetPos, time, roboticArm));
ExecuteNextCommand();
}
}
외부에선 EnQueueRoboticArmMove()를 호출하여 명령 예약.
roboticArm.MovePieceToPos() 마지막에 CompleteCommand()를 넣어놓음.
락으로 동시 실행 방지.

public class PieceGrave : MonoBehaviour
{
private float dx;
private float dz;
private int xIdx = 0;
private int zIdx = 0;
private List<GameObject> dead_pieces = new List<GameObject>();
public void InitPieceGrave(float dx, float dz)
{
this.dx = dx;
this.dz = dz;
}
public void ResetGrave()
{
xIdx = 0;
zIdx = 0;
foreach (GameObject piece in dead_pieces)
{
Destroy(piece);
}
}
/// <summary>
/// AI 기물 앞에 있는 무덤 위치 반환하면서 리스트에도 넣어놓는다
/// </summary>
public Vector3 GetAIGravePos(GameObject piece)
{
dead_pieces.Add(piece);
Vector3 gravePos = transform.position + new Vector3(xIdx * dx, 0, zIdx * dz);
xIdx++;
if (xIdx > 4)
{
xIdx = 0;
zIdx++;
}
return gravePos;
}
}
board에서 DestroyPieceAt() 호출할 때 EnQueueRoboticArmMove()에 넣을 정보에 GetAIGravePos() 반환 값 넣는다.
게임을 리셋할 때 무덤에 있는 것들도 지워주기 위해 리스트에 넣어놓는다.
transform.position 부분은 ai와 플레이어 별도로 오브젝트를 설정하는 것으로 바꿀 예정.
public bool DestroyPieceAt(int x, int z)
{
if (pieces[x, z] == null) { return false; }
bool isWhiteNow = gameManager.whiteTurn; // 백이 플레이어
if (isWhiteNow)
{
Destroy(pieces[x, z]);
}
else
{
pieceCommandManager.EnQueueRoboticArmMove(pieces[x, z], piece_grave.GetAIGravePos(pieces[x, z]), 1.0f);
}
pieces[x, z] = null;
return true;
}

https://www.youtube.com/watch?v=dPdmJ0RDLSI


해결 완료.
내일은 레트로 효과 넣기.