ものづくりのブログ

うちのネコを題材にしたものづくりができたらいいなと思っていろいろ奮闘してます。

Unity で 2DRPG を作る - プレイヤー(player)の歩かせ方編

2DのRPGを作ってみたいということで、Unity を勉強してみました。
お題としては、昔から馴染みのある2次元RPGに挑戦してます。
覚えることがいっぱいありそうなので、頭の整理用にこのブログに少しづつまとめていきたいと思います。
まずはプレイヤー(player)の歩かせ方を勉強したので、このブログにUnityでの2次元RPGの作り方を少しづつまとめていこうと思います。

やりたいこと

  • 歩行アニメーション作成
  • キャラクターの操作


準備するもの

  • キャラクター歩行素材(透過png)を用意

以下のサイトの猫をお借りしました。
二足歩行のネコ - 犬分補給が最優先だ! -


設定

画像アップロード

用意した画像をProjectAssetsにドラッグ&ドロップするとプロジェクトに画像が登録される。



[Pixels Per Unit]の変更と[Sprite Editor]の設定

Unityで認識できる画像データを、Sprite(スプライト)という形式で読み込こませると、2Dオブジェクトとして画像を表示することができる。

  • [Inspector]の[Sprite Mode]を[Multiple]に変更する。
  • [Inspector]の[Pixels Per Unit]の設定を[100]->[32]に変更する。
  • [Sprite Editor]ボタンをクリックする。




[Sprite Editor]で画像スライス

[Sprite Editor]で画像を分割する。

  • [Slice]の[Type]を[Grid By Cell Size]に変更する。
  • [Slice]の[Pixel Size]を[X:32][Y:32]に変更する。




  • [Slice]の[Slice]ボタンをクリックすると以下のように画像が分割される。




[Hierarchy]にスライスした画像をドラック&ドロップ




アニメーション作成

[Hierarchy]にスライスした画像をもっていき[Player]という名前に変更する。
[Player]を選択した状態で[Window]->[Animation]->[Animation]を選択する。


アニメーション作成のウィンドウが表示されるので、[Create]ボタンをクリックする。


以下の4つのアニメーションを作成する。

  • [Player_Walk_Down]
  • [Player_Walk_Up]
  • [Player_Walk_Right]
  • [Player_Walk_Left]




[Animator]編集
  1. [Parameters]に[x]を追加する。
  2. [Parameters]に[y]を追加する。
  3. [Inspector]の[BlendType]を[2D Simple Directional]にする。
  4. [Inspector]の[Parameters]に[x][y]を指定する。
  5. [Motion]に[Player_Walk_Up]を追加する。([PosX/PosY]の指定も忘れず)
  6. [Motion]に[Player_Walk_Down]を追加する。([PosX/PosY]の指定も忘れず)
  7. [Motion]に[Player_Walk_Right]を追加する。([PosX/PosY]の指定も忘れず)
  8. [Motion]に[Player_Walk_left]を追加する。([PosX/PosY]の指定も忘れず)




[Rigidbody 2D]追加
  • [Hierarchy]->[Player]を選択し[Inspector]から[Add Componet]で[Rigidbody 2D]を追加する。
  • [BodyType]で[Dynamic]を選択する。
  • [GravityScale]を[0]にする。




[Circle Collider 2D]追加
  • [Hierarchy]->[Player]を選択し[Inspector]から[Add Componet]で[Circle Collider 2D]を追加する。




ジョイステック追加

以下のサイトからジョイステックを取得
assetstore.unity.com
[GameObject]->[UI]->[Canvas]を選択しキャンバスの設定を追加する。

[canvas]の設定を変更する。

[canvas]にジョイステックをドラック&ドロップ

簡単にサイズと座標を調整する。



[Move Controller](Script)追加
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;
    [SerializeField]
    public FixedJoystick joystick;

    void Start()
    {
        // オブジェクトに設定しているRigidbody2Dの参照を取得する
        this.rigidBody = GetComponent<Rigidbody2D>();
        // 衝突時にobjectを回転させない設定
        this.rigidBody.constraints = RigidbodyConstraints2D.FreezeRotation;
    }

    void Update()
    {
        // x,yの入力値を得る
        inputAxis.x = joystick.Horizontal;
        inputAxis.y = joystick.Vertical;
    }

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



[Animation Controller](Script)追加
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnimationStateController : MonoBehaviour
{
    Animator animator;
    [SerializeField]
    public FixedJoystick joystick;
    [SerializeField]

    void Start()
    {
        // Animatorを取得する
        this.animator = GetComponent<Animator>();
    }

    void Update()
    {
        if (Input.anyKeyDown)
        {
            Vector2? action = this.actionKeyDown();
            if (action.HasValue)
            {
                // キー入力があればAnimatorにstateをセットする
                setStateToAnimator(vector: action.Value);
                return;
            }
        }
        // 入力からVector2インスタンスを作成
        Vector2 vector = new Vector2(
            joystick.Horizontal,
            joystick.Vertical);
        // キー入力が続いている場合は、入力から作成したVector2を渡す
        // キー入力がなければ null
        setStateToAnimator(vector: vector != Vector2.zero ? vector : (Vector2?)null);
    }

    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;
    }
}



スクリプトに設定追加

[Joystick]の項目に設定したジョイステックを選択する。



動作確認

ジョイステックをグリグリすると、それっぽく動きます。

www.youtube.com