如何在 SceneKit 中以编程方式旋转具有特定角度的粒子?

How to rotate a particle with a specific angle programmatically in SceneKit?

我想旋转一个粒子,它是一条简单的线,在屏幕中央发射一次。

我触摸屏幕后,方法被调用,旋转一直在变化。对于 10° 或 180°,围绕 xz 轴,结果是相同的:角度为 N°,然后是 Y°,然后是 Z°(始终是不同的数字,随机彼此之间的差异:10°,不是每次都偏移 10,而是一个随机数)。你知道为什么吗?

func addParticleSceneKit(str:String){
    var fire = SCNParticleSystem(named: str, inDirectory: "art.scnassets/Particles")
    fire.orientationMode = .Free
    fire.particleAngle = 90
    //fire.propertyControllers = [ SCNParticlePropertyRotationAxis : [1,0,0] ] // should it be a SCNParticlePropertyController? I don't know how to use it then. But it would not be for an animation in my case.
    emitter.addParticleSystem(fire)

谢谢

particleAngleVariation 属性 控制初始粒子角度的随机变化。通常默认为零,这意味着粒子角度不是随机的,但是你从一个文件加载一个粒子系统,所以你得到了那个文件中的任何东西——将它设置为零应该会停止你看到的随机化。 (您也可以通过在 Xcode 中编辑该文件来对要加载它的文件中的粒子系统执行此操作。)


顺便说一句,您不会在每次要发射单个粒子时都向场景中添加另一个新的粒子系统,对吗?这迟早会引起问题。相反,保留单个粒子系统,并在单击时发射更多粒子。

大概你已经设置了它的emissionDuration, birthRate, and loops properties in the Xcode Particle System Editor so that it emits a single particle when you add it to the scene? Then just call its reset方法,它会重新开始,而不需要你在场景中添加另一个。


此外,关于您的评论...

fire.propertyControllers = [ SCNParticlePropertyRotationAxis : [1,0,0] ] 

should it be a SCNParticlePropertyController? I don't know how to use it then. But it would not be for an animation in my case.

阅读 the documentation 可能对此有所帮助。但它的要点是:propertyControllers 应该是 [String: SCNParticlePropertyController] 的字典。我知道,它说 [NSObject : AnyObject],但那是因为这个 API 是从没有类型化集合的 ObjC 导入的。这就是文档很重要的原因 - 它说 "Each key in this dictionary is one of the constants listed in Particle Property Keys, and the value for each key is a SCNParticlePropertyController object..." 这只是同一件事的冗长英语。

因此,传递键为字符串且值为整数数组的字典对您没有帮助。

docs 还说 属性 控制器用于动画属性,您可以从 Core Animation 动画创建一个。因此,如果您希望每个粒子随时间旋转,您可以使用 属性 角度控制器:

let angleAnimation = CABasicAnimation()
angleAnimation.fromValue = 0 // degrees
angleAnimation.toValue = 90 // degrees
angleAnimation.duration = 1 // sec
let angleController = SCNParticlePropertyController(animation: angleAnimation)
fire.propertyControllers = [ SCNParticlePropertyAngle: angleController ]

或者对于旋转轴,如果您希望粒子(由于定向模式和 angular 速度已经自由旋转)从一个旋转轴平滑过渡到另一个旋转轴:

let axisAnimation = CABasicAnimation()
axisAnimation.fromValue = NSValue(SCNVector3: SCNVector3(x: 0, y: 0, z: 1))
axisAnimation.toValue =NSValue(SCNVector3: SCNVector3(x: 0, y: 1, z: 0))
axisAnimation.duration = 1 // sec
let axisController = SCNParticlePropertyController(animation: axisAnimation)
fire.propertyControllers = [ SCNParticlePropertyRotationAxis: axisController ]