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 wolodo · Apr 25, 2014 at 08:37 AM · androidmobileperformance

Mobile performance tips

Hello,

I am trying to make RTS/TD game for mobile platforms and I would be glad, if you could share some performance optimization tips with me.

I made simple scene with A* navigation plugin. I used blender plane (4000 tris) as terrain. Than I spawn simple rigged and animated humanoid characters (800 tris), that move towards their goal and every bit of time check for near enemies. Shaders are all mobile difuse. no shadows, no point/spot lights.

When there is 50 or more of such moving characters on the screen, the FPS drops on my Galaxy S3 (25-30 FPS), which is fairly fast device. I can not find the bottle neck. When I use animated characters without AI script, the game runs well. When I use cubes instead of characters with AI, the game also runs well. But together it is quite slow.

Is there something, I could do to improve the performance even, when there is 50 or more characters in the scene? Is it possible to batch them some way? I am afraid, that when I add more details to the scene, slower mobile devices won't handle it.

Pseudo AI script is here:

 private void makeDecision() {
         //nothing to do, find tower or base to attack
         if(currentState == STATE.IDLE) {
             move();
             findTarget();
         }
         if(currentState == STATE.MOVING_TO_TOWER) {
             move();
         }
             move();
             StartCoroutine(findTower());
         }
         if(currentState == STATE.ATTACKING_TOWER) {
             if(!base.target) {
                 currentState = STATE.IDLE;
                 return;
             }
 
             RotateTowards (base.target.parent.position - transform.position);
             StartCoroutine(attack());
         }
         if(currentState == STATE.MOVING_TO_FRIEND) {
             if(!base.target) {
                 currentState = STATE.IDLE;
                 return;
             }
 
             if(base.target && Vector3.Distance(transform.position, base.target.position) <= transform.GetComponent<CapsuleCollider>().radius/2 + base.target.GetComponent<CapsuleCollider>().radius/2) {
                 currentState = STATE.ATTACKING_FRIEND;
             } else {
                 move();
                 if(Time.time - lastRepathTime > 0.3F) {
                     doRepath();
                     lastRepathTime = Time.time;
                 }
             }
         }
         if(currentState == STATE.ATTACKING_FRIEND) {
             if(!base.target) {
                 currentState = STATE.IDLE;
                 return;
             }
             RotateTowards (base.target.position - transform.position);
             if(base.target && Vector3.Distance(transform.position, base.target.position) <= transform.GetComponent<CapsuleCollider>().radius/2 + base.target.GetComponent<CapsuleCollider>().radius/2) {
                 currentState = STATE.ATTACKING_FRIEND;
             }
             StartCoroutine("attack");
             if(base.target && Vector3.Distance(transform.position, base.target.position) > transform.GetComponent<CapsuleCollider>().radius/2 + base.target.GetComponent<CapsuleCollider>().radius/2) {
                 currentState = STATE.IDLE;
             } 
         }
     }

