このブログは「ファイブボックス一分間Unity講座」の補足説明となる記事です。主にUnityに初めて触れる方や初心者向けの講座になります。
またUnityに慣れてきている方でも、もう少し知識や技術を磨きたい方にとっても有益な情報も記載していますので、もしよろしければご参照ください。
今回は3Dオブジェクトにジャンプの力を与える方法です。以前の記「AssetStoreから素材を取り込む方法」で取得したUnity-Chanのキャラクターを使って説明します。
また、キャラクターにはRigidbodyコンポーネント、CapsuleColliderコンポーネントが追加されています。追加方法は前回の記事「3Dオブジェクトに重力を与える方法」をご参照ください。
1,基本のジャンプ動作
一分間Unity講座 3Dオブジェクトのジャンプ Step1 のショート動画です。ご興味がございましたら、こちらの動画もご参照ください!
1.1 スクリプトファイルの追加
Assets 内で Create ⇒ C# Script でスクリプトファイルを作成し、「PlayerController」という名前に指定します。
作成したスクリプトファイルをHierarchy上のオブジェクト、またはオブジェクトのInspectorにドラッグ&ドロップ、プログラムを適用させます。これを「Attach(アタッチ)」と言います。
アタッチすることでスクリプトファイルは、このオブジェクトのコンポーネントの一つとしてふるまうことができるようになります。
1. 2 プログラムの作成
作成したスクリプトファイルに以下のコードを追記します。
Rigidbody rb; //Rigidbody型の変数
public float jumpPower; //ジャンプ力 アクセス修飾子をpublicに指定
void Start()
{
rb= GetComponent<Rigidbody>(); //Rigidbodyを取得、変数に代入
}
void Update()
{
//上矢印キーが押されたとき
if (Input.GetKeyDown(KeyCode.UpArrow))
{
//Rigidbodyに上方向にJumpPowerの力を加える
rb.AddForce(transform.up * jumpPower);
}
}
ここでは変数を2つ宣言しています。 c# では変数を宣言する際、「型」を指定する必要があります。型については、下で詳しく説明しますので、そちらをご参照ください。
1.2.1 変数の宣言
1つ目は「Rigidbody型」、Rigidbodyコンポーネントの情報を格納できる型です。
2つ目は「float型(浮動小数点型)」の jumpPower 、こちらはアクセス修飾子に public を指定しています。このことにより、inspectorから値を指定することができるようになります。サンプルでは InspectorでjumpPower に200 の力を与えています。
1.2.2 変数の初期値取得
start関数は、Unityが起動して最初に1回だけ実行されるイベント関数です。実際は Awake関数が一番最初に起動し、その後Update関数とStart関数が同時に呼び出されます。今回のように単体のオブジェクトのみのプログラムの時は、Start関数内で初期値を取得します。取得するのは変数で宣言した RIgidbody型のrbです。
コンポーネントを取得するには、GetComponent関数 を使用します。
1.2.3 ジャンププログラム
ジャンプはRIgidbodyコンポーネントの Velocityプロパティに力を与えます。ジャンプの様に瞬間的に力を加える際は、AddForce()メソッド を使用します。
上向き矢印キーが押された際に以下のコードでRigidbodyのVelocity に jumpPowerで上向きの力を加えます。
rb.AddForce(transform.up * jumpPower);
1.3 C#の型について
C#では、型(データ型)は変数がどのような種類のデータを持つことができるかを定義します。これにより、メモリの効率的な使用とデータの正確な操作が可能になります。C#の型は大きく分けて値型と参照型の二つに分類されます。
Unityで個人的によく使用するのは、青色で示しています。
1. 値型 (Value Types)
値型は、変数が直接そのデータを格納する型です。これにより、値型の変数はメモリ上にその実際の値を持ちます。基本的に、値型はスタック(メモリの一部)に格納され、スコープを離れるとメモリが自動的に解放されます。
数値型: 整数 (int, long, short, byte, など) や浮動小数点数 (float, double, decimal)、Unityでは計算の速い int型、float型がよく利用されます。
ブール型: 真偽値 (bool)。trueまたはfalseのいずれか。
文字型: 一つの文字を扱う (char)
構造体: カスタムの値型 (struct)
列挙型: 列挙された定数の集合 (enum)
2. 参照型 (Reference Types)
参照型は、実際のデータではなくデータへの参照(ポインタ)を保持する型です。参照型の変数はヒープ(メモリの別の部分)にある実際のオブジェクトを指します。参照型のオブジェクトはガベージコレクションによって管理され、使用されなくなったときにメモリが解放されます。
クラス: オブジェクト指向プログラミングの基本要素 (class)。この課題で定義したコンポーネント型もオブジェクト指向フレームワーク内で使われるクラスの一種です
配列: 同じ型のデータのコレクション (array)
文字列: 文字のシーケンス (string)
デリゲート: メソッドへの参照 (delegate)
インターフェース: 他のクラスが実装すべきメソッドの定義 (interface)
これで基本のジャンプができるようになりました。
2,空中ジャンプの制御
2.1 空中ジャンプの回避
上で作成したジャンプは空中でジャンプすることができてしまいます。
まずは空中ジャンプをなくすプログラムを作成します。
ピンクのコードが修正部分です。
bool isGround = false; //地面接地フラグを宣言
void Update()
{
//上矢印キーが押されたとき かつ isGround が true の時
if (Input.GetKeyDown(KeyCode.UpArrow) && isGround )
{
//Rigidbodyに上方向にJumpPowerの力を加え
rb.AddForce(transform.up * jumpPower);
}
}
//当たり判定
void OnCollisionEnter(Collision collision)
{
//当たった相手の名前が「Plane」なら
if (collision.gameObject.name == "Plane")
{
isGround = true; //isGround を true に
}
}
//脱出判定
void OnCollisionExit(Collision collision)
{
//脱出した相手の名前が「Plane」なら
if (collision.gameObject.name == "Plane")
{
// isGround = false; //isGround を false に
}
}
当たり判定系のイベント関数は次の3つが用意されています。
OnCollisionEnter(Collision collision) Collitionを持った相手に当たった時発動
OnCollisionStay(Collision collision) Collitionを持った相手に当たっている間発動
OnCollisionExit(Collision collision) Collitionを持った相手から離れたときは発動
引数:collition はCollition型、つまり当たった相手の当たり判定になります。このcollitionを使って当たった相手の情報を取得することができます。
使用例:
collition.gameObject.name : 当たった相手の名前
collition.transform.position : 当たった相手の座標
collition.gameObject.GetComponent<Rigidbody>() : 当たった相手からRIgidbodyコンポーネントを取得
今回は当たった相手の名前が "Plane"(地面)なら、つまり地面に着地したら、変数 : isGround を true にして、再度再度ジャンプができるようにしています。
また、離れた相手の名前が "Plane"(地面)なら、つまりジャンプで地面から離れたら、変数 : isGround を false にしてジャンプができないようにしています。
2.2 空中ジャンプ1回有効
1回だけ空中でジャンプができるように指定します。
作成済みのコードを以下のように修正します。
今度は、整数型(int型)の変数:jumpCount を宣言しました。初期値に 0 を入れました。ジャンプができる条件を かつ条件で jumpCount が1以下としました。
jumpCount <= 1
さらに、ジャンプのタイミングで jumpCount をインクリメント(1ずつ増やす)しています。
地面に触れたとき jumpCount をリセット(0に戻す)しています。
int jumpCount = 0; //ジャンプの回数をカウントする変数を宣言
void Update()
{
//上矢印キーが押されたとき かつ jumpCpunt が 0以下のとき
if (Input.GetKeyDown(KeyCode.UpArrow) && jumpCount <= 1 )
{
//Rigidbodyに上方向にJumpPowerの力を加え
rb.AddForce(transform.up * jumpPower);
jumpCount++; //jumpCount をインクリメント
}
}
//当たり判定
void OnCollisionEnter(Collision collision)
{
//当たった相手の名前が「Plane」なら
if (collision.gameObject.name == "Plane")
{
jumpCount = 0; //jumpCount を 0 に指定
}
}
//脱出判定
void OnCollisionExit(Collision collision)
{
//脱出した相手の名前が「Plane」なら
if (collision.gameObject.name == "Plane")
{
// isGround = false; //コメントアウト
}
}
これで空中で1回だけジャンプができるようになりました。
3,空中ジャンプのアニメーション制御
3.1 ジャンプアニメーション
次の手順で、AnimationController を修正します。
事前に取得済みの素材から「JUMP00」という素材を AnimationController に取り込んでおきましょう。
Trigger型の Parameter を1つ用意します。名前を「Jump1Trigger」などの任意の名前にしておきます。
「Any State」から「JUMP00」への Transition を作成、作成方法は遷移元のステート(AnimationClip)で右クリック、「Make Transition」をクリック、遷移先のステートでドロップ。 Inspector で次のようにパラメータを指定 ・Conditions:Jump1Trigger を指定
「JUMP00」から「WAIT01」へのTransition を作成します。 Inspectorでのパラメータはそのまま
補足
「JUMP00」は通常のジャンプのアニメーションです。他にもジャンプのアニメーションがありますので、任意のものを選択してください。 ジャンプアニメーションへは事前に用意してある複数のState(AnimationClip)、どこからでも遷移できるようにします。そこで水色の「AnyState」というステートから遷移を作成します。「AnyState」の上で右クリック、表示されたメニューから「Make Transition」を選択、「JUMP00」の上でドロップ&ダウンでトランジションを作成します。作成したTransitionの遷移条件には、ConditionsにでTrigger型のパラメータ「Jump1Trigger 」を指定します。また、Has Exit Time を false にしますが、AnyState から遷移した場合は、デフォルトで falseの状態になります。 「JUMP00」が終了したら、最初のStateの「WAIT01」に戻します。上と同じ要領でトランジションを作成します。Trigger型ので指定した場合、戻りのトランジションには何も指定しなくても大丈夫です。
スクリプトファイルを次のように修正します。
Animator animator; //Animator型の変数を宣言
void Start()
{
animator = GetComponent<Animator>(); //初期値を取得
}
void Update()
{
if (Input.GetKeyDown(KeyCode.UpArrow) && jumpCount<=1)
{
rb.AddForce(transform.up * jumpPower);
if (jumpCount == 0) //もし最初のジャンプなら
{
//Parameter「Jump1Trigger」を呼び出す
animator.SetTrigger("Jump1Trigger");
}
jumpCount++;
}
}
Trigger型のパラメータを呼び出すには、Animatorコンポーネントが持つ SetTrigger()コンポーネントを使用します。引数には呼び出したいパラメーター名をダブルコーテーションで囲って入力します。ダブルクォーテーション内の文字列は間違えてもエラーを返しませんので、間違わないように注意しましょう。
3.2 二段ジャンプのアニメーション
さらに二段ジャンプ対応の Animation を作成します。
取得済みの素材から「UMATOBI00」という素材を AnimationController に取り込みます(任意のanimatorClipで結構です)
Trigger型の Parameter を1つ用意します。名前を「Jump2Trigger」などの任意の名前にしておきます。
上の課題で作成した「JUMP00」から「UMATOBI00」への Transition を作成、Inspector で次のようにパラメータを指定 ・Has Exit Time:チェックを外し「false」に ・Conditions:Jump2Trigger を指定
「UMATOBI00」から「WAIT00」へのTransition を作成します。Inspectorでのパラメータはそのまま
二段ジャンプは最初のジャンプのアニメーションが発動している時のみ呼び出されます。従って「JUMP00」からのTransitionを作成します。
スクリプトファイルを以下のように修正します。
void Update()
{
if (Input.GetKeyDown(KeyCode.UpArrow) && jumpCount<=1)
{
rb.AddForce(transform.up * jumpPower);
if (jumpCount == 0)
{
animator.SetTrigger("Jump1Trigger");
}
else //でなければ(二段ジャンプなら)
{
//Parameter「Jump2Trigger」を呼び出す
animator.SetTrigger("Jump2Trigger");
}
jumpCount++;
}
}
変数:jumpCount が 0 でない、つまり2段ジャンプなら 作成したparameter「Jump2Trigger」を呼び出します。
これで二段階のアニメーションを作ることが出来ました。
ファイブボックスでは、Unityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。
Comments