「どうぶつしょうぎ」をUnityで作成する。第4回目です。
はじめに
Part1は下記です。
今回やること
パート1では駒の初期配置を作成、パート2では移動先の表示、パート3では駒の移動を実装しました。今回は交互に駒を動かすのを実装していきます。
実装開始
交互に駒を動かすのを実装するのと同時に、前回からいくつか修正するポイントがあるのでそちらも実装します。
駒移動に伴う修正
下記のように相手の駒がある場所に移動すると正しくない動きをするので修正していきます。

修正箇所は、盤内の駒情報(boardpiece)更新、移動後にタイル削除、移動場所に相手の駒があった場合、一旦削除(後で変更)を行っていきます。
スクリプトを変更
まずはGameManagerスクリプトを下記のように変更します。変更のない場所は省略してあります。
追加した処理は、「boardpieceに駒オブジェクトをセット」するのと、「プレイヤーを交代する」です。
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager instance { get; private set; }
public string currentPlayer { get; private set; }
public GameObject selectPiece { get; private set; }
[SerializeField] private GameObject _piece;
private GameObject[,] boardpiece;
private void Awake()
{
instance = this;
}
void Start()
{
//省略
}
private void CreateInitPiece(string player, string name, int x, int y)
{
//省略
}
public bool OnBoardCheck(int x, int y)
{
//省略
}
public GameObject GetBoardPiece(int x, int y)
{
return boardpiece[x, y];
}
public void SetBoardPieceNull(int x, int y)
{
boardpiece[x, y] = null;
}
public void SetBoardPiece(GameObject obj)
{
int x = Mathf.RoundToInt(obj.transform.position.x);
int y = Mathf.RoundToInt(obj.transform.position.y);
boardpiece[x, y] = obj;
}
public void SetSelectPiece(GameObject piece)
{
selectPiece = piece;
}
public void ChangePlayer()
{
if (currentPlayer == Const.player_forest)
{
currentPlayer = Const.player_sky;
Debug.Log("空プレイヤーの番です。");
}
else
{
currentPlayer = Const.player_forest;
Debug.Log("森プレイヤーの番です。");
}
}
}
Pieceスクリプトは下記のように変更します。
駒を移動したときに「boardpieceの駒情報を更新」、駒を移動後に「タイル削除追加」です。
using UnityEngine;
public class Piece : MonoBehaviour
{
public string ownership { get; private set; }
[SerializeField] private Sprite hiyoko, kirin, raion, zou, niwatori;
private TileManager TileManager;
private void Start()
{
TileManager = GameObject.Find("TileManager").GetComponent<TileManager>();
}
public void InitPiece(string player, string name)
{
//省略
}
private void OnMouseUp()
{
//自分の駒のみ
if (GameManager.instance.currentPlayer != ownership) return;
int x = Mathf.RoundToInt(transform.position.x);
int y = Mathf.RoundToInt(transform.position.y);
//選択した駒
GameManager.instance.SetSelectPiece(this.gameObject);
//移動先タイル表示
TileManager.MoveTileSpawn(this.name, x, y);
}
public void MovePiece(Vector2 toPos)
{
int x = Mathf.RoundToInt(transform.position.x);
int y = Mathf.RoundToInt(transform.position.y);
//駒を移動
GameManager.instance.SetBoardPieceNull(x, y);
transform.position = toPos;
GameManager.instance.SetBoardPiece(this.gameObject);
//タイル削除
TileManager.DestroyTile();
}
}
Tileスクリプトは下記のように変更します。
駒を動かした時、選択したタイル上に相手の駒がある場合、削除します。タイルの位置に駒を移動したらプレイヤーを交代します。
using UnityEngine;
public class Tile : MonoBehaviour
{
private bool pieceExist = false;
private void OnMouseUp()
{
if (pieceExist)
{
int x = Mathf.RoundToInt(transform.position.x);
int y = Mathf.RoundToInt(transform.position.y);
//タイル上の駒を削除(->持ち駒にする)
GameObject tilepiece = GameManager.instance.GetBoardPiece(x, y);
Destroy(tilepiece);
}
//駒をタイルの位置に移動
GameObject selectpiece = GameManager.instance.selectPiece;
selectpiece.GetComponent<Piece>().MovePiece(transform.position);
//プレイヤー交代
GameManager.instance.ChangePlayer();
}
public void SetPieceExist(bool exist)
{
pieceExist = exist;
}
}
TileManagerは下記のように変更します。
タイル生成時、相手の駒があるときにtrueをセットします。
using UnityEngine;
public class TileManager : MonoBehaviour
{
[SerializeField] private GameObject _tile;
public void MoveTileSpawn(string name, int x, int y)
{
//省略
}
private void TileSpawn(int x,int y)
{
// 盤内かチェック
if (!GameManager.instance.OnBoardCheck(x, y)) return;
GameObject piece = GameManager.instance.GetBoardPiece(x, y);
if (piece == null)
{
Instantiate(_tile, new Vector3(x, y), Quaternion.identity, this.transform);
}
else if (piece.GetComponent<Piece>().ownership != GameManager.instance.currentPlayer)
{
GameObject obj = Instantiate(_tile, new Vector3(x, y), Quaternion.identity,
this.transform);
obj.GetComponent<Tile>().SetPieceExist(true);
}
}
public void DestroyTile()
{
//省略
}
}
結構変更ポイントがありますが、細かく切ると同じスクリプトが並ぶので一度に載せました。
実行すると下記のように交互に駒を動かすことができるようになります。

仮でゲームの勝敗をセット
GameManagerスクリプトに下記を追加。
public void GameOver()
{
if (currentPlayer == Const.player_forest)
{
Debug.Log("森プレイヤーの勝ちです。");
}
else
{
Debug.Log("空プレイヤーの勝ちです。");
}
}
Tileスクリプトを下記に変更。
using UnityEngine;
public class Tile : MonoBehaviour
{
private bool pieceExist = false;
private void OnMouseUp()
{
if (pieceExist)
{
int x = Mathf.RoundToInt(transform.position.x);
int y = Mathf.RoundToInt(transform.position.y);
//タイル上の駒を削除(->持ち駒にする)
GameObject tilepiece = GameManager.instance.GetBoardPiece(x, y);
Destroy(tilepiece);
//ライオンなら終了
if (tilepiece.name == Const.raion) GameManager.instance.GameOver();
}
//駒をタイルの位置に移動
GameObject selectpiece = GameManager.instance.selectPiece;
selectpiece.GetComponent<Piece>().MovePiece(transform.position);
//プレイヤー交代
GameManager.instance.ChangePlayer();
}
public void SetPieceExist(bool exist)
{
pieceExist = exist;
}
}
これでライオンを取った方が勝ちになります。
