連載
» 2017年02月20日 05時00分 公開

Unity実用Tips――衝突判定とCollider、複数Tagの使い方ゲーム開発初心者のためのUnity入門(13)(4/4 ページ)

[薬師寺国安,PROJECT KySS]
前のページへ 1|2|3|4       

蹴る動作のスクリプトでタグごとの処理を書く

 次に「UnityMask」を選択して、「UnitymanAction」スクリプトを追加する。コードはリスト2になる。

private GameObject obj1;
private GameObject obj2;
private GameObject obj3;
 
void Start () {
    obj1 = GameObject.Find("Orc");
    obj2 = GameObject.Find("Orc2");
    obj3 = GameObject.Find("Orc3");
    obj1.SetActive(false);
    obj2.SetActive(false);
    obj3.SetActive(false);
}
 
void Update () {
    if (BorderScript.flag == true) {
        obj1.SetActive(true);
        obj2.SetActive(true);
        obj3.SetActive(true);
    }
}
 
void OnControllerColliderHit(ControllerColliderHit hit){
    checkItem(hit.collider.gameObject);
}
 
void checkItem(GameObject obj)
{
    Animator anim = GetComponent<Animator>();
    if(obj.tag=="Orc" || obj.tag=="Orc2" || obj.tag=="Orc3")
    {
        anim.SetBool("is_kicking", true);
    }
    AnimatorStateInfo state = anim.GetCurrentAnimatorStateInfo(0);
 
    if(state.IsName("Locomotion.SpinKick"))
    {
        anim.SetBool("is_kicking", false);
        obj.GetComponent<Rigidbody>().AddForce(Vector3.forward * 5000, ForceMode.Force);
     }
}
リスト2 モンスターが出現しUnityマンが妖怪を蹴り落とす処理(UnitymanAction.cs)

 まず、「obj1」から「obj3」までのGameObject型の変数を宣言する(1〜3行目)。

ゲームオブジェクトのタグを検索するFind関数

 Find関数で「Orc」「Orc2」「Orc3」という名前のゲームオブジェクトを検索し、変数「obj1」〜「obj3」で参照する(6〜8行目)。

ゲームオブジェクトの表示/非常時を切り替えるSetActive関数

 この各変数のSetActive関数に「false」を指定して、実行時点では各モンスターを非表示としておく(9〜11行目)

 Update関数の中では以下の処理を行う。リスト1のBorderScript.csの中で宣言しておいたpublicな静的変数「flag」の値が「true」の場合(15行目)、つまりUnityマンが「Border」に接触した時点で、SetActive関数に「true」を指定して、非表示になっていたモンスターたちを表示する(16〜18行目)。

OnControllerColliderHitとOnTriggerEnterの使い分け

 前回も紹介した22行目のOnControllerColliderHitも、リスト1のOnTriggerEnterと同じく、衝突判定時に使われる関数だ。違いは、ゲームオブジェクトに「Is Trigger」を付けなくても呼び出せるという点にあるが、例えば、今回の境界線のように位置が固定されて動かないオブジェクトにぶつかるときはOnTriggerEnterを、今回のUnityマンのように「Character Controller」で動くオブジェクト(3Dキャラクター)の衝突判定には「Is Trigger」を付けずに「OnControllerColliderHit」を使うといいだろう。

 前回も紹介したが、3DキャラクターにはInspectorで「Character Controller」を付けて「Center」を設定すると、衝突判定が付いてくるのだ。

 なお、「Character Controller」を付けない衝突判定については次回解説する。

制御するゲームオブジェクトの識別をタグで行う

 checkItem関数内では、まずGetComponent関数でAnimatorコンポーネントを取得し、変数「anim」で参照する(27行目)。

 checkItem関数の引数であるGameObjectインスタンス「obj」の「tag」が「Orc」「Orc2」「Orc3」のいずれかだった場合には、SetBool関数で「is_kicking」に「true」を指定する(28〜31行目)。これにより、Unityマンが妖怪を蹴り飛ばすようになる。

 次に、ステートの情報を取得し、変数「state」で参照する(32行目)。「Locomotion.SpinKick」ステートになれば(34行目)、「is_kicking」パラメーターは使用しないので、次の「SpinKick」のために元の状態に戻す。具体的には、「is_kicking」の値を「false」にしている(36行目)。

 以降の処理については、ほとんどが前回の「3DキャラクターがCubeを蹴散らすスクリプトを記述する」と同じであるため、そちらを参照してほしい。

JavaScriptのコード

 JavaScriptのコードも記載しておく、コードの解説はC#と同じだ。

private var obj1:GameObject;
private var obj2:GameObject;
private var obj3:GameObject;
 
function Start () {
    obj1=GameObject.Find("Orc");
    obj2=GameObject.Find("Orc2");
    obj3=GameObject.Find("Orc3");
    obj1.SetActive(false);
    obj2.SetActive(false);
    obj3.SetActive(false);
}
 
function Update () {
    if(BorderScript.flag==true){
        obj1.SetActive(true);
        obj2.SetActive(true);
        obj3.SetActive(true);
    }
}
 
function OnControllerColliderHit(hit:ControllerColliderHit)
{
    checkItem(hit.collider.gameObject);
} 
 
function checkItem(obj:GameObject)
{
    var anim=GetComponent(Animator);
    if(obj.tag=="Orc" || obj.tag=="Orc2" || obj.tag=="Orc3")
    {
      anim.SetBool("is_kicking", true);
    }
    var state:AnimatorStateInfo=anim.GetCurrentAnimatorStateInfo(0);
    if (state.IsName("Locomotion.SpinKick"))
    {
        animator.SetBool("is_kicking", false);
        obj.transform.rigidbody.AddForce(Vector3.forward*5000,ForceMode.Force);
    }
}
リスト2 モンスターが出現しUnityマンが妖怪を蹴り落とす処理(UnitymanActionJS.js)

実行結果

 Unityメニューの「File」→「Save Scene as」から「タグの使い方」という名前で保存し、実行すると動画2のようになるはずだ。

動画2 Unityマンがモンスターを蹴散らす

次回は、Animator Controllerを使わないアニメーション制御

 今回は、「Border」に接触したらモンスターたちを出現させたり、各モンスターにタグ名を振って、接触するGameObjectを判別させたりと、結構ゲーム作成に役に立つ情報が多かったのではないかと思う。いろいろアレンジしてゲーム作成に利用していただければうれしい。

 Asset Storeから他の3Dキャラクターをインポートして、キャラクターだけ変更させてみるのも面白いだろう。

 次回はAnimator Controllerを使わないアニメーション制御について解説するので、お楽しみに。

参考文献

■更新履歴

【2017/2/20】Windows 10、Unity 5.4に対応しました。C#のスクリプトを追加しました。


著者プロフィール

薬師寺 国安(やくしじ くにやす) / 薬師寺国安事務所

薬師寺国安事務所代表。Visual Basicプログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。

1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。

1997年に薬師寺聖とコラボレーション・ユニット「PROJECT KySS」を結成。

2003年よりフリーになり、PROJECT KySSの活動に本格的に参加。.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。

Windows Phoneアプリ開発を経て、現在はWindowsストアアプリを多数公開中。

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。

Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。

Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。

Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。


前のページへ 1|2|3|4       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。