
[unity] [手軽]×[手軽]=[最強]のプレイヤー移動コンポーネントを作ってみる。
unity初心者の3Dデザイナーさん向けに、とにかく手軽に「自分のキャラクタを動かす!」「アニメーションさせる!」を目標にコンポーネントを作ってみます。
あのAnimatorを使うのは段取りが面倒で保守も大変という人にも向いています。なお、今回、unityはバージョン2019のものを使っています。
またキャラクタのセットアップ、追尾カメラなどはとりあえず本記事の範囲外です。
1.CharacterControllerとは
Rigidbdy による処理を持たなくても衝突判定によって簡単に動きの制限を行うことが可能なコントローラ。手軽。
2.SimpleAnimationとは
スクリプト中から簡単にアニメーションクリップを再生する仕組み。こちらも手軽。
3.アセットのセットアップ
unityプロジェクトを作り、以下のアセットを取り込みます。
1) ユニティちゃん(なぜか無料)
左上のDOWNLOADをたどっていって、ユニティちゃん 3Dモデルデータ(ver1.2.1)をダウンロードします。
今回の記事では、アニメーションデータのみを流用させてもらいます。
なお、ユニティちゃんを使うときは、アセットストアのものではなく、公式からダウンロードし、インポートたほうがよいです。

ユニティちゃん 3Dモデルデータ。最新は1.2.1でした。
インポートは、基本的にはダウンロードした「UnityChan_1_2_1.unitypackage」をダブルクリックするだけでよいはずです。
また、アニメーションファイルしかつかいませんので、インポート時は□Animations 以外のチェックを外してみてください。
※Scriptの一部でエラーが起こるようで、プロジェクトが実行できなくなる可能性がありますので、その対処でもあります。

2) SimpleAnimationコンポーネント(なぜか無料)
Unity-Technologies製のSimpleAnimationです。簡単にアニメーションさせるための手段です。
リンク先のgithubのページを開いたら、緑色の[↓Code]ボタンから、[Download ZIP]でzipファイルをダウンロードし、展開します。
展開したフォルダのなかの「Asset」フォルダの中にある「SimpleAnimationComponent」フォルダをまるごと unityエディタの Project > Assetsに放り込んでください。

3) SimpleControllerスクリプト(当然無料)
自作のキャラクタコントローラです。無料です。
ダウンロードしたら、先程のSimpleAnimationコンポーネントと同じような位置に放り込んでおいてください。改造もご自由にどうぞ!
・(おまけ)ATART Casual Warrior Pack(有料)
有料のアセットですが、アクションゲームにはかなりいいかんじのデータなのでここで紹介しておきます。
どんな感じのアニメーションがあるかは、いけべるさんのブログがとても参考になります。みたら欲しくなるかも?
4.サンプルプロジェクト
1) 使うキャラクタをセットアップする
自作のキャラクターなどをインポートし、Humanoidでセットアップしておきます。必要に応じてprefab化しておいてください。
(詳細は省略します)
(プログラマのかたが試しになにかよいモデルがないか? というのであれば、いしかわさんの Junko chan(なんと無料) をどうぞ!)
2) 地形をセットアップする
unityエディタの Hierarchy → SampleScene で右クリックして、3D Object → Cube を作ってみてください。


Cubeの大きさをInspectorから変更します。
X=30、Z=30あたりにしてみましょう。

おお、平地ができたよ!

30m×30mで作ってみましたが、もちろん好きな寸法でかまいません。
2) キャラクタの配置
マイキャラをカメラに映るところにキャラクタを配置します。平面のどまんなかなんてよさそうですね。

ぽいっ
適当にぽいっとしても、地面に接地するよ。えらい。
3) アニメーションクリップの抽出
SimpleAnimatinは、アニメーションクリップしか利用できないため、ユニティちゃんのアニメーションデータからアニメーションクリップを抽出します。
(1) 立ちポーズのアニメーションクリップ
Project の Assets → UnityChan → Animations から、unitychan_WAIT00のなかの「WAIT00」アニメーションクリップを選んで、CTRL+D (Windowsのとき) して、立ちポーズのアニメーションクリップを抽出します。

(2) 走りアニメーションのアニメーションクリップ
同様に、unitychan_RUN00_F からも「RUN00_F」アニメーションクリップを抽出します。


上の2つのファイル(アニメーションクリップ)ができているはずです。
これらはそれぞれ、実はWAIT00.anim、RUN00.animというファイルです。
これらを自分のPCのフォルダにコピーしておくいて、わかりやすい名前をつけておくと、あとで自由に使いまわしできます。(さりげなく重要)
他にも必要なアニメーションクリップがある場合は、同様の操作でアニメーションクリップを抽出してください。
このアニメーションクリップは後ほど使います。
4) CharactorControllerコンポーネントの追加
(1) Hierarchyからキャラクタを選択し、Inspectorの[Add Compornent] > Physics > Character Controller にてコンポーネントを追加します。

(2) Character Controllerカプセルの調整
図中の緑色のカプセルが衝突判定なので、CenterとHeight、Radiusを変更して、キャラクタがだいたいカプセルのなかにおさまるようにします。

↓ 下のようになるよう調整する

ここで数字が2(2m)を超えるとか、1を下回るようであればキャラクタのサイズが想定とずれているため、他のアセットに悪い影響が出る場合があります。
Scaleでも調整できますが、できれば、モデリングソフトからエクスポートするときに調整してみてください。
今回はユニティちゃんのモーションデータを利用していますが、実はジャンコちゃんにはモーションデータも同梱されています。もちろん、それを使うこともできます。わざわざ別のモーションを持ってきているのは、記事のためなんだからね!
5) SimpleAnimationコンポーネントの追加
(1) 同様にHierarchyからキャラクタを選択し、Inspectorの[Add Compornent] → Scripts → Simple Animation にてコンポーネントを追加します。

