前回の記事「Unityゲーム制作研究(2):アセット(水面、樹木、岩、建物等)の配置とメッシュコライダーの設定方法」ではAsset Storeからアセットを入手して、シーンを拡充する方法について考察しました。これでお好みのアセットでシーンを賑やかにすることができます。

今回は、再びキャラクターに話を戻して、ゲームらしいアクションの組み込み方法を考えていきたいと思っています。この連載記事の第1回で組み込んだ「Starter Assets – Third Person Character Controller」は歩く・走る・ジャンプするなどの三人称キャラクターの基本的なアクションが最初から組み込まれており、Unity初学者が学ぶには大変有用なサンプルなのですが、敵を攻撃したり、防御したりといったその他のアクションは自分で組み込まなければなりません。

そこで今回は、このThird Person Character Controllerに、オリジナルのアクション、例えば攻撃や防御のようなアクションを追加する方法について考察していきたいと思います。

この記事を書くにあたり使用した環境と必要となるスキルについて

この記事を書くにあたり、当方が使用した環境、及びこの記事の対象者のスキルを明記しておきたいと思います。

  • OS: macOS Monterey 12.5
  • Unity: 2021.3.5f1 Personal(バージョンが異なる場合、機能や画面の様子が異なる場合があります)
  • 対象者: 前回の記事「Unityゲーム制作研究(2)」を終えた方、もしくは同程度のスキルをお持ちの方

Third Person Character Controllerの単純な組み込みに関しては「Unityゲーム制作研究(1):Third Person Character Controllerを使ってユニティーちゃんを動かす方法」をご覧ください。


© Unity Technologies Japan/UCL
※「ユニティーちゃん」はUnity-Chan License (UCL)の下に配布されており、当サイトでもこのライセンス条項に基づき使用させていただいております。

スポンサーリンク




目次

  1. ユニティーちゃんに武具アイテムを追加しよう!
    1. Elven Weaponsの入手
    2. ユニティーちゃんにソードを装備する
    3. ユニティーちゃんにシールドを装備する
  2. ThirdPersonCharacterControllerのアクションの追加
    1. Animatorウィンドウでアクションフローを設定する
    2. InputSystemウィンドウで入力の設定をする
  3. Third Person Character Controllerのソースコードの改修
    1. StarterAssetsInputs.csの改修
    2. ThirdPersonController.csの改修
  4. まとめ

1. ユニティーちゃんに武具アイテムを追加しよう!

ではまず、ユニティーちゃんに武具アイテムを持たせるところから始めてみたいと思います。

今回は「Unity Asset Store」でこのようなFreeアセットを選んでみました。

1-1. Elven Weaponsの入手

https://assetstore.unity.com/packages/3d/props/weapons/elven-weapons-36901

入手したら、メニューバーの「Window > Package Manager」を開いて、タブのすぐ下の「」の横をクリックし「My Assets」を選択して上記のアセットをInportしておいてください。

1-2. ユニティーちゃんにソードを装備する

ではまず、ユニティーちゃんにソードを持たせてみましょう。Projectに予めInportしておいた「Elven Weapons > Prefabs > Elven_Sword_01」をSceneにドラッグしてユニティーちゃんの右手に収まるようにポジションを調整します。

またHierarchyですが、この「Elven_Sword_01」は「unitychan_dynamic」内の「Character1_RightHand」に収めるようにしてください。

このような階層にすることで、右手と同一の座標に収めることができます。

1-3. ユニティーちゃんにシールドを装備する

今度はシールドを持たせてみましょう。「Elven Weapons > Prefabs > Elven_Shield_01」をSceneにドラッグしてユニティーちゃんの左手に収まるようにポジションを調整します。

またHierarchyですが、この「Elven_Shield_01」は「unitychan_dynamic」内の「Character1_LeftHand」に収めるようにしてください。

ちなみに両手の指の動きは、アニメーション側で制御されているため握らせる必要はありません

これでユニティーちゃんにソードシールドを装備させることができました。ソードとシールドのポジションの微調整は、これから行うアクション設定が全て完了した後、実際の動作を見ながら調整してみてください。この段階では両手の中に収められており、正しい階層に含められていれば問題ありません。

2. Third Person Character Controllerのアクションの追加

今度は今回の記事の本論となるアクションを追加していきます。

2-1. Animatorウィンドウでアクションフローを設定する

まずProjectの「StarterAssets > ThirdPersonController > Animations > StarterAssetsThirdPerson」をダブルクリックして開いてみてください。すると下図のように「Animator」ウィンドウが開きます。

Animatorには各アクションのフロー図が表示されています。各アクションは「State」と呼ばれ、そこから伸びる矢印のついた遷移線は「Transition」と呼ばれています。この「Transition」には、動作の流れの方向が明示されていることにも注意してください。

