首页 > 其他分享 >CryEngine引擎开发:角色控制与状态机_高级角色控制技术

CryEngine引擎开发:角色控制与状态机_高级角色控制技术

时间:2024-12-02 21:29:34浏览次数:7  
标签:const 角色 stateMachine deltaTime void float character 状态机 CryEngine

高级角色控制技术

在上一节中,我们介绍了角色控制的基本原理和实现方法,包括输入处理、物理模拟和动画融合。在这一节中,我们将深入探讨高级角色控制技术,这些技术将帮助您创建更加复杂和逼真的人物角色。我们将重点讨论以下几个方面:

  1. 角色状态机设计

  2. 角色动作平滑过渡

  3. 环境交互与动态响应

  4. 智能角色行为

  5. 多层控制与混合状态

1. 角色状态机设计

角色状态机( Finite State Machine, FSM)是一种常用的控制行为的方法,它将角色的行为分为多个状态,并定义状态之间的转换条件。在CryEngine中,使用状态机可以有效地管理角色的不同行为,如行走、奔跑、跳跃、攻击等。

1.1 状态机的基本概念

状态机由以下几部分组成:

  • 状态(State):角色在某一时刻的行为模式。

  • 转换(Transition):从一个状态到另一个状态的条件。

  • 动作(Action):在状态中执行的具体操作。

1.2 CryEngine中的状态机实现

在CryEngine中,状态机可以通过脚本语言(如Lua)或C++进行实现。以下是一个使用C++实现的简单状态机示例:


// 角色状态机基类

class CharacterStateMachine

{

public:

    CharacterStateMachine(Character* character) : m_character(character) {}

    virtual ~CharacterStateMachine() {}



    // 更新状态机

    virtual void Update(float deltaTime) = 0;



    // 设置当前状态

    void SetState(CharacterState* state)

    {

        if (m_currentState)

        {

            m_currentState->Exit();

        }



        m_currentState = state;

        if (m_currentState)

        {

            m_currentState->Enter();

        }

    }



protected:

    Character* m_character;

    CharacterState* m_currentState;

};



// 角色状态基类

class CharacterState

{

public:

    CharacterState(CharacterStateMachine* stateMachine) : m_stateMachine(stateMachine) {}

    virtual ~CharacterState() {}



    // 状态进入时的初始化

    virtual void Enter() = 0;



    // 状态更新

    virtual void Update(float deltaTime) = 0;



    // 状态退出时的清理

    virtual void Exit() = 0;



protected:

    CharacterStateMachine* m_stateMachine;

};



// 具体状态示例:行走状态

class WalkingState : public CharacterState

{

public:

    WalkingState(CharacterStateMachine* stateMachine) : CharacterState(stateMachine) {}



    void Enter() override

    {

        m_stateMachine->GetCharacter()->PlayAnimation("walk");

    }



    void Update(float deltaTime) override

    {

        // 检查是否需要转换到其他状态

        if (m_stateMachine->GetCharacter()->IsJumping())

        {

            m_stateMachine->SetState(new JumpingState(m_stateMachine));

        }

    }



    void Exit() override

    {

        m_stateMachine->GetCharacter()->StopAnimation("walk");

    }

};



// 具体状态示例:跳跃状态

class JumpingState : public CharacterState

{

public:

    JumpingState(CharacterStateMachine* stateMachine) : CharacterState(stateMachine) {}



    void Enter() override

    {

        m_stateMachine->GetCharacter()->PlayAnimation("jump");

        m_stateMachine->GetCharacter()->ApplyForce(Vector3(0, 0, 10));

    }



    void Update(float deltaTime) override

    {

        // 检查是否需要转换到其他状态

        if (m_stateMachine->GetCharacter()->IsOnGround())

        {

            m_stateMachine->SetState(new IdleState(m_stateMachine));

        }

    }



    void Exit() override

    {

        m_stateMachine->GetCharacter()->StopAnimation("jump");

    }

};



