今回は、Unityテーマは前回に引き続き、「Animator Controllerを作成して立ち・移動・攻撃・ジャンプ アニメーションを実装する方法」第二回目です。
前回は、立ちモーションと移動モーションまで作成しました。
今回は、攻撃モーションとジャンプモーションの作成を行います。
前準備
第一回目の内容の把握
この記事は、第一回目の内容の続きになっていますのでまだやっていないという方は先にそちらの記事から確認して下さい。
この記事では、第一回で作成したプロジェクトを引き続き利用します。

mixamoで攻撃モーションのダウンロード
第一回目でダウンロードしたには「Action Adventure Pack」には攻撃モーションが入っていないので、mixamoから攻撃モーションをダウンロードします。
Animationタブで「panching」で検索して気に入ったpunchingモーションを見つけてダウンロードします。

ダウンロード後、第一回で利用していた、「Project>Assets>Action Adventure Pack」フォルダへインポートします。
「Punching」のインスペクターから、「Rig>Animation Type」を「Humanoid」に変更します。

また「Animation」タブから名前を「punching」に変更してApplyをクリックします。

攻撃モーションの実装
攻撃の実装 Animatorの遷移条件の設定
第一回目で作成したAnimation Controllerでは、立ち状態と走る状態を実装しました。攻撃モーションは、この両方の状態から遷移できるようにします。
前回作成したPlayerControllerにAnimatorタブで、前準備した「punching」をドラッグアンドドロップします。
punchingは「Idle2」と「running」から遷移できるようにします。また、「punching」が完了した際には、Idle2に戻るようにします。

今回「punching」の遷移には、パラメータのTrigerを利用します。
Parametersの「+」からTrigerを選択して名前を「punching」にします。


punchingへの遷移2つの「Conditions」に今作成したパラメータ「punching」を追加します。また「HasExitTime」のチェックを外して「Transition Offset」の値を0にしておきます。


逆に、punchingからIdle2への遷移は攻撃モーションが終わるまで待ちたいので、何も変更せずそのままにすることで、攻撃モーションが終わったら自動でIdle2に戻るようになります。

これで攻撃モーションの遷移設定ができたので、再生してパラメータ「punching」のTriggerをオンオフしてみましょう。

攻撃の実装 スクリプトによる制御
スクリプトから攻撃のトリガーを変更するには、Animatorからパラメータの取得をして変更を行うことで実装できます。
第一回目のときに、パラメータ「Speed」の変更を行いました。その時と同じ考え方になります。
「Project>Assets>Scripts」フォルダの「PlayerControllManager」を修正します。
Update関数を以下のように修正します。
void Update()
{
//■キーボード入力を取得
x = Input.GetAxisRaw("Horizontal"); //横方向の取得
z = Input.GetAxisRaw("Vertical"); //奥方向の取得
//攻撃の入力を取得(Vで攻撃)
if (Input.GetKeyDown(KeyCode.V)){
animator.SetTrigger("punching");
}
}
再生をして動作を確認してみます。

これで、攻撃モーションの実装が完了しました。
※普段であれば、この後攻撃の当たり判定の実装などをすることですが、今回はAnimator Controllerの使い方の紹介なのでそれはまた別の記事で紹介することにします。
ジャンプの実装
地面のタグ設定
コライダーの判断のために、HierarchyのPlaneに地面のタグをつけます。「AddTag」から「Ground」を作成し、Planeのタグを「Ground」に変更します。

ジャンプの実装 ~コンポーネントの設定
ジャンプを実装するために、unitychanのRigidbodyの重力に関する設定を変更します。
重量を意味する「Mass」に50を設定します。また、「Use Gravity」にチェックをいれて、Constrainsの「Freeze Rotation」のXYZにチェックを入れます。

次に「Add Component」から「Capsule Collider」を追加して以下のように設定します。

※床を抜けて落ちて言ってしまう場合は、コライダーの設定が正しいか再確認しましょう。
ジャンプの実装 ~ Animatorの設定
次に、アニメーションの設定を行います。
「Action Adventure Pack」の「jumping up」を他と同様に、Rigを「Humanoid」に変更、Animationタブで名前を「jumping」に変更してApplyを押します。
セットアップした「jumping」をPlayerControllerのAnimatorタブで設定します。
「jumping」をドラッグアンドドロップして、「Idel2」からjumpingへ往復と、「running」から「jumping」への遷移を追加します。

そして、パラメータを追加します。
- jumping : trigger
- IsGround : bool
- JumpPower : float

次に遷移の設定を行います。
Runningからjumpingへの遷移の設定を行います。

Has Exit Time のチェックを外します。そして、Transition Durationを0にします。
Conditionsに「jumping」を追加、「JumpPower」をGreaterで0.01に設定します。

