我的GKEntity
有一个GKAgent2D
组件。它的行为是GKGoal
,toWander:
和toStayOnPath:maxPredictionTime:
。实体在场景中不断徘徊;但是,我希望它停止徘徊一段时间。例如,如果实体是一只徘徊的绵羊,我希望它能够定期停止进食,经过一段时间后,又开始徘徊。
更新
在实体:
中addComponent(MoveIdleComponent(maxSpeed: 60, maxAcceleration: 6, radius: Float(node.texture!.size().width * 0.3), entityManager: entityManager))
MoveIdleComponent
class MoveIdleComponent : GKAgent2D, GKAgentDelegate {
let entityManager: EntityManager
init(maxSpeed: Float, maxAcceleration: Float, radius: Float, entityManager: EntityManager) {
self.entityManager = entityManager
super.init()
delegate = self
self.maxSpeed = maxSpeed
self.maxAcceleration = maxAcceleration
self.radius = radius
print(self.mass)
self.mass = 0.01
}
func agentWillUpdate(agent: GKAgent) {
guard let spriteComponent = entity?.componentForClass(SpriteComponent.self) else {
return
}
self.position = float2(spriteComponent.node.position)
}
func agentDidUpdate(agent: GKAgent) {
guard let spriteComponent = entity?.componentForClass(SpriteComponent.self) else {
return
}
spriteComponent.node.position = CGPoint(position)
}
override func updateWithDeltaTime(seconds: NSTimeInterval) {
super.updateWithDeltaTime(seconds)
behavior = WanderBehavoir(targetSpeed: maxSpeed)
}
}
WanderBehavoir:
class WanderBehavoir: GKBehavior {
init(targetSpeed: Float) {
super.init()
if targetSpeed > 0 {
setWeight(0.5, forGoal: GKGoal(toWander: targetSpeed))
}
}
}
我该怎么做?
提前致谢
答案 0 :(得分:1)
似乎没有GKGoal(toEatFood:withFrequency:)
API,因此您必须退一步思考如何设置代理的目标以实现您的< / em>目标。
如果您希望代理停止游荡,或者停止跟踪路径,在一段时间内,您想要的就是那些不再是目标的人。 (而且,你希望它停止,当你取消目标时不要继续任何方向和速度,所以你要为速度为零引入toReachTargetSpeed:
目标。)
通常有两种方法可以做到这一点:
让你的行为包括漫游,跟随路径和速度(零)目标,权重设置使得漫游和跟随路径超过速度。如果要在漫游+路径行为和停止行为之间切换,请使用setWeight(_:forGoal:)
使速度目标超过其他目标。
有一个行为包含漫游和跟踪路径目标,另一个行为具有速度(零)目标,并在您想要在它们之间切换时设置代理的behavior
属性。
答案 1 :(得分:0)
好的,我找到了@rickster建议的解决方案。我发布它可以帮助某人。
我添加了暂停值。
如果暂停为真,则速度权重变为1,GKGoal(toReachTargetSpeed: 0)
在 WanderBehavoir 课程中:
class WanderBehavoir: GKBehavior {
init(targetSpeed: Float, entityManager: EntityManager, pause: Bool) {
super.init()
var weightWander : Float = 1.0
var weightSpeed : Float = 0.0
if pause {
weightWander = 0
weightSpeed = 1
}
// | |
// --A--B--
// | |
if targetSpeed > 0 {
let lato = Float(500.0)
let pts = [vector_float2(-lato,0),vector_float2(+lato,0)]
let path = GKPath(points: UnsafeMutablePointer(pts), count: pts.count, radius: 980, cyclical: true)
let obstacleNode = entityManager.nodesWithUnitType(Tree)
let obstacles = SKNode.obstaclesFromNodePhysicsBodies(obstacleNode)
setWeight(0.5, forGoal: GKGoal(toAvoidObstacles: obstacles, maxPredictionTime: 0.5))
setWeight(0.2, forGoal: GKGoal(toStayOnPath: path, maxPredictionTime: 0.5))
setWeight(weightWander, forGoal: GKGoal(toWander: targetSpeed))
setWeight(weightSpeed, forGoal: GKGoal(toReachTargetSpeed: 0))
}
}
}
在班级 class MoveIdleComponent : GKAgent2D, GKAgentDelegate
暂停时,在随机增量时间后切换为true和false
private var lastUpdateInterval: NSTimeInterval = 0
var setPause = true
var randomTimeStop = NSTimeInterval(Int(5...8))
var randomTimeMove = NSTimeInterval(Int(10...20))
override func updateWithDeltaTime(seconds: NSTimeInterval) {
super.updateWithDeltaTime(seconds)
lastUpdateInterval += seconds
if setPause {
if lastUpdateInterval > randomTimeStop {
setPause = !setPause
lastUpdateInterval = 0
randomTimeMove = NSTimeInterval(Int(10...20))
}
}
else {
if lastUpdateInterval > randomTimeMove {
setPause = !setPause
lastUpdateInterval = 0
randomTimeStop = NSTimeInterval(Int(5...8))
}
}
print("randomTimeMove \(randomTimeMove)")
behavior = WanderBehavoir(targetSpeed: maxSpeed, entityManager: entityManager, pause: setPause)
}