将棋の駒の動きが分からない人もプレイできるように、駒の動きをガイドしてくれるシステムが欲しいなと思いました。そこで、やっつけで物理的に駒が動けないように動いてはいけないマスと駒の物理的な衝突を起こすという考えに至りました。同じマスに無理やり三つ押し込むと上の画像のようになります。
何をしたかというと、実際にマス目の上にキューブを25個作って左上から順に1~25の番号を付けました。そして、動けるマスはCollider2dとspriteRendererをオフにするという仕掛けになっています。まずは自分の駒がいるマスをオフにしてあげないといけないので、駒の現在地をマスの番号で取得する必要があります。そこでMasuHandler.csを作成しマスの番号を取得するクラスを書きました。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MasuHandler : MonoBehaviour { DirectionDeterminator directionDeterminator; public int masuNum; public int komaShu; public bool komaNaru; public void MasuCordinator(float x, float y,int cardIndex,bool Naru) { if (-1.5f > x && x > -2.5f) { if (1.5f < y && y < 2.5f) { masuNum = 1; Debug.Log(masuNum); } else if (0.5f < y && y < 1.5f) { masuNum = 6; Debug.Log(masuNum); } else if (-0.5f < y && y < 0.5f) { masuNum = 11; Debug.Log(masuNum); } else if (-1.5f < y && y < -0.5f) { masuNum = 16; Debug.Log(masuNum); } else if (-2.5f < y && y < -1.5f) { masuNum = 21; Debug.Log(masuNum); } else { masuNum = 26; } } else if (-0.5f > x && x > -1.5f) { if (1.5f < y && y < 2.5f) { masuNum = 2; Debug.Log(masuNum); } else if (0.5f < y && y < 1.5f) { masuNum = 7; Debug.Log(masuNum); } else if (-0.5f < y && y < 0.5f) { masuNum = 12; Debug.Log(masuNum); } else if (-1.5f < y && y < -0.5f) { masuNum = 17; Debug.Log(masuNum); } else if (-2.5f < y && y < -1.5f) { masuNum = 22; Debug.Log(masuNum); } else { masuNum = 26; } } else if (0.5f > x && x > -0.5f) { if (1.5f < y && y < 2.5f) { masuNum = 3; Debug.Log(masuNum); } else if (0.5f < y && y < 1.5f) { masuNum = 8; Debug.Log(masuNum); } else if (-0.5f < y && y < 0.5f) { masuNum = 13; Debug.Log(masuNum); } else if (-1.5f < y && y < -0.5f) { masuNum = 18; Debug.Log(masuNum); } else if (-2.5f < y && y < -1.5f) { masuNum = 23; Debug.Log(masuNum); } else { masuNum = 26; } } else if (1.5f > x && x > 0.5f) { if (1.5f < y && y < 2.5f) { masuNum = 4; Debug.Log(masuNum); } else if (0.5f < y && y < 1.5f) { masuNum = 9; Debug.Log(masuNum); } else if (-0.5f < y && y < 0.5f) { masuNum = 14; Debug.Log(masuNum); } else if (-1.5f < y && y < -0.5f) { masuNum = 19; Debug.Log(masuNum); } else if (-2.5f < y && y < -1.5f) { masuNum = 24; Debug.Log(masuNum); } else { masuNum = 26; } } else if (2.5f > x && x > 1.5f) { if (1.5f < y && y < 2.5f) { masuNum = 5; Debug.Log(masuNum); } else if (0.5f < y && y < 1.5f) { masuNum = 10; Debug.Log(masuNum); } else if (-0.5f < y && y < 0.5f) { masuNum = 15; Debug.Log(masuNum); } else if (-1.5f < y && y < -0.5f) { masuNum = 20; Debug.Log(masuNum); } else if (-2.5f < y && y < -1.5f) { masuNum = 25; Debug.Log(masuNum); } else { masuNum = 26; } } else { masuNum = 26; } komaShu = cardIndex; komaNaru = Naru; directionDeterminator.DirectionDetermine(komaNaru, komaShu); } // Start is called before the first frame update void Start() { directionDeterminator = GameObject.Find("DirectionDeterminator").GetComponent<DirectionDeterminator>(); } }
x座標とy座標によって場合分けしてマスの番号を取得しています。そして、駒が成っているかどうかのbool値と駒種の整数値を引数としています。
その引数はマウスを押した時に取得されるようにしたいのでmouse.csを改変します。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Mouse : MonoBehaviour { MasuHandler masuHandler; KomaModel komaModel; DirectionDeterminator directionDeterminator; Collider2D m_ObjectCollider; public float xzahyou; public float yzahyou; public int KomaShu; public int KomaNaru; public int YukoGoma; //マウスでドラッグするスクリプト private Vector3 screenPoint; private Vector3 offset; private void Start() { directionDeterminator = GameObject.Find("DirectionDeterminator").GetComponent<DirectionDeterminator>(); masuHandler = GameObject.Find("MasuHandler").GetComponent<MasuHandler>(); komaModel = GetComponent<KomaModel>(); } void OnMouseDown() { this.screenPoint = Camera.main.WorldToScreenPoint(transform.position); this.offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z)); xzahyou = transform.position.x;//現在地のX座標 yzahyou = transform.position.y;//現在地のy座標 KomaShu = komaModel.cardIndex;//駒種 KomaNaru = komaModel.komaBackIndex;//成駒種 if (komaModel.naru)//成っている場合 { YukoGoma = KomaNaru;//成駒の値を判定に使用 } else//成っていない場合 { YukoGoma = KomaShu;//駒の値を判定に使用 } masuHandler.MasuCordinator(xzahyou, yzahyou,YukoGoma,komaModel.naru); m_ObjectCollider = GetComponent<BoxCollider2D>(); m_ObjectCollider.isTrigger = false;//マウスを押したら衝突が発生するように } void OnMouseDrag() { Vector3 currentScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z); Vector3 currentPosition = Camera.main.ScreenToWorldPoint(currentScreenPoint) + this.offset; transform.position = currentPosition; } void OnMouseUp() { xzahyou = transform.position.x; yzahyou = transform.position.y; KomaShu = komaModel.cardIndex; KomaNaru = komaModel.komaBackIndex; if (komaModel.naru) { YukoGoma = KomaNaru; } else { YukoGoma = KomaShu; } masuHandler.MasuCordinator(xzahyou, yzahyou, YukoGoma, komaModel.naru); m_ObjectCollider = GetComponent<BoxCollider2D>(); m_ObjectCollider.isTrigger = true;//マウスを離したらもう衝突しない directionDeterminator.ResetAll(masuHandler.masuNum); //マスを自分の駒がいるマス以外全部表示する関数を呼ぶ } }
成っている場合と成っていない場合でインデックス値が被っているので、その場合分けのためにbool値をつけています。置いてある駒とガイドするマスがぶつかって駒が動かないように、マウスを押した駒しか衝突が起きないように工夫してあります。
directionDeterminator.ResetAll関数の中身は下記のようになっています。引数を駒がいるマスの番号に取り、そのマス以外のマスの2dColliderとMeshRendererを全部有効にしています。
public void ResetAll(int a) { int i; for (i = 0; i < 26; i++) { if(i != a) { Masu[i].GetComponent<BoxCollider2D>().enabled = true; Masu[i].GetComponent<MeshRenderer>().enabled = true; } else { Masu[i].GetComponent<BoxCollider2D>().enabled = false; Masu[i].GetComponent<MeshRenderer>().enabled = false; } } }
それから、マスに置いてあるキューブと駒がZ軸方向に被っていると、駒を選択できなくなってしまうため、駒はキューブよりも物理的な場所が手前側に表示されるようにInstantiateされる座標を改変しています。
これで、キューブがあるマスにある駒も選択できるようになりました。
それから、駒の成り面が全部桂馬になってしまうバグがありましたが、これはkomamodel.csを下記のように改変して場合分けして対応しました。
if (showFace == 2) { naru = true; if (cardIndex == 0)//金の場合 { spriteRenderer.sprite = komaBack; }else if (cardIndex == 1)//桂馬の場合 { spriteRenderer.sprite = komaNaru[0]; } else if (cardIndex == 2)//飛車の場合 { spriteRenderer.sprite = komaNaru[1]; } else if (cardIndex == 3)//角の場合 { spriteRenderer.sprite = komaNaru[2]; } else if (cardIndex == 4)//玉の場合 { spriteRenderer.sprite = komaBack; } }
次回は、これに加え、駒の動きを考えていきたいと思います。まずは簡単そうな金からですね。次に飛車、角、といった順番でひとつづつ潰していこうと思います。飛車と角はかなり難しそうなイメージです。