では早速、攻撃アクションを追加してみましょう。フロー図の余白で右クリックして「Create State > Empty」してください。するとグレーの新しい「State」が追加されます。このStateは、Inspectorで「Attack」と命名してください。

今度は「Transition」を追加します。「Idle Walk Run Blend」で右クリックして「Make Transition」します。動作の行き着く先となる「Attack」までドラックして作成を完了させてください。

今度は「Attack2」という名の新しいStateを追加して、「Attack」から「Attack2」までの新しいTransitionを追加しておきます。最後に「Attack2」から「Idle Walk Run Blend」までのTransitionも追加してください。

これで攻撃アクションのフローは完了です。今度は防御アクションを追加します。攻撃アクションの時と全く同様の方法で「Defense」というStateを追加し、双方向のTransitionを追加しておいてください。

今度は動作トリガーとなる「Parameter」を作成します。上図を参考にBool値の「Attack」と「Defense」という名称のParameterを作成しておいてください。ここまででアクションのStateTransition、またParameterを作ることができました。

今度は「Attack」「Attack2」「Defense」にアクション(アニメーション)を設定します。ユニティーちゃんには予めいくつかのポーズが組み込まれていますので、今回はそれを使用してみたいと思います。

Projectの「unity-chan! > Unity-chan! Model > Art > Animations > Character_1_Reference」内の「POSE28」を「Attack」のMotion設定までドラッグします。

同様にして「Character_1_Reference」内の「POSE30」を「Attack2」のMotion設定までドラッグします。

ここで設定した2つのポーズ「POSE28」と「POSE30」が攻撃アクション(アニメーション)を構成します。

今度は「Idle Walk Run Blend」から「Attack」まで流れるTransitionをクリックして選択しておきます。「Idle Walk Run Blend」の動作完了を待たず攻撃トリガーが呼ばれたらすぐに動作させたいので「Has Exit Time」のチェックは外しておきます。また先ほど設定したパラメーター「Attack」を「true」に設定します。

これで「Attack」パラメーターが「true」になった時に、攻撃アクションが実行され「Attack > Attack2 > Idle Walk Run Blend」までの一連のアクションが実行されます。

今までやった同様の方法で、今度は防御アクションを設定していきます。「Character_1_Reference」内の「POSE29」を「Defense」のMotion設定までドラッグします。

今度は「Idle Walk Run Blend」から「Defense」まで流れるTransitionをクリックして選択しておきます。防御アクションも「Idle Walk Run Blend」の動作完了を待たず防御トリガーが呼ばれたらすぐに動作させたいので「Has Exit Time」のチェックは外しておきます。また先ほど設定したパラメーター「Defense」を「true」に設定します。

今度は「Defense」から「Idle Walk Run Blend」まで流れるTransitionを設定しますが、こちらはトリガーが引かれた状態(つまり操作キーやボタンが押された状態)の時はアクションを継続して欲しいので、パラメーター「Defense」を「false」に設定します。こうすることで「false」になるまでアクションが止まります。この点は攻撃アクションの時とは異なる設定ということになります。

これでAnimatorウィンドウの設定は完了です!

では実際に設定したアクションが動くのかどうか確認してみましょう。Animatorウィンドウが見える状態のまま、画面上部中央の「▶︎」をクリックして動作を確認してみましょう!

先ほど設定したパラメーターの「Attack」と「Defense」のチェックを入れたり外したりしてみましょう。ユニティーちゃんがちゃんとアクションすればここまでの設定が正しいということになります!

2-2. InputSystemウィンドウで入力の設定をする

実際のゲームでは、キーボードやコントローラーなどから操作することになりますので、入力側の設定も必要となります。Projectの「StarterAssets > InputSystem > StarterAssets」をダブルクリックで下記のようなウィンドウが開きます。この「Action」タブ上の「+」をクリックして「Attack」と「Defense」というActionをそれぞれ追加しておきます。また「Action Type」は「Pass Through」、「Control Type」は「Any」としておきます。

今設定した「Attack」と「Defense」のそれぞれの「+」をクリックすることで入力デバイスの設定ができますが、ここでは「Keyboard」と「Gamepad」をそれぞれ設定しておきたいと思います。

Path」という項目でお好みの入力キーを設定しておきます。同様にしてGamepadのお好みの入力キーも設定しておいてください。

3. Third Person Character Controllerのソースコードの改修

さて、ここまでは全くコードを書かずにUnityの画面のみで改修を試みてきましたが、最後にソースコードの改修が必要となります。下記の左右二つのコードにそれぞれ追記が必要となります。

3-1. StarterAssetsInputs.csの改修

StarterAssets > InputSystem > StarterAssetsInputs」をダブルクリックしてください。設定されているエディターで開くはずです。

publicな変数「attack」と「defense」を定義して、入力値を取得する記述を追加します。以下を参考に追記してください。

