I currently have 3 different types of enemies spawning into a scene.
Each of these three enemy types are spawned based off of a prefab; enemy1, enemy2, enemy3.
Each enemy takes damage individually although there may be 5 of enemy 1, 5 of enemy2, and 5 of enemy3 in the scene at any given time (often even more than 5 of each).
At the moment when the enemies take damage I have the individual enemy change colors (using: this.renderer.material.color) from green to yellow to red as they get closer to death (these colors were just a proof of concept for myself).
I am concerned about overall performance, as this game is being designed for a mobile platform, and was recently told that somehow changing individual colors of my spawned enemies would cut down the graphical performance of the game and that I should use vertex shaders in place of “this.renderer.material.color.”
I do not understand why the performance would be better (and specifically for a mobile platform) if I made the replacement. Can someone attempt to explain this or point me in the right direction?
Thank you.
1 Answer
1
My guess is that whoever told you this was referring to the instancing of materials. When you change the property of a material, Unity makes a new instance of a material to accommodate the change. This way only the individual object changes. But the biggest drawback is that the object won’t be batched anymore, and that adds draw calls which is a problem on mobile platforms.
Vertex colors could be what this person meant by vertex shaders. You can use a vertex colored shader, then change the vertex colors of the mesh. You need this line in your fixed-function shader:
ColorMaterial AmbientAndDiffuse
If you don’t understand shaders, then there are several built-in vertex colored shaders that will do what you want.
Then you need to get the mesh data of your model and change its vertex colors.
var mesh : Mesh = GetComponent.<MeshFilter>().mesh;
var colors = mesh.colors;
for (var i = 0; i < colors.Length ; i++){
colors *= Color.Red;*
//just for example.
}
mesh.colors = colors;
I haven’t done side by side testing so I can’t say which way is faster. If you don’t have that many characters, it really doesn’t make much difference. If you have lots of objects then the second choice might be faster.
Sounds reasonable. As far as implementation, I tried the following:
– anon46463775function DrawHealth() { var mesh : Mesh = GetComponent.<MeshFilter>().mesh; var colors = mesh.colors; if (health <=90) { colors = Color.Green; } if (health <=60) { colors = Color.Yellow; } if (health <=30) { colors = Color.Red; } if (health <=10) { colors = Color.Black; } mesh.colors = colors; }I get no errors, but as my units' health decreases I do not get color change for some reason. I am using the Mobile / Vertex Colored shader that came with Unity.Ok, here's the issue. mesh.colors is an array of Colors so you need to assign it an array of values. if (health <= 90) { for (var color in Colors) { color = Color.Green; } } You really should use a for(;;) loop doing this especially on mobile platforms because its more efficient with arrays, but the foreach loop gets the idea across better.
– Peter_GSorry to take so long to answer, I haven't been around UA that frequently lately. You are trying to smooth out the color it looks like. The cleanest way would be a spline interpolation, but that's somewhat complicated to implement so you can do it with a few
– Peter_Gifstatements and somewhile()blocks. You will probably need someyieldstatements. Unity uses yield differently than the C# keyword so check the reference on how to effectively use them.