Ios 动画的替代品(forKey:)(现在已弃用)?
我正在使用iOS 11(用于Ios 动画的替代品(forKey:)(现在已弃用)?,ios,swift,scenekit,ios11,Ios,Swift,Scenekit,Ios11,我正在使用iOS 11(用于ARKit),虽然许多人都指向苹果公司的一个带有福克斯的SceneKit示例应用程序,但我对该示例项目()中用于添加动画的扩展有问题: extension CAAnimation { class func animationWithSceneNamed(_ name: String) -> CAAnimation? { var animation: CAAnimation? if let scene = SCNScene(
ARKit
),虽然许多人都指向苹果公司的一个带有福克斯的SceneKit
示例应用程序,但我对该示例项目()中用于添加动画的扩展有问题:
extension CAAnimation {
class func animationWithSceneNamed(_ name: String) -> CAAnimation? {
var animation: CAAnimation?
if let scene = SCNScene(named: name) {
scene.rootNode.enumerateChildNodes({ (child, stop) in
if child.animationKeys.count > 0 {
animation = child.animation(forKey: child.animationKeys.first!)
stop.initialize(to: true)
}
})
}
return animation
}
}
看起来这个扩展非常方便,但我不知道如何迁移它,因为它已经被弃用了?它现在是否默认内置在SceneKit
中
文档中并没有显示太多关于它被弃用的原因或者从这里到哪里的信息
谢谢TL;DR:关于如何使用新API的示例可以在苹果的(搜索
SCNAnimationPlayer
)
尽管
animation(forKey:)
及其与CAAnimation
一起工作的姐妹方法在iOS11
中已被弃用,但您可以继续使用它们–一切都会正常工作
但是如果您想使用新的API,并且不关心向后兼容性(在ARKit
的情况下,您不需要向后兼容性,因为它只在iOS11
之后才可用),请继续阅读
新推出的SCNAnimationPlayer
与以前的版本相比提供了更方便的API。现在更容易实时处理动画。
从WWDC2017
开始学习将是一个很好的起点
作为一个简短的总结:SCNAnimationPlayer
允许您动态更改动画的速度。与添加和删除CAAnimation
s相比,它使用play()
和stop()
等方法为动画播放提供了更直观的界面。
您还可以将两个动画混合在一起,例如,可以使用这两个动画在它们之间进行平滑过渡
您可以在中找到如何使用所有这些的示例
以下是您发布的扩展,它适用于使用
SCNAnimationPlayer
(您可以在Fox 2示例项目的Character
类中找到):
您可以按如下方式使用它:
let jumpAnimation = SCNAnimationPlayer.loadAnimation(fromSceneNamed: "jump.scn")
jumpAnimation.stop() // stop it for now so that we can use it later when it's appropriate
model.addAnimationPlayer(jumpAnimation, forKey: "jump")
model.animationPlayer(forKey: "jump")?.play()
Lësha Turkowski毫不费力地回答了问题
extension SCNAnimationPlayer {
class func loadAnimationPlayer(from sceneName: String) -> SCNAnimationPlayer? {
var animationPlayer: SCNAnimationPlayer?
if let scene = SCNScene(named: sceneName) {
scene.rootNode.enumerateChildNodes { (child, stop) in
if !child.animationKeys.isEmpty {
animationPlayer = child.animationPlayer(forKey: child.animationKeys[0])
stop.pointee = true
}
}
}
return animationPlayer
}
}
下面是一个SwiftUI和SceneKit的示例
import SwiftUI
import SceneKit
struct ScenekitView : UIViewRepresentable {
@Binding var isPlayingAnimation: Bool
let scene = SCNScene(named: "art.scnassets/TestScene.scn")!
func makeUIView(context: Context) -> SCNView {
// create and add a camera to the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
let scnView = SCNView()
return scnView
}
func updateUIView(_ scnView: SCNView, context: Context) {
scnView.scene = scene
// allows the user to manipulate the camera
scnView.allowsCameraControl = true
controlAnimation(isAnimating: isPlayingAnimation, nodeName: "TestNode", animationName: "TestAnimationName")
}
func controlAnimation(isAnimating: Bool, nodeName: String, animationName: String) {
guard let node = scene.rootNode.childNode(withName: nodeName, recursively: true) else { return }
guard let animationPlayer: SCNAnimationPlayer = node.animationPlayer(forKey: animationName) else { return }
if isAnimating {
print("Play Animation")
animationPlayer.play()
} else {
print("Stop Animation")
animationPlayer.stop()
}
}
}
struct DogAnimation_Previews: PreviewProvider {
static var previews: some View {
ScenekitView(isPlayingAnimation: .constant(true))
}
}
非常感谢。我按照你的链接做了这件事,用SCNAnimationPlayer替换了我的动画代码,但我无法让它在我的生命中播放。网格跳到动画的第一帧,因此我知道它正在加载它。我可以记录动画并查看正确的帧数,但play()什么也不做。使用CAAnimation的相同动画效果很好。有什么我可以测试的吗?
import SwiftUI
import SceneKit
struct ScenekitView : UIViewRepresentable {
@Binding var isPlayingAnimation: Bool
let scene = SCNScene(named: "art.scnassets/TestScene.scn")!
func makeUIView(context: Context) -> SCNView {
// create and add a camera to the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
let scnView = SCNView()
return scnView
}
func updateUIView(_ scnView: SCNView, context: Context) {
scnView.scene = scene
// allows the user to manipulate the camera
scnView.allowsCameraControl = true
controlAnimation(isAnimating: isPlayingAnimation, nodeName: "TestNode", animationName: "TestAnimationName")
}
func controlAnimation(isAnimating: Bool, nodeName: String, animationName: String) {
guard let node = scene.rootNode.childNode(withName: nodeName, recursively: true) else { return }
guard let animationPlayer: SCNAnimationPlayer = node.animationPlayer(forKey: animationName) else { return }
if isAnimating {
print("Play Animation")
animationPlayer.play()
} else {
print("Stop Animation")
animationPlayer.stop()
}
}
}
struct DogAnimation_Previews: PreviewProvider {
static var previews: some View {
ScenekitView(isPlayingAnimation: .constant(true))
}
}