using UnityEngine;
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
using UnityEngine.InputSystem;
#endif

namespace StarterAssets
{
	public class StarterAssetsInputs : MonoBehaviour
	{
		[Header("Character Input Values")]

		### ※中略 ###

		public bool attack;
		public bool defense;

		### ※中略 ###

#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED

		### ※中略 ###

		public void OnAttack(InputValue value)
		{
			AttackInput(value.isPressed);
		}

		public void OnDefense(InputValue value)
		{
			DefenseInput(value.isPressed);
		}
#endif

		### ※中略 ###

		public void AttackInput(bool newAttackState)
		{
			attack = newAttackState;
		}

		public void DefenseInput(bool newDefenseState)
		{
			defense = newDefenseState;
		}
	}
}

3-2. ThirdPersonController.csの改修

ThirdPersonController > Scripts > ThirdPersonController」をダブルクリックしてください。設定されているエディターで開くはずです。

Update関数内から呼ばれるAttack関数とDefense関数を定義します。これらの関数はUnity側で設定したパラメーターにBool値を渡す役割を持っています。ちなみに「_input.move = Vector2.zero;」は、攻撃または防御時に動きを止めるために記述してあります。以下を参考に追記してください。

using UnityEngine;
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
using UnityEngine.InputSystem;
#endif

namespace StarterAssets
{
    [RequireComponent(typeof(CharacterController))]
#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    [RequireComponent(typeof(PlayerInput))]
#endif
    public class ThirdPersonController : MonoBehaviour
    {
        ### ※中略 ###

        private int _animIDAttack;
        private int _animIDDefense;

        ### ※中略 ###

        private void Update()
        {
            ### ※中略 ###

            Attack();
            Defense();
        }

        private void AssignAnimationIDs()
        {
            ### ※中略 ###

            _animIDAttack = Animator.StringToHash("Attack");
            _animIDDefense = Animator.StringToHash("Defense");
        }

        private void Attack()
        {
            if (Grounded)
            {
                if (_input.attack)
                {
                    // update animator if using character
                    if (_hasAnimator)
                    {
                        _animator.SetBool(_animIDAttack, true);
                        _input.move = Vector2.zero;
                    }
                }
                else
                {
                    // update animator if using character
                    if (_hasAnimator)
                    {
                        _animator.SetBool(_animIDAttack, false);
                    }
                }
            }
            else
            {
                // if we are not grounded, do not attack
                _input.attack = false;
            }
        }

        private void Defense()
        {
            if (Grounded)
            {
                if (_input.defense)
                {
                    // update animator if using character
                    if (_hasAnimator)
                    {
                        _animator.SetBool(_animIDDefense, true);
                        _input.move = Vector2.zero;
                    }
                }
                else
                {
                    // update animator if using character
                    if (_hasAnimator)
                    {
                        _animator.SetBool(_animIDDefense, false);
                    }
                }
            }
            else
            {
                // if we are not grounded, do not defense
                _input.defense = false;
            }
        }

        ### ※中略 ###
    }
}

4. GameViewでPlayしてみよう!

さて、設定した通りに攻撃・防御のアクションが動くかどうか実際に動かしてみましょう!もしソードやシールドの位置や角度がおかしい場合(顔にソードが突き刺さってしまっていたり、シールドにソードが突き刺さってしまっていたりする場合)は角度を微調整してみましょう!

6-1. ゲームコントローラーで操作したい場合

キーボードでも操作できますが、「Starter Assets – Third Person Character Controller」は、市販のゲームコントローラーにも対応しています。以下の製品で問題なく動作することを確認できました。

※上記のリンクはamazonへのリンクとなっています。

6-2. ゲームコントローラーのキー操作について

左スティック:ユニティーちゃんの操作
右スティック:カメラの操作
L2ボタン:左スティックと併用で走る動作
Aボタン:ジャンプ動作
あなたが設定したボタン:攻撃
あなたが設定したボタン:防御

4. まとめ

いかがだったでしょうか。今回はユニティーちゃんに新しいアクションを追加すべく、Third Person Character Controllerに、攻撃や防御のようなオリジナルのアクションを追加する方法について考察してきました。

これまでと比べると少し難易度も増したような感じもしますが、今回の改修方法をマスターすれば、Third Person Character Controllerをベースにしてキャラクターのアクションをさらに充実させていくことも可能です。

今回は扱いませんでしたが、BlendTreeという機能などを使ってさらに複雑で完成度の高いアニメーションを付与することもできます。Unityのゲーム開発は本当に奥が深いです!

この記事の続き:


© Unity Technologies Japan/UCL
※「ユニティーちゃん」はUnity-Chan License (UCL)の下に配布されており、当サイトでもこのライセンス条項に基づき使用させていただいております。