(2) Simple Animationコンポーネントに、アニメーションクリップを登録します。まずは、登録する個数を設定します。

Sizeを3に、2番目の名前をWAITに、2番目の名前をRUNに変更します。
(3) ここにさきほど抽出したアニメーションクリップを設定します。
1つずつぽいぽいしていくとよいでしょう。

ちなみに、Animation[ None (Animation Clip) ] に試したいアニメーションクリップをいれて実行(RUN)すれば、スクリプトなしでとりあえずアニメーションの確認ができたりします。
7) 移動Scriptの追加
プレイヤーキャラクタのInspectorから Add Compornent > Scripts > Move With Controler にてスクリプトを追加してください。

移動スクリプトの内容は、noteの末尾(6章)に記載しております。
このプロジェクトを実行すると、キーボードのカーソルキーやWASDキーで移動できます。
その際、歩行⇔停止に伴いそれぞれのアニメーションが再生されます。
Junko chanが歩くよ。スタタタタ。
8) スクリプトの調整
アニメーションの再生タイミングや再生速度などは、スクリプトから調整できます。意味がわからなければ飛ばしてください。
1)アニメーションクリップの再生速度
GetState.speedにて調整できます。この数字が 1.0より小さくなると遅くなり、1.0より大きくなると速くなるようです。
_simpleAnimation.GetState("WAIT").speed = 0.7f; //この数字で調整できます。
2)アニメーション種類の増加
Simple AnimationコンポーネントのAnimationのSizeを増やし、アニメーションクリップを追加します。
たとえばWALKという名前でアニメーションを追加した場合は、以下のようなスクリプトで再生できます。
_simpleAnimation.CrossFade("WALK", 0.5f);
このとき、今再生されているアニメーションがなんであっても0.5秒かけてWALKのアニメーションになめらかに移行します。
スティックの傾きがある一定以下だったらWALKに、それより上だったらRUNに移行するなんていうのも簡単です。すばらしい使いやすさです。
9) 追尾カメラの追加など(別途)
カメラが動かないので、キャラクタが画面外に出ると状況がわからなくなります。応じてカメラに追尾機能があると良いのですが、これは別の機会に紹介します。
5.参照ブログなど
SimpleAnimationについては以下のKANさんとテラシュールブログさんの記事を参考にしました。
アニメーションクリップの再生終了を検知するために、以下の改修をくわえておくか、再生終了後に呼び出されるよう設定するのもよさそうです。
6.サンプルコード
手軽×手軽 = 最強。ということで、キャラクタコントローラのサンプルです。
機能:コントローラやキー入力に応じキャラクタを移動させる。
// 2019.07 K1Togami MoveWithControler
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveWithControler : MonoBehaviour
{
private Vector3 moveDirection = Vector3.zero;
private CharacterController controller;
public float maxspeed = 3.0f;
public float rotatespeed = 360.0f;
private SimpleAnimation _simpleAnimation = null; // Unity製 SimpleAnimationシステムを使用する。
private Camera mainCamera = null;
// 入力保持用
private Vector3 inputDirection;
private Vector3 lookingDirection;
// Start は最初のフレーム更新の前に呼び出されます。
void Start()
{
controller = GetComponent<CharacterController>();
_simpleAnimation = GetComponent<SimpleAnimation>();
lookingDirection = new Vector3(1, 0, 1);
_simpleAnimation.GetState("WAIT").speed = 0.7f; // アニメーションクリップの再生速度を1.0倍
_simpleAnimation.GetState("RUN").speed = 1.2f; // アニメーションクリップの再生速度を1.0倍
mainCamera = Camera.main;
}
// Update is called once per frame
void Update()
{
// キー入力を取得
inputDirection.z = Input.GetAxis("Horizontal");
inputDirection.x = Input.GetAxis("Vertical");
// メインカメラの向きによって入力を調整
Vector3 cameraForward = Vector3.Scale(mainCamera.transform.forward, new Vector3(1, 0, 1)).normalized;
inputDirection = cameraForward * inputDirection.x + mainCamera.transform.right * inputDirection.z;
moveDirection = inputDirection * maxspeed;
// いずれかの方向に入力がある場合。
if (inputDirection != Vector3.zero)
{
// 回転!
lookingDirection = inputDirection;
// 走行アニメーションに遷移
_simpleAnimation.CrossFade("RUN", 0.2f);
}
else
{
// コントローラからの入力がなく、停止アニメーションに遷移。
_simpleAnimation.CrossFade("WAIT", 0.2f);
}
// 方向転換処理(スムーズに回転するよう、若干ディレイをかけています)
transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(lookingDirection), (rotatespeed * Time.deltaTime));
controller.Move(moveDirection * Time.deltaTime);
}
}
おわりに
なぜ、キャラクタコントローラなんて世の中にたくさんあるのに、自分で作るのか。それはきっと、キャラクタコントロールがゲームルールの重要な柱のひとつだからです。
他のゲームの柱をそのまま使えるなんてことは、あまりない。だから3Dゲーム制作者は、今日もキャラクタコントローラを作り続けます。
Rev1:2021.02
サンプルスクリプトに、カメラの向きを移動の補正に使う仕組みを導入。カメラの向きを移動の補正に使う仕組みを導入。
Rocky Hills アセットではメインカメラがうまく取得できないため、使用をやめました。
また、いけべるさんのブログへのリンクを追加。誤記を修正しました。