Files
Cielonos/Assets/Opsive/BehaviorDesigner/Add-Ons/CielonosPack/Conditionals/CheckEnergy.cs
SoulliesOfficial 9a9e48f8a5
2026-06-27 12:52:03 -04:00

88 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.GraphDesigner.Runtime.Variables;
using Opsive.Shared.Utility;
using UnityEngine;
namespace Cielonos.MainGame.Characters.AI
{
public enum WeightCalculationMode
{
None,
Coefficient,
Curve
}
[Category("Cielonos")]
[Description("检查能量是否足够。在开启权重计算后,可通过公式或曲线动态得出权重值,输出到共享变量用于自定义 Selector。")]
public class CheckEnergy : AutomataConditionalBase
{
private AttributeSubmodule attributeSm;
[Tooltip("需要消耗的目标能量值")]
public SharedVariable<float> energyCost;
[Tooltip("除了当前消耗外,还需要额外保留的最低能量。若扣除消耗后能量小于保留值,则判定失败。")]
public SharedVariable<float> reserveEnergy;
[Space(10)]
[Tooltip("权重计算模式:无、系数线性计算、曲线非线性计算")]
public WeightCalculationMode weightMode = WeightCalculationMode.None;
[Tooltip("权重公式的放大系数。公式: 1 + (系数 * (当前能量/消耗能量 - 1))")]
public SharedVariable<float> weightCoefficient = 1.0f;
[Tooltip("权重计算曲线。X轴为 当前能量/消耗能量 的比例1及以上Y轴为输出权重。")]
public AnimationCurve weightCurve = new AnimationCurve(new Keyframe(1, 1), new Keyframe(5, 5));
[Tooltip("将计算得到的权重输出到该变量中,供其他自定义机制使用")]
public SharedVariable<float> outputWeight;
public override void OnAwake()
{
base.OnAwake();
attributeSm = self.attributeSm;
}
public override TaskStatus OnUpdate()
{
if (!attributeSm.Has("Energy")) return TaskStatus.Failure;
float currentEnergy = attributeSm["Energy"];
float cost = energyCost.Value;
float reserve = reserveEnergy != null ? reserveEnergy.Value : 0f;
// 检查能量是否足够,并且满足保留最低能量的阈值
if (currentEnergy >= cost && (currentEnergy - cost) >= reserve)
{
if (weightMode != WeightCalculationMode.None && outputWeight != null)
{
outputWeight.Value = CalculateWeight(currentEnergy, cost);
}
return TaskStatus.Success;
}
return TaskStatus.Failure;
}
private float CalculateWeight(float currentEnergy, float cost)
{
if (cost <= 0) return 1.0f; // 避免除以0直接返回基础权重
float ratio = currentEnergy / cost;
if (weightMode == WeightCalculationMode.Curve)
{
if (weightCurve != null)
{
return weightCurve.Evaluate(ratio);
}
return 1.0f;
}
else // Coefficient
{
return 1.0f + (weightCoefficient.Value * (ratio - 1.0f));
}
}
}
}