【バイオハザード風のゲームを作ってみよう。その9】
今回も下記を参考にやっていきましょう。
youtu.be
今回は、ゾンビがプレイヤーを探知する仕組みを作っていきます。
・ゾンビはプレイヤーが一定範囲内にいて、壁等の後ろにいない場合、つまりゾンビからプレイヤーが視認できる場合にプレイヤーを探知したことにします。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class IdleState : State //EP8追加 ゾンビ直下のstatesオブジェクトにアタッチ { PurseTargetState purseTargetState; //The layer used to detect potential attack taeget [Header("Detection Layer")] [SerializeField] LayerMask detectionLayer; //EP9追加 //How far away can detect a target [Header("Detection Radius")] [SerializeField] float detectionRadius = 5f; //EP9追加 //How wide can see a target within our FIELD OF VIEW [Header("Detection Angle Radius")] [SerializeField] float minimumDetectionRadiusAngle = -50f; //EP9追加 [SerializeField] float maximumDetectionRadiusAngle = 50f; //EP9追加 //we make our character idle until they find a potential target //if a target is found we proceed to the "PursueTarget" state //if no target is found we remain in the idle position private void Awake() { purseTargetState = GetComponent<PurseTargetState>(); } public override State Tick(ZombieManager zombieManager) { //LOGIC TO FIND A TARGET GOES HERE. if (zombieManager.currentTarget!=null)//EP9変更 { // Debug.Log("we have found a target!"); return purseTargetState; } else { FindATargetViaLineOfSight(zombieManager); //EP9追加 // Debug.Log("We have no target yet."); return this; } } //EP9追加 private void FindATargetViaLineOfSight(ZombieManager zombieManager) { //We are searching ALL colliders on the layer of PLAYER within a certain radius //Physics.OverlapSphere戻り値: Collider[] 球体の内部や触れたすべてのコライダーの配列を取得します. Collider[] colliders = Physics.OverlapSphere(transform.position, detectionRadius, detectionLayer); // Debug.Log(colliders.Length); Debug.Log("we are checking for colliders"); //For every collider that we find, that is on the same layer pf the player, we try and serch it for PlayerManager script for(int i = 0; i < colliders.Length; i++) { PlayerManager player = colliders[i].transform.GetComponent<PlayerManager>(); //If rhe playerManager is detected, we then check for line of sight if (player != null) { Debug.Log("we have found the player collider"); //The target mudt be infront of us Vector3 targetDirection = transform.position - player.transform.position; float viewableAngle = Vector3.Angle(targetDirection, transform.forward); // Debug.Log("VIEWABLE ANGLE=" + viewableAngle); if(viewableAngle>minimumDetectionRadiusAngle && viewableAngle < maximumDetectionRadiusAngle) { Debug.Log("we have passed the field of view check"); RaycastHit hit; //This just makes it so our raycast does not start from the floor float characterHeight = 2f; Vector3 playerStartPoint = new Vector3(player.transform.position.x, characterHeight, player.transform.position.z); Vector3 zombieStartPoint = new Vector3(transform.position.x, characterHeight, transform.position.z); Debug.DrawLine(playerStartPoint, zombieStartPoint,Color.yellow); //CHECK ONE LAST TIME OUR //Linecast:始点と終点を設定してそこに線を張り、コライダーがヒットした場合 true を返します. if (Physics.Linecast(playerStartPoint,zombieStartPoint,out hit)) { Debug.Log("There is something iin the way"); //Cannot find the target, there is an object in the way } else { Debug.Log("We have a target, switching states"); zombieManager.currentTarget = player; } } } } } }
今回は以上です。