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

时间:2015-04-03 15:35:08

标签: ios scenekit particles

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

触摸屏幕后,调用方法,旋转一直在变化。在xz轴附近有10°或180°,结果是相同的:角度是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)

由于

1 个答案:

答案 0 :(得分:1)

particleAngleVariation属性控制初始粒子角度的随机变化。通常默认为零,这意味着粒子角度不是随机的,而是从文件中加载粒子系统,因此您获得该文件中的任何内容 - 将其设置为零应该停止您看到的随机化。 (您也可以通过在Xcode中编辑该文件来对正在加载它的文件中的粒子系统执行此操作。)


顺便说一句,每次想要发射单个粒子时,你都不会在场景中添加另一个新的粒子系统,是吗?迟早会导致问题。相反,保持单个粒子系统,并在单击时发出更多粒子。

据推测,您已经在Xcode粒子系统编辑器中设置了emissionDurationbirthRateloops属性,以便在将其添加到场景时发出单个粒子?然后只需调用它的reset方法,它就会重新开始,而不需要在场景中添加另一个。


另外,关于你的评论......

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

它应该是SCNParticlePropertyController吗?我不知道如何使用它。但在我的情况下,它不适用于动画。

阅读the documentation可能对此有所帮助。但这是它的要点:propertyControllers应该是[String: SCNParticlePropertyController]的字典。我知道,它说[NSObject : AnyObject],但那是因为这个API是从没有类型集合的ObjC导入的。这就是为什么文档很重要的原因 - 它说“这个字典中的每个键都是粒子属性键中列出的常量之一,每个键的值是一个SCNParticlePropertyController对象......”这对于同样的东西来说只是啰嗦的英语

因此,传递一个字典,其中键是一个字符串,值是一个整数数组,这对你没有帮助。

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 ]

或者对于旋转轴,如果您想要粒子(由于方向模式和角速度而已经自由旋转)从一个旋转轴平滑过渡到另一个旋转轴:

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 ]