gpt4 book ai didi

用于多种 NPC 类型的 C# FSM

转载 作者:行者123 更新时间:2023-11-30 15:55:09 25 4
gpt4 key购买 nike

好的,这将是一些我需要帮助的代码。

前言

下面的代码现在描述了 FSM 的实现,因为我使用的是 unity,这允许我根据我的状态/ Action 和决策创建 Assets 。

[CreateAssetMenu(menuName = "PluggableAI/States")]
public class State : ScriptableObject
{
public Action[] actions;
public Transition[] transitions;
public Color sceneGizmoColor = Color.grey;
public EnumProfession Profession;

/// <summary>
/// Updates current state
/// </summary>
/// <param name="controller"></param>
public void UpdateState(StateController controller)
{
DoActions(controller);
CheckTransitions(controller);
}

/// <summary>
/// Does each action
/// </summary>
/// <param name="controller"></param>
private void DoActions(StateController controller)
{
for (int i = 0; i < actions.Length; i++)
{
actions[i].Act(controller);
}
}

/// <summary>
/// Check which transition we have to ggo in
/// </summary>
/// <param name="controller"></param>
private void CheckTransitions(StateController controller)
{
for (int i = 0; i < transitions.Length; i++)
{
bool decisionSucceeded = transitions[i].decision.Decide(controller);

if (decisionSucceeded)
{
controller.TransitionToState(transitions[i].trueState);
}
else
{
controller.TransitionToState(transitions[i].falseState);
}
}
}
}

Action

    public abstract class Action : ScriptableObject
{
public abstract void Act(StateController controller);
}

决定

public abstract class Decision : ScriptableObject
{
public abstract bool Decide (StateController controller);
}

过渡

public class Transition
{
public Decision decision;
public State trueState;
public State falseState;
}

为了控制状态及其转换,我创建了以下类 StateController:

    public class StateController : MonoBehaviour
{
public State CurrentState;
public State RemainState;
public NpcHuman NpcHuman;

/// <summary>
/// When the game starts
/// </summary>
private void Awake()
{
if (NpcHuman == null)
{
NpcHuman = GetComponent<NpcHuman>();
}
}

/// <summary>
/// Updates every frame
/// </summary>
void Update()
{
CurrentState.UpdateState(this);
}

/// <summary>
/// Transitions to next state
/// </summary>
/// <param name="nextState"></param>
public void TransitionToState(State nextState)
{
if (nextState != RemainState)
{
CurrentState = nextState;
onExitState();
}
}

/// <summary>
/// Is Called everytime a state exits
/// </summary>
private void onExitState()
{
}

public void ForceChangeState(State state)
{
CurrentState = state;
}
}

现在我所做的是,我已经根据它们的类型确定了游戏中的不同类型的 AI:

NPC 的类型

Villager  - Humanoid

Soldier - Humanoid

Archer - Humanoid

Catapult (vehicles) - Generic

Spirits - Generic

Animals - Generic

现在让我们从人形角色开始,为此我创建了以下关系:

enter image description here

现在你可以看到每个人形类都派生自类 NpcHumanoid 编辑 - 我在图表中的命名有错误抱歉

如果您一直密切关注,您会发现此代码存在问题。

我现在的主要问题是对不同类型对象的引用。

所以我的问题是最好的方法是什么?

我是否应该为状态机创建一个抽象类,然后创建它的子类,然后可以保存它所控制的 AI/NPC 类型的引用。这对我的州有何影响?看到它们都将 StateController 作为参数,我将不断地 cast statecontroller 到使用状态的类型(这看起来很邋and和意大利面条式)

另外,可能有一个我没有看到的解决方案,我很乐意听取你们的意见。

最佳答案

Unity 使用基于组件的方法来组织游戏逻辑。因此,我认为最好的方法是为您的 NPC 类型使用组件而不是常规的 OOP 方法。

只需将不同类型的 NPC 视为具有不同组件的 GameObject。例如,

村民.cs

class Villager: MonoBehaviour
{
public float Fatigue;
public int Carrying;
}

您可以创建一个NPCFactory来创建不同的NPC。

class NPCFactory
{
public GameObject CreateNPC(NPCType npcType)
{
GameObject obj = new GameObject();
obj.AddComponent<StateController>();
switch(npcType)
{
case NPCType.Villager:
obj.AddComponent<Villager>();
break;
//case ....
}
return obj;
}
}

然后您可以通过操作 NPC 上的 StateController 来处理 NPC 的状态。

关于用于多种 NPC 类型的 C# FSM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49101923/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com