【问题标题】:SCNParticleSystem: animating "particleColor" property in codeSCNParticleSystem:在代码中为“particleColor”属性设置动画
【发布时间】:2023-04-08 20:38:01
【问题描述】:

我想仅在代码中为 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 是这样说的:

苹果讨论

此属性的值是一个四分量向量(一个 NSValue 对象,其中包含用于粒子属性控制器的 SCNVector4 值,或者包含用于粒子事件或修改块的四个浮点值的数组)。 粒子系统的particleColor 和particleColorVariation 属性决定了每个粒子的初始颜色。

【问题讨论】:

    标签: swift xcode core-animation scenekit particle-system


    【解决方案1】:

    我认为文档是错误的。您的动画值数组应包含 UIColor 对象。

    animation.values = [UIColor.red, UIColor.green, UIColor.blue, UIColor.yellow]
    

    【讨论】:

    • 这是正确的解决方案。可能不使用文档中描述的 SCNVector4,而只是使用你提到的 UIColor 。太好了,tnx! - 另外,我发现,初始的“particleColor”属性值应该设置为 UIColor.white(当它是黑色时,整个粒子系统发出黑色 - 不知道为什么)
    【解决方案2】:

    有趣的问题 这:https://developer.apple.com/documentation/scenekit/animation/animating_scenekit_content 显示了一个带有 SCNTransaction 的类似调用,所以看起来你正在做的事情“应该”工作。但是,它不是 SCNParticle 系统组件。使用粒子可能有点棘手。我对选择器的东西不是很好,所以我不能仅仅看代码。

    particleColorVration - 向量随机化指定的颜色。这听起来与您想要做的不太一样,但它可能会让您接近 - 矢量按该顺序指定范围(色调、饱和度、亮度、Alpha)。

    【讨论】:

    • 我也在尝试一个 SCNTransaction,它确实有效,但同时影响所有生成的粒子,而不是在各自的时间段内影响每个粒子。我更新了我最初的问题,但仍然没有有效的解决方案。这很奇怪。
    • 是的 - 与其他 sceenkit 组件相比,粒子会做一些奇怪的事情,我已经看到类似的问题试图迫使他们单独做事。抱歉没有回答问题。
    猜你喜欢
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 2011-04-15
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 2013-09-10
    相关资源
    最近更新 更多