[Unity]2D牧場ゲームを作ってみる　その１[歩行アニメーション]


# 前置き
子供からの夢で「牧場物語やルーンファクトリーみたいな牧場ゲームを作ってみたい！」と思っていました。
QiitaでUnityを使った2Dゲームはないかと調べたところ、素晴らしい記事を発見しました。

- [UnityでRPGを作るpart1 歩行アニメーションと操作](https://qiita.com/_tybt/items/bc9c3be75c04ab547c35)

こちらの神記事を参考に2D牧場ゲームを作成していこうと思います。

# 今回作成するもの

- 1.キャラのドット絵
- 2.画像の読み込み、分割
- 3.キャラの歩行アニメーション
- 4.スクリプトの作成


## 1.キャラのドット絵を作成

- [EDGE](https://takabosoft.com/edge)でドット絵を作成

- ゲームの主人公を[ルーンファクトリー4](https://www.marv.jp/special/game/runefactory4SP/)の女主人公に設定。~~ルーンファクトリー4は神ゲームなのでプレイしましょう~~
- ドット絵制作に慣れてきたら、オリジナルの主人公描く予定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/4976d3a1-9fb7-a10e-adb1-c1eb3820c574.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/4d638f62-5842-f9b8-5842-90704b59a344.png)

## 2.画像の読み込み、分割

### 2-1.画像の読み込み

- 画像をドラッグ＆ドロップすることで、下の画像のように登録ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/7e4cb33a-80e4-0f96-99a3-791f0b407049.png)

---


- 登録した画像を選択すると右側にinspectorタブが表示されます。

- 下の画像のように、6つの箇所の初期値を変更します。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/00897fce-f427-13be-15af-11ae67bd19ce.png)

||設定値|説明|
|---|---|---|
|Texture Type|Sprite (2D and UI)|2Dゲームでスプライト（2Dグラフィックオブジェクト）としてテクスチャを使用する場合に選択します。|
|Sprite Mode|Multiple|画像に複数の要素がある場合に選択する必要がある。|
|Pixels Per Unit|1|デフォルトでは100。1ユニットの幅に対して100pixel詰め込むという意味になります。今回は1ユニットに1pixel詰め込むため1に設定する。|
|Mesh Type|Full Rect|スプライトをマッピングするクアッドが生成されます。|
|Filter Mode|Pointer (no filter)|ピクセルを1つ1つブロックのように表示する|
|Compression|None|テクスチャを圧縮しません。|

### 2-2.画像の分割

- `Sprite Editor`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/34d9e97f-f855-b213-4243-32ffb2af902a.png)

- Typeを`Grid By Cell Count`、C:`3`、R:`4`と変更をします。（横を３，縦に４に分けるため）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/926960e8-a83d-7389-67b3-ac1d02439627.png)

- Applyボタンを押すと完了。Asset内の画像の右矢印を押すと、分割した状態が見れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/a2b00b97-458d-5645-2c1d-ac91c6db7031.png)


## 3.キャラの歩行アニメーション

### 3-1.AnimationClipファイルの作成
- 画面を分割したので、歩行アニメーションを作成していきます。
- 先ほど作成した画像ファイルを左のhierarchyタブにドラッグ＆ドロップします。
- 追加しらオブジェクトを選択した状態で`Windows > Animation > Animation`を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/0fa4ddd3-cc3e-029b-f3f8-ddc7012cd2c5.png)


- 別ウィンドウに`To begin animationg Grid,…`のメッセージが表示されます、`Create`ボータンを押すとAnimationファイルが新規作成されます。
- 左上にファイル名が表示され、`Add Property`ボタンを押し`Sprite Renderer -> Sprite`を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/76c0a5ad-d847-6475-280d-7b7bcbf8ad5a.png)

- プロパティが追加されたらファイル名の横に表示されている`Samples`を4にしましょう。
- Samplesが表示されない場合は、右上の`：`を押し、`Show Sample Rate`をクリックしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/ced0505e-7f07-78d1-ad20-f898ec5ae70f.png)

- 以下の通りのアニメーションを繰り返して設定します。