// 具体状态示例:空闲状态

class IdleState : public CharacterState

{

public:

    IdleState(CharacterStateMachine* stateMachine) : CharacterState(stateMachine) {}



    void Enter() override

    {

        m_stateMachine->GetCharacter()->PlayAnimation("idle");

    }



    void Update(float deltaTime) override

    {

        // 检查是否需要转换到其他状态

        if (m_stateMachine->GetCharacter()->IsMoving())

        {

            m_stateMachine->SetState(new WalkingState(m_stateMachine));

        }

    }



    void Exit() override

    {

        m_stateMachine->GetCharacter()->StopAnimation("idle");

    }

};



// 角色类

class Character

{

public:

    Character() : m_stateMachine(new CharacterStateMachine(this)), m_isMoving(false), m_isJumping(false), m_isOnGround(true) {}



    void Update(float deltaTime)

    {

        m_stateMachine->Update(deltaTime);

    }



    void PlayAnimation(const char* animationName)

    {

        // 播放动画的代码

    }



    void StopAnimation(const char* animationName)

    {

        // 停止动画的代码

    }



    void ApplyForce(const Vector3& force)

    {

        // 应用力的代码

    }



    bool IsMoving() const

    {

        return m_isMoving;

    }



    bool IsJumping() const

    {

        return m_isJumping;

    }



    bool IsOnGround() const

    {

        return m_isOnGround;

    }



    void SetIsMoving(bool isMoving)

    {

        m_isMoving = isMoving;

    }



    void SetIsJumping(bool isJumping)

    {

        m_isJumping = isJumping;

    }



    void SetIsOnGround(bool isOnGround)

    {

        m_isOnGround = isOnGround;

    }



private:

    CharacterStateMachine* m_stateMachine;

    bool m_isMoving;

    bool m_isJumping;

    bool m_isOnGround;

};

1.3 状态机的优势

  • 模块化:每个状态都是独立的模块,可以单独开发和测试。

  • 扩展性:添加新状态或修改现有状态时,对其他状态的影响较小。

  • 可读性:状态机的结构清晰,易于理解和维护。

1.4 状态机的限制

  • 复杂性:状态过多时,状态机的管理会变得复杂。

  • 性能:频繁的状态转换可能会导致性能问题。

2. 角色动作平滑过渡

在角色状态机中,状态之间的转换通常会导致动画的突然切换,这会破坏游戏的流畅性和沉浸感。为了实现平滑的动作过渡,CryEngine提供了多种方法,包括动画混合和过渡曲线。

2.1 动画混合

动画混合是指将两个或多个动画混合在一起,以实现平滑的过渡效果。CryEngine的动画系统支持多层混合,可以通过脚本或动画编辑器进行配置。

2.1.1 使用动画编辑器进行混合

在CryEngine的动画编辑器中,可以创建混合树(Blend Tree),将多个动画节点连接起来,并设置权重来控制每个动画的贡献度。

2.1.2 代码示例:多层动画混合

// 动画控制器类

class AnimationController

{

public:

    AnimationController(Character* character) : m_character(character) {}



    void Update(float deltaTime)

    {

        // 更新动画混合权重

        float walkWeight = m_character->GetWalkSpeed() / m_maxWalkSpeed;

        float idleWeight = 1.0f - walkWeight;



        // 设置动画混合权重

        m_character->SetAnimationWeight("walk", walkWeight);

        m_character->SetAnimationWeight("idle", idleWeight);

    }



private:

    Character* m_character;

    float m_maxWalkSpeed = 5.0f;

};



// 角色类

class Character

{

public:

    Character() : m_animationController(new AnimationController(this)), m_walkSpeed(0.0f) {}



    void Update(float deltaTime)

    {

        m_animationController->Update(deltaTime);

    }



    void SetWalkSpeed(float speed)

    {

        m_walkSpeed = speed;

    }



    float GetWalkSpeed() const

