我正在寻找一种在SceneKit中为精灵表制作动画的方法。经过一些研究后,我找到了Core Animation这样做的方法,这将是完美的,因为我需要尽可能多地控制动画。
我准备了一个简单的平面网格,其UV限制为一个spritesheet框架的大小。这样我只需要水平设置UV动画。我发现材料的contentsTransform矩阵的相关元素是m14(负责水平翻译的那个)。
但是,在运行时,SceneKit会回显以下错误:
[SCNKit ERROR] geometry?.firstMaterial?.diffuse.contentsTransform.m14 is not an animatable path
这是相关代码:
let spritesheetAnimation = CABasicAnimation(keyPath: "geometry?.firstMaterial?.diffuse.contentsTransform.m14")
spritesheetAnimation.fromValue = 1 - 1 / spritesheetFrameCount
spritesheetAnimation.toValue = 0
spritesheetAnimation.byValue = 1 / spritesheetFrameCount
spritesheetAnimation.duration = 1.0
spritesheetAnimation.repeatCount = Float.infinity
node.geometry?.insertMaterial(material, atIndex: 0)
node.addAnimation(spritesheetAnimation, forKey: "SpritesheetAnimation")
任何有此经验的人?我不知道是否有更简单的方法可以做到这一点,或者我是以错误的方式或任何方式看待它。所以,任何指针都会受到赞赏!
答案 0 :(得分:3)
这里有两个问题。
CoreAnimation将可动画的关键路径扩展到它可以设置动画的数据结构中 - 也就是说,它不是仅仅在一个完整的CATransform3D
和另一个完整的transform.translation.x
之间设置动画,而是让您为描述某个成员或属性的关键路径设置动画变换(如contentsTransform
)。
SceneKit不会这样做 - 您只能为完整的结构值设置动画。也就是说,您只能为contentsTransform.something
制作动画,而不能为SCNMatrix4
设置动画,为此,您需要提供完整的toValue
作为fromValue
/ geometry?.firstMaterial?.diffuse.contentsTransform
的动画。动画。
KVC密钥路径与Swift选项无关,因此let spritesheetAnimation = CABasicAnimation(keyPath: "geometry.firstMaterial.diffuse.contentsTransform")
let translation = SCNMatrix4MakeTranslation(1 - 1 / spritesheetFrameCount, 0, 0)
spritesheetAnimation.fromValue = NSValue(SCNMatrix4: translation)
spritesheetAnimation.toValue = NSValue(SCNMatrix4: SCNMatrix4Identity)
spritesheetAnimation.duration = 1.0
spritesheetAnimation.repeatCount = .infinity
不是合法的密钥路径。丢失问号,你应该没问题。
所以,你的代码应该看起来像这样(未经测试):
SCNMatrix4
请注意,您需要在NSValue
中包含fromValue
以传递给toValue
和Float.infinity
,因为Swift无法像标量数字一样自动转换它类型。
另请注意,如果您愿意,可以使用{{1}}的类型推断。
答案 1 :(得分:0)
您可以尝试contentsTransform.translation.x
- Core Animation在处理图层时非常聪明,因此SceneKit也可以处理它。
答案 2 :(得分:0)
这应该有效:
让spritesheetAnimation = CABasicAnimation(keyPath:“geometry.firstMaterial.diffuse.contentsTransform.m41”)
[...]
SceneKit不会将矩阵分解为“转换/旋转/缩放”等组件,因此您无法使用“contentsTransform.translation.x”之类的路径。但您仍然可以在显式动画键路径中定位矩阵组件,如“contentsTransform.m41”。