![見出し画像](https://assets.st-note.com/production/uploads/images/23997044/rectangle_large_type_2_aba169b008adb245799bf690edad701f.png?width=1200)
【Unity】3Dローグライクゲームの作り方〜Step3-3〜
前回の記事はこちら。
前回はEDirを定義し、ユニティちゃんをキー操作で自由に動かすところまで行いました。
Pos2Dの定義
少し内容が前後しますが、先に「Pos2D」クラスを定義しておきます。
Scriptsフォルダ内で右クリックして、C#スクリプトを作成、「Pos2D」という名前にします。
/**
* 2次元の座標クラス
*/
[System.Serializable]
public class Pos2D
{
public int x, z;
}
[System.Serializable]について簡単に説明するならば、このクラスを別のクラスで呼び出した時、その別のクラスからインスペクター上でこのクラスにある内部のパラメーターを編集できるようになる、といった所でしょうか。
説明するとややこしいので、一度試してみましょう。
「PlayerMovement」スクリプトをダブルクリックして下さい。
public Pos2D grid = new Pos2D();
「PlayerMovement」クラスにこのパラメーターを追加しましょう。そしてビルド、Unityエディターの「PlayerMovement」コンポーネントを見てみます。グリッドというパラメーターができています。こんな感じで内部のパラメーターにアクセスできます。
グリッド座標とワールド座標の相互変換
グリッド移動を実装するにあたって、こちらで作成したグリッド座標とゲームオブジェクトの位置(ワールド座標)を相互に変換する必要があります。という訳で「PlayerMovement」スクリプトを開き、このクラスに以下のメソッドを書き加えて下さい。
/**
* グリッド座標をワールド座標に変換
*/
private float ToWorldX(int xgrid)
{
return xgrid * 2;
}
private float ToWorldZ(int zgrid)
{
return zgrid * 2;
}
/**
* ワールド座標をグリッド座標に変換
*/
private int ToGridX(float xworld)
{
return Mathf.FloorToInt(xworld / 2);
}
private int ToGridZ(float zworld)
{
return Mathf.FloorToInt(zworld / 2);
}
「FloorToInt」は小数点以下の値を切り捨てる関数です。
今回は「ワールド座標×2 = グリッド座標」の計算で値を算出することにしました。
ユニティちゃんをグリッド移動させる
準備が整ったところで、ユニティちゃんをグリッド移動させてみましょう。
まず、以下のパラメーターとメソッドを「PlayerMovement」クラスに書き加えて下さい。
public int maxFrame = 100;
private int currentFrame = 0;
private Pos2D newGrid = null;
/**
* 補完で計算して進む
*/
private Pos2D Move(Pos2D currentPos, Pos2D newPos, ref int frame)
{
float px1 = ToWorldX(currentPos.x);
float pz1 = ToWorldZ(currentPos.z);
float px2 = ToWorldX(newPos.x);
float pz2 = ToWorldZ(newPos.z);
frame += 1;
float t = (float)frame / maxFrame;
float newX = px1 + (px2 - px1) * t;
float newZ = pz1 + (pz2 - pz1) * t;
transform.position = new Vector3(newX, 0, newZ);
animator.SetFloat(hashSpeedPara, speed, speedDampTime, Time.deltaTime);
if (maxFrame == frame)
{
frame = 0;
return newPos;
}
return currentPos;
}
/**
* 現在の座標(position)と移動したい方向(d)を渡すと
* 移動先の座標を取得
*/
private Pos2D GetNewGrid(Pos2D position, EDir d)
{
Pos2D newP = new Pos2D();
newP.x = position.x;
newP.z = position.z;
switch (d)
{
case EDir.Left:
newP.x -= 1; break;
case EDir.Up:
newP.z += 1; break;
case EDir.Right:
newP.x += 1; break;
case EDir.Down:
newP.z -= 1; break;
}
return newP;
}
そして「Update」メソッドを以下のように書き換えて下さい。
private void Update()
{
if(currentFrame == 0)
{
EDir d = KeyToDir();
if (d == EDir.Pause)
animator.SetFloat(hashSpeedPara, 0.0f, speedDampTime, Time.deltaTime);
else
{
direction = d;
transform.rotation = DirToRotation(direction);
newGrid = GetNewGrid(grid, direction);
grid = Move(grid, newGrid, ref currentFrame);
}
}
else grid = Move(grid, newGrid, ref currentFrame);
}
時間がないので説明は省略致します。ご了承下さい(もしわからないところがあればご連絡下さい。すみません......)。
テストプレイをしてみて、以下のようになれば成功です。
この記事が気に入ったらサポートをしてみませんか?