gpt4 book ai didi

ios - 检查 SCNNode SCNAction 是否完成

转载 作者:搜寻专家 更新时间:2023-10-30 22:09:29 27 4
gpt4 key购买 nike

我创建了一个玩家可以在其中移动的 SceneKit 3D 迷宫世界。跳跃等一些 Action 涉及上下移动相机,同时在几秒钟的时间内改变观察方向。在此期间,我想忽略用户的点击和滑动,这些点击和滑动通常会导致其他类型的移动,例如转身和前进。

我可以创建一个与跳跃持续时间相匹配的计时器并设置一个 bool 值,但我希望有一种更简单的方法来检查相机的 SCNNode。

是否有一种简单的方法来查看相机的 SCNNode 是否不再运行用于跳跃的 SCNAction,以便我可以在其他点击和滑动操作之前添加此逻辑?

或者也许有一个 SCNAction 可以设置 Bool,我可以把它放在我的跳跃序列的开始和结束处?

这是我的跳转代码:

        let jumpUp: SCNAction = SCNAction.move(to: SCNVector3Make(Float(Int(-yPos)), Float(Int(xPos)), jumpHeight), duration: jumpTime)
let jumpAppex: SCNAction = SCNAction.wait(duration: jumpWaitTime)
let fallDown: SCNAction = SCNAction.move(to: SCNVector3Make(Float(Int(-yPos)), Float(Int(xPos)), cameraHeight), duration: jumpTime)

var lookDown: SCNAction = SCNAction.rotateTo(x: 0, y: 0, z: CGFloat(π), duration: jumpTurnTime)
let noLook: SCNAction = SCNAction.wait(duration: jumpTime*2.0)
var lookBack: SCNAction = SCNAction.rotateTo(x: 0, y: 0, z: 0, duration: jumpTurnTime)

switch playerDirection.direction
{
case .south:
lookDown = SCNAction.rotateTo(x: 0, y: 0, z: CGFloat(southZ), duration: jumpTurnTime)
lookBack = SCNAction.rotateTo(x: CGFloat(π/2), y: 0, z: CGFloat(southZ), duration: jumpTurnTime)
case .north:
lookDown = SCNAction.rotateTo(x: 0, y: 0, z: CGFloat(northZ), duration: jumpTurnTime)
lookBack = SCNAction.rotateTo(x: CGFloat(π/2), y: 0, z: CGFloat(northZ), duration: jumpTurnTime)
case .east:
lookDown = SCNAction.rotateTo(x: 0, y: 0, z: CGFloat(eastZ), duration: jumpTurnTime)
lookBack = SCNAction.rotateTo(x: CGFloat(π/2), y: 0, z: CGFloat(eastZ), duration: jumpTurnTime)
case .west:
lookDown = SCNAction.rotateTo(x: 0, y: 0, z: CGFloat(westZ), duration: jumpTurnTime)
lookBack = SCNAction.rotateTo(x: CGFloat(π/2), y: 0, z: CGFloat(westZ), duration: jumpTurnTime)
}

let sequenceJump = SCNAction.sequence([jumpUp, jumpAppex, fallDown])
let sequenceLook = SCNAction.sequence([lookDown, noLook, lookBack])

mazeScene.mazeCamera.runAction(sequenceJump)
mazeScene.mazeCamera.runAction(sequenceLook)

谢谢

格雷格

最佳答案

我认为 Action 是很奇怪的东西。

这个想法深受 cocos2D 的启发(基本上是 1:1 映射和“窃取”),在 cocos2D 中,它们被用作避免与游戏循环、状态和时间(某种程度上)直接交互的一种方式。 Action 提供了一种模块化和抽象,用于处理时间以及事件的创建和调用,以及对其结论的非常原始的处理。

阅读此处时,您可以看到 SpriteKit 和 SceneKit 的 Actions 与原始想法有多么相似:http://python.cocos2d.org/doc/programming_guide/actions.html

由于它们的创造具有不同和不断发展的性质,有人忘记让它们了解自己的状态,尽管它们会影响节点状态的某些方面。如果 Action 对象具有“运行”状态,这将近乎完美。但据我所知,他们没有。

相反,您可以检查节点是否具有给定的操作,如果有,则推断该操作正在运行。

尽管大多数操作在一段时间内做某事,但您也无法查询它们在持续时间内完成了多远,也无法查询它们刚刚触发或接下来将发送的值。但是有一些操作可以做到这一点,特别是为了应对所有操作都缺少这个的事实,这意味着如果你想要这个,你需要使用一个特殊的操作来提供这个。

而这种本应与生俱来的设施的递归和返回 self 是操作中最令人讨厌的部分,没有从熟悉时间轴和关键帧的人的角度考虑。

整体而言,总而言之:您无法查询操作的状态,也无法查询其进度,也无法查询它刚刚执行或将要使用的值。这绝对是荒谬的。

我不知道这在 Actions 的各种演变中是如何被忽视的……他们是时间管理和模块化事件的创造者。在其中包含状态和进度报告似乎是合乎逻辑的……好吧,我不知道……奇怪的是他们没有。

所以,回答你的问题:

  1. 您可以使用完成处理程序(当 Action 完成时调用一些代码)来设置值或调用其他函数或清理内容,或者任何您想要的。

  2. 序列操作,在 SCNAction.sequence 中...这是一种让操作按顺序运行的方法,并在内部使用一些操作,这些操作在您需要时运行代码块,调用设置您需要的内容,当你需要的时候,按照 Action 的顺序。如果 Actions 当前具有的时间和属性的值是透明的,那么所有这些都可以避免……但是……

  3. 您还可以使用一些特殊操作,这些操作通过对它们所做的更改来了解它们正在编辑的值。我只熟悉 SKEaseKit 中的 float 设置能力,但你可能可以在 SceneKit 和 SpriteKit 中做到这一点(如果你比我更擅长编码)。 SKEaseKit 隐藏了几个非常有用的值更改操作。

我使用它,例如,像这样,其中这个困惑在持续时间(时间)内将值从 0 更改为 1,在这种情况下是线性的,并且每个帧(希望如此)更新节点的 .xScale这个 growAction 运行:

let growAction = SKEase.createFloatTween(
start: 0,
ender: 1,
timer: time,
easer: SKEase.getEaseFunction(.curveTypeLinear,
easeType: .easeTypeOut),
setterBlock: {(node, i) in
node.xScale = i}
)

关于ios - 检查 SCNNode SCNAction 是否完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40929527/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com