次は、「jumping」から「idle2」への遷移設定を行います。

こちらも同様に、Has Exit Timeのチェックを外して、Transition Durationを0にします。
そしてConditionsに 「IsGround」にtrue、JumpPowerをLessで0.01を設定します。

最後に、「Idle2」からjumpingの遷移設定です。

同様に、Has Exit Timeのチェックを外して、 Transition Durationを0にします。
Conditionsに「jumping」を追加し、「JumpPower」を「Greater」0.01で追加します。

ジャンプの実装 ~スクリプトの修正
「Project>Assets>Scripts」フォルダの「PlayerControllManager.cs」を修正します。
ジャンプは少し複雑なためコードが少し長くなっています。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControllManager : MonoBehaviour
{
//移動速度
[SerializeField] float moveSpeed = 2;
//ジャンプ速度 追加
[SerializeField] float jumpSpped = 200; //追加!
private float x; //横方向の移動
private float z; //奥方向の移動
private Rigidbody rb;
private Animator animator;
private Vector3 forceUp;
//追加
private bool isJump = false;
// Start is called before the first frame update
void Start()
{
//リジッドボディコンポーネントを取得
rb = GetComponent<Rigidbody>();
//animatorコンポーネントを取得
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
//■キーボード入力を取得
x = Input.GetAxisRaw("Horizontal"); //横方向の取得
z = Input.GetAxisRaw("Vertical"); //奥方向の取得
//攻撃の入力を取得(Vで攻撃)
if (Input.GetKeyDown(KeyCode.V)){
animator.SetTrigger("punching");
}
//追加
//ジャンプの入力を取得(スペース) + 設地しているか
if (Input.GetKeyDown(KeyCode.Space))
{
//ジャンプフラグを立てる
isJump = true;
}
}
private void FixedUpdate()
{
//横方向の速度設定
rb.velocity = new Vector3(x * moveSpeed, rb.velocity.y , z * moveSpeed);
//Animator Controllerからパラメータを取得する
animator.SetFloat("Speed", rb.velocity.magnitude);
//方向の取得
Vector3 direction = transform.position + new Vector3(x, 0, z);
//向きの変更
transform.LookAt(direction);
}
//追加
//コライダーに接触している間ここに入ってくる
private void OnCollisionStay(Collision other)
{
if (isJump)
{
if (animator.GetBool("IsGround"))
{
//ジャンプする(上方向に力を加える)
rb.AddForce(transform.up * jumpSpped, ForceMode.Impulse);
animator.SetTrigger("jumping");
animator.SetFloat("JumpPower",1);
isJump = false;
}
}
}
//追加
//コライダーに入った時
private void OnCollisionEnter(Collision other)
{
if (other.gameObject.CompareTag("Ground"))
{
animator.SetBool("IsGround", true);
animator.SetFloat("JumpPower", 0);
}
}
//追加
//コライダーが離れた時
private void OnCollisionExit(Collision other)
{
if (other.gameObject.CompareTag("Ground"))
{
animator.SetBool("IsGround", false);
}
}
}
スペースを押すことでジャンプするコードです。
地面に接地している場合にジャンプができるようになっています。その関係で、地面の接地をコライダーでタグ「Ground」との当たり判定を取得し、フラグによってジャンプができるかどうかを確認しています。
ジャンプはAddForceを使って、リジッドボディに上方向の力を加えています。
JumpSpeedはシリアライズフィールドにしているので、インスペクターで調整可能です。

これで完成です。動作を確認してみましょう。

少しジャンプのアニメーションがださいですが無事ジャンプできました。
まとめ
今回、「攻撃・ジャンプ アニメーションを実装する方法」を紹介しました。
- 攻撃の実装 Animatorの遷移条件の設定
- 攻撃の実装 スクリプトによる制御
- 地面のタグによるコライダーの当たり判定取得
- ジャンプに関連するコンポーネントの設定
- ジャンプに関連するAnimatorの設定
- ジャンプに関連するスクリプトの修正
今回は、必要最低限のアクションゲームに利用するようなAnimator Controllerの実装をしてみました。簡単な動作ですが、意外と大変だったのではないかと思います。ですが、実際に自分で作って動かしてみると楽しさを感じてもらえたのではないでしょうか?
今後は、攻撃判定をつけて敵にダメージを与えたりだとか、AnimatorにはBlend Treeというアニメーションを合成することでなめらかにアニメーションを切り替えるという手法もあるのでそういった実装の紹介ができたらいいなと思っています。
今回の記事が、皆さんの技術力向上につながると嬉しいです。
もしこの記事が気に入りましたら、ぜひテクリエイトへのブックマーク登録をして頂けると喜びます。
以上、おつかれさまでした!
