2017-02-17 229 views
1

我正在为实体系统添加物理,并对ECS的系统部分感到困惑。ECS(实体组件系统)中的交互系统?

例如,在非ECS项目我可能有这样的事情:

function updatePhysics() 
    foreach(thisRobot in robots) 
     thisRobot.move() 
     foreach(otherRobot in robots) 
      if(response = thisRobot.isColliding(otherRobot)) 
       thisRobot.resolveCollision(response) 

但是在ECS项目,我想有一个PositionComponent和VelocityComponent工作以及一个一个MovementSystem在PositionComponent和ShapeComponent上运行的CollisionSystem。其结果是这样的:

MovementSystem 
    function update() 
     foreach(entity in entities) 
      this.move(entity) 

CollisionSystem 
    function update() 
     foreach(thisEntity in entities) 
      foreach(otherEntity in entities) 
       if(response = this.isColliding(thisEntity, otherEntity) 
        this.resolve(thisEntity, response) 

的区别是在非精英版的运动和碰撞交错其中,作为ECS版本它们分隔。在实体系统中是否有正常的模式来模拟这种行为?我知道ECS的要点是摆脱继承,但是可能让MovementSystem和CollisionSystem成为更一般的物理系统的一部分,该系统会在单个实体上调用其他系统更新函数,而不是每个系统维护自己的循环?

回答

0

并不是每一个动作是通过物理模拟中影响实体...

我会分裂MovementSystem分为两类

  1. 运动对它们的影响物理实体。
  2. 实体运动是不是受物理影响。

在后一种情况下,你可以继续采取的方向上MovementComponent结合的VelocityComponent速度和计算实体的运动和位置。

在前者的情况下,您需要允许物理运行其模拟,确定碰撞并处理它们。无论哪种情况,您都需要为受物理影响的所有实体更新位置。

所以从一个循环的角度看,我希望看到

  1. 输入系统捕捉键/鼠标输入。
  2. 玩家控制器系统根据需要分析输入并生成意图。
  3. 运行非物理影响实体的运动。
  4. 执行对影响实体的所有物理学的RigidBodyMovementSystem
  5. 解决冲突
  6. 更新位置。

请记住,即使根据您对系统的描述方式,也可以将其分解为更小的系统组件,这些组件专门处理一个较小的任务,该步骤的输出是另一个系统的输入。

+0

在你的循环中,你有4和5分开。我的问题是针对如何交错这两个系统。 – zorqy

0

一个简单的方法可能是将运动组件添加到所需的目的地以及实际的目的地。然后只更新移动系统中的前者。
另一方面,碰撞系统将试图应用新的位置,通过切换所需的位置并一次检查一个实体的碰撞。

另一种方法是仅更新运动系统内的速度。然后添加一个更一般的物理系统,一次更新实体的位置,并检查碰撞,如果需要调整速度和位置。

您甚至可以定义一个完全按照您之前所做的操作的系统:遍历所有实体,一次更新实体的位置并检查冲突,然后继续执行下一个实体。
你不一定要分开移动系统和碰撞系统,做你的和你的游戏的声音。