How do i make particle textures rotate or have a random rotation?
Unity currently doesn't support this. The only ways that I'm aware of at the moment are:
- Use a collection of textures that show the particles in different rotations - either played through as an animation using UV animation, or if you want static but random rotation, use a separate particle system for each rotated texture.
or:
- Roll your own system of displaying particles (perhaps using spriteManager as a base).
Neither option is particularly appealing, however there's a Unity Feedback entry requesting native support for this, so add your votes, here:
Currently particle rotation is limited and unsupported. If you really need it, you can use the undocumented ParticleRenderer.rotationCurve property, which lets you assign an AnimationCurve to map particle energy to rotation.
However, this API may be removed in the future, when we add proper support for particle animation, which could cause your content to break in the web player.
The best way currently would be to roll your own particle system. This is not as complicated as it may seem, especially depending on your needs. If you can limit the requirements of your custom particle system (say to 2 dimensions, rather than 3), the implementation may be very fast.
The spriteManager is definitely a good resource, but most of the code is highly specific to its needs, and can be trimmed for example purposes. All you need to get started is
A: a particle manager - which houses the mesh information - vertices, uvs, triangles and colors>
B: a transform node for each particle. Each particle should cache the initial positions of its vertices, and then can transform them by the transform node. This will give you full translation, rotation and scale in all 3 dimensions.
The basics of mesh generation from code. Take a look at Brady's sprite manager for more detail, as this is not complete.
private Vector3[] theVertices;
private Color[] theColors;
private Vector2[] theUVs;
private int[] theTriangles;
private Mesh spriteMesh;
private MeshFilter meshFilter;
private MeshRenderer meshRenderer;
private int maxParticleCount;
private void CreateSystem() {
gameObject.AddComponent("MeshFilter");
gameObject.AddComponent("MeshRenderer");
meshFilter = (MeshFilter)GetComponent(typeof(MeshFilter));
meshRenderer = (MeshRenderer)GetComponent(typeof(MeshRenderer));
spriteMesh = meshFilter.mesh;
theVertices = new Vector3[maxParticleCount * 4];
theColors = new Color[maxParticleCount * 4];
theUVs = new Vector2[maxParticleCount * 4];
theTriangles = new int[maxParticleCount * 6];
}
public void RebuildMesh(){
spriteMesh.Clear();
spriteMesh.vertices = theVertices;
spriteMesh.uv = theUVs;
spriteMesh.triangles = theTriangles;
spriteMesh.colors = theColors;
spriteMesh.RecalculateBounds();
}
private ParticleSprite CreateNewSprite(){
GameObject Sprite = new GameObject();
Sprite.tag = "ParticleSprite";
Sprite.name = "ParticleSprite";
Sprite.AddComponent(typeof (ParticleSprite));
return((ParticleSprite)Sprite.GetComponent(typeof (ParticleSprite)));
}
public void SetVertices(int iUL,int iLL,int iLR,int iUR, Vector3 ul, Vector3 ll, Vector3 lr, Vector3 ur){
theVertices[iUL] = ul;
theVertices[iLL] = ll;
theVertices[iLR] = lr;
theVertices[iUR] = ur;
updateVerts = true;
}
public void LateUpdate(){
if(updateVerts){
updateVerts = false;
spriteMesh.vertices = theVertices;
}
}
The most important part of each ParticleSprite. I have cached the indices, and initial positions of each vertex, and based on the local transform on the gameObject, you can rotate the particle any way you like.
public void DoTransform(){
manager.SetVertices(
indexUL,indexLL,indexLR,indexUR,
theTransform.TransformPoint(vUL),
theTransform.TransformPoint(vLL),
theTransform.TransformPoint(vLR),
theTransform.TransformPoint(vUR)
);
}
I know two ways to do this, but neither are ideal:
First, if the particle render mode is Stretched, the particles will rotate along their movement vector. I've used this for the bird 'particles' in a Unity3d iPhone game. In this video, the seagull that makes a brief appearance is a particles that rotates:
http://www.youtube.com/watch?v=PBMoZaq0lWY
Just a bit of random velocity will rotate the textures. Be sure that the stretch scale and velocity scale are set to 1 (I think) so that there is no actually stretching.
The second method is a hybrid method: Generate 'invisible' particles and then, in an Update() method, access the particleEmitter.particles[] array, position your own billboard sprites at each particle.position, then rotate them:
Particle[] p = gameObject.particleEmitter.particles;
for (int i = 0; i < p.Length; i++) { billboardPool_.transform.position = p*.position;*_ _billboardPool*.transform.rotation = // Do your own rotation here!*_ _*}
*_Unity supports this now with Shuriken.