【自作ゲーム開発4】プレイヤーキャラクターの滑らかな回転動作【Unity】


注意
本記事で掲載されている動作の実装方法及びプログラムのソースコードは最適な方法ではない可能性があります。
今後不具合等が判明した場合には修正及び改良をおこなう可能性があります。
また今後自分で同機能を実装する場合の参考にする可能性もあるためソースコードだけではなく説明しつつ記事を進めていきます。

はじめに

Unityによる自作ゲーム開発進捗その4になります!

プレイヤーキャラクターモデルの反映とアニメーションの実装及びキャラクターの回転動作を実装します。

以下にソースコードを掲載します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour{
    private Vector3 m_vector3;
    private Rigidbody m_rigidbody;
    private Animator m_animator;

    private Quaternion m_rotation = Quaternion.identity;

    private const float m_turn_speed = 20.0f;

    private float m_move_speed = 0.1f;
    private float m_horizontal = 0.0f;
    private float m_vertical = 0.0f;

    enum STATE{
        MOVE
    }; STATE e_state;

    private void Start(){
        m_rigidbody = GetComponent<Rigidbody>();
        m_animator = GetComponent<Animator>();
    }

    private void Update(){
        m_horizontal = Input.GetAxis("Horizontal"); // タスク2
        m_vertical = Input.GetAxis("Vertical"); // タスク2
    }

    private void FixedUpdate(){
        switch(e_state){
            case STATE.MOVE:
                m_vector3.Set(m_horizontal, 0f, m_vertical);
                m_vector3.Normalize();

                bool l_horizontal_input = !Mathf.Approximately (m_horizontal, 0f);
                bool l_vertical_input = !Mathf.Approximately (m_vertical, 0f);
                bool l_move = l_horizontal_input || l_vertical_input;
                m_animator.SetBool ("animation_move", l_move);

                Vector3 l_rotation = Vector3.RotateTowards (transform.forward, m_vector3, m_turn_speed * Time.deltaTime, 0f);
                m_rotation = Quaternion.LookRotation (l_rotation);

                m_rigidbody.MovePosition (m_rigidbody.position + m_vector3 * m_move_speed);
                m_rigidbody.MoveRotation (m_rotation); 
            break;
        }

        m_horizontal = m_vertical = 0.0f;
    }

    public void PlayerSpeedSet(float a_speed){
        m_move_speed = a_speed; // タスク1
    }
}

/*
    [規則]
    p_ 外部アクセス
    m_ メンバー変数
    l_ ローカル変数
    a_ 引数
    e_ 列挙型

    [説明]

    [バージョン]
    2020-12-30 キーボードによるプレイヤーキャラの移動実装(回転無し)
    2021-01-09 プレイヤーキャラのモデルとアニメーション反映及び回転動作

    [タスク]
    タスク1 上限値の制限が必要
    タスク2 コントローラーによる動作も追加する
*/

キャラクターモデル

今回も使用するのはSURIYUN様のモデルになります。

操作キャラクターによってモデルを分岐するようになりますが当分はこの1キャラのみでゲーム開発を進めていきます。

もし自作3Dモデルを作成してゲーム内で使用する場合はこの作者様の世界観に合わせて作成する予定です。


アニメーション

現在のプレイヤーキャラクターアニメーションは待機状態と移動状態のみを実装します。

ユーザーからの入力

Update関数でユーザーの入力を受け付ける

入力内容による分岐動作

FixedUpdate関数で入力による待機と走る動きを切り替える

入力内容のリセット

動作終了後に入力内容をリセットする

private void Update(){
    m_horizontal = Input.GetAxis("Horizontal"); // タスク2
    m_vertical = Input.GetAxis("Vertical"); // タスク2
}

ユーザーからの入力はUpdate関数内で受け取るようにしました。
理由は後述します

bool l_horizontal_input = !Mathf.Approximately (m_horizontal, 0f);
bool l_vertical_input = !Mathf.Approximately (m_vertical, 0f);
bool l_move = l_horizontal_input || l_vertical_input;
m_animator.SetBool ("animation_move", l_move);

移動入力が有るかどうかの判定をおこないbool変数に結果を格納した後にアニメーション切り替えのbool値を変更しています。

FixedUpdateの周期を20msから16msに変更しました。
初期値が20msなのは理由があるのかもしれませんが現状の私では判断出来なかったため60fpsを少し超える程度の周期に変更しています。


ユーザーからの入力について

注意
以下の内容は最適ではない可能性が非常に高く今後修正が必要になる可能性があるため単品で使用する場合はご注意ください。

今回からユーザーからの入力をUpdateで判定して処理をFixedUpdateに記述するようにしています。

毎フレーム処理されるUpdate内で入力を受け取り一定周期処理のFixedUpdate内で処理をおこなった後に入力をリセットしています。

FixedUpdateに入力処理も入れて1つの関数で処理

FixedUpdateが呼ばれるタイミングで入力されていないと動作しないためボタンを押したはずなのに動作しない現象が起こる?

Updateに入力をFixedUpdateに処理の場合

一度でも入力されるとFixedUpdateでリセットされるまで入力されたままの状態になるため入力された動作は必ず実行出来る?


今回から使用するアセット


動画


記事のリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です