7

我正在尝试将 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 ...
}

为了安全起见,我不仅复制了SCNParticleSystem,而且还复制了。我发现我不得不“手动”手动执行这些“深度”副本,因为 a on不会复制动画等。SCNParticlePropertyControllerCAKeyframeAnimation.copy()SCNParticleSystem

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

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

还有一点可能值得一提:场景是从 .scn 文件加载的,而不是在代码中以编程方式创建的。理论上应该不会影响任何事情,但谁知道......

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

4

1 回答 1

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)


改为使用clone()节点方法!

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

let particlesNode02 = particlesNode01.clone()                  // INDIGO

particlesNode02.position.y = 3
sceneView.scene.rootNode.addChildNode(particlesNode02)
于 2020-04-04T18:50:56.183 回答