完成4种基础ai

This commit is contained in:
2024-10-17 00:46:27 +08:00
parent 4920837ed7
commit cdd391ca36
74 changed files with 1094 additions and 4449 deletions

View File

@@ -1,7 +1,9 @@
using System;
using Framework.Timer;
using Framework.Utils.Extend;
using Pathfinding;
using UnityEngine;
using UnityEngine.Serialization;
using XFFSM;
namespace Game.Component
@@ -20,18 +22,23 @@ namespace Game.Component
[SerializeField] protected FSMController _fsmController;
[SerializeField] protected AILerp _aiLerp;
[Header ("最大活动区域")] public Vector2 ActiveArea = new Vector2 (10 , 5);
[Header ("随机巡逻区域")] public Vector2 WalkArea = new Vector2 (5 , 5);
[Header ("攻击检测半径")] public float TriggerDistance = -1f;
[Header ("追逐检测半径")] public float FollowDistance = -1f;
[Header ("攻击最小持续时间")] public float AttackStateDuration = 5f; //攻击状态最小持续时间
[Header ("仇恨丢失冷却时间")] public float AttackCDDuration = 2f;
[Header ("单位移动速度")] public float MoveSpeed = 3;
private FsmData _fsmData;
private float _curAttackingTime;
private float _curAttackCDTime;
[Header ("最大活动区域")] public Vector2 ActiveArea = new Vector2 (10 , 5);
[Header ("随机巡逻区域")] public Vector2 WalkArea = new Vector2 (5 , 5);
[Header ("攻击检测半径")] public float TriggerDistance = -1f;
[Header ("追逐检测半径")] public float FollowDistance = -1f;
[Header ("攻击最小持续时间")] public float AttackStateDuration = 5f; //攻击状态最小持续时间
[Header ("仇恨丢失冷却时间")] public float AttackCDDuration = 2f;
[Header ("单位移动速度")] public float MaxMoveSpeed = 3;
[Header ("常规移动速度系数"), Range (0, 1)] public float WalkSpeedOffset = 1;
[Header ("攻击移动速度系数"), Range (0, 1)] public float AttackSpeedOffset = 1;
[Header ("速度变化系数&插值t")] public float SpeedChangeT = 0.5f;
private FsmData _fsmData;
private float _curAttackingTime;
private float _curAttackCDTime;
private float _curMoveSpeedOffset;
private TimeHandler _speedTimeHandler;
private bool _hasAtkState; //是否为攻击状态
//出生点
[HideInInspector] public Vector2 CreatePos;
@@ -40,7 +47,7 @@ namespace Game.Component
public bool IsDebugDraw = true;
private void OnDrawGizmos ()
{
this._aiLerp.speed = this.MoveSpeed;
this._aiLerp.speed = this.CurMoveSpeed;
if (!IsDebugDraw)
{
@@ -56,21 +63,21 @@ namespace Game.Component
if (this.ActiveArea.y != 0 && this.ActiveArea.x != 0)
{
UnityEditor.Handles.color = new Color (0f, 1f, 0f, 0.5f);
UnityEditor.Handles.color = new Color (0f, 1f, 0f, 0.35f);
UnityEditor.Handles.DrawSolidRectangleWithOutline (
new Rect (CreatePos.x - ActiveArea.x / 2, CreatePos.y - ActiveArea.y / 2, ActiveArea.x, ActiveArea.y),
new Color (0f, 1f, 0f, 0.25f),
Color.black);
Color.white);
// 在圆顶部绘制文本“活动范围”
UnityEditor.Handles.Label (CreatePos + new Vector2 (0f, ActiveArea.y / 2), "活动范围");
}
if ( this.WalkArea.y != 0 && this.WalkArea.x != 0)
{
UnityEditor.Handles.color = new Color (0f, 0f, 1f, 0.5f);
UnityEditor.Handles.color = new Color (0f, 0f, 1f, 0.35f);
UnityEditor.Handles.DrawSolidRectangleWithOutline (
new Rect (CreatePos.x - this.WalkArea.x / 2, CreatePos.y - WalkArea.y / 2, WalkArea.x, WalkArea.y), new Color (0f, 0f, 1f, 0.25f),
Color.black);
Color.white);
// 在圆顶部绘制文本“巡逻范围”
UnityEditor.Handles.Label (CreatePos + new Vector2 (0f, WalkArea.y / 2), "巡逻范围");
}
@@ -78,7 +85,7 @@ namespace Game.Component
if (TriggerDistance > 0)
{
//绘制一个半径为TriggerDistance的圆形
UnityEditor.Handles.color = new Color (1f, 0f, 0f, 0.5f);
UnityEditor.Handles.color = new Color (1f, 0f, 0f, 0.35f);
UnityEditor.Handles.DrawSolidDisc (enemyTransform, Vector3.back, TriggerDistance);
//在圆顶部绘制文本“攻击范围”
UnityEditor.Handles.Label (enemyTransform + new Vector3 (0f, TriggerDistance, 0f), "攻击范围");
@@ -109,6 +116,35 @@ namespace Game.Component
{
get
{
if (this.ActiveArea.x.Compare (-1) && this.ActiveArea.y.Compare (-1))
{
return true;
}
//特殊情况 ,如果值为-1 ,表示不限制
//x如果为-1
if (this.ActiveArea.x.Compare (-1))
{
if (transform.position.y < this.CreatePos.y - this.ActiveArea.y / 2 ||
transform.position.y > this.CreatePos.y + this.ActiveArea.y / 2)
{
return false;
}
return true;
}
//y如果为-1
if (this.ActiveArea.y.Compare (-1))
{
if (transform.position.x < this.CreatePos.x - this.ActiveArea.x / 2 ||
transform.position.x > this.CreatePos.x + this.ActiveArea.x / 2)
{
return false;
}
return true;
}
//检测当前位置是否在活动范围内, 如果不在活动范围内直接返回false
if (transform.position.x < this.CreatePos.x - this.ActiveArea.x / 2 ||
transform.position.x > this.CreatePos.x + this.ActiveArea.x / 2 ||
@@ -124,13 +160,32 @@ namespace Game.Component
public bool HasRunaway { get; private set; } = false;
public float CurMoveSpeed => this._curMoveSpeedOffset * this.MaxMoveSpeed;
private void ResetState ()
{
this.UpdateSpeedState (false , false);
_curAttackingTime = 0;
_curAttackCDTime = 0;
this._aiLerp.speed = this.MoveSpeed;
this._aiLerp.speed = this.CurMoveSpeed;
}
public void UpdateSpeedState (bool hasAtk , bool anim = true)
{
this._hasAtkState = hasAtk;
var targetSpeedOffset = this._hasAtkState ? this.AttackSpeedOffset : this.WalkSpeedOffset;
if (anim)
{
this._curMoveSpeedOffset = Mathf.Lerp (this._curMoveSpeedOffset , targetSpeedOffset , this.SpeedChangeT);
}
else
{
this._curMoveSpeedOffset = targetSpeedOffset;
}
}
#region
private void OnDisable ()
{
GameUpdateMgr.Instance.RemoveUpdater (DoUpdate);
@@ -149,6 +204,7 @@ namespace Game.Component
private void DoUpdate ()
{
UpdateSpeedState (this._hasAtkState);
if (_curAttackingTime > 0)
{
this._curAttackingTime -= Time.deltaTime;
@@ -180,13 +236,13 @@ namespace Game.Component
if (this._curAttackingTime > 0)
{
//追逐中使用追逐半径检测
hasAttack = this.FollowDistance < 0 ||
hasAttack = this.FollowDistance < 0 ||
Vector2.Distance ( MapContent.Instance.PlayerPosition , this.transform.position) < this.FollowDistance;
}
else
{
hasAttack = this.TriggerDistance < 0 ||
Vector2.Distance ( MapContent.Instance.PlayerPosition , this.transform.position) < this.TriggerDistance;
Vector2.Distance ( MapContent.Instance.PlayerPosition , this.transform.position) < this.TriggerDistance;
}
if (hasAttack)
@@ -195,12 +251,6 @@ namespace Game.Component
}
}
public void EndAttack ()
{
this._curAttackingTime = 0;
this._curAttackCDTime = this.AttackCDDuration;
}
public void CheckUpdateFsmData (bool isUpdate = false)
{
isUpdate |= _fsmData.HasAttack != this.HasAttack;
@@ -219,6 +269,16 @@ namespace Game.Component
}
}
#endregion
public void EndAttack ()
{
this._hasAtkState = false;
this._curAttackingTime = 0;
this._curAttackCDTime = this.AttackCDDuration;
}
private void Init ()
{
this._fsmData = new FsmData ()