人工知性を作りたい

私が日々、挑戦したことや学んだことなどを紹介していく雑記ブログです。 (新しいAI技術HTM, 専門の音声信号処理, 趣味のアニメ等も書いてます。)

衝突検知(OnCollisionEnter)とイベント発生(Timeline)の実装【Unity】

 

本記事はDEMO動画にある、

「Unity+AIを用いた手書き数字識別システム」の実装方法について説明する。

前回の記事 

www.hiro877.com

 

 

本記事のテーマ

「衝突検知(OnCollisionEnter)とイベント発生(Timeline)の実装」

下記DEMO動画内の1:24付近。

小さいCubeが自動で出現するところまでを実装する。

Demo


www.youtube.com

 

実装動画

本記事の実装を録画した動画です。

 


www.youtube.com

 

実装環境

  • Ubuntu20.04
  • UnityHub2.4.2
  • Unity 2019.4.21f1

 

ソースコード

Githubで管理

・collision-detection-timelineブランチ

ブランチの切り替えは下記画像の赤枠をクリックして変更できる。

f:id:hiro-htm877:20210502170814p:plain

github.com


 

Objectの追加

・Road (Plane)

・GoalArea  (Plane)

・EventPlane (Plane)

・BlackCube (Cube)

・SmallBlackCube (Cube)

上記4つを追加する。

※詳しくは実装動画をご覧ください!

f:id:hiro-htm877:20210503103337p:plain

 

Materialの追加

BlackCubeとSmallBlackCubeに黒色のMaterialを追加する。

Project画面で右クリックを押してCreate→Materialで作成。

作成したものを選択して、AlbedoというパラメータをクリックするとColorパレットが開く。

好きな色を選択して閉じる。

最後に、ドラッグ・アンド・ドロップでBlackCube, SmallBlackCubeに追加して終了。

f:id:hiro-htm877:20210503105532p:plain

 

衝突を検知する方法

スクリプトの実装

・EventPlane.cs

OnCollisionEnter()関数をオーバライドする。

if(collision.gameObject.name=="SD_unitychan_humanoid"){

↑ここでEventPlaneがユニティちゃんと衝突したかどうかを検知出来る。 

 

 

▶クリックでソースコードを展開
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;


public class EventPlane : MonoBehaviour
{
    // Timeline
    private GameObject _child;
    public PlayableDirector director;

    // Collision Param
    public int collisionedEventCount = 0;
    private bool isCollisioned = false;

    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void OnCollisionEnter(Collision collision)
    {
        
        //EventPlaneが衝突したオブジェクトがSD_unitychan_humanoidだった場合
        if(collision.gameObject.name=="SD_unitychan_humanoid"){
            Debug.Log("EventPlane is collisioned");
        }
    }

}

 

 

 SD_unitychan_humaroidの設定

OncCollisionEnter()が呼ばれるための設定を行わなければならない。

 SD_unitychan_humaroidはデフォルトではColliderがついておらず、このままでは他のObjectと衝突したと判定されない。

なのでSD_unitychan_humaroidのInspector画面

→Add ComponentからRigidbodyとCapsule Colliderを追加する。

CapsuleColliderの設定を画像のように変更する。

f:id:hiro-htm877:20210503104758p:plain

 

Timelineでイベントを発生させる方法

今回はEventPlaneを踏んだときにBlackCubeの中からSmallBlackCubeが現れるといったイベントを発生させます。

Timelineの生成〜Animationの録画

まず Project画面で右クリックを押してCreate→Timelineで作成。

作成したTimelineをEventPlaneの下に配置する。

f:id:hiro-htm877:20210503105953p:plain

TimelineをクリックしてTimeline画面を出す。

 SmallBlackCubeをTimeline画面の中へドラッグ・アンド・ドロップで追加する。

そして、赤い録画ボタンを押してSmallBlackCubeが出現する演出を作る。

作り方は、録画ボタンを押下した後、SmallBlackCubeの位置(Position)を変えるだけです。

今回は2秒後に指定した位置で止まるようにしています。

※細かいところは動画でご確認ください。

f:id:hiro-htm877:20210503110429p:plain

次にデフォルトではゲーム開始時にTimelineが開始してしまうため、TimelineオブジェクトのInspector画面にあるPlay On Awakeのチェックボックスを外す。

f:id:hiro-htm877:20210503211946p:plain

スクリプトの実装

EventPlaneが踏まれたときにTimelineが動く処理を実装します。

・EventPlane.cs

Start()内でEventPlaneの子オブジェクト担っているTimelineを検索して実行するために必要なPlayableDirectorというComponentを取得します。

// 子オブジェクトのTimeLineを探す
_child = this.transform.Find ("Timeline").gameObject;
director = _child.GetComponent<PlayableDirector>();

 そして、ユニティちゃんと衝突したときにdirector.Play();でTimelineが起動しています。

//EventPlaneが衝突したオブジェクトがSD_unitychan_humanoidだった場合
if(collision.gameObject.name=="SD_unitychan_humanoid"){
Debug.Log("EventPlane is collisioned");
if (this.collisionedEventCount == 0){
// Start Timeline
director.Play();
this.isCollisioned = true;
this.collisionedEventCount += 1;
}

 

 

▶クリックでソースコードを展開
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;


public class EventPlane : MonoBehaviour
{
    // Timeline
    private GameObject _child;
    public PlayableDirector director;

    // Collision Param
    public int collisionedEventCount = 0;
    private bool isCollisioned = false;

    // Start is called before the first frame update
    void Start()
    {
        // 子オブジェクトのTimeLineを探す
        _child = this.transform.Find ("Timeline").gameObject;
        director = _child.GetComponent();
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void OnCollisionEnter(Collision collision)
    {
        
        //EventPlaneが衝突したオブジェクトがSD_unitychan_humanoidだった場合
        if(collision.gameObject.name=="SD_unitychan_humanoid"){
            Debug.Log("EventPlane is collisioned");
            if (this.collisionedEventCount == 0){
                // Start Timeline
                director.Play();
                this.isCollisioned = true;
                this.collisionedEventCount += 1;
            }
        }
    }

}

 

 

 

 

 

 

 

 

以上で実装は終了になります。

EventPlaneを踏んだときにSmallBlackCubeがユニティちゃんに近づいてきます。

Timelineの機能は他にもたくさんありますのでぜひ検索して使ってみてください!

 

 

もし、動かない場合はコメント欄にて報告して頂けますと助かります。

 

参考記事

styly.cc

styly.cc

kimama-up.net

関連記事 

www.hiro877.com