Post

玩家实体--MMO服务器开发技术点记录

玩家实体--MMO服务器开发技术点记录

了解完ECS架构后,我们先来设计我们的第一个实体,玩家实体。

Player / 玩家实体

玩家实体继承于实体类,表示场景中的玩家,可以是当前操作的玩家,或者联机下场景中的其他玩家,也可以是npc或者敌人。

玩家实体的ID随机生成,初始化的玩家拥有四个组件:

  • MovementComponent:移动组件
  • SpaceComponent: 场景组件
  • CombatComponent:战斗逻辑组件
  • ConnectionComponent:连接组件

下面我们来一一介绍这些实体。

MovementComponent / 移动组件

移动组件负责控制玩家实体的位置信息,负责玩家的移动和旋转,在Unity中,表示一个玩家位置信息需要位置 / position和视角 / rotation,表示玩家的移动信息需要速度 / velocity,加速度 / acceleration,角速度 / angular velocity。

移动可以分类成行走,跳跃,蹲下等,这里统一称为move mode,不同mode下的状态变化符合固定的逻辑。

为了实现网络同步,我们需要实现移动组件的序列化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class MovementComponent : public IComponent {
public:
    static inline const char* COMPONENT_NAME = "MovementComponent";

    MovementComponent(Entity* entity) : IComponent(entity) {}

    virtual void net_serialize(OutputBitStream& bs, bool to_self) const override;
    virtual bool net_delta_serialize(OutputBitStream& bs, bool to_self) override;

    void update(float dt) override;

    void set_position(float x, float y, float z);
    Vector3f get_position() const;

    void set_velocity(float x, float y, float z);
    Vector3f get_velocity() const;

    void set_acceleration(float x, float y, float z);
    Vector3f get_acceleration() const;

    void set_angular_velocity(float x, float y, float z);
    Vector3f get_angular_velocity() const;

    void set_mode(int mode);
    int get_mode() const;

    int get_move_timestamp() const;
    void set_move_timestamp(int timestamp);

private:
    Vector3f _position;
    Rotation _rotation;
    Vector3f _velocity;
    Vector3f _acceleration;
    Vector3f _angular_velocity;
    
    int _mode;
    int _move_timestamp;
}

SpaceComponent / 场景组件

比较简单,就是保存了场景服务的指针,方便调用场景服务。这个不需要进行同步,信息只存在在服务器。

1
2
3
4
5
6
7
8
9
10
11
12
13
class SpaceComponent : public IComponent {
public:
    static inline const char* COMPONENT_NAME = "SpaceComponent";

    SpaceComponent(Entity* entity) : IComponent(entity) {}

    void enter_scene(Scene* scene);
    void leave_scene();
    Scene* get_scene() const;

private:
    Scene* _scene;
};
This post is licensed under CC BY 4.0 by the author.