    {

        return m_walkSpeed;

    }



    void SetAnimationWeight(const char* animationName, float weight)

    {

        // 设置动画权重的代码

    }



private:

    AnimationController* m_animationController;

    float m_walkSpeed;

};

2.2 过渡曲线

过渡曲线是一种控制动画过渡时间的方法,可以通过曲线来平滑地调整动画的权重。CryEngine的动画系统支持使用不同的过渡曲线,如线性曲线、贝塞尔曲线等。

2.2.1 代码示例:使用过渡曲线

// 动画控制器类

class AnimationController

{

public:

    AnimationController(Character* character) : m_character(character), m_transitionTime(0.5f), m_transitionProgress(0.0f) {}



    void Update(float deltaTime)

    {

        if (m_isTransitioning)

        {

            m_transitionProgress += deltaTime / m_transitionTime;



            if (m_transitionProgress >= 1.0f)

            {

                m_transitionProgress = 1.0f;

                m_isTransitioning = false;

            }



            float fromWeight = 1.0f - m_transitionProgress;

            float toWeight = m_transitionProgress;



            m_character->SetAnimationWeight(m_fromAnimation, fromWeight);

            m_character->SetAnimationWeight(m_toAnimation, toWeight);

        }

    }



    void Transition(const char* fromAnimation, const char* toAnimation)

    {

        m_fromAnimation = fromAnimation;

        m_toAnimation = toAnimation;

        m_isTransitioning = true;

        m_transitionProgress = 0.0f;

    }



private:

    Character* m_character;

    float m_transitionTime;

    float m_transitionProgress;

    bool m_isTransitioning;

    const char* m_fromAnimation;

    const char* m_toAnimation;

};



// 角色类

class Character

{

public:

    Character() : m_animationController(new AnimationController(this)), m_currentState("idle") {}



    void Update(float deltaTime)

    {

        m_animationController->Update(deltaTime);

    }



    void SetState(const char* state)

    {

        if (strcmp(state, "walk") == 0)

        {

            m_animationController->Transition("idle", "walk");

        }

        else if (strcmp(state, "idle") == 0)

        {

            m_animationController->Transition("walk", "idle");

        }



        m_currentState = state;

    }



    const char* GetState() const

    {

        return m_currentState;

    }



    void SetAnimationWeight(const char* animationName, float weight)

    {

        // 设置动画权重的代码

    }



private:

    AnimationController* m_animationController;

    const char* m_currentState;

};

3. 环境交互与动态响应

角色与环境的交互是游戏开发中的重要部分,包括与地面的接触、与其他物体的碰撞等。CryEngine提供了强大的物理引擎和碰撞检测系统,可以实现复杂的环境交互。

3.1 地面接触检测

地面接触检测是确保角色在地面行走和跳跃时正确行为的关键。CryEngine的物理引擎提供了多种方法来检测角色是否接触地面。

3.1.1 代码示例:地面接触检测

// 角色类

class Character

{

public:

    Character() : m_isOnGround(false) {}



    void Update(float deltaTime)

    {

        // 更新地面接触检测

        CheckGroundContact();

    }



    bool IsOnGround() const

    {

        return m_isOnGround;

    }



private:

    bool m_isOnGround;



    void CheckGroundContact()

    {

        // 发射射线检测地面

        Ray groundRay;

        groundRay.start = m_characterEntity->GetWorldPos();

        groundRay.start.z -= 0.1f; // 射线起点在角色下方

        groundRay.dir = Vector3(0, 0, -1);

        groundRay.len = 1.0f;



        IPhysicalEntity* hitEntity = nullptr;

        if (gEnv->pPhysicalWorld->RayWorldIntersection(groundRay, 0, pierceability_all, &hitEntity, nullptr))

        {

            m_isOnGround = true;

        }

        else

        {

            m_isOnGround = false;

        }

    }

};

3.2 物体碰撞检测

