问题描述
我只想在SceneKit粒子系统中用代码对特定的颜色序列进行动画处理。 (就像一个人可以在XCode的粒子系统编辑器中一样。)
我正在尝试以下操作,并且每次将动画附加到粒子系统时,应用程序都会崩溃。编译器不会抱怨,Xcode不会在语法中指出任何错误。 (没有动画部分,粒子系统运行正常)
func particleSystemTesting(shape: SCNGeometry) -> SCNParticleSystem {
let explosion = SCNParticleSystem(named: "explosion.scnp",inDirectory: nil)!
explosion.emitterShape = shape
explosion.birthLocation = .surface
explosion.birthDirection = .surfaceNormal
explosion.isAffectedByGravity = true
explosion.isLightingEnabled = false
explosion.loops = true
explosion.sortingMode = .none
explosion.isBlackPassEnabled = true
explosion.blendMode = .additive
explosion.particleColor = UIColor.white // using as default,should even not be required
// Animation Part
let animation = CABasicAnimation(keyPath: "particleColor")
animation.fromValue = UIColor.blue
animation.toValue = UIColor.red
animation.duration = 2.0
animation.isRemovedOnCompletion = true
explosion.addAnimation(animation,forKey: nil) // causing the crash
return explosion
}
这是控制台打印出来的错误:
2020-08-23 18:25:53.281120+0200 MyTestApp[1684:892874] Metal GPU Frame Capture Enabled
2020-08-23 18:25:53.281349+0200 MyTestApp[1684:892874] Metal API Validation Enabled
2020-08-23 18:25:56.563208+0200 MyTestApp[1684:892874] -[SCNParticleSystem copyAnimationChannelForKeyPath:animation:]: unrecognized selector sent to instance 0x101041500
2020-08-23 18:25:56.564524+0200 MyTestApp[1684:892874] *** Terminating app due to uncaught exception 'NSInvalidArgumentException',reason: '-[SCNParticleSystem copyAnimationChannelForKeyPath:animation:]: unrecognized selector sent to instance 0x101041500'
*** First throw call stack:
(0x1998d5654 0x1995f7bcc 0x1997d9dd8 0x1998d97f8 0x1998db71c 0x1ade571f8 0x1ade55f24 0x1ade59268 0x1ade5af2c 0x1ade23d84 0x1adf18cf0 0x199852f2c 0x19984de20 0x19984e29c 0x19984dba8 0x1a39bd344 0x19d9893e4 0x100566384 0x1996d58f0)
libc++abi.dylib: terminating with uncaught exception of type NSException
经过更多研究和咨询后,苹果文档reference似乎是我的第一种方法是错误的,因为这会同时影响所有生成的粒子。
但是仍然无法按预期进行-场景中所有粒子均消失/不可见-否则没有错误。随着时间的推移,这应该改变每个粒子的颜色。怎么了?
func particleSystemTesting(shape: SCNGeometry) -> SCNParticleSystem {
let explosion = SCNParticleSystem(named: "explosion_testing.scnp",inDirectory: nil)!
// let explosion = SCNParticleSystem() // makes no difference
explosion.emitterShape = shape
explosion.birthLocation = .surface
explosion.birthDirection = .surfaceNormal
explosion.isAffectedByGravity = true
explosion.isLightingEnabled = false
explosion.loops = true
explosion.sortingMode = .none
explosion.isBlackPassEnabled = true
explosion.blendMode = .additive
// explosion.particleColor = UIColor.black
let red = UIColor.red
let green = UIColor.green
let blue = UIColor.blue
let yellow = UIColor.yellow
let color1 = SCNVector4(red.redValue,red.greenValue,red.blueValue,1.0)
let color2 = SCNVector4(green.redValue,green.greenValue,green.blueValue,1.0)
let color3 = SCNVector4(blue.redValue,blue.greenValue,blue.blueValue,1.0)
let color4 = SCNVector4(yellow.redValue,yellow.greenValue,yellow.blueValue,1.0)
let animation = CAKeyframeAnimation()
// animation.keyPath = "color" // has like no effect (?...)
animation.values = [color1,color2,color3,color4]
animation.keyTimes = [0,0.333,0.666,1]
animation.duration = 2.0
animation.isAdditive = false // should overwrite default colours
animation.isRemovedOnCompletion = true
let colorController = SCNParticlePropertyController(animation: animation)
explosion.propertyControllers = [SCNParticleSystem.ParticleProperty.color: colorController]
return explosion
}
Apple Docs这样说:
Apple讨论
此属性的值是一个四分量向量(NSValue对象包含用于粒子属性控制器的SCNVector4值,或用于粒子事件或修饰符块的四个浮点值的数组)。 粒子系统的particleColor和particleColorVariation属性确定每个粒子的初始颜色。
解决方法
我认为文档有误。您的动画值数组应包含UIColor
个对象。
animation.values = [UIColor.red,UIColor.green,UIColor.blue,UIColor.yellow]
,
有趣的问题 这:https://developer.apple.com/documentation/scenekit/animation/animating_scenekit_content显示了一个带有SCNTransaction的类似调用,因此看起来您在做“应该”工作。但是,它不是SCNParticle系统组件。使用粒子可能会有些棘手。我对选择器的东西不太满意,因此仅看代码我就无法分辨。
particleColorVaration-向量使指定的颜色随机化。这听起来并不完全像您想要的那样,但它可能会使您接近-向量按此顺序指定范围(色相,饱和度,亮度,alpha)。