```
右足前　＞　静止　＞　左足前　＞　静止
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/cd8973d5-101b-aa20-f912-825df69857c0.png)

- ▶ボタンを押すことで動きを確認できます。
- 今は前に進む`char_cro_down`を作成しました。
- `Create New Clip`を押して別方向のアニメーションを作成していきましょう。
  - char_cro_down:下方向
  - char_cro_left:左方向
  - char_cro_right:右方向
  - char_cro_up:上方向
- 名前は自由ですが、downやupと名前を付けたほうがわかりやすいです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/27d5ab64-87f9-7dae-83b6-c8df42c42b1a.png)

### 3-2.AnimatorColtollerの作成

- 次に「上移動のときに上に移動するアニメーションを再生する」というコントロール、AnimatorControllerを作成していきます。
- `BlenderTree`を使って、アニメーションを表示する制御をしてくれるものを使います。

- アニメーションファイルと一緒に作成された下のファイルをダブルクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/da003536-78d4-704f-69d2-5acca7ccfa6b.png)

- とりあえず、`右クリック > Create State > From New Blend Tree`を選択し、作成された`BlendTree`を右クリックして`Set as Layer Default State`を選択します。
- そうすると、`Entry`から生えている線が作ったブロックに向きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/c90a72cc-340b-9b22-151c-e4abb58464e9.png)

### 3-3.Parameterの設定

- `Parameter`をクリックします。
- `+`ボタンを押し、`Float`を押します。
- 名前を`x`に設定し、数値を0にします。`y`でも同じ作業をしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/4198de6f-5b2e-b388-1ec2-673409427e27.png)

### 3-4.BlenderTreeの設定
- 上で作った`BlenderTree`をダブルクリックすると、下の画像のような何も設定されていない状態の`BlenderTree`が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/3bb0f053-1286-a016-9b3b-54eb1214f490.png)

- `BlendType`を`1D`から`2D Simple Directional`を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/88106345-fec3-6118-3c85-85bf219eb7fd.png)

- `Parameters`を`Blend`から`x`に変えましょう。`y`でも同じ作業をしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/464a53dd-6bf3-9b86-2310-09398327f2f3.png)

- `+`ボタンを押し、`Add Motion Field`を押しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/e119598a-ab93-89e9-c076-1d1a917a2f36.png)

- `Motion`の左下の`+`を押すと、新しいMotionを追加できます。
- 上下4方向のMotionを作成するため、3回ほどクリックしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/789609e5-b969-7a81-4102-1a1fd1490d54.png)

- 下の画像のようになればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/b254a2ce-dddf-ccde-5a2f-90ca086dae15.png)

- これで`AnimatorColtroler`の設定が完了です。

## 4.スクリプトの作成


## 4-1.RididBody2Dをセットする

- 先ほど作成したオブジェクトをクリックし、右の`Inspector`を表示します。
- `Add Component`をクリックし、`RigidBody2D`を選択しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/dd7ce63a-6021-35ec-222b-6ee591a7c9b5.png)

- `RididBody2D`という枠が表示されます。
- `Body Type`を`Kinematic`にすることで、物理演算が無視され2Dっぽい動きになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/e04a45de-a1b2-9bb6-e289-c560af3da9ab.png)

### 4-2.スクリプトの作成
- 右クリックから`Create > C# Script`を選択してファイルを作成します。
- できれば`Asset > Scripts`というフォルダを作成して、そこでファイルを作ったほうがわかりやすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/81364b6b-fdc8-042f-0ad3-048ea9484049.png)

- `#`をいうアイコンのファイルがされます。
- `MoveController.cs`の名前を付けましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/21419d42-f490-1650-5777-8c042aa8b75f.png)

- キー操作でオブジェクトを動かすスクリプトを作成。[とむお](https://qiita.com/_tybt)さんのコードをそのままコピペしてます。

```cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/**
 * キャラの座標を変更するController
 */
public class MoveController : MonoBehaviour {
    [SerializeField]
    float SPEED = 1.0f;
    private Rigidbody2D rigidBody;
    private Vector2 inputAxis;

    void Start() {
        // オブジェクトに設定しているRigidbody2Dの参照を取得する
        this.rigidBody = GetComponent<Rigidbody2D>();
    }

    void Update() {
        // x,ｙの入力値を得る
        // それぞれ+や-の値と入力の関連付けはInput Managerで設定されている
        inputAxis.x = Input.GetAxis("Horizontal");
        inputAxis.y = Input.GetAxis("Vertical");
    }

    private void FixedUpdate() {
        // 速度を代入する
        rigidBody.velocity = inputAxis.normalized * SPEED;
    }
}
```

- 次はキー操作にあわせてアニメーションに状態をわたすスクリプトを作成
- 名前は`AnimationStateController.cs`に設定。

```cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/**
 * キャラの向き状態を変更するController
 */
public class AnimationStateController : MonoBehaviour {
    Animator animator;

    void Start() {
        // 初期化
        // コントローラをセットしたオブジェクトに紐付いている
        // Animatorを取得する
        this.animator = GetComponent<Animator>();
    }

    /**
     * Update は MonoBehaviour が有効の場合に、毎フレーム呼び出されます
     * https://docs.unity3d.com/ja/current/ScriptReference/MonoBehaviour.Update.html
     */
    void Update() {

        if (Input.anyKeyDown) {
            Vector2? action = this.actionKeyDown();
            if (action.HasValue) {
                // キー入力があればAnimatorにstateをセットする
                setStateToAnimator(vector: action.Value);
                return;
            }
        }
        // 入力からVector2インスタンスを作成
        Vector2 vector = new Vector2(
            (int)Input.GetAxis("Horizontal"),
            (int)Input.GetAxis("Vertical"));

        // キー入力が続いている場合は、入力から作成したVector2を渡す
        // キー入力がなければ null
        setStateToAnimator(vector: vector != Vector2.zero? vector : (Vector2?)null);

    }

    /**
     * Animatorに状態をセットする
     *    
     */
    private void setStateToAnimator(Vector2? vector) {
        if (!vector.HasValue) {
            this.animator.speed = 0.0f;
            return;
        }

        Debug.Log(vector.Value);
        this.animator.speed = 1.0f;
        this.animator.SetFloat("x", vector.Value.x);
        this.animator.SetFloat("y", vector.Value.y);

    }

    /**
     * 特定のキーの入力があればキーにあわせたVector2インスタンスを返す
     * なければnullを返す   
     */
    private Vector2? actionKeyDown() {
        if (Input.GetKeyDown(KeyCode.UpArrow)) return Vector2.up;
        if (Input.GetKeyDown(KeyCode.LeftArrow)) return Vector2.left;
        if (Input.GetKeyDown(KeyCode.DownArrow)) return Vector2.down;
        if (Input.GetKeyDown(KeyCode.RightArrow)) return Vector2.right;
        return null;
    }
}
```


# 完成
![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763295/71aa25d9-2a35-e443-f63c-8c564a0b7a38.gif)



# 次回作成するもの（仮）

- マップの作成


# 参考にしたサイト

- [UnityでRPGを作るpart1 歩行アニメーションと操作](https://qiita.com/_tybt/items/bc9c3be75c04ab547c35)