using BehaviorDesigner.Runtime.Tasks;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using BehaviorDesigner.Runtime.Tasks.EnemyAI;
namespace BehaviorDesigner.Runtime.Tasks
{
[TaskDescription("近战警戒。前后游走")]
[TaskCategory("YLSJ")]
public class ActionSurroundAlert : NavMeshMovementBase
{
[Tooltip("围绕的目标")]
public SharedTransform target;
[Tooltip("警戒的最小总时间")]
public SharedFloat alertMinTime = 6.0f;
[Tooltip("警戒的最大总时间")]
public SharedFloat alertMaxTime = 12.0f;
[Tooltip("在当前位置后退的最小距离(比如攻击距离是2,后退的距离是1,怪物和人物之间的实际距离是2+1=3,实际距离不要超过alertDistance距离)")]
public SharedFloat backMinDis = 1;
[Tooltip("在当前位置后退的最大距离(比如攻击距离是2,后退的距离是3,怪物和人物之间的实际距离是2+3=5,实际距离不要超过alertDistance距离)")]
public SharedFloat backMaxDis = 3;
[Tooltip("警戒的最大范围,超过这个范围则进行追逐)")]
public SharedFloat alertDistance = 6;
[Tooltip("停留的最小时间(后退完成/围绕完成 都会停留一小段时间)")]
public SharedFloat stayMinTime = 0.5f;
[Tooltip("停留的最大时间(后退完成/围绕完成 都会停留一小段时间)")]
public SharedFloat stayMaxTime = 1.0f;
[Tooltip("围绕片断的最小时间")]
public SharedFloat aroundFragmentMinTime = 2.0f;
[Tooltip("围绕片断的最大时间")]
public SharedFloat aroundFragmentMaxTime = 5.0f;
[Tooltip("旋转速度(看向目标的旋转速度)")]
public float rotationToTargetSpeed = 3;
///
/// 出生地的警戒范围 (从出生地算,超出这个范围则不再追击目标)
///
private float liveAlertDistance = 0;
private float attackDistance = 0;
///
/// 是否后退中
///
private bool backing = true;
///
/// 是否顺时针围绕
///
private int clockwiseAround = 1;
private float curAroundTotalTime = 0;
private float curStayTime = 0;
private float curAroundFragmentTime = 0;
private float curBackDis = 0;
private BehaviorTree behaviorTree = null;
private Role role = null;
private bool bSeek = false;
public override void OnAwake()
{
base.OnAwake();
behaviorTree = gameObject.GetComponent();
role = gameObject.GetComponent();
}
public override void OnStart()
{
base.OnStart();
liveAlertDistance = (float)behaviorTree.GetVariable("liveAlertDistance").GetValue();
attackDistance = (float)behaviorTree.GetVariable("attackDistance").GetValue();
curAroundTotalTime = Random.Range(alertMinTime.Value, alertMaxTime.Value);
backing = true;
bSeek = false;
m_NavMeshAgent.component.updateRotation = false;//禁用旋转
m_NavMeshAgent.component.isStopped = false;
Vector3 dir = target.Value.position - m_NavMeshAgent.component.transform.position;
dir.Normalize();
curBackDis = Random.Range(backMinDis.Value, backMaxDis.Value);
Vector3 backPos = m_NavMeshAgent.component.transform.position - dir * curBackDis;
SetDestination(backPos);
}
public override TaskStatus OnUpdate()
{
// 目标死亡
if (target.Value == null)
{
return TaskStatus.Success;
}
// 时间到达
curAroundTotalTime -= time.deltaTime;
if (curAroundTotalTime <= 0)
{
return TaskStatus.Success;
}
float liveDis = Vector3.Distance(transform.position, role.mLivePos);
float targetDis = Vector3.Distance(transform.position, target.Value.position);
// 超出出生地活动范围
if (liveDis > liveAlertDistance)
{
return TaskStatus.Success;
}
Vector3 centerPos = target.Value.position;
Vector3 dir = transform.position - centerPos;
float dis = Vector3.Distance(transform.position, centerPos);
dir.Normalize();
dir.y = 0;
// 超出 警戒范围
if (targetDis > alertDistance.Value)
{
backing = false;
bSeek = true;
m_NavMeshAgent.component.updateRotation = true;
m_NavMeshAgent.component.speed = (float)behaviorTree.GetVariable("runSpeed").GetValue();
}
// 停留期间不做任何处理
if (curStayTime > 0)
{
if (m_NavMeshAgent.component.isOnNavMesh && m_NavMeshAgent.component.isStopped != true)
{
m_NavMeshAgent.component.isStopped = true;
}
curStayTime -= time.deltaTime;
return TaskStatus.Running;
}
else
{
if (m_NavMeshAgent.component.isOnNavMesh && m_NavMeshAgent.component.isStopped != false)
{
m_NavMeshAgent.component.isStopped = false;
}
}
// 后退
if (backing)
{
if (HasArrived())
{
backing = false;
ResetAround();
}
}
// 围绕目标
else
{
if (bSeek == false)
{
// 旋转
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(-dir), rotationToTargetSpeed * Time.deltaTime);
curAroundFragmentTime -= time.deltaTime;
if (curAroundFragmentTime > 0)
{
Vector3 aroundPos = target.Value.position + dir * dis + transform.right * clockwiseAround;
SetDestination(aroundPos);
}
else
{
ResetAround();
}
}
else
{
if (targetDis > curBackDis + attackDistance)
{
Vector3 targetDir = target.Value.position - m_NavMeshAgent.component.transform.position;
targetDir.Normalize();
SetDestination(target.Value.position + targetDir * (curBackDis + attackDistance));
}
else
{
bSeek = false;
m_NavMeshAgent.component.updateRotation = false;
m_NavMeshAgent.component.speed = (float)behaviorTree.GetVariable("moveSpeed").GetValue();
}
}
}
return TaskStatus.Running;
}
///
/// 重置围绕
///
private void ResetAround()
{
int clockwiseRan = Random.Range(0, 2);
if (clockwiseRan == 0)
{
clockwiseAround = -1;
}
else
{
clockwiseAround = 1;
}
curStayTime = Random.Range(stayMinTime.Value, stayMaxTime.Value);
curAroundFragmentTime = Random.Range(aroundFragmentMinTime.Value, aroundFragmentMaxTime.Value);
}
public override void OnEnd()
{
base.OnEnd();
if (m_NavMeshAgent.component != null && m_NavMeshAgent.component.isOnNavMesh && role.isDie == false)
{
m_NavMeshAgent.component.isStopped = true;
m_NavMeshAgent.component.updateRotation = true;
}
}
}
}