【问题标题】:GameplayKit > Make agent stop moving after goal to follow pathGameplayKit > 让代理在目标后停止移动以跟随路径
【发布时间】:2016-12-23 15:33:00
【问题描述】:

我通过在其行为中添加目标 toFollow: GKPath 来使代理遵循 GKPath。一切正常,但是当到达路径上的目标点时,代理会继续以类似 8 的形状移动。如何防止代理在到达 GKPath 上的目标点时徘徊?

我想到的一个解决方案是在接近目标点时设置另一个目标 toReachTargetSpeed: 0.0。但是,我不确定最佳做法是什么,因为没有内置方法可以查看目标何时“完成”。

  1. 是否在每次更新时使用 IF 语句检查目标距离:?性能如何?
  2. 我是否使用某种 GKRule?

您的建议将不胜感激。谢谢。

【问题讨论】:

    标签: ios gameplay-kit


    【解决方案1】:

    我选择了第一个选项,即在移动组件更新函数中跟踪到目标的距离:

    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)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      • 1970-01-01
      • 2020-02-14
      • 2019-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多