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 Wrymnn · Nov 17, 2014 at 08:55 PM · onguioptimize

Is this the best for performance?

Hello,

I need to have health bars above enemies. There is a LOT of enemies in the map and I need the most optimized solution. I want to enable the OnGUI only when the camera is near enough to those objects.

What I did is I attached separate Script to each object, which has only OnGUI with drawing of the healthBar.

What I am doing now is enabling / disabling this component when the object is around like this:

 (This function is called only once half a second to optimize it even more)
  void updateGUI()
     {
         GUI_SpaceShip[] script = GameObject.FindObjectsOfType<GUI_SpaceShip>();
         foreach(Component ship in script)
         {
             Vector2 distance = ship.gameObject.transform.position - cameraTransform.position;
             if (distance.magnitude < 300)
                 ship.GetComponent<GUI_SpaceShip>().enabled = true;
             else
                 ship.GetComponent<GUI_SpaceShip>().enabled = false;
         }
         
     }


But ofc the thing is there could be even 500+ objects in the scene. Do you think it could be done better way?

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

2 Replies

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

Answer by Kiwasi · Nov 17, 2014 at 11:39 PM

This is very bad. Very, very bad. I'll run through some of your performance fails here.

1) From the documentation of FindObjectsOfType:

Please note that this function is very slow. It is not recommended to use this function every frame. In most cases you can use the singleton pattern instead.

Build a single manager script. Have every GUI_SpaceShip register in Awake and deregister in OnDestroy. (Or use OnEnable and OnDisable if you prefer). Then run through your loop.

2) Store the actual components you wish to access. Using GetComponent is relatively slow. Calling GetComponent to get the component you already have is madness. So change your for loop to

 foreach(GUI_SpaceShip ship in script)

3) For straight distance comparisons use sqrMagnitude, instead of magnitude. Its cheaper and achieves the identical result. Don't use square roots unless you have to.

@GrahamDunnett's approach of only registering when ready to display is another valid optimisation. Typically you don't display health bars on items with no damage, so that could be further used to optimise.

The other big optimisation would be to abandon OnGUI. OnGUI is notoriously slow and inefficient, and is seldom used on high performance published games.

Comment
Add comment · Show 2 · 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 Wrymnn · Nov 18, 2014 at 06:52 AM 0
Share

1) Ah so when the ship is spawned/created it will add itself to some array of the main script right? And when destroyed it will remove it self? - How would I go about removing itself from the array?

2) Very good point. Will surely do that.

3) Ok will try it but I think sqr$$anonymous$$agnitude is multiplied so it isn`t good measure of length.

avatar image Alverik · Jan 12, 2018 at 12:55 PM 0
Share

For those still interested in the following question: "How would I go about removing itself from the array?" You can't. You just use a List ins$$anonymous$$d, then you can use the Add() o Remove() methods.

avatar image
1

Answer by Graham-Dunnett · Nov 17, 2014 at 09:30 PM

I think what I would do is have a script which handles the health bar drawing. The spaceships can then individually call this script and tell the script that they are close enough to be drawn, or have moved too far away to be visible. All the health bar script then needs do is iterate over the list of spaceships it contains and draw the health bar for each.

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 Wrymnn · Nov 17, 2014 at 09:47 PM 0
Share

Yes but I can`t "call" GUI. The GUI is and I don`t believe I can pass there parameters as ships health or position.

Or I don`t understand :) Would I then have one GUI script, that loops through each ship and draws the bar, or I would have every ship individually checking distance to player and calling some other function. (But other functions cant draw)

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

29 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

Related Questions

Selecting shader based on video card 1 Answer

How to speed up loading and optimize my game? 1 Answer

Mesh with multiple Material IDs 0 Answers

Optimizing script to improve lag 1 Answer

Function On GUI 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