【Unity】2Dと3Dのジャンプ移動やアニメーションの実装方法を解説
今回はUnityを始めたばかりの人向けに、キャラクターの移動方法を覚えた次のステップとして2Dおよび3Dにおいてキャラクターにジャンプ動作をさせる機能の実装方法を紹介いたします。
※本記事の操作キャラクターには「Unity-Chan(ユニティちゃん)」を使用しています。
© Unity Technologies Japan/UCL
参考ページ)ユニティちゃん公式サイト ガイドライン
Contents
Unityを使って「2Dキャラ」をジャンプさせる基礎知識
2D空間におけるキャラクターにジャンプをさせるフロー
2D空間におけるキャラクターにジャンプをさせるための大まかなフローは下記になります。
- キャラクター、床のオブジェクトを配置
- キャラクター及び床に必要なコンポーネントを用意
- キャラクターにジャンプをさせるためのスクリプトを用意
ジャンプをさせるために使用するコンポーネント
使用する主なコンポーネントはrigidbody,colliderの二つになります。
・rigidbody:「力の計算(物体に働く重力や摩擦などの力の計算)」を行うコンポーネント
・collider:「物体の当たり判定(衝突)」を行うコンポーネント
上記のコンポーネントは、Add Component>Physics 3Dの項目にあります。
2D用と3D用のものが用意されていますので、2D空間で使用する場合は、「2D」と付いている方を利用します。
colliderに関しては複数の形状がありますので下記の表でご紹介いたします。
Box Collider 2D | ボックス状の衝突判定 | |
Capsule Collider 2D | カプセル状の衝突判定 | |
Circle Collider 2D | サークル状の衝突判定 | |
Edge Collider 2D | 線状の衝突判定 | |
Polygon Collider 2D | 自由な形状の衝突判定 | |
Composite Collider 2D | BoxとPolygonの衝突判定を組み合わせる |
必要な形状の衝突判定を選ぶ必要があります。
ジャンプをさせるためのスクリプト
ジャンプをされるためのスクリプトは、C#にて記述をしていきます。
先ほど追加したコンポーネントによる力の計算により、キャラクターにジャンプをさせることになります。
ジャンプ部分のスクリプトは下記のようになります。
1 2 3 4 5 |
float jumpForce = 390.0f; // ジャンプ時に加える力 if (Input.GetKeyDown(KeyCode.Space)) { this.rb.AddForce(transform.up * this.jumpForce); } |
スペースキーを押した時に、計算により求められた力を与えることでキャラクターがジャンプします。
これだけでは、キャラクターがスペースキーを押すたびにジャンプをしてしまいますので、地面に接地している時だけなどジャンプに制限をかけるスクリプトを追加する必要があります。
Unityを使って「3D」キャラをジャンプさせる基礎知識
3D空間でキャラクターをジャンプさせるフロー自体は、2Dと同様ですがジャンプ動作をさせる方法は3つあります。
1.CharacterController関数を利用する
キャラクターを操作するための関数がCharacterControllerになります。
実装自体も簡単で、何個かの設定をすればしようか可能です。
物理演算を行わないようなゲームによく使われる手法となります。
1 |
CharacterController.Move(Vector3); |
と呼び出すだけでキャラクターを動かすことが可能です。
2.Rigidbodyを使用する
CharacterControllerと違い、物理演算を使用してキャラクターを動かします。
1 |
RigidBody.velocity = Vector3; |
と記述することで、物理的な速度がキャラクターに与えられ動かすことができます。
参考記事)【Unity】Rigidbodyを使用して重力・空気抵抗を発生させる方法
3.transform.positionを利用する
キャラクターの座標を数値で指定して動かす手法になります。
Update関数内で、transformを徐々に変化させることで、キャラクターが動いているように見せます。
本記事の後半では、こちらを利用してスクリプトを組んでいます。
参考記事→)【Unity】Transformを使って3Dオブジェクトを移動させる方法
【2D】実際にユニティちゃんをジャンプさせる手順
今まで紹介した内容を組み合わせて実際に2D、3D空間でユニティちゃんにジャンプの動作をできるように実装をしていきましょう。
事前準備として、テストに使用する下記2つのユニティちゃんのデジタルアセットデータをダウンロードしておきます。
・ユニティちゃん 2Dデータ
・ユニティちゃん 3Dデータ
それでは2Dでunityちゃんをジャンプさせてみよう
新規プロジェクトの立ち上げ
Unityを起動して、新規プロジェクトを立ち上げます。
2Dユニティちゃんにジャンプをさせるので、テンプレートは「2D」を選択しておきます。
プロジェクト名称は自由で構いませんが今回は「UnityChan2D」としておきます。
ユニティちゃん(2D)のアセットデータのインポート
事前にダウンロードしておいたデジタルアセットデータのインポートを行います。
File > Open Scenes > UnityChan2D.unitypackage
インポートが完了すると、プロジェクトウィンドウ内にあるAssetsに「UnityChan2D」が追加されます。
ユニティちゃん(2D)と床となるマテリアルの追加
今回はキャラクターとしてユニティちゃん、床となるマテリアルとして背景素材を利用します。
ユニティちゃんは、UnityChan2D > Sprites にある「UnityChan_footwork_0」をドラッグ&ドロップして、ヒエラルキーウィンドウへ追加します。
背景素材は、UnityChan 2D > Demo > Sprites にある「BG_02」をドラッグ&ドロップして、ヒエラルキーウィンドウへ追加します。
BG_02のサイズは適宜変更します。
ヒエラルキーウィンドウへ各素材を追加をすると、シーンウィンドウは下記のような状態になります。
コンポーネントの追加
ユニティちゃんと床となるマテリアルに必要となるコンポーネントを追加します。
ユニティちゃんと床となるマテリアルにRigidbody 2Dを追加。
Add Components > Physics 2D > Rigidbody 2D
ユニティちゃんを動かした時に転ばないように、RigidBodyのConstraints内にあるFreeze Rotetion Zにチェックを入れておきます。
床となるマテリアル(BG_02)が落下しないようにRigidBodyのBody TypeはKinematicを選択しておきます。
ユニティちゃんにはCapsule Collider 2DとBox Collider 2Dを、床となるマテリアル(BG_02)にはBox Collider 2Dのみを追加。
ユニティちゃんへの衝突判定の追加
下記の手順でColliderを追加します。
Add Components > Physics 2D > Capsule Collider 2D
Add Components > Physics 2D > Box Collider 2D
Colliderの追加後、サイズ変更及び位置調整を行い、下記の画像のようにしておきます。
床の接地判定に使用するために、ユニティちゃんに追加したBox Collider2Dを選択し、Is Triggerにチェックを入れておきます。
床となるマテリアルへの衝突判定の追加
下記の手順でColliderを追加します。
Add Components > Physics 2D > Box Collider 2D
Colliderの追加後、サイズ変更及び位置調整を行い、下記の画像のようにしておきます。
ジャンプ及び左右移動のスクリプト追加
ジャンプ及び左右移動をさせるスクリプトを作成します。
プロジェクトウィンドウのCreateよりC♯ Scriptを選択し、「PlayerController」と名前をつけます。
作成した「PlayerController」をダブルクリックで開き、スクリプトを作成していきます。
ジャンプ及び左右移動をさせるスクリプトは下記になります。
ジャンプ制限及び左右反転もスクリプト内に記述していますので参考にしてみてください。
Unityを使ったC♯入門はこちら→)[第1回] C#(C Sharp)言語とは?|Unityで学ぶC#入門
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { Rigidbody2D rb; float jumpForce = 390.0f; // ジャンプ時に加える力 float jumpThreshold = 2.0f; // ジャンプ中か判定するための閾値 float runForce = 30.0f; // 走り始めに加える力 float runSpeed = 0.5f; // 走っている間の速度 float runThreshold = 2.0f; // 速度切り替え判定のための閾値 bool isGround = true; // 地面と接地しているか管理するフラグ int key = 0; // 左右の入力管理 void Start() { this.rb = GetComponent<Rigidbody2D>(); } void Update() { GetInputKey(); // 入力を取得 Move(); // 入力に応じて移動する } void GetInputKey() { key = 0; if (Input.GetKey(KeyCode.RightArrow)) key = 1; if (Input.GetKey(KeyCode.LeftArrow)) key = -1; } void Move() { // 接地している時にSpaceキー押下でジャンプ if (isGround) { if (Input.GetKeyDown(KeyCode.Space)) { this.rb.AddForce(transform.up * this.jumpForce); isGround = false; } } // 左右の移動。一定の速度に達するまではAddforceで力を加え、それ以降はtransform.positionを直接書き換えて同一速度で移動する float speedX = Mathf.Abs(this.rb.velocity.x); if (speedX < this.runThreshold) { this.rb.AddForce(transform.right * key * this.runForce * stateEffect); //未入力の場合は key の値が0になるため移動しない } else { this.transform.position += new Vector3(runSpeed * Time.deltaTime * key * stateEffect, 0, 0); } } //着地判定 void OnTriggerEnter2D(Collider2D col) { if (col.gameObject.tag == "Ground") { if (!isGround) isGround = true; } } void OnTriggerStay2D(Collider2D col) { if (col.gameObject.tag == "Ground") { if (!isGround) isGround = true; } } } |
スクリプトを入力・保存を行ったら、プロジェクトウィンドウの「PlayerController」を選択し、ヒエラルキーウィンドウのユニティちゃんにドラッグ&ドロップします。
実際に動かしてみると下記のようになります。
アニメーションの遷移の設定
待機、ジャンプ及び歩行におけるアニメーションの遷移を設定していきます。
Animator Controllerの作成
プロジェクトウィンドウのCreateよりAnimator Controllerを選択し、「unity_move」と名前をつけます。
ノードの作成
作成した「unity_move」をダブルクリックするとアニメーションウィンドウが開きます。
アニメーションウィンドウ内で右クリック > Create State > Emptyを選択し、Emptyノードを追加します。
Emptyノードをクリックし、インスペクターウィンドウで待機状態「Idle」の名称設定と適用するアニメーションの設定を行います。
今回アニメーション自体は、アセットデータに含まれるものを使用します。
待機状態:Footwork
設定は下記のように行います。
同様にして、「Move」、「Jump_up」、「Jump_down」の3つのノードを作成します。
各項目に適用するアニメーションは下記を使用します。
- 歩行:Move
- ジャンプ(上昇):Jump_up
- ジャンプ(下降):Jump_down
ノード間の遷移の設定
ノード間の遷移の設定を行います。
「Idel」ノードの上で右クリックし、Make Transitionを選択します。
マウスを動かすと「Idle」から矢印がのびるので、「Move」の上でクリックをします。
これで「Idle」から「Move」への遷移が設定されました。
設定のフローは下記を参考にしてください。
「Move」から「Idle」への遷移やその他の遷移に関しても同様に設定を行います。
遷移の全景は下記のようになります。
遷移の条件の設定
次に遷移の条件の設定をします。
「Idle」から「Move」への遷移を例にとって手順を示すと下記になります。
- アニメーターウィンドウのParametersの+ボタンをクリックし、Boolを選択。
- 作成されたパラメータの名称を「Run」にする。
- 「Idle」から「Move」への矢印を選択。
- インスペクターウィンドウにあるHas Exit Timeのチェックボックスを外す。
- インスペクターウィンドウにあるConditionsの+ボタンをクリックし、ドロップダウンからRunと trueを選択。
上記の作成方法でパラメータとしてIdle、JumpUp、JumpDownを作成し、同様の設定で各矢印の設定を行えばAnimator Controllerの設定は完了です。
キャラクターへのAnimator Controllerの適用
作成した「unity_move」をヒエラルキーウィンドウのユニティちゃんにドラッグ&ドロップし、遷移情報を適用します。
アニメーションを遷移させるスクリプトの作成
「Player Controller」にアニメーションの遷移に関するスクリプトの追加を行います。
アニメーションの遷移を追加したスクリプトは下記のようになります。
今回はswich-case文を使用してアニメーションの遷移を行っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { Rigidbody2D rb; Animator animator; float jumpForce = 390.0f; // ジャンプ時に加える力 float jumpThreshold = 2.0f; // ジャンプ中か判定するための閾値 float runForce = 30.0f; // 走り始めに加える力 float runSpeed = 0.5f; // 走っている間の速度 float runThreshold = 2.0f; // 速度切り替え判定のための閾値 bool isGround = true; // 地面と接地しているか管理するフラグ int key = 0; // 左右の入力管理 string state; // プレイヤーの状態管理 string prevState; // 前の状態を保存 float stateEffect = 1; // 状態に応じて横移動速度を変えるための係数 void Start() { this.rb = GetComponent<Rigidbody2D>(); this.animator = GetComponent<Animator>(); } void Update() { GetInputKey(); // ① 入力を取得 ChangeState(); // ② 状態を変更する ChangeAnimation(); // ③ 状態に応じてアニメーションを変更する Move(); // ④ 入力に応じて移動する } void GetInputKey() { key = 0; if (Input.GetKey(KeyCode.RightArrow)) key = 1; if (Input.GetKey(KeyCode.LeftArrow)) key = -1; } void ChangeState() { // 空中にいるかどうかの判定。上下の速度(rigidbody.velocity)が一定の値を超えている場合、空中とみなす if (Mathf.Abs(rb.velocity.y) > jumpThreshold) { isGround = false; } // 接地している場合 if (isGround) { // 走行中 if (key != 0) { state = "RUN"; //待機状態 } else { state = "IDLE"; } // 空中にいる場合 } else { // 上昇中 if (rb.velocity.y > 0) { state = "JUMP"; // 下降中 } else if (rb.velocity.y < 0) { state = "FALL"; } } } void ChangeAnimation() { // 状態が変わった場合のみアニメーションを変更する if (prevState != state) { switch (state) { case "JUMP": animator.SetBool("JumpUp", true); animator.SetBool("JumpDown", false); animator.SetBool("Run", false); animator.SetBool("Idle", false); stateEffect = 0.5f; break; case "FALL": animator.SetBool("JumpDown", true); animator.SetBool("JumpUp", false); animator.SetBool("Run", false); animator.SetBool("Idle", false); stateEffect = 0.5f; break; case "RUN": animator.SetBool("Run", true); animator.SetBool("JumpDown", false); animator.SetBool("JumpUp", false); animator.SetBool("Idle", false); stateEffect = 1f; transform.localScale = new Vector3(key, 1, 1); // 向きに応じてキャラクターを反転 break; default: animator.SetBool("Idle", true); animator.SetBool("JumpDown", false); animator.SetBool("Run", false); animator.SetBool("JumpUp", false); stateEffect = 1f; break; } // 状態の変更を判定するために状態を保存しておく prevState = state; } } void Move() { // 接地している時にSpaceキー押下でジャンプ if (isGround) { if (Input.GetKeyDown(KeyCode.Space)) { this.rb.AddForce(transform.up * this.jumpForce); isGround = false; } } // 左右の移動。一定の速度に達するまではAddforceで力を加え、それ以降はtransform.positionを直接書き換えて同一速度で移動する float speedX = Mathf.Abs(this.rb.velocity.x); if (speedX < this.runThreshold) { this.rb.AddForce(transform.right * key * this.runForce * stateEffect); //未入力の場合は key の値が0になるため移動しない } else { this.transform.position += new Vector3(runSpeed * Time.deltaTime * key * stateEffect, 0, 0); } } //着地判定 void OnTriggerEnter2D(Collider2D col) { if (col.gameObject.tag == "Ground") { if (!isGround) isGround = true; } } void OnTriggerStay2D(Collider2D col) { if (col.gameObject.tag == "Ground") { if (!isGround) isGround = true; } } } |
これで2D空間におけるアニメーションを含めたジャンプ及び移動の設定が完了です。
実際に動作をさせると下記のようになります。
【3D】実際にユニティちゃんをジャンプさせる手順
新規プロジェクトの立ち上げ
Unityを起動して、新規プロジェクトを立ち上げます。
3Dユニティちゃんにジャンプをさせるので、テンプレートは「3D」を選択しておきます。
プロジェクト名称は自由で構いません。
今回は「UnityChan3D」としておきます。
ユニティちゃん(3D)のアセットデータのインポート
事前にダウンロードしておいたデジタルアセットデータのインポートを行います。
File > Open Scenes > UnityChan_1_2_1.unitypackage
インポートが完了すると、プロジェクトウィンドウ内にあるAssetsに「UnityChan」が追加されます。
ユニティちゃん(3D)と床となるマテリアルの追加
今回はキャラクターとしてユニティちゃん、床となるマテリアルとしてPlaneオブジェクトを利用します。
ユニティちゃんは、UnityChan > Modelsにある「unitychan」をドラッグ&ドロップして、ヒエラルキーウィンドウへ追加します。
Planeオブジェクトは、ヒエラルキーウィンドウのCreateから3D Object > Planeを選択し追加します。
Planeオブジェクトのサイズは適宜変更します。
ヒエラルキーウィンドウへ各素材を追加をすると、シーンウィンドウは下記のような状態になります。
コンポーネントの追加
ユニティちゃんと床となるマテリアルに必要となるコンポーネントを追加します。
ユニティちゃんと床となるマテリアルにRigidbodyを追加します。
追加の仕方は、2Dの時と同じですが、Phsics2DではなくPhysicsを使用します。
Add Components > Physics > Rigidbody
ユニティちゃんを動かした時に転ばないように、RigidBodyのConstraints内にあるFreeze Rotetion XおよびZにチェックを入れておきます。
床となるマテリアルは、2Dの時と同じように落下しないようにRigidBodyのBody TypeはKinematicを選択しておきます。
次に、ユニティちゃんにCapsule ColliderとBox Colliderを追加します。
床となるマテリアルであるPlaneオブジェクトにはMesh Colliderが設定されているため追加は不要です。
ユニティちゃんへの衝突判定の追加
下記の手順でColliderを追加します。
Add Components > Physics > Capsule Collider
Add Components > Physics > Box Collider
Colliderの追加後、サイズ変更及び位置調整を行い、下記の画像のようにしておきます。
床の接地判定に使用するために、ユニティちゃんに追加したBox Colliderを選択し、Is Triggerにチェックを入れておきます。
設定完了後、再生をスタートすると下記のような動作となります。
ジャンプ及び左右移動のスクリプト追加
ジャンプ及び左右移動をさせるスクリプトを作成します。
プロジェクトウィンドウのCreateよりC♯ Scriptを選択し、「Player」と名前をつけます。
作成した「Player」をダブルクリックで開き、スクリプトを作成していきます。
ジャンプ及び左右移動をさせるスクリプトは下記になります。
ジャンプ制限及び左右反転もスクリプト内に記述していますので参考にしてみてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { //Rigidbodyを変数に入れる Rigidbody rb; //移動スピード float speed = 3.0f; //ジャンプ力 float jumpForce =400.0f; //ユニティちゃんの位置を入れる Vector3 playerPos; //地面に接触しているか否か bool Ground = true; int key = 0; void Start() { //Rigidbodyを取得 rb = GetComponent<Rigidbody>(); //ユニティちゃんの現在より少し前の位置を保存 playerPos = transform.position; } void Update() { GetInputKey(); Move(); } void GetInputKey() { //A・Dキー、←→キーで横移動 float x = Input.GetAxisRaw("Horizontal") * Time.deltaTime * speed; //W・Sキー、↑↓キーで前後移動 float z = Input.GetAxisRaw("Vertical") * Time.deltaTime * speed; if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.RightArrow)) { key = 1; } if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.LeftArrow)) { key = -1; } } void Move() { if (Ground) { if (Input.GetButton("Jump")) { //jumpForceの分だけ上方に力がかかる rb.AddForce(transform.up * jumpForce); Ground = false; } } //現在の位置+入力した数値の場所に移動する rb.MovePosition(transform.position + new Vector3(Input.GetAxisRaw("Horizontal") * Time.deltaTime * speed, 0, Input.GetAxisRaw("Vertical") * Time.deltaTime * speed)); //ユニティちゃんの最新の位置から少し前の位置を引いて方向を割り出す Vector3 direction = transform.position - playerPos; //移動距離が少しでもあった場合に方向転換 if (direction.magnitude >= 0.01f) { //directionのX軸とZ軸の方向を向かせる transform.rotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z)); } else { key = 0; } //ユニティちゃんの位置を更新する playerPos = transform.position; } //ジャンプ後、Planeに接触した時に接触判定をtrueに戻す void OnTriggerEnter(Collider col) { if (col.gameObject.tag == "Ground") { if (!Ground) Ground = true; } } } |
スクリプトを入力・保存を行ったら、プロジェクトウィンドウの「Player」を選択し、ヒエラルキーウィンドウのユニティちゃんにドラッグ&ドロップします。
実際に動かしてみると下記のようになります。
アニメーションの遷移の設定
待機、ジャンプ及び歩行におけるアニメーションの遷移を設定していきます。
Animator Controllerの作成
2Dの時と同じようにプロジェクトウィンドウのCreateよりAnimator Controllerを選択し、「UnityAction」と名前をつけます。
ノードの作成
作成した「UnityAction」をダブルクリックするとアニメーションウィンドウが開きます。
2Dの時と同じ作成方法で、下記のノードを作成します。
- 待機状態:Idle
- 歩行:Run
- ジャンプ:Jump
各状態に適用するアニメーションは、アセットデータに入っているものを使用します。
- 待機状態:WAIT00
- 歩行:RUM00_F
- ジャンプ:JUMP00
ノード間の遷移の設定
2Dの時と同様にノード間の遷移の設定を行います。
3つの状態が下記のようになるように設定をおこなってください。
遷移の条件の設定
次に遷移の条件の設定をします。
「Idle」から「Run」への遷移を例にとって手順を示すと下記になります。
- アニメーターウィンドウのParametersの+ボタンをクリックし、Boolを選択。
- 作成されたパラメータの名称を「Running」にする。
- 「Idle」から「Run」への矢印を選択。
- インスペクターウィンドウにあるHas Exit Timeのチェックボックスを外す。
- インスペクターウィンドウにあるConditionsの+ボタンをクリックし、ドロップダウンからRunningとtrueを選択。
上記の作成方法でパラメータとしてIdle、Jumpingを作成し、同様の設定で各矢印の設定を行えばAnimator Controllerの設定は完了です。
キャラクターへのAnimator Controllerの適用
作成した「UnityAction」をヒエラルキーウィンドウのユニティちゃんにドラッグ&ドロップし、遷移情報を適用します。
アニメーションを遷移させるスクリプトの作成
「Player」にアニメーションの遷移に関するスクリプトの追加を行います。
アニメーションの遷移を追加したスクリプトは下記のようになります。
今回は2Dの時と同じようにswich-case文を使用してアニメーションの遷移を行っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { //Rigidbodyを変数に入れる Rigidbody rb; //移動スピード float speed = 3.0f; //ジャンプ力 float jumpForce =400.0f; //Animatorを入れる変数 private Animator animator; //ユニティちゃんの位置を入れる Vector3 playerPos; //地面に接触しているか否か bool Ground = true; int key = 0; string state; string prevState; void Start() { //Rigidbodyを取得 rb = GetComponent<Rigidbody>(); //ユニティちゃんのAnimatorにアクセスする animator = GetComponent<Animator>(); //ユニティちゃんの現在より少し前の位置を保存 playerPos = transform.position; } void Update() { GetInputKey(); ChangeState(); ChangeAnimation(); Move(); } void GetInputKey() { //A・Dキー、←→キーで横移動 float x = Input.GetAxisRaw("Horizontal") * Time.deltaTime * speed; //W・Sキー、↑↓キーで前後移動 float z = Input.GetAxisRaw("Vertical") * Time.deltaTime * speed; if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.RightArrow)) { key = 1; } if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.LeftArrow)) { key = -1; } } void ChangeState() { if (Ground) { if (key != 0) { state = "RUN"; } else { state = "IDLE"; } } else { state = "JUMP"; } } void ChangeAnimation() { if (prevState != state) { switch (state) { case "JUMP": animator.SetBool("Jumping", true); animator.SetBool("Running", false); animator.SetBool("Idle", false); break; case "RUN": animator.SetBool("Jumping", false); animator.SetBool("Running", true); animator.SetBool("Idle", false); break; default: animator.SetBool("Jumping", false); animator.SetBool("Running", false); animator.SetBool("Idle", true); break; } prevState = state; } } void Move() { if (Ground) { if (Input.GetButton("Jump")) { //jumpForceの分だけ上方に力がかかる rb.AddForce(transform.up * jumpForce); Ground = false; } } //現在の位置+入力した数値の場所に移動する rb.MovePosition(transform.position + new Vector3(Input.GetAxisRaw("Horizontal") * Time.deltaTime * speed, 0, Input.GetAxisRaw("Vertical") * Time.deltaTime * speed)); //ユニティちゃんの最新の位置から少し前の位置を引いて方向を割り出す Vector3 direction = transform.position - playerPos; //移動距離が少しでもあった場合に方向転換 if (direction.magnitude >= 0.01f) { //directionのX軸とZ軸の方向を向かせる transform.rotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z)); } else { key = 0; } //ユニティちゃんの位置を更新する playerPos = transform.position; } //ジャンプ後、Planeに接触した時に接触判定をtrueに戻す void OnTriggerEnter(Collider col) { if (col.gameObject.tag == "Ground") { if (!Ground) Ground = true; } } } |
これで3D空間におけるアニメーションを含めたジャンプ及び移動の設定が完了です。
実際に動作をさせると下記のようになります。
まとめ
いかがでしたでしょうか。
Unityの2D及び3Dキャラクターにジャンプ移動をさせる方法についてご紹介してきました。
どちらの場合においても、キャラクターに対してどのように接触判定を与えるか、動作をさせるために力の計算をどのように処理するかが重要でした。
これは、障害物などを増やした場合なども同様なのでゲームを作成する時の参考にしてもらえればと思います。
合わせて読みたい関連記事
■Unityちゃんをカメラで追従する方法はこちら→【Unity】カメラの基本設定を理解しよう!|Camera入門①
■Unityちゃんを用いた当たり判定についてはこちら→【Unity】ユニティちゃんに攻撃アニメーションをつけて当たり判定を設定しよう!
この記事はいかがでしたか?
もし「参考になった」「面白かった」という場合は、応援シェアお願いします!