Screenshot of the scene is also included (it's from editor, so do not mind the FPS value).alt text

screen.jpg (377.0 kB)
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

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by maddFrogg · Apr 25, 2014 at 08:52 AM

Take a look at this: http://www.gamasutra.com/blogs/AmirFassihi/20130828/199134/0__60_fps_in_14_days_What_we_learned_trying_to_optimize_our_game_using_Unity3D.php

I learnt some new things, I hope you do aswell.

Comment
Add comment · Show 1 · 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 wolodo · Apr 25, 2014 at 08:58 AM 0
Share

Thank you. There is a lot of interesting info there, however I fulfill the most of it. I was wondering from the beginning, if there is a trick to batch rigged animated character, but I can not find anything. Is it even possible?

avatar image
0

Answer by socialspiel · Apr 25, 2014 at 09:11 AM

We made the experience, that not the tris are what limits you, but the draw calls. We optimised our character meshes so that they consist of only one mesh (1 drawcall per mesh and material) and so we got the draw calls down from 100 per character to 4 and where suddenly able to display 180+ of them.

Use the "Stats" button in the "Game" window and take a look at the draw calls and try to figure out the draw call limit for your device.

I estimated them by spawning one enemy after another until i noticed a significant fps drop. when you spawn the same amount of enemies in the editor you get an approximate draw call limit.

Comment
Add comment · Show 1 · 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 wolodo · Apr 25, 2014 at 09:26 AM 0
Share

I thought about that. $$anonymous$$y characters actually are just one mesh with one material. Every one takes only 1 draw call. They are holding weapons, but these could be dynamically batched, so they are not the problem. What about the animation? Could be a humanoid rig with 22 bones the main problem?

avatar image
0

Answer by zugsoft · Apr 25, 2014 at 10:35 AM

You have 44'000 poly with 50xAI, it's normal to have some bad performance. 1/Limit the number of enemies, 50 it's too much 2/Reduce again the Poly if possible. 3/Detect the distance between you and the enemies, and show/hide the enemies

4/Reduce the AI speed loop by 10 for example 5/Limit the number of AI at the same time, if your enemies are a object in a table, you can add a property int AIEnabled=0; and check if your enemy has a AIEnabled or not.

 //Add a property to your enemy object
 int AIEnabled=0;
 
 //Declare counter as public variable
 int counter = 0;
 int slowBy=10;
 
 //In your AI loop
 counter++;
 if(counter==slowBy){
     For each enemies>0{
         if(enemy.AIEnabled==0 && enemy.live>0){
             //Calculate AI
         }else{
             enemy.AIEnabled--;
         }
     }
     counter=0;
 }
Comment
Add comment · Show 16 · 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 wolodo · Apr 25, 2014 at 11:13 AM 0
Share

I have something similar in my AI script. After each decision I set timer variable to current time and when the difference between current time and time variable is smaller than certain treshold I just skip that round. For example in finding new target:

 private void findTarget() {
                 if(Time.time - findTargetStartTime < 0.3F)
                     return;
         
         findTargetStartTime = Time.time;
                 StartCoroutine(findTower());
             }

What performance impact could have an animation? $$anonymous$$ecanim humanoid RIG with 22 bones and mocap animation (1 frame = 1 keyframe with all the bones animated)?

avatar image zugsoft · Apr 25, 2014 at 11:50 AM 0
Share

I don't think your problem is animation, the poly count is the same, physics are the same. Polygon impact GPU Physics impact CPU AI impact CPU

But you can try to delete the animation to see the improvement.

findTargetStartTime is global or a enemy proprety ? Did you try a random number(0.2f to 0.5f) ins$$anonymous$$d of 0.3F ?

avatar image wolodo · Apr 25, 2014 at 11:59 AM 0
Share

findTargetStartTime is enemy private property and threshold is still 0.3f. should it be random? I think, that I see small improvement (sometimes +10 fps improvement), when I turn off animations, but I have just my device to test it. The animation files are quite big (300 - 400 kB), because of every frame animated. No extrapolation. Could it be the reason?

avatar image zugsoft · Apr 25, 2014 at 12:13 PM 0
Share

I don't know if you use a Thread or not for each enemy AI, but if your loop is under the same Thread, and your threshold is 0.3f, your AI is launch at the same time for your 50 enemies.

I made a 2D game for iOS with 40 enemies, so the GPU is not the problem. The enemies pathFinding is under the update method, so only 1 Thread. I must launch my pathFinding with a random threshold, and with a maximum time, else I had 3 frames per seconds.

The best solution is different for each Game, you must find where is your problem. 1 / CPU or GPU ? Reduce the polygon to 50 to see the impact(if only 1-2fps it's not a GPU problem) Increase your threshold to 0.6f Use a random threshold Use Thread Reduce enemies.

avatar image wolodo · Apr 25, 2014 at 12:49 PM 0
Share

I forgot about profiler (editor profiler, not mobile) :D Alright...it says, that AI takes about 30% of frame time, animator.update and camera.render 20% each. Reducing tne enemy count is the last option. TD game would be boring, if there would be to few enemies. I could use also your advice about random threshold.

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

21 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 avatar image avatar image avatar image

Related Questions

Performance problems on Android (apk) 1 Answer

Device.Present is killing my Android game!! 3 Answers

What's wrong? Heavy game for Mobile ? 1 Answer

Bad performance on Galaxy Tab 4 1 Answer

What are the best android phones for developing games in unity3d? 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