using BehaviorDesigner.Runtime.Tasks.EnemyAI;
using UnityEngine;
using UnityEngine.AI;
namespace BehaviorDesigner.Runtime.Tasks.Movement
{
[TaskDescription("追寻目标.")]
[TaskCategory("YLSJ")]
[HelpURL("http://www.opsive.com/assets/BehaviorDesigner/Movement/documentation.php?id=9")]
[TaskIcon("Assets/Behavior Designer Movement/Editor/Icons/{SkinColor}WanderIcon.png")]
public class ActionSeekTarget : NavMeshMovementBase
{
[Tooltip("追寻的目标")]
public SharedTransform target;
[Tooltip("追寻成功的距离")]
public SharedFloat seekSuccessDistance = 2;
[Tooltip("追寻失败的距离(不能超过观察范围,否则永远不会追寻目标)")]
public SharedFloat seekFailDistance = 7;
[Tooltip("偏移(误差)")]
public SharedFloat seekOffsetDistance = 0.5f;
[BehaviorDesigner.Runtime.Tasks.Tooltip("攻击射线检测,启用后到达攻击距离会检测中间是否有障碍,有障碍则继续寻路")]
public bool attackRayCheck = false;
///
/// 出生地的警戒范围 (从出生地算,超出这个范围则不再追击目标)
///
private float liveAlertDistance = 0;
private BehaviorTree behaviorTree = null;
private Role role = null;
public override void OnAwake()
{
base.OnAwake();
behaviorTree = gameObject.GetComponent();
role = gameObject.GetComponent();
}
public override void OnStart()
{
liveAlertDistance = (float)behaviorTree.GetVariable("liveAlertDistance").GetValue();
if (m_NavMeshAgent.component.isOnNavMesh)
{
m_NavMeshAgent.component.isStopped = false;
}
//m_NavMeshAgent.component.stoppingDistance = seekSuccessDistance.Value;
base.OnStart();
}
// There is no success or fail state with wander - the agent will just keep wandering
public override TaskStatus OnUpdate()
{
if (target.Value == null)
{
return TaskStatus.Failure;
}
float liveDis = Vector3.Distance(transform.position, role.mLivePos);
// 超出 出生地范围,则不再追击
if (liveDis > liveAlertDistance)
{
// 返回出生地
SetDestination(role.mLivePos);
return TaskStatus.Failure;
}
float dis = Vector3.Distance(m_NavMeshAgent.component.transform.position, target.Value.position);
Vector3 dir = target.Value.position - role.transform.position;
dir.Normalize();
Debug.DrawRay(role.transform.position + Vector3.up + role.transform.right, dir * dis, Color.red);
Debug.DrawRay(role.transform.position + Vector3.up - role.transform.right, dir * dis, Color.red);
if (dis <= seekSuccessDistance.Value && IsObstacle(dis) == false)
{
if (m_NavMeshAgent.component.isOnNavMesh)
{
m_NavMeshAgent.component.ResetPath();
m_NavMeshAgent.component.isStopped = true;
}
return TaskStatus.Success;
}
else if (dis > seekFailDistance.Value + seekOffsetDistance.Value)
{
if (m_NavMeshAgent.component.isOnNavMesh)
{
m_NavMeshAgent.component.ResetPath();
m_NavMeshAgent.component.isStopped = true;
}
return TaskStatus.Failure;
}
SetDestination(target.Value.position);
//// 设置战斗状态
//if (UI_BaseMainWindow.Instance() != null)
//{
// UI_BaseMainWindow.Instance().SetFightingState(true);
//}
return TaskStatus.Running;
}
///
/// 是否没有障碍
///
/// true没有障碍 false有障碍
private bool IsObstacle(float dis)
{
if (attackRayCheck)
{
RaycastHit hit;
Vector3 dir = target.Value.position - role.transform.position;
dir.Normalize();
bool isHit1 = Physics.Raycast(role.transform.position + Vector3.up + role.transform.right, dir, out hit, dis, 1 << LayerMask.NameToLayer("Stop"));
bool isHit2 = Physics.Raycast(role.transform.position + Vector3.up - role.transform.right, dir, out hit, dis, 1 << LayerMask.NameToLayer("Stop"));
if (isHit1 == false && isHit2 == false)
{
return false;
}
else
{
return true;
}
}
else
{
return false;
}
}
public override void OnEnd()
{
base.OnEnd();
}
}
}