アセット（残り1日メガバンドルセール）を使用して3Dキャラクターを自然に階段を上らせる

残すところ後1日ちょっとですが、Unity Assets が[プロトタイプピング・メガバンドルセール](https://assetstore.unity.com/mega-bundles/prototype-your-project?locale=ja_JP)をやっています。

このメガバンドルに3Dキャラクターを簡単に動かすアセット（[Easy Character Movement](https://assetstore.unity.com/packages/templates/systems/easy-character-movement-57985)）が入っています。
このアセットだけで凸凹道も、階段も上れるし、高さによってはちゃんと引っかかるように設定もできます。

![trim4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/72eeef5f-f885-6be6-e94a-b35f5cff9a43.gif)

無料のジョイスティックアセットを合わせれば、モバイルでもタッチでキャラクターを操作できます。
メガバンドルのアセットと無料のJoystickアセットと合わせて、操作する方法をまとめました。

# 1. アセットのインポート
* [Easy Character Movement](https://assetstore.unity.com/packages/templates/systems/easy-character-movement-57985) と [Joystick](https://assetstore.unity.com/packages/tools/input-management/joystick-pack-107631) をインポートします
* インポート方法は[こちら](https://qiita.com/matchyy/items/3a7bdfa2152249c82606)

# 2. Joystick の準備
1. Hierarchy 上の空白スペースを左クリックし、UI -> Canvas を選択して Canvas を作成します  
<img width=320 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/035d3dc9-0f1b-9ea2-6fd2-9d5edbf2a143.png" >
1. Fixed Joystick を今作った Canvas にドラッグアンドドロップします  
<img width=320 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/6c922398-cc55-62b9-e0ec-66e143f2f98a.png" >
1. GameとHierarchyの画面がこんな感じになっていると思います。  
<img width=320 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/a84ffb8a-e539-e251-78eb-bcae62bb865b.png" >
1. 画面真ん中上部のプレイボタンを押して、Joystick操作できるか確認します  
![trim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/be0b7f70-2306-019e-0a60-81ad22da5d69.gif)

# 3. 動かすキャラクターの準備
1. Easy Character Movement の Demo シーンを開いて、Hierarchy 上の ECM_EthanCharacter を Projcet の Asset にドラッグアンドロップして prefab 化します。  
<img width=320 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/020db5d8-89ab-36c9-4517-609337e75e0f.png" />
1. SampleScene に戻ります。
1. Project の空いたスペースを右クリック、3D Object -> Plane を選択し、地面を作ります。  
<img width=320 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/193f9a20-3017-7a94-d98d-f29ae205af41.png">
1. 1 で prefab 化した ECM_EthanCharacter を Hierarchy にドラッグアンドドロップします。
<img width=320 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/5c569c11-0b9d-10c9-0cf2-10cbd6b9bec3.png" >
1. ここまで来ると、Game 画面がこんな感じで Ethan が後ろを向いていて、でかいジョイスティックがある状態になっているはずです。  
<img width=320 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/8b4c4399-c8ec-fad3-48c5-e9dec0a3708d.png" >

# 4. Joystick と Easy Charactor Movement を繋ぐプログラム
1. Project の Assets を右クリックして Create -> C# Script を選択し、OriginalCharacterController.cs（Unity 上は拡張子が表示されません）を作成します。  
<img width=320 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/3d85abbd-6366-527a-9c17-50cae8d2a7d8.png" >
1. OriginalCharacterController.cs は以下の通り。基本は BaseCharacterController を継承して、HandleInput を override したところに、Joystick の入力値をセットしてあげるだけです！

```C#
using UnityEngine;
using ECM.Controllers;

public class OriginalCharacterController : BaseCharacterController
{
    private Joystick joystick;

    void Start()
    {
        joystick = FindObjectOfType<Joystick>();
    }
    
    protected override void HandleInput()
    {
        moveDirection = new Vector3
        {
            x = joystick.Horizontal,
            z = joystick.Vertical
        };
    }
}

```

# 5. Ethan にプログラムを設定
1. prefab 化した ECM_EthanCharacter についている EthanCharacterController を削除します。
<img width=320 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/9bc469e5-f5d3-8f52-7cd1-e7bdc4d93922.png" >
1. Add Componet ボタンを押して、先ほど作った MyCharacterController を追加します。
<img width=320 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/981395ca-ac87-6ecc-7a2d-8fe061b4a5a5.png" >

# 6. 実行して Ethan を Joystick で動かす
1. 三角ボタンを押して実行します
1. Ethan が立ったままですが、Joystick に合わせて動くはずです。  
![trim2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/31a76a86-34f6-957d-8150-a584beb207af.gif)

# 7. これでは物足りない人はこちら
先ほど作ったプログラムをこちらに更新して実行します。

* HandleInput にジャンプとしゃがむ動作を入れています。
* Animate メソッドを追加して、移動時などにアニメーションするようにしています。  

```C#
using UnityEngine;
using ECM.Controllers;

public class OriginalCharacterController : BaseCharacterController
{
    private Joystick joystick;

    void Start()
    {
        joystick = FindObjectOfType<Joystick>();
    }

    protected override void HandleInput()
    {
        moveDirection = new Vector3
        {
            x = joystick.Horizontal,
            z = joystick.Vertical
        };

        jump = Input.GetKey(KeyCode.J);
        crouch = Input.GetKey(KeyCode.C);
    }
    
    protected override void Animate()
    {
        if (animator == null)  return;

        var move = transform.InverseTransformDirection(moveDirection);

        var forwardAmount = move.z;

        animator.SetFloat("Forward", forwardAmount, 0.1f, Time.deltaTime);
        animator.SetFloat("Turn", Mathf.Atan2(move.x, move.z), 0.1f, Time.deltaTime);
        animator.SetBool("OnGround", movement.isGrounded);
        animator.SetBool("Crouch", isCrouching);

        if (!movement.isGrounded)
            animator.SetFloat("Jump", movement.velocity.y, 0.1f, Time.deltaTime);

        var runCycle = Mathf.Repeat(animator.GetCurrentAnimatorStateInfo(0).normalizedTime + 0.2f, 1.0f);
        var jumpLeg = (runCycle < 0.5f ? 1.0f : -1.0f) * forwardAmount;

        if (movement.isGrounded)
            animator.SetFloat("JumpLeg", jumpLeg);
    }
}
```

こんな感じで動きます。ちゃんと Joystick の位置に応じて歩いたり走ったりしていますね。
キーボードのJキーを押すことでジャンプもできます。
![trim3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/9c91a299-1c31-c1dc-01a1-3db2808cc4a5.gif)