視界に入ったキャラクターを感知する(障害物で隠れられる)

<動作概要>

一定のエリア内に入ったキャラクターを感知する。ShereColliderとRayCastを使う。ShereColliderで視界の範囲(現実的ではないが360°)を設定。障害物の感知はRayCastで実現する。
今回Cubeを敵と見立てた。球状の緑線が索敵範囲。Unityちゃんを見つけると近づいてくる。Unityちゃんの前に障害物がある場合見失うようにした。

<動作環境>

Unity 2019.3.9f1

<ソースコード>

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Search : MonoBehaviour
{
    //------------------------------public変数の宣言---------------------------------------

    //移動速度
    public float moveSpeed;

    //------------------------------private変数の宣言--------------------------------------

    CharacterController controller;

    //追跡対象の方向
    Vector3 targetDirection;

    void Start()
    {
        //private変数の初期化
        controller = GetComponent<CharacterController>();
        targetDirection = Vector3.zero;
    }

    void Update()
    {

    }

    void OnTriggerStay(Collider other)  
    {
        if (other.gameObject.layer == LayerConst.PLAYER){
            targetDirection = (other.transform.position - transform.position).normalized;
            Debug.DrawRay(transform.position, targetDirection * 10.0f, Color.red);
            RaycastHit hit;
            Physics.Raycast(transform.position, targetDirection, out hit);
            if(hit.transform.position == other.transform.position)
            {
                controller.Move(targetDirection * moveSpeed * Time.deltaTime);
            }
        }
    }

    void OnTriggerExit(Collider other)
    {
        targetDirection = Vector3.zero;
    }
}

public static class LayerConst
{
    public static int PLAYER = 8;
}

<ソースコード解説>

①Colliderのイベント関数”OnTriggerStay(Collider)”について

Colliderはオブジェクト同士の衝突を検知するのに利用するが、InspectorでColliderのIsTriggerにチェックを入れるとCollider同士の衝突が発生しなくなる(すり抜ける)。イベント関数OnTriggerStayはColliderが重なっている間実行される関数である。今回、敵の視界を表すSphereColliderのIsTriggerにチェックを入れた。

② “OnTriggerStay(Collider)” の引数でキャラとの接触を検知する。

イベント関数”OnTriggerStay(Collider)”の引数には、接触しているColliderの情報が自動的に格納される。

今回UnityちゃんのレイヤーをLayerConst.PLAYER に設定したので、もし接触したオブジェクトがUnityちゃんだったら以下のif文がtrueを返す。(レイヤーの設定に関しては別記事参照)

if (other.gameObject.layer == LayerConst.PLAYER)

③RayCastで視界を遮る障害物がないか確認する

RayCastはオブジェクトから光線を発する関数。光線がオブジェクトにあたれば、そこで光線は止まる。以下のようにすると、光線と衝突したオブジェクトの情報が引数hitに自動的に格納される。(hitの前のoutはC#特有の文法)

RaycastHit hit;
Physics.Raycast(transform.position, targetDirection, out hit);

この引数hitのpositionと②で検知したUnityちゃんのpositionが一致する場合、索敵成功となる。もしUnityちゃんの前に障害物があったら、引数hitには障害物の情報が格納されるので、索敵失敗となる。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です