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
1
Question by Krannx · Mar 11, 2011 at 12:05 AM · meshoptimizationruntimecombine

Combining Mesh at Runtime via Script causes temporary FPS drop

In the game that I am making, a common task is to create new meshes to add to a pre-determined object. (The code for how I am currently doing this is included at the bottom of this post).

I create meshes by calculating the vertexes at 8 points on in the game, and generating a new temporary object mesh between those points (Parallelogram), then I create a new temporary empty gameObject, combine the master mesh with the temporary mesh in that object, then finally save the new temporary mesh back into the master mesh.

Obviously this is an extremely memory process, and when I test the game my FPS averages between 250 and 300, which drops to 25 while making objects (1 per frame, yes it is necessary), then immediately returns to its previous higher number when I stop creating. My question is: is there a more optimized process for creating meshes and adding them to an object?

//temp1 is the First Temporary Mesh (in which I set vertices), temp2 is the second, and Master is the gameObject I am attatching them to.
var meshFilters = temp1.GetComponent(MeshFilter);
var combine : CombineInstance[] = new CombineInstance[2];
combine[0].mesh = meshFilters.sharedMesh;
combine[0].transform = meshFilters.transform.localToWorldMatrix;
var meshFilters2 = GameObject.Find("Master").GetComponent(MeshFilter);
combine[1].mesh = meshFilters2.sharedMesh;
combine[1].transform = meshFilters2.transform.localToWorldMatrix;
var temp2 : Mesh = new Mesh();
temp2.CombineMeshes(combine, true, true);
GameObject.Find("Master").GetComponent(MeshFilter).mesh = temp2;
GameObject.Find("Master").GetComponent(MeshFilter).mesh.RecalculateNormals();
GameObject.Find("Master").GetComponent(MeshFilter).mesh.RecalculateBounds();
GameObject.Find("Master").GetComponent(MeshFilter).mesh.Optimize();
GameObject.Find("Master").GetComponent(MeshCollider).mesh = GameObject.Find("Master").GetComponent(MeshFilter).mesh;
Destroy(temp1);

Thank you all very much for tolerating my wordiness. I just thought more information would be better than less.

Comment
Add comment · Show 1
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 Krannx · Mar 11, 2011 at 01:42 AM 0
Share

Also, I have gone through it, by just creating thousands of gameObjects that each have a meshRenderer and a meshCollider on them with 8 vertices, (ie. my code but without combining them) my RrameRate hardly drops until the obvious memory issues with that catch up to me a few $$anonymous$$utes later.

Again, Thanks!

1 Reply

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

Answer by Statement · Mar 11, 2011 at 12:32 AM

I don't have your project so I can't really pinpoint what is consuming most resources here. Some obvious ones are you're finding GameObjects several times, and looking up components several times. I rewrote your code (I hope it is still the same) to fix some obvious (potential) slowdowns, and renamed some variables to better reflect their purpose.

// Cache the results. var master : GameObject = GameObject.Find("Master"); var masterFilter : MeshFilter = master.GetComponent(MeshFilter); var masterCollider : MeshColider = master.GetComponent(MeshCollider);

var oldFilter = temp1.GetComponent(MeshFilter);

var combine : CombineInstance[] = new CombineInstance[2];

combine[0].mesh = oldFilter.sharedMesh; combine[0].transform = oldFilter.transform.localToWorldMatrix;

combine[1].mesh = masterFilter.sharedMesh; combine[1].transform = masterFilter.transform.localToWorldMatrix;

var newMesh : Mesh = new Mesh();

newMesh.CombineMeshes(combine, true, true); newMesh.RecalculateNormals(); newMesh.RecalculateBounds(); newMesh.Optimize();

masterFilter.mesh = newMesh; masterCollider.mesh = newMesh; // Potential bottleneck?

Destroy(temp1);

I know since before when I was working on some voxel system in Unity that assigning a mesh to a MeshCollider is a real pain performance wise. You'd have to profile your game to see exactly what calls here are too expensive. Also, you might sometimes be better off without Optimize() since it is quite heavy to perform.

This operation might take a while but will make the geometry displayed be faster. For example it generates triangle strips out of the triangles. You should use it if you generate a mesh from scratch procedurally and you want to trade better runtime performance against higher load time.

With other words, it's not always a good idea to call it while the game is running.

Comment
Add comment · Show 11 · 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 Statement · Mar 11, 2011 at 12:35 AM 0
Share

Also, are you sure you need to recalculate normals on the combined mesh? Are you sure you need to recalculate bounds? Can you try without, does it yield any errors?

avatar image loopyllama · Mar 11, 2011 at 01:04 AM 0
Share

call the generic version of those 3 getcomponent calls. boxing and unboxing ain't free!

avatar image Krannx · Mar 11, 2011 at 01:35 AM 0
Share

Thankyou very much for the quick reply, and after doing some tests with your code here are my results.

RecalculateNormals() is not needed, RecalculateBounds() is inorder for it to display, and Optimize() is not needed. I went on to change around the order of calls so the RecalculateBounds() is after the masterFilter is set, and then the masterCollider command became "masterCollider.shared$$anonymous$$esh = masterFilter.shared$$anonymous$$esh;"

With your script and the slight tweaks I mentioned (discovered by trial and error) the Frame Rate now only drops to 35 FPS...Any other tips?

avatar image Statement · Mar 11, 2011 at 02:37 AM 0
Share

If possible, use smaller meshes. $$anonymous$$aybe you don't need to combine every mesh, you might do with a limit on how large meshes are. If they become too large (and too expensive to combine), create a new GameObject or renderer or collider that you parent to the object.

avatar image Krannx · Mar 17, 2011 at 12:29 AM 1
Share

I solved my problems by approaching it from a slightly different standpoint, I am avoiding directly combining meshes but simply adding vertices and triangles to an existing mesh, then when it gets too large or I stop adding, it THEN combines with the master mesh, which has the script on it to ensure a correct size. Once that is combined, the mesh I am adding to is at zero, and again I am just adding vertices. This allows me to maintain between 130 and 85 FPS, which spikes to 35 for one frame. Which is not perfect, but the best I have managed to do. Thank you for all the help!

Show more comments

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

No one has followed this question yet.

Related Questions

Uncombine Children? 1 Answer

Optimize mesh for runtime performance 0 Answers

Combine Children and Unity 4.0.1 not working the same as in previous version 0 Answers

merge vertices at runtime? 1 Answer

What's the Script for Combining Prefabs 2 Answers


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