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 DayyanSisson · Nov 12, 2011 at 02:25 AM · guivariableoptimizationif-statements

Same Code, Different Variables (Optimization)

I have an optimization question :

I have lines of code, repeating the same function over, and over, and over again, but each time it has a different variable. The problem for example I have some attributes I need, and I need to make sure that if it's value is at 0, it won't go negative. So I write my code like this :

 void Update () {

 if(energy <= 0){
 energy = 0;
 }
 }

This code works, so when my energy becomes 0, it doesn't go into the negative. But then I'm not just counting how much energy the player has, I'm counting health, ammo, power, mana, etc.... So then I have to write the code like this :

 void Update () {

 if(energy <= 0){
 energy = 0;
 }
 
 if(health <= 0){
 health = 0;
 }
 
 if(power <= 0){
 power = 0;
 }
 
 if(mana <= 0){
 mana = 0;
 }
 }

Suddenly, I have more lines of code then I need and it checks for each of them every frame, making the script do more work. What I could make it do is check for it only under certain circumstances, not every frame, but even then, the code is longer and probably gives performance a hit. Is there another way of writing something like this? Here's my code for my specific situation :

 void Update () {
     
     if(health <= 0){
         health = 0;
     } 
     
     if(energy <= 0){
         energy = 0;
     } 
     
     if(speed <= 0){
         speed = 0;
     } 
     
     if(mana <= 0){
         mana = 0;
     } 
     
     if(power <= 0){
         power = 0;
     } 
             
     if(agility == maxAgility){
     canAddAgility = false;
     }
     else{
     canAddAgility = true;
     }    
     
     if(toughness == maxToughness){
     canAddToughness = false;
     }
     else{
     canAddToughness = true;
     }
     
     if(stamina == maxStamina){
     canAddStamina = false;
     }
     else{
     canAddStamina = true;
     }
     
     if(supernaturalFocus == maxSupernaturalFocus){
     canAddSupernaturalFocus = false;
     }
     else{
     canAddSupernaturalFocus = true;
     }
     
     if(strength == maxStrength){
     canAddStrength = false;
     }
     else{
     canAddStrength = true;
     }
     
     if(agility == minAgility){
     canSubtractAgility = false;
     }
     else{
     canSubtractAgility = true;
     }    
     
     if(toughness == minToughness){
     canSubtractToughness = false;
     }
     else{
     canSubtractToughness = true;
     }
     
     if(stamina == minStamina){
     canSubtractStamina = false;
     }
     else{
     canSubtractStamina = true;
     }
     
     if(supernaturalFocus == minSupernaturalFocus){
     canSubtractSupernaturalFocus = false;
     }
     else{
     canSubtractSupernaturalFocus = true;
     }
     
     if(strength == minStrength){
     canSubtractStrength = false;
     }
     else{
     canSubtractStrength = true;
     }
 }

And for the GUI (same script) :

 if(GUI.Button(new Rect(350, 60, 30, 25), "+") && canAddAgility && pointsLeft > 0){
     agility ++;
     pointsLeft --;
     StatusModifier();
 }
  
 if(GUI.Button(new Rect(350, 90, 30, 25), "+") && canAddToughness && pointsLeft > 0){
     toughness ++;
     pointsLeft --;
     StatusModifier();
 }
 
 if(GUI.Button(new Rect(350, 120, 30, 25), "+") && canAddStamina && pointsLeft > 0){
     stamina ++;
     pointsLeft --;
     StatusModifier();
 }
 
 if(GUI.Button(new Rect(350, 150, 30, 25), "+") && canAddSupernaturalFocus && pointsLeft > 0){
     supernaturalFocus ++;
     pointsLeft --;
     StatusModifier();
 }
 
 if(GUI.Button(new Rect(350, 180, 30, 25), "+") && canAddStrength && pointsLeft > 0){
     strength ++;
     pointsLeft --;
     StatusModifier();
 }
 
 if(GUI.Button(new Rect(380, 60, 30, 25), "-") && canSubtractAgility){
     agility --;
     pointsLeft ++;
     StatusModifier();
 }
 
 if(GUI.Button(new Rect(380, 90, 30, 25), "-") && canSubtractToughness){
     toughness --;
     pointsLeft ++;
     StatusModifier();
 }
 
 if(GUI.Button(new Rect(380, 120, 30, 25), "-") && canSubtractStamina){
     stamina --;
     pointsLeft ++;
     StatusModifier();
 }
 
 if(GUI.Button(new Rect(380, 150, 30, 25), "-") && canSubtractSupernaturalFocus){
     supernaturalFocus --;
     pointsLeft ++;
     StatusModifier();
 }
 
 if(GUI.Button(new Rect(380, 180, 30, 25), "-") && canSubtractStrength){
     strength --;
     pointsLeft ++;
     StatusModifier();
 }

As you can see, the code is long, but it's just doing basically the same thing over and over again, making the script long and giving it a performance hit. There must be another way to write this. Thanks in Advance.

Comment
Add comment · Show 2
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 Owen-Reynolds · Nov 12, 2011 at 03:59 PM 0
Share

If this is a start screen, or pops up whenever you gain a level, the speed won't matter. Some buttons just sitting there won't stutter, even if you somehow drop down to 10FPS. Just wrap all the overly long ifs in your OnGui with if(showGainGUI==true).

avatar image DayyanSisson · Nov 12, 2011 at 05:33 PM 0
Share

