Unityで2DRPGゲームを作っております。今現在、普段は特定の地点を巡回し続けるが、視界判定内に主人公が入った場合、それを追いかける設定の敵キャラクターを製作しています。またその際、主人公が壁の裏に隠れれば、敵がこちらを見失う設定にしたいとも考えております。しかし、敵が追いかけるかどうか判別するためのプログラミングが上手く作動せず、困っております。追いかける条件として(1)特定の距離内(trackingRange)に主人公が入る(2)敵前方に広がる一定の角度内(ChaseRange)に主人公が入った場合(3)敵と主人公の間に障害物がない、この三つを設定しております。どこが問題なのか、ご教授いただければ幸いです。
コード:
using UnityEditor.UI;
using UnityEngine;
//NavMeshAgent使うときに必要
//オブジェクトにNavMeshAgentコンポーネントを設置
[RequireComponent(typeof(NavMeshAgent2D))]
public class OnlyFowardSsarch : MonoBehaviour
{
GameObject seenGameObject;
public Transform[] points;
public float speedDown;
public float speedUp;
public float ChaseRange;
// このキャラの進行方向
public float chaseAngle;
// プレイヤーの進行方向
public float playerAngle;
[SerializeField] int destPoint = 0;
// 前回のベクトル
public Vector2 prev;
// 前回との差分
public Vector2 diff;
public Vector2 diffPlayer;
private NavMeshAgent2D agent;
Vector3 playerPos;
GameObject player;
float distance;
[SerializeField] float trackingRange = 3f;
[SerializeField] float quitRange = 5f;
[SerializeField] bool tracking = false;
GameObject[] fireUnits = GameObject.FindGameObjectsWithTag("Unit");
// 向きベクトル
public float AngleDir()
{
return transform.eulerAngles.z * (Mathf.PI / 180.0f);
}
// 角度からベクトルを算出
public Vector2 GetVector(Vector3 center,float angle)
{
float x = Mathf.Cos(angle) + center.x;
float y = Mathf.Sin(angle) + center.y;
return new Vector2(x, y);
}
public float GetAngle(Vector2 start, Vector2 target)
{
Vector2 dt = target - start;
float rad = Mathf.Atan2(dt.y, dt.x);
float degree = rad * Mathf.Rad2Deg;
return degree;
}
void Start()
{
agent = GetComponent<NavMeshAgent2D>();
prev = transform.position;
// autoBraking を無効にすると、目標地点の間を継続的に移動します
//(つまり、エージェントは目標地点に近づいても
// 速度をおとしません)
agent.autoBraking = false;
GotoNextPoint();
//追跡したいオブジェクトの名前を入れる
player = GameObject.Find("主人公");
}
void GotoNextPoint()
{
// 地点がなにも設定されていないときに返します
if (points.Length == 0)
return;
// エージェントが現在設定された目標地点に行くように設定します
agent.destination = points[destPoint].position;
// 配列内の次の位置を目標地点に設定し、
// 必要ならば出発地点にもどります
destPoint = (destPoint + 1) % points.Length;
}
void Update()
{
float diffX = this.transform.position.x - prev.x;
float diffY = this.transform.position.y - prev.y;
diff = new Vector2(diffX, diffY).normalized;
Debug.Log("敵の向き" );
//Playerとこのオブジェクトの前回フレームを保存
prev = this.transform.position;
//Playerとこのオブジェクトの距離を測る
fireUnits = GameObject.FindGameObjectsWithTag("Unit");
playerPos = player.transform.position;
Transform agentTransform = this.transform;
Vector2 agentState = agentTransform.position;
Transform playerTransform = player.transform;
Vector2 playerState = playerTransform.position;
distance = Vector2.Distance(this.transform.position, playerPos);
RaycastHit2D hit = Physics2D.Linecast(agentState, playerState);
chaseAngle = Mathf.Atan2(diff.y, diff.x) * 180.0f / Mathf.PI;
if (hit)
{
seenGameObject = hit.transform.gameObject;
}
Debug.Log(seenGameObject);
string seentarget = seenGameObject.name;
if (tracking)
{
// 追跡の時、quitRangeより距離が離れたら中止
// 目的地まで来たら一時中止
if (distance > quitRange || seentarget != "主人公" && !seentarget.Contains("HumanSoul_0")
|| chaseAngle >= (ChaseRange + chaseAngle) && chaseAngle >= (chaseAngle + chaseAngle))
tracking = false;
//Playerを目標とする
agent.destination = playerPos;
agent.speed = speedUp;
}
else
{
//PlayerがtrackingRangeより近づいたら追跡開始
if (distance < trackingRange && seentarget == "主人公" && (ChaseRange + chaseAngle) < chaseAngle && chaseAngle < (ChaseRange - chaseAngle))
tracking = true;
agent.speed = speedDown;
// エージェントが現目標地点に近づいてきたら、
// 次の目標地点を選択します
if (!agent.pathPending && agent.remainingDistance < 0.5f)
GotoNextPoint();
}
}