Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 joshuapeacock · Sep 18, 2018 at 07:53 PM · mobileperformanceoptimizationoptimize

How can I optimize this code?

Here is my Fixed Update code... It has very poor performance on mobile devices. There is anywhere from 100-500 objects in the scene running this code at any given time. I was hoping maybing someone could give me some insight on how this code could potentionally be optimized. Once the game reaches about 300+ of these objects on a high end mobile device frame rate drops to around 15 fps.

alt text

 void FixedUpdate()
     {
         if (GetComponent<Chicken>().isFollowing)
         {
             transform.LookAt(GetComponent<Chicken>().GetFollowingPlayer());
             GetComponent<Rigidbody>().velocity = Vector3.Slerp(GetComponent<Rigidbody>().velocity, transform.forward * GetComponent<Chicken>().followSpeed, Time.deltaTime * turnSpeed);
         }
         else
         {
             Wander();
         }
     }
 
     public void Wander()
     {
         transform.LookAt(wanderDestination);
         GetComponent<Rigidbody>().velocity = Vector3.Slerp(GetComponent<Rigidbody>().velocity, transform.forward * speed, Time.deltaTime * turnSpeed);
         distanceToDestination = wanderDestination - GetComponent<Rigidbody>().position;
         if (distanceToDestination.magnitude < 1)
         {
             SetRandomDestination();
         }
     }
 
     public void SetRandomDestination()
     {
         wanderDestination = RandomNavSphere(transform.position, wanderRadius, -1);
     }
 
     public static Vector3 RandomNavSphere(Vector3 origin, float dist, int layermask)
     {
         NavMesh.SamplePosition((Random.insideUnitSphere * dist) + origin, out navHit, dist, layermask);
         return navHit.position;
     }


screeny.png (46.0 kB)
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 TreyH · Sep 18, 2018 at 08:06 PM 0
Share

You can start by not using .GetComponent so casually. It's expensive and you're better off saving that reference the first time you encounter it.

2 Replies

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

Answer by andrew-lukasik · Sep 18, 2018 at 10:11 PM

Separate Physics updates from your ai/decision making code and run these in batches:

 using System.Collections;
 using System.Collections.Generic;
 using System.Threading.Tasks;
 
 using UnityEngine;
 
 [RequireComponent(typeof(Rigidbody))]
 public class Mob : MonoBehaviour
 {
 
     static List<Mob> _instances = new List<Mob>(100);
 
     [SerializeField] [HideInInspector] Rigidbody _rigidbody;
     Vector3 _targetVelocity;
 
     #if UNITY_EDITOR
     void OnValidate ()
     {
         if( _rigidbody==null ) { _rigidbody = GetComponent<Rigidbody>(); }
     }
     void OnDrawGizmos ()
     {
         Vector3 position = transform.position; 
         Gizmos.color = Color.blue;
         Gizmos.DrawLine( position , position + _targetVelocity );
         Gizmos.color = Color.cyan;
         Gizmos.DrawLine( position , position + _rigidbody.velocity );
     }
     #endif
 
     void OnEnable ()
     {
         //register instance:
         if( _instances.Count==_instances.Capacity )
         {
             _instances.Capacity *= 2;
         }
         _instances.Add( this );
     }
 
     void OnDisable ()
     {
         //unregister instance:
         _instances.Remove( this );
     }
 
     void FixedUpdate ()
     {
         //NO AI CODE, simple operations only
         _rigidbody.velocity = Vector3.Lerp( _rigidbody.velocity , _targetVelocity , Time.fixedDeltaTime );
     }
     
     async Task AiTick ()
     {
         //AI CODE GOES HERE
         if( Random.value>0.5f )
         {
             Vector2 vec = Random.insideUnitCircle;
             _targetVelocity = new Vector3( vec.x , 0f , vec.y );
         }
         else
         {
             _targetVelocity = Vector3.zero;
         }
         await Task.CompletedTask;
     }
 
     [RuntimeInitializeOnLoadMethod]
     static async void MobAi ()
     {
         List<Mob> batch = new List<Mob>();
         while( Application.isPlaying )
         {
             //grab new batch:
             batch.Clear();
             batch.AddRange( _instances );
 
             //process batch:
             foreach( Mob mob in batch )
             {
                 //execute ai code:
                 await mob.AiTick();
             }
 
             //await:
             await Task.Delay( 1000/4 );
         }
     }
 
 }
 

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 joshuapeacock · Sep 19, 2018 at 07:08 AM 0
Share

This has made the performance impeccable! BUT I am struggling to get this to run smoothly. It creates a very choppy movement.

This batching is very interesting! Also, a bit beyond my current skill set but has really opened my eyes to taking my program$$anonymous$$g to the next level. Thank you for this.

$$anonymous$$y fixed Timestep is .05. It seems interpolation no longer works?. Only if lower the fixed timestep will it run smooth. But increasing the timestep will bring me back to low performance. Some insight on how I might address the choppy movement of the game objects would be much appreciated! Thanks!

avatar image
6

Answer by Eno-Khaon · Sep 18, 2018 at 08:54 PM

The biggest piece of advice here:

CACHE YOUR COMPONENT CALLS!

Every time you call GetComponent(), you're making a very complex check for a component on your GameObject. If you cache the results of those into each object, that alone will save a ton of unnecessary calculation work.

As an example of how to approach this:

 Rigidbody rb;
 Chicken ckn;
 
 void Start()
 {
     rb = GetComponent<Rigidbody>();
     ckn = GetComponent<Chicken>();
 }
 
 void FixedUpdate()
 {
     if (ckn.isFollowing)
     // etc.
 }
Comment
Add comment · Show 3 · 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 Baalhug · Sep 18, 2018 at 09:58 PM 0
Share

Yes, that's the 99.9% of the problem. The other operations you do are O$$anonymous$$ including the random functions.

avatar image Zodiarc · Sep 19, 2018 at 07:15 AM 0
Share

While I agree with the caching, I don't agree with the variable na$$anonymous$$g :P

avatar image joshuapeacock · Sep 19, 2018 at 07:32 AM 0
Share

This did improve performance. It's Certainly not 99% of the problem as @Baalhug suggested. It is a step in the right direction for sure. I still get a low FPS on mobile though. @andrew-lukasik suggestion has dramatically increased performance.

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

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

Related Questions

Performance of 2D Apps on mobile: Optimizations? 0 Answers

SketchUp Sandbox vs. Unity Terrain 2 Answers

How performant is performant? 0 Answers

Improving code performance 1 Answer

Device.Present is killing my Android game!! 3 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