This is a Character Generator, where the Character has points to spend on attributes that will affect things like speed, health, energy, etc... The GUI function allows them to modify it using buttons and visually see what they're doing.

1 Reply

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

Answer by Bunny83 · Nov 12, 2011 at 02:37 AM

The best and easiest way is to use properties, that's the real advantage of properties:

private float m_Health;

public float Health { get {return m_Health;} set { m_Health = Mathf.Max(0,value); } }

That way it get only checked when you change the value. It's also a good place to check for the player death or to play a hitsound or something like that.

Another advantage is if you have weird behaviour of your health var, you can put a Debug.Log in the setter to see when, how often and to what value it gets set.

edit

There are some disadvantages of course. The biggest one is that you can't show this variable in the inspector since it's not a variable. You could turn the private m_Health into a public var but make sure you don't set this variable from one of your scripts since it would bypass the check ...

Comment
Add comment · Show 6 · 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 DayyanSisson · Nov 12, 2011 at 02:54 AM 0
Share

I'm not exactly sure what properties are or how to replicate them in other instances. Things like maxHealth and such have to be used and assigned in the Inspector. Also, things like health have checks for a separate static variable that has the same value. Like this for example :

 public float health;
 public static float healthDisplay;

 void Update () {
 
 healthDisplay = health;
 }

That way I can have a float that I can edit in the Inspector and a separate static float that other scripts can access. So things like health and maxHealth have to be variables. As for properties, I couldn't find anything on them in the Script Reference or the $$anonymous$$anual.

avatar image Bunny83 · Nov 12, 2011 at 03:35 AM 0
Share

Properties consists just of a setter and a getter method but the property itself can be used like a variable.

e.g: if you use this assignment:

 Health = 100.0f;

behind the scenes the "set" method of this property get called. Inside the set method you have a special parameter available: "value". It hold the assigned value. In this case 100.0f;

This would would call the "get" method to get the current value, increment it and call the "set" method to assign in back:

 Health++;

What you do in the setter or getter is up to you. I just clamped it like you wanted so it doesn't get below 0.0 and then assigning it to the "true" variable. Getter and setter are one of the very basics in OOP encapsulation.

Nearly every so called "variable" of all Unity objects are properties:

 .transform
 .gameObject
 .position
 .parent

All those "variables" just wrap get and set methods.

btw. to keep a value between an upper and lower value you can use `V = $$anonymous$$athf.Clamp(V, $$anonymous$$Value, maxValue);`

avatar image DayyanSisson · Nov 12, 2011 at 07:20 AM 0
Share

That makes sense. Thanks for that. But I still have this repeating problem for the GUI code and the "canSubtract" and "canAdd". Is there a way to solve those?

avatar image aldonaletto · Nov 12, 2011 at 09:54 AM 2
Share

You could replace all those if's with this code:

    canAddAgility = agility < maxAgility;
    canAddToughness = toughness < maxToughness;
    canAddSta$$anonymous$$a = sta$$anonymous$$a < maxSta$$anonymous$$a;
    canAddSupernaturalFocus = supernaturalFocus < maxSupernaturalFocus;
    canAddStrength = strength < maxStrength;
    canSubtractAgility = agility > $$anonymous$$Agility;
    canSubtractToughness = toughness > $$anonymous$$Toughness;
    canSubtractSta$$anonymous$$a = sta$$anonymous$$a > $$anonymous$$Sta$$anonymous$$a;
    canSubtractSupernaturalFocus = supernaturalFocus > $$anonymous$$SupernaturalFocus;
    canSubtractStrength = strength > $$anonymous$$Strength;
Anything you test in if, while etc. clauses actually returns a bool value and can directly be assigned to a variable.
But if you don't need canAddAnything or canSubtractWhatever for other purposes, you can do the comparison inside the OnGUI code directly:

if(GUI.Button(new Rect(350, 60, 30, 25), "+") && agility < maxAgility && pointsLeft > 0){
    agility ++;
    pointsLeft --;
    Status$$anonymous$$odifier();
}
avatar image aldonaletto · Nov 12, 2011 at 10:21 AM 2
Share

$$anonymous$$aybe you could reduce your code even more passing the variable by reference to these specific functions:

void AddButton(Rect rect, ref int variable, int max){ if (GUI.Button(rect, "+") && variable < max && pointsLeft > 0){ variable++; pointsLeft--; Status$$anonymous$$odifier(); } }

void SubButton(Rect rect, ref int variable, int $$anonymous$$){ if (GUI.Button(rect, "-") && variable > $$anonymous$$){ variable--; pointsLeft++; Status$$anonymous$$odifier(); } } Call the functions above for each variable in OnGUI:

void OnGUI(){
    AddButton(new Rect(350, 60, 30, 25), ref agility, maxAgility);
    SubButton(new Rect(380, 60, 30, 25), ref agility, $$anonymous$$Agility);
    AddButton(new Rect(...), ref sta$$anonymous$$a, maxSta$$anonymous$$a);
    SubButton(new Rect(...), ref sta$$anonymous$$a, $$anonymous$$Sta$$anonymous$$a);
    ...
}
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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Optimizing OnGUI 1 Answer

Help! Hiding/showing GUITextures! 1 Answer

[Fixed] Unity UI Text Code Reference magically dissapears 1 Answer

How do I change GUI elements from outside of the OnGUI function? 3 Answers

UI button change variables in another script 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