今後不具合等が判明した場合には修正及び改良をおこなう可能性があります。
また今後自分で同機能を実装する場合の参考にする可能性もあるためソースコードだけではなく説明しつつ記事を進めていきます。
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が呼ばれるタイミングで入力されていないと動作しないためボタンを押したはずなのに動作しない現象が起こる?
一度でも入力されるとFixedUpdateでリセットされるまで入力されたままの状態になるため入力された動作は必ず実行出来る?