mirror of
http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite.git
synced 2025-11-20 05:37:11 +08:00
(client) feat:健康给予,路径优化,结算界面,商店界面 (#60)
Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite/pulls/60
This commit is contained in:
@@ -1,25 +1,23 @@
|
||||
using Data;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AI
|
||||
{
|
||||
public class JobNode_Wander : LeafNodeBase
|
||||
{
|
||||
private float _wanderRange = 10f; // 徘徊的最大范围
|
||||
private float _minWanderDistance = 2f; // 随机目标点距离当前位置的最小距离,避免原地踏步
|
||||
private int _maxTargetSearchAttempts = 20; // 寻找可达目标点的最大尝试次数
|
||||
private float _positionCheckThreshold = 0.001f; // 检测是否卡住的距离阈值
|
||||
|
||||
private const int _maxStuckFrames = 5; // 超过此帧数认为卡住
|
||||
|
||||
private Vector3 _wanderTargetPosition; // 当前徘徊的目标点
|
||||
private readonly int _maxTargetSearchAttempts = 20; // 寻找可达目标点的最大尝试次数
|
||||
private readonly float _minWanderDistance = 2f; // 随机目标点距离当前位置的最小距离,避免原地踏步
|
||||
private readonly float _positionCheckThreshold = 0.001f; // 检测是否卡住的距离阈值
|
||||
private readonly float _wanderRange = 10f; // 徘徊的最大范围
|
||||
private Vector3 _lastPosition; // 上一帧的实体位置
|
||||
private int _stuckFrameCount; // 累计在同一位置的帧数
|
||||
|
||||
private Vector3 _wanderTargetPosition; // 当前徘徊的目标点
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 核心业务逻辑,用于执行随机徘徊。
|
||||
/// LeafNodeBase 会在计时器管理后调用此方法。
|
||||
/// 核心业务逻辑,用于执行随机徘徊。
|
||||
/// LeafNodeBase 会在计时器管理后调用此方法。
|
||||
/// </summary>
|
||||
/// <returns>节点的执行状态(Running, Success, Failure)。</returns>
|
||||
protected override Status ExecuteLeafLogic()
|
||||
@@ -27,26 +25,22 @@ namespace AI
|
||||
// 如果没有目标点,尝试寻找一个
|
||||
if (_wanderTargetPosition == Vector3.zero) // Vector3.zero 作为未设置目标的标志
|
||||
{
|
||||
if (!FindRandomWanderTarget())
|
||||
{
|
||||
// 无法找到有效目标点,判定为失败
|
||||
Debug.LogError(
|
||||
$"实体 {SelfEntity.currentDimensionId} 在 {_wanderRange} 范围内尝试 {_maxTargetSearchAttempts} 次后未能找到徘徊目标。");
|
||||
return Status.Failure;
|
||||
}
|
||||
if (!FindRandomWanderTarget()) return Status.Failure;
|
||||
|
||||
// 找到目标后,设置初始上一帧位置,并重置卡住计数
|
||||
// 找到目标并成功生成路径后,设置初始上一帧位置,并重置卡住计数
|
||||
_lastPosition = SelfEntity.Position;
|
||||
_stuckFrameCount = 0;
|
||||
}
|
||||
|
||||
|
||||
if (SelfEntity.AttributesNow.moveSpeed <= 0)
|
||||
return Status.Success;
|
||||
|
||||
// 尝试沿着路径移动
|
||||
SelfEntity.TryMove();
|
||||
// 检查是否到达目标点
|
||||
if (SelfEntity.OnTargetPoint)
|
||||
{
|
||||
return Status.Success;
|
||||
}
|
||||
if (SelfEntity.OnTargetPoint) return Status.Success;
|
||||
|
||||
|
||||
|
||||
// 检查是否卡住
|
||||
var currentPosition = SelfEntity.Position;
|
||||
@@ -57,9 +51,8 @@ namespace AI
|
||||
_stuckFrameCount++;
|
||||
if (_stuckFrameCount > _maxStuckFrames)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"实体 {SelfEntity.currentDimensionId} 在 {currentPosition} 卡住 {_stuckFrameCount} 帧。当前目标: {_wanderTargetPosition}");
|
||||
return Status.Failure; // 卡住,返回失败
|
||||
_wanderTargetPosition = Vector3.zero; // 清除可能导致卡住的目标点
|
||||
return Status.Failure;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -73,9 +66,9 @@ namespace AI
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找一个随机且可达的徘徊目标点。
|
||||
/// 寻找一个随机且可达的徘徊目标点,并尝试生成路径。
|
||||
/// </summary>
|
||||
/// <returns>如果成功找到并设置目标点,则返回true;否则返回false。</returns>
|
||||
/// <returns>如果成功找到并设置目标点且路径生成成功,则返回true;否则返回false。</returns>
|
||||
private bool FindRandomWanderTarget()
|
||||
{
|
||||
var currentEntityPosition = SelfEntity.Position;
|
||||
@@ -86,28 +79,35 @@ namespace AI
|
||||
var randomOffset = Random.insideUnitCircle * _wanderRange;
|
||||
var potentialTarget =
|
||||
currentEntityPosition + new Vector3(randomOffset.x, randomOffset.y, 0); // 假定2D平面,Z轴不变
|
||||
// 确保新目标点与当前位置有足够的距离
|
||||
if (Vector3.Distance(potentialTarget, currentEntityPosition) < _minWanderDistance)
|
||||
{
|
||||
continue; // 距离太近,重试
|
||||
}
|
||||
|
||||
// 检查目标点的可达性
|
||||
// 确保新目标点与当前位置有足够的距离
|
||||
if (Vector3.Distance(potentialTarget, currentEntityPosition) < _minWanderDistance) continue; // 距离太近,重试
|
||||
|
||||
// 检查目标点的地貌可达性
|
||||
var travelCost = Program.Instance.GetDimension(currentDimensionId).landform
|
||||
.GetTravelCost(potentialTarget);
|
||||
if (travelCost < 1.0f) // 小于1表示可达
|
||||
|
||||
if (travelCost < 1.0f) // 小于1表示地貌允许通过
|
||||
{
|
||||
_wanderTargetPosition = potentialTarget;
|
||||
SelfEntity.SetTarget(_wanderTargetPosition);
|
||||
return true;
|
||||
_wanderTargetPosition = potentialTarget; // 暂定此为目标
|
||||
|
||||
// 尝试设置目标并生成路径,路径规划也可能失败
|
||||
if (SelfEntity.SetTarget(_wanderTargetPosition))
|
||||
// 目标点地貌可达且路径成功生成
|
||||
return true;
|
||||
|
||||
// 目标点地貌可达,但路径生成失败(例如,路径被其他临时障碍物阻挡,或路径计算失败)
|
||||
// 重置_wanderTargetPosition,以便在下一次循环中尝试新的目标点
|
||||
_wanderTargetPosition = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
return false; // 达到最大尝试次数仍未找到有效目标
|
||||
_wanderTargetPosition = Vector3.zero; // 最终未能找到有效目标,确保目标点被清空
|
||||
return false; // 达到最大尝试次数仍未找到有效目标或路径
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置叶节点的状态,包括基类状态和内部计时器。
|
||||
/// 重置叶节点的状态,包括基类状态和内部计时器。
|
||||
/// </summary>
|
||||
public override void Reset()
|
||||
{
|
||||
@@ -117,4 +117,4 @@ namespace AI
|
||||
_stuckFrameCount = 0; // 重置卡住计数
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user