物体碰撞检测用于检测角色与其他物体的碰撞,可以用于实现角色的阻挡、推开等行为。

3.2.1 代码示例:物体碰撞检测

// 角色类

class Character

{

public:

    Character() : m_isColliding(false) {}



    void Update(float deltaTime)

    {

        // 更新物体碰撞检测

        CheckCollision();

    }



    bool IsColliding() const

    {

        return m_isColliding;

    }



private:

    bool m_isColliding;



    void CheckCollision()

    {

        // 获取角色实体的碰撞信息

        IPhysicalEntity* characterEntity = m_characterEntity->GetPhysics();

        if (characterEntity)

        {

            // 检测碰撞

            IPhysicalEntity::EventPhysCollision collisionEvent;

            if (characterEntity->ReadEvent(PE_EVENT_COLLISION, &collisionEvent))

            {

                m_isColliding = true;

                // 处理碰撞

                HandleCollision(collisionEvent);

            }

            else

            {

                m_isColliding = false;

            }

        }

    }



    void HandleCollision(const IPhysicalEntity::EventPhysCollision& collisionEvent)

    {

        // 根据碰撞类型处理不同行为

        switch (collisionEvent.eventType)

        {

        case IPhysicalEntity::ePE_CollisionEnter:

            // 处理碰撞进入

            break;

        case IPhysicalEntity::ePE_CollisionStay:

            // 处理持续碰撞

            break;

        case IPhysicalEntity::ePE_CollisionExit:

            // 处理碰撞退出

            break;

        }

    }

};

4. 智能角色行为

智能角色行为是指角色能够根据当前环境和玩家行为做出合理的决策。CryEngine提供了行为树(Behavior Tree)和状态机(FSM)等工具来实现角色的智能行为。

4.1 行为树

行为树是一种层次化的决策结构,可以用于实现复杂的行为逻辑。每个节点代表一个行为或决策,节点之间通过逻辑关系连接起来。

4.1.1 代码示例:行为树节点

// 行为树节点基类

class BehaviorTreeNode

{

public:

    virtual ~BehaviorTreeNode() {}

    virtual EStatus Update(float deltaTime) = 0;



    enum class EStatus

    {

        Success,

        Failure,

        Running

    };

};



// 具体行为节点:移动到目标位置

class MoveToTarget : public BehaviorTreeNode

{

public:

    MoveToTarget(Character* character, const Vector3& target) : m_character(character), m_target(target) {}



    EStatus Update(float deltaTime) override

    {

        // 计算移动方向

        Vector3 direction = m_target - m_character->GetWorldPos();

        direction.Normalize();



        // 应用移动

        m_character->ApplyForce(direction * m_character->GetMoveSpeed() * deltaTime);



        // 检查是否到达目标

        if (direction.Length() < 0.1f)

        {

            return EStatus::Success;

        }



        return EStatus::Running;

    }



private:

    Character* m_character;

    Vector3 m_target;

};



// 具体行为节点:攻击目标

class AttackTarget : public BehaviorTreeNode

{

public:

    AttackTarget(Character* character, const Vector3& target) : m_character(character), m_target(target) {}



    EStatus Update(float deltaTime) override

    {

        // 播放攻击动画

        m_character->PlayAnimation("attack");



        // 检查是否攻击成功

        if (m_character->IsAttackSuccess())

        {

            return EStatus::Success;

        }



        return EStatus::Running;

    }



private:

    Character* m_character;

    Vector3 m_target;

};



// 行为树类

class BehaviorTree

{

public:

    BehaviorTree(Character* character) : m_character(character) {}



    void Update(float deltaTime)

    {

        for (BehaviorTreeNode* node : m_behaviorTree)

        {

            EStatus status = node->Update(deltaTime);

            if (status == EStatus::Running)

            {

                return;

            }

        }

    }



    void AddNode(BehaviorTreeNode* node)

    {

        m_behaviorTree.push_back(node);

    }



private:

    Character* m_character;

