复制SCNParticleSystem似乎不能很好地工作

kev*_*lar 5 scenekit swift

我正在尝试将SCNParticleSystem用作其他人的"模板".我基本上想要完全相同的属性,除了粒子的颜色动画.这是我到目前为止所得到的:

if let node = self.findNodeWithName(nodeName),
    let copiedParticleSystem: SCNParticleSystem = particleSystemToCopy.copy() as? SCNParticleSystem,
    let colorController = copiedParticleSystem.propertyControllers?[SCNParticleSystem.ParticleProperty.color],
    let animation: CAKeyframeAnimation = colorController.animation as? CAKeyframeAnimation {

    guard animation.values?.count == animationColors.count else {

        return nil
    }

    // Need to copy both the animations and the controllers
    let copiedAnimation: CAKeyframeAnimation = animation.copy() as! CAKeyframeAnimation
    copiedAnimation.values = animationColors

    let copiedController: SCNParticlePropertyController = colorController.copy() as! SCNParticlePropertyController
    copiedController.animation = copiedAnimation

    // Finally set the new copied controller
    copiedParticleSystem.propertyControllers?[SCNParticleSystem.ParticleProperty.color] = copiedController

    // Add the particle system to the desired node
    node.addParticleSystem(copiedParticleSystem)

    // Some other work ...
}
Run Code Online (Sandbox Code Playgroud)

我复制不仅SCNParticleSystem,而且还SCNParticlePropertyControllerCAKeyframeAnimation为了安全起见.我发现我必须手动"手动"执行这些"深度"复制,因为.copy()on SCNParticleSystem不会复制动画等.

当我在添加到的节点上打开复制的粒子系统时(通过设置birthRate为正数),没有任何反应.

我不认为问题出在我添加它的节点上,因为我已经尝试particleSystemToCopy将该节点添加到该节点并打开它,原始粒子系统在这种情况下变得可见.这似乎向我表明,我添加复制粒子系统的节点在几何,渲染顺序等方面都是可以的.

或许值得一提的其他内容:场景是从.scn文件加载而不是以编程方式在代码中创建的.在理论上,不应该影响任何事情,但谁知道......

关于为什么这个复制的粒子系统在打开时没有做任何事情的想法?

ARG*_*Geo 2

不要使用copy()粒子系统的方法!

copy()方法不允许复制粒子的颜色(复制的粒子将默认为白色)。

您可以使用以下代码进行测试:

let particleSystem01 = SCNParticleSystem()
particleSystem01.birthRate = 2
particleSystem01.particleSize = 0.5
particleSystem01.particleColor = .systemIndigo                 // INDIGO
particleSystem01.emitterShape = .some(SCNSphere(radius: 2.0))

let particlesNode01 = SCNNode()
particlesNode01.addParticleSystem(particleSystem01)
particlesNode01.position.y = -3
sceneView.scene.rootNode.addChildNode(particlesNode01)

let particleSystem02 = particleSystem01.copy()                 // WHITE

let particlesNode02 = SCNNode()
particlesNode02.addParticleSystem(particleSystem02 as! SCNParticleSystem)
particlesNode02.position.y = 3
sceneView.scene.rootNode.addChildNode(particlesNode02)
Run Code Online (Sandbox Code Playgroud)


请改用clone()节点方法!

clone()方法对于 3D 对象和粒子系统更加一致,它可以帮助您保存粒子的颜色,但当然不允许保存每个粒子的位置。

let particlesNode02 = particlesNode01.clone()                  // INDIGO

particlesNode02.position.y = 3
sceneView.scene.rootNode.addChildNode(particlesNode02)
Run Code Online (Sandbox Code Playgroud)