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 Azmodii · Aug 27, 2013 at 10:58 PM · c#gameobjectproceduraldrawcalls

Batch drawcalls of GameObjects with a script attached?

Hi all,

I have a hexagonal grid that is procedurally generated at runtime, and currently it has between 100-300 draw calls depending on the map size, and it batches most - if not all - of the related tiles.

I am using GameObject.Instantiate to create these.

My issue is that as soon as I attach a script to the hex tile prefab (for functionality like OnMouseEnter, Input.MouseButtonDown etc... ) it stops batching them and increases the draw calls well into the thousands.

Any clues how to get around this?

I thought of simply creating a script that interacted with the hex grids, but was attached to another game object - but this seems inelegant. Is this really the only solution?

Here is the code;

 foreach (Object_System.shell.tile _tile in _shell.tileList) {
 
         GameObject tile = (GameObject)Instantiate(_tilePrefab);
         Interface _script = (Interface)tile.GetComponent("Interface");
         Manager_Interface _interfaceManager = (Manager_Interface)this.GetComponent("Manager_Interface");
         _script._tileInstance = _tile;
         tile.tag = "SystemMap_Tile";
         tile.transform.position = _tile.position;
         tile.transform.parent = shell.transform;

And the a snippet of code from the script attached to the GameObject;

 void Update () {
 
         // When mouse enters, start highlighting the tile
         if (OnEnter == true) {
 
             colorEnd = colorOnEnter;
             colorNow = renderer.material.color;
             colorEnd.a = Opacity;
             Duration = OnEnterDuration;
             float lerp = Mathf.PingPong (Time.time, Duration) / Duration;
             renderer.material.color = Color.Lerp (colorNow, colorEnd, lerp);
 
         }
Comment
Add comment · Show 11
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 Azmodii · Sep 10, 2013 at 02:04 AM 0
Share

As far as solving this issue goes, I was unable to do that and it seems very unlikely that I will be able to. $$anonymous$$y research concluded with a simple answer. No. For functionality like that, each "Object" must be unique.

As a quick and dirty workaround, I resorted to raycasthit's on the camera script. Performance hit is negligible, certainly a lot less than the thousands of draw calls I was getting.

avatar image dorpeleg · Sep 10, 2013 at 10:40 AM 0
Share

As far As I know, draw calls should not be effected by scripts (unless you have something inside the script that is effecting draw calls).

If you can tell us what you are doing in the script (or even better, show code) then maybe we can see why the draw calls increase.

avatar image ArkaneX · Sep 10, 2013 at 10:56 AM 0
Share

And my question is - why it has 100-300 drawcalls without scripts? Are you using separate textures or texture atlas? If separate, you should consider atlasing them, but if you're already using atlas, then maybe there's some issue with materials. For example you might assigned separate material instance for each hex, during procedural generation.

avatar image dorpeleg · Sep 10, 2013 at 05:19 PM 1
Share

Please read here: link.

from the tips:

Batching dynamic objects has certain overhead per vertex, so batching is applied only to meshes containing less than 900 vertex attributes in total.

avatar image robertbu · Sep 11, 2013 at 05:52 AM 1
Share

Are you absolutely sure you are not modifying the material directly or indirectly with a script? That is, do you get the same behavior if you attach a script derived from $$anonymous$$onobehaviour that does absolutely nothing?

Show more comments

1 Reply

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

Answer by whydoidoit · Sep 11, 2013 at 06:48 AM

You need to write your own shader to shade your hexes. As I believe was pointed in the comments, as soon as you do renderer.material = anything you have broken batching.

What you need to do is shade the hexes based on "something else" apart from the material's color: probably the best thing would be the vertex colours of the model which you can change without breaking batching.

You could of course go the whole hog and guarantee 1 draw call by drawing all of the hexes as part of a single mesh. Your hex scripts could be used to add the necessary points to the mesh - but that is a bit more advanced but ideal in these cases.

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 whydoidoit · Sep 11, 2013 at 06:51 AM 0
Share

Something like this would probably do it:

 Shader "whydoidoit/Vertex Color Tinted" {
     Properties {
       _$$anonymous$$ainTex ("Texture", 2D) = "white" {}
     }
     SubShader {
       Tags { "RenderType" = "Opaque" }
       CGPROGRA$$anonymous$$
       #pragma surface surf Lambert
       struct Input {
           float2 uv_$$anonymous$$ainTex;
           float4 color;
       };
       sampler2D _$$anonymous$$ainTex;
       void surf (Input IN, inout SurfaceOutput o) {
           o.Albedo = tex2D (_$$anonymous$$ainTex, IN.uv_$$anonymous$$ainTex).rgb * IN.color;
       }
       ENDCG
     } 
     Fallback "Diffuse"
   }
avatar image whydoidoit · Sep 11, 2013 at 06:52 AM 0
Share

You would need to set the vertex colour of all of the vertices of the hex to the tinted color. See mesh.colours

avatar image Azmodii · Sep 11, 2013 at 07:10 AM 0
Share

Thanks for the custom shader! That will help me a great deal, I am still looking into coding shaders but I havent touched on that quite yet,

The issue is a little more complicated though, as any script attached to these objects - with or without modifying the material, results in Unity ignoring them during batch operations. Any script with $$anonymous$$onoBehaviour to be exact.

I am setting a public custom variable inside each "Instance" of this script, but surely that cant be resulting in the behaviour?

 public Object_System.shell.tile _tileinstance;

This is set during the Awake function of my scene.

And I think I may have to resort to a single mesh solution. Early performance profiling suggests the draw calls will be an issue down the track.

avatar image whydoidoit · Sep 11, 2013 at 07:15 AM 0
Share

I doubt that - the reason for not dynamically batching can be:

  • Not the same material

  • Not close enough together

  • Too many polygons

When you run the game, click on the hexes and ensure that the inspector doesn't show an "instance" after the material name - which is a dead giveaway that "something" has gone and fiddled with it.

So a script will only break batching if it manages to make the mesh more complicated or changes any property of the renderer.material.

avatar image Azmodii · Sep 11, 2013 at 07:29 AM 0
Share

Your dead right. It 100% says instance after the material name.

Just to throw a spanner in the works, if I attach the script in the code behind - it works like a charm. Attach the script to the prefab, same behaviour.

I can mark this as solved (as practically all the answers here have provided me with good alternatives - Thanks guys!) but its still rather curious why this is happening.

Beats me!

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

18 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

C# Adding Components From Other Gameobjects 3 Answers

How to handle a MASSIVE amount of game objects? 2 Answers

Camera to follow a target within a circle? 1 Answer

Assigning current color to a variable for fade out (C#) 0 Answers

Destroy + Score 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