    std::vector<BehaviorTreeNode*> m_behaviorTree;

};



// 角色类

class Character

{

public:

    Character() : m_behaviorTree(new BehaviorTree(this)) {}



    void Update(float deltaTime)

    {

        m_behaviorTree->Update(deltaTime);

    }



    void MoveTo(const Vector3& target)

    {

        m_behaviorTree->AddNode(new MoveToTarget(this, target));

    }



    void Attack(const Vector3& target)

    {

        m_behaviorTree->AddNode(new AttackTarget(this, target));

    }



    void PlayAnimation(const char* animationName)

    {

        // 播放动画的代码

    }



    bool IsAttackSuccess() const

    {

        // 检查攻击是否成功的代码

        return true;

    }



private:

    BehaviorTree* m_behaviorTree;

};

4.2 状态机与行为树的结合

状态机和行为树可以结合使用,以实现更加复杂的角色行为。状态机管理角色的行为模式,而行为树在每个状态下执行具体的决策和动作。

4.2.1 代码示例:结合状态机和行为树

// 角色状态机基类

class CharacterStateMachine

{

public:

    CharacterStateMachine(Character* character) : m_character(character) {}

    virtual ~CharacterStateMachine() {}



    void Update(float deltaTime)

    {

        if (m_currentState)

        {

            m_currentState->Update(deltaTime);

        }

    }



    void SetState(CharacterState* state)

    {

        if (m_currentState)

        {

            m_currentState->Exit();

        }



        m_currentState = state;

        if (m_currentState)

        {

            m_currentState->Enter();

        }

    }



private:

    Character* m_character;

    CharacterState* m_currentState;

};



// 角色状态基类

class CharacterState

{

public:

    CharacterState(CharacterStateMachine* stateMachine) : m_stateMachine(stateMachine), m_behaviorTree(new BehaviorTree(stateMachine->GetCharacter())) {}

    virtual ~CharacterState()

    {

        delete m_behaviorTree;

    }



    virtual void Enter() = 0;

    virtual void Update(float deltaTime) = 0;

    virtual void Exit() = 0;



protected:

    CharacterStateMachine* m_stateMachine;

    BehaviorTree* m_behaviorTree;

};



// 具体状态示例:探索状态

class ExploreState : public CharacterState

{

public:

    ExploreState(CharacterStateMachine* stateMachine) : CharacterState(stateMachine) {}



    void Enter() override

    {

        m_stateMachine->GetCharacter()->PlayAnimation("explore");

    }



    void Update(float deltaTime) override

    {

        // 更新行为树

        m_behaviorTree->Update(deltaTime);



        // 检查是否需要转换到其他状态

        if (m_stateMachine->GetCharacter()->IsTargetDetected())

        {

            m_stateMachine->SetState(new CombatState(m_stateMachine));

        }

    }



    void Exit() override

    {

        m_stateMachine->GetCharacter()->StopAnimation("explore");

    }

};



// 具体状态示例:战斗状态

class CombatState : public CharacterState

{

public:

    CombatState(CharacterStateMachine* stateMachine) : CharacterState(stateMachine) {}



    void Enter() override

    {

        m_stateMachine->GetCharacter()->PlayAnimation("combat_ready");

    }



    void Update(float deltaTime) override

    {

        // 更新行为树

        m_behaviorTree->Update(deltaTime);



        // 检查是否需要转换到其他状态

        if (!m_stateMachine->GetCharacter()->IsTargetDetected())

        {

            m_stateMachine->SetState(new ExploreState(m_stateMachine));

        }

    }



    void Exit() override

    {

        m_stateMachine->GetCharacter()->StopAnimation("combat_ready");

    }

};



// 角色类

class Character

{

public:

    Character() : m_stateMachine(new CharacterStateMachine(this)), m_isTargetDetected(false) {}



    void Update(float deltaTime)

    {

        m_stateMachine->Update(deltaTime);

    }



    void SetIsTargetDetected(bool isDetected)

    {

        m_isTargetDetected = isDetected;

    }



    bool IsTargetDetected() const

    {

        return m_isTargetDetected;

    }



    void PlayAnimation(const char* animationName)

    {

        // 播放动画的代码

    }



    void StopAnimation(const char* animationName)

    {

        // 停止动画的代码

    }



    void ApplyForce(const Vector3& force)

    {

        // 应用力的代码

    }



    Vector3 GetWorldPos() const

    {

        // 获取角色世界位置的代码

        return Vector3(0, 0, 0);

    }



    float GetMoveSpeed() const

    {

        // 获取角色移动速度的代码

        return 5.0f;

    }



    bool IsAttackSuccess() const

    {

        // 检查攻击是否成功的代码

        return true;

    }



private:

    CharacterStateMachine* m_stateMachine;

    bool m_isTargetDetected;

};

4.3 智能角色行为的优势

  • 灵活性:行为树和状态机结合使用可以灵活地处理多种行为和决策。

  • 可扩展性:可以轻松地添加新的行为节点或状态,而不会影响现有的逻辑。

  • 模块化:每个行为节点和状态都是独立的模块,易于开发和维护。

4.4 智能角色行为的挑战

  • 复杂性:随着行为树和状态机的复杂度增加,管理这些结构会变得更加困难。

  • 性能:频繁的行为树更新和状态转换可能会导致性能问题,需要优化。

5. 多层控制与混合状态

多层控制和混合状态是高级角色控制技术中的重要概念,它们允许角色在多个层次上同时执行不同的行为,或者在多个状态之间进行混合。

5.1 多层控制

多层控制是指角色可以在多个层次上同时执行不同的行为。例如,角色可以同时执行移动和攻击动作,或者在行走时进行环境观察。

5.1.1 代码示例:多层控制

// 多层控制类

class MultiLayerController

{

public:

    MultiLayerController(Character* character) : m_character(character) {}

    virtual ~MultiLayerController() {}



    void Update(float deltaTime)

    {

        for (LayerController* layer : m_layers)

        {

            layer->Update(deltaTime);

        }

    }



    void AddLayer(LayerController* layer)

    {

        m_layers.push_back(layer);

    }



private:

    Character* m_character;

    std::vector<LayerController*> m_layers;

};



// 层控制器基类

class LayerController

{

public:

    LayerController(Character* character) : m_character(character) {}

    virtual ~LayerController() {}



    virtual void Update(float deltaTime) = 0;



protected:

    Character* m_character;

};



// 移动层控制器

class MovementLayer : public LayerController

{

public:

    MovementLayer(Character* character) : LayerController(character) {}



    void Update(float deltaTime) override

    {

        // 更新移动逻辑

        if (m_character->IsMoving())

        {

            m_character->ApplyForce(Vector3(1, 0, 0) * m_character->GetMoveSpeed() * deltaTime);

        }

    }

};



// 攻击层控制器

class AttackLayer : public LayerController

{

public:

    AttackLayer(Character* character) : LayerController(character) {}



    void Update(float deltaTime) override

    {

        // 更新攻击逻辑

        if (m_character->IsAttacking())

        {

            m_character->PlayAnimation("attack");

        }

    }

};



// 角色类

class Character

{

public:

    Character() : m_multiLayerController(new MultiLayerController(this)), m_isMoving(false), m_isAttacking(false) {}



    void Update(float deltaTime)

    {

        m_multiLayerController->Update(deltaTime);

    }



    void SetIsMoving(bool isMoving)

    {

        m_isMoving = isMoving;

    }



    bool IsMoving() const

    {

        return m_isMoving;

    }



    void SetIsAttacking(bool isAttacking)

    {

        m_isAttacking = isAttacking;

    }



    bool IsAttacking() const

    {

        return m_isAttacking;

    }



    void PlayAnimation(const char* animationName)

