Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Ecnalyr · Oct 23, 2011 at 06:48 PM · iosprefabmobilerenderer.material.colorvertexshader

Mobile efficiency: this.renderer.material.color vs vertex shaders for changing object color.

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.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Peter G · Oct 23, 2011 at 08:24 PM

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[i] = 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.

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Ecnalyr · Oct 23, 2011 at 11:28 PM 0
Share

Sounds reasonable.

As far as implementation, I tried the following:

function DrawHealth()

{ var mesh : $$anonymous$$esh = GetComponent.<$$anonymous$$eshFilter>().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 $$anonymous$$obile / Vertex Colored shader that came with Unity.

avatar image Peter G · Oct 25, 2011 at 01:31 AM 0
Share

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.

avatar image Ecnalyr · Oct 25, 2011 at 02:17 AM 0
Share

Interesting, when it calls the line

"color = Color.Green;"

I get the following error:

NullReferenceException: Object reference not set to an instance of an object EnemyExistence.DrawHealth () (at Assets/TowerDefense Assets/Scripts/EnemyExistence.js:52) EnemyExistence.OnCollisionEnter (UnityEngine.Collision hit) (at Assets/TowerDefense Assets/Scripts/EnemyExistence.js:30)

I have not really trouble shooted (shot? ha) this yet, but I do like to post a notification comment as soon as you can so you know I am working on it. Will work on this tonight/tomorrow (more tomorrow) and reply back.

Thank you for the tips so far.

avatar image Ecnalyr · Oct 25, 2011 at 10:58 AM 0
Share

O$$anonymous$$, I took the information you gave me, looked at the Unity Script Reference for $$anonymous$$esh.colors.

I replaced all of the above code with :

 var mesh : $$anonymous$$esh = GetComponent($$anonymous$$eshFilter).mesh;
 var vertices : Vector3[] = mesh.vertices;
 var colors : Color[] = new Color[vertices.Length];

 for (var i = 0; i < vertices.Length;i++)
     colors[i] = Color.Lerp(Color.red, Color.green, vertices[i].y);

 mesh.colors = colors;

The result is that when I call this set of code my objects change to a red/green color (the bottom of them appears to be red, the top of them appears to be green) - which is progress - but I do not quite understand what is going on.

What would I need to change in the above snippet of code to get the color of the entire object to change based on a variable I have labeled as health? (I want the objects to get more and more red with the more damage they take, with maximum damage being "red" - just before they 'die.')

UPDATE *

I changed my code to this:

 var mesh : $$anonymous$$esh = GetComponent($$anonymous$$eshFilter).mesh;
 var vertices : Vector3[] = mesh.vertices;
 var colors : Color[] = new Color[vertices.Length];

 for (var i = 0; i < vertices.Length;i++)
     /*colors[i] = Color.Lerp(Color.red, Color.green, Time.time);*/
     
 //while (health <= 100)
     colors[i] = Color.Lerp(Color.black, Color.blue, Time.time);
 
 /*while (health <= 80)
     colors[i] = Color.Lerp(Color.blue, Color.green, Time.time);
 
 while (health <= 60)
     colors[i] = Color.Lerp(Color.green, Color.yellow, Time.time);
 
 while (health <= 40)
     colors[i] = Color.Lerp(Color.yellow, Color.orange, Time.time);
     
 while (health <= 20)
     colors[i] = Color.Lerp(Color.orange, Color.red, Time.time);*/

 mesh.colors = colors;

--But I have all my while statements commented out as it causes Unity to lock up. I want to follow roughly this logic, how would I implement this correctly?

(I know I cannot use the while statements like I am above (infinite loops much?), but I want to follow this 'kind' of logic, should I go back to using if statements?)

avatar image Peter G · Oct 28, 2011 at 01:22 AM 0
Share

Sorry 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 if statements and some while() blocks. You will probably need some yield statements. Unity uses yield differently than the C# keyword so check the reference on how to effectively use them.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Is this a good practice for mobile devices? 2 Answers

Vertical mobile input 0 Answers

Mobile 2.5D MMO Game Development Advice 0 Answers

Problem with GUI on different resolutions 1 Answer

Shader optim ? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges