1

エージェントの動作に目標 toFollow: GKPath を追加することで、エージェントが GKPath をたどるようにしています。すべて正常に動作しますが、パス上のターゲット ポイントに到達すると、エージェントは 8 のような形で移動し続けます。GKPath のターゲット ポイントに到達するときにエージェントがさまようのを防ぐにはどうすればよいですか?

私が考えた解決策は、別の目標を toReachTargetSpeed: 0.0 に設定して、ターゲット ポイントに近づくことです。ただし、目標がいつ「完了」したかを確認する方法が組み込まれていないため、何がベストプラクティスになるかはわかりません。

  1. 更新ごとにターゲットまでの距離を確認するために IF ステートメントを使用しますか? パフォーマンスはどうですか?
  2. ある種の GKRule を使用しますか?

あなたの提案は非常に高く評価されます。ありがとう。

4

1 に答える 1

1

最初のオプションを使用しました。つまり、motionComponent 更新関数でターゲットまでの距離を追跡します。

override func update(deltaTime seconds: TimeInterval) {
    guard let entity = self.entity as? BaseEntity else { return }
    if entity.moving {
        let targetPoint = CGPoint(x: 100, y: 100)
        let distanceToTarget = distanceFrom(point: point)
        if distanceToTarget < GameConfiguration.Movement.targetProximity {
            stopMovement(afterTraversing: distanceToTarget)
        }
    }
}

func distanceFrom(point: CGPoint) -> Float {
    guard let entity = self.entity as? BaseEntity else { return CGFloat.greatestFiniteMagnitude }
    let dx = point.x - entity.visualComponent.node.position.x
    let dy = point.y - entity.visualComponent.node.position.y
    return hypotf(Float(dx), Float(dy))
}

エージェントがターゲットに十分近づいたら、stopMovement 関数を実行します。次に、これにより、ターゲットまでの距離を移動するのに必要な時間が計算され (一定の速度で)、エージェントを強制停止するタイミングに関するタイマーが設定されます。

func stopMovement(afterTraversing distance: Float) {
    guard let entity = self.entity as? BaseEntity else { return }
    guard (entity.moving) else { return }
    guard let behavior = entity.agent.behavior as? MovingBehavior else { return }
    let timeToTarget = TimeInterval(distance / entity.agent.maxSpeed)
    Timer.scheduledTimer(withTimeInterval: timeToTarget, repeats: false, block: {_ in
        behavior.stopMoving()
        entity.agent.maxSpeed = 0.0
        entity.moving = false
    })
}

class MovingBehavior: GKBehavior {

    var reachMaxSpeed: GKGoal
    var followPathGoal: GKGoal
    var stopMovingGoal = GKGoal(toReachTargetSpeed: 0.0)

    init(path: GKPath, target: GKGraphNode, maxSpeed: Float) {
        reachMaxSpeed = GKGoal(toReachTargetSpeed: maxSpeed)
        followPathGoal = GKGoal(toFollow: path, maxPredictionTime: 1.0, forward: true)
        super.init()
        setWeight(1.0, for: reachMaxSpeed)
        setWeight(0.8, for: followPathGoal)
        setWeight(0.0, for: stopMovingGoal)
    }

    func stopMoving() {
        setWeight(0.0, for: reachMaxSpeed)
        setWeight(0.0, for: followPathGoal)
        setWeight(1.0, for: stopMovingGoal)
    }
}
于 2017-01-10T12:03:56.500 に答える