    {

        // 播放动画的代码

    }



    void StopAnimation(const char* animationName)

    {

        // 停止动画的代码

    }



    void ApplyForce(const Vector3& force)

    {

        // 应用力的代码

    }



    Vector3 GetWorldPos() const

    {

        // 获取角色世界位置的代码

        return Vector3(0, 0, 0);

    }



    float GetMoveSpeed() const

    {

        // 获取角色移动速度的代码

        return 5.0f;

    }



private:

    MultiLayerController* m_multiLayerController;

    bool m_isMoving;

    bool m_isAttacking;

};

5.2 混合状态

混合状态是指角色可以在多个状态之间进行平滑的混合,以实现更自然的行为。例如,角色在从行走状态转换到跑步状态时,可以通过混合这两种状态的动画来实现平滑过渡。

5.2.1 代码示例:混合状态

// 混合状态基类

class BlendedState

{

public:

    BlendedState(CharacterStateMachine* stateMachine) : m_stateMachine(stateMachine) {}

    virtual ~BlendedState() {}



    void Enter()

    {

        for (CharacterState* state : m_states)

        {

            state->Enter();

        }

    }



    void Update(float deltaTime)

    {

        for (CharacterState* state : m_states)

        {

            state->Update(deltaTime);

        }

    }



    void Exit()

    {

        for (CharacterState* state : m_states)

        {

            state->Exit();

        }

    }



    void AddState(CharacterState* state)

    {

        m_states.push_back(state);

    }



    void SetBlendWeight(const char* stateName, float weight)

    {

        for (CharacterState* state : m_states)

        {

            if (strcmp(state->GetName(), stateName) == 0)

            {

                m_character->SetAnimationWeight(state->GetAnimationName(), weight);

            }

        }

    }



protected:

    CharacterStateMachine* m_stateMachine;

    Character* m_character;

    std::vector<CharacterState*> m_states;

};



// 具体混合状态示例:行走和跑步混合

class WalkAndRunBlendedState : public BlendedState

{

public:

    WalkAndRunBlendedState(CharacterStateMachine* stateMachine) : BlendedState(stateMachine)

    {

        AddState(new WalkingState(stateMachine));

        AddState(new RunningState(stateMachine));

    }



    void Update(float deltaTime) override

    {

        // 更新混合状态

        float walkWeight = m_stateMachine->GetCharacter()->GetWalkSpeed() / m_maxWalkSpeed;

        float runWeight = 1.0f - walkWeight;



        SetBlendWeight("walk", walkWeight);

        SetBlendWeight("run", runWeight);



        // 调用基类的更新方法

        BlendedState::Update(deltaTime);

    }



private:

    float m_maxWalkSpeed = 5.0f;

};



// 角色类

class Character

{

public:

    Character() : m_stateMachine(new CharacterStateMachine(this)), m_walkSpeed(0.0f) {}



    void Update(float deltaTime)

    {

        m_stateMachine->Update(deltaTime);

    }



    void SetWalkSpeed(float speed)

    {

        m_walkSpeed = speed;

    }



    float GetWalkSpeed() const

    {

        return m_walkSpeed;

    }



    void PlayAnimation(const char* animationName)

    {

        // 播放动画的代码

    }



    void StopAnimation(const char* animationName)

    {

        // 停止动画的代码

    }



    void SetAnimationWeight(const char* animationName, float weight)

    {

        // 设置动画权重的代码

    }



private:

    CharacterStateMachine* m_stateMachine;

    float m_walkSpeed;

};

5.3 多层控制与混合状态的优势

  • 自然性:多层控制和混合状态可以使角色的行为更加自然和流畅。

  • 复杂性:可以处理复杂的角色行为,如同时移动和观察环境。

  • 可扩展性:可以轻松地添加新的层控制器和混合状态,而不会影响现有的逻辑。

5.4 多层控制与混合状态的挑战

  • 管理复杂性:多层控制和混合状态的管理可能会变得更加复杂,需要仔细设计。

  • 性能优化:需要对多层控制和混合状态的更新逻辑进行优化,以确保性能。

通过结合状态机、动画平滑过渡、环境交互、智能角色行为以及多层控制与混合状态,您可以创建更加复杂和逼真的角色控制系统。这些技术不仅提高了角色的行为自然性,还增强了游戏的沉浸感和玩家体验。
在这里插入图片描述

标签:const,角色,stateMachine,deltaTime,void,float,character,状态机,CryEngine
From: https://blog.csdn.net/chenlz2007/article/details/144119238

相关文章

  • 【Unity 插件】Visual State Machine 通过图形化的界面帮助开发者设计和管理复杂的状
    VisualStateMachine是一款用于Unity编辑器中的插件,旨在通过图形化的界面帮助开发者设计和管理复杂的状态机逻辑。它为Unity提供了一个直观的拖拽式状态机系统,可以用来控制角色行为、AI、动画、UI交互等各种状态转换。主要特点:图形化界面:使用拖拽式界面来创建和管理......
  • 人工智能:在传统行业中的挑战、机遇与数据科学家角色的演变
    生成式人工智能(GenAI)为我们开启了更快的开发周期、更少的技术和维护工作,以及之前看起来无法实现的创新应用场景的大门。但与此同时,它也带来了新的风险——比如幻觉问题,以及对第三方API的依赖。对于数据科学家和机器学习团队来说,这一变革直接影响了他们的工作方式。一种新的AI项......
  • 基于SSM + Vue的架的校园外卖管理系统(角色:用户、商家、管理员)
    文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例结语前言......
  • 基于SSM + Vue的酒店管理系统(角色:用户、员工、管理员)
    文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例结语前言......
  • 从“整理”到“思考”:文档管理工具的新角色
    在信息爆炸的时代,文档管理的核心挑战已不再是存储,而是高效组织和提取知识。传统文档管理工具通常以文件夹和标签为基础,这种层级化结构容易造成知识孤岛。然而,语义网络的引入为知识管理开辟了新的路径:它不再以孤立的文档为单元,而是基于内容、上下文和关联性建立知识图谱,使信息真正......
  • Unity中的数学应用 之 插值函数处理角色朝向 (初中难度 +Matlab)
            CodeMonkey教程:https://www.youtube.com/watch?v=QDWlGOocKm8    Siki学院汉化教程:如何使用Unity开发分手厨房(胡闹厨房)-Unity2023-SiKi学院|SiKi学堂-unity|u3d|虚幻|ue4/5|java|python|人工智能|视频教程|在线课程版本:Unity6模板:3D核心(渲......
  • python+Django+MySQL+echarts+bootstrap制作的教学质量评价系统,包括学生、老师、管理
    项目介绍该教学质量评价系统基于Python、Django、MySQL、ECharts和Bootstrap技术,旨在为学校或教育机构提供一个全面的教学质量评估平台。系统主要包括三种角色:学生、老师和管理员,每个角色有不同的功能权限。学生角色:学生可以通过该平台对所选课程进行评价,评价内容包括老师的......
  • 8 位 RISC 模型机 状态机控制 ALU双端口
    8位RISC模型机状态机控制双端口项目地址:8位RISC模型机状态机控制双端口从8位寄存器(D触发器)开始DDD:8位输入......
  • 【状态机DP】力扣309. 买卖股票的最佳时机含冷冻期
    给定一个整数数组prices,其中第prices[i]表示第i天的股票价格。​设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):卖出股票后,你无法在第二天买入股票(即冷冻期为1天)。注意:你不能同时参与多笔交易(你必须在再次购......
  • 【状态机DP】【hard】力扣188. 买卖股票的最佳时机 IV
    给你一个整数数组prices和一个整数k,其中prices[i]是某支给定的股票在第i天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成k笔交易。也就是说,你最多可以买k次,卖k次。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。示例......