• 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
5
Question by mirrorfish · Mar 13, 2014 at 11:43 PM · getcomponentpoweruplevelingstatic variablesstatic class

Design Advice: Power Up System (static variables?)

hey there,

I have a game in progress in which the player can fly around in 3d space and shoot weapons. I have various variables for the player like: movement speed, rate of fire, damage, hit points etc. I would like to create a system of powerups to modify these variables as the player's score increases.

I have a static variable for score in a game object that manages global stats. The player variables are on various game objects as children of the main player object.

I am trying to decide whether it makes more sense to write code for the changes into each script which controls the player variable (like put different power up modifiers in the gun script for example) and then have those check a static variable in the global stats to turn them on or off, or whether I should try to track all that in the global stats object and just set the different variables to new values from that object.

I guess the heart of the matter is: will I be better off having many scripts checking a static variable or variables as to the players state of progress or should I have my object tracking score linked to all the weapons etc and modifying their variables from logic inside the score tracking script? Hope the question is clear.

I know this is more of a design question than a strict scripting question, but I feel like the decision I make here will have wide ranging consequences including how organized my scripts are and for overall performance and wanted to seek some advice.

thanks in advance! M.

Comment
Add comment · Show 3
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 IntergalacticSloth · Aug 09, 2016 at 09:42 PM 0
Share

Just watched @Xevoius ' video (linked at bottom) implementing @Fattie 's GRID approach. I'm excited. And very confused.

What can Singletons do that Grids can ALSO do. What are their unique abilities???

Second of all... I'm wondering if anyone can take a look at "Toolbox" and tell me how it compares? It also claims to be an alternative to Singletons... http://wiki.unity3d.com/index.php/Toolbox

I'll ask again:

  1. Can someone draw me an $$anonymous$$S Pain Venn diagram or table showing: (a) the things Singletons can do, (b) some things that both Singletons and Grids can do, and (c) things that only Grids can do. Why switch to Grids!?

  2. I'm sure exactly what the Toolbox is doing yet. (Like would I use it along with Grids?)

PS. I'm a dummy. So bizarre metaphors and short videos and $$anonymous$$S Drawings are $$anonymous$$OST welcome.


That great video again, for reference: https://www.youtube.com/watch?v=lWmk2QXy4wU

P.S.S. I would love to know if Grids solve any of these issues https://blogs.msdn.microsoft.com/scottdensmore/2004/05/25/why-singletons-are-evil/

avatar image Fattie IntergalacticSloth · Aug 10, 2016 at 02:56 AM 0
Share

hi Sloth, this is all

INCREDIBLY OUT OF DATE

Just go here:

http://stackoverflow.com/a/35891919/294884

Everything you say about singletons is totally irrelevant. (There are no singletons in Unity, it's an ECS system.) Honestly there is absolutely nothing to think about or do these days. Just do what it explains in the linked post above!

If you must use "Grid" (ie to avoid typing one line of code) just go here http://answers.unity3d.com/answers/1124859/view.html

avatar image Fattie IntergalacticSloth · Aug 10, 2016 at 02:58 AM 0
Share

(the "toobox" thing is utter rubbish and like 10 years out of date)

honestly it is

JUST THIS SI$$anonymous$$PLE

http://stackoverflow.com/a/35891919/294884

there is literally nothing to it these days. it's a non-issue.

Sure, use a "Grid" script if you want to save one line of code.

1 Reply

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

Answer by Fattie · Mar 14, 2014 at 07:37 AM

it is honestly just this simple:

http://stackoverflow.com/a/35891919/294884

Use a "Grid" like this: Grid.cs

 using Assets.scripts.network;
 using UnityEngine;
 
 static class Grid
 {
     public static Comms comms;
     public static State state;
     public static Launch launch;
     public static INetworkCommunicator iNetworkCommunicator;
     public static Sfx sfx;
 
     static Grid()
     {
         GameObject g = GameObject.Find("_app");
 
         comms = g.GetComponent<Comms>();
         state = g.GetComponent<State>();
         launch = g.GetComponent<Launch>();
         iNetworkCommunicator = g.GetComponent<INetworkCommunicator>();
         sfx = g.GetComponent<Sfx>();
     }
 }



Then, anywhere in the project you can say

  Grid.sfx.Explosions();



and so on. Be sure to read this http://stackoverflow.com/a/35891919/294884

Be aware of incredibly out of date discussions on this topic on the web; there are 100s of pages of total crap out there, which is now completely irrelevant.



Comment
Add comment · Show 8 · 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 mirrorfish · Apr 02, 2014 at 02:08 AM 0
Share

Just wanted to double back and say that I implemented this system and it's A$$anonymous$$AZING!!!!

In addition to being able to fire off whatever functions I wanted from whatever script I also used this to replace a bunch of GetComponent uses where I was passing variables between scripts. By using this setup I've been able to reduce my use of GetComponent by about 80%. Wonderful! I think this aspect of this was actually a way bigger time/headache/efficiency saver for me.

This has really opened a world of usefulness for me.

A few questions:

1) Is the way I'm using this to pass variables back and forth between scripts efficient? Is it Ok to for example put something in an update function that is continuously accessing a variable, for example:

 void  FixedUpdate (){
 speed = Grid.playerAllStats.playerSpeed;
 //do more physics stuff
 }

Actually I ended up finding a better way to script that without putting that in update, but I'm still wondering about how fast this is in general.

2) Do I need to set my __PlayerAllStats and __Proc$$anonymous$$anagerGrid (for example) objects that are in my preEverythingScene to DontDestroyOnLoad? I did it for one of them but then forgot to do it for my second one and it seemed to work any way. Confusing.

Anyway, thanks again!

avatar image mirrorfish · Apr 09, 2014 at 02:23 AM 0
Share

@Xevoius It gets a little more cumbersome because you have to hit play from the prescene, so you may end up swapping back and forth between scenes as you work.

For my project it hasn't been too much of a problem because I'm working mostly on scripts and prefabs and so I dont need to have that scene open to tweak. I just make changes to the assets with PreScene loaded and then launch the main scene via script. If anyone has a more slick way to handle this though it would be cool.

avatar image Fattie · Apr 09, 2014 at 05:37 AM 0
Share

Hey $$anonymous$$irrorfish!

When you are working in Unity, you always have to go to your loading scene (your scene zero) before hitting play.

It's just how it is working with Unity.

Every Unity project (other than just a test project) will have a "pre-loading" scene.

Here's a very trivial solution to automate "going back to the zero scene" (at the bottom of the page...) http://stackoverflow.com/a/35891919/294884

avatar image Tarodev Fattie · Jul 26, 2021 at 12:55 AM 1
Share

Fattie, I see how much you post and how you help so many people, so let it be known I appreciate that before I start this next section.

First and foremost, I really HATE how you're talking in such a factual way when this is purely subjective and very opinionated. I feel like somebody told you a singleton is bad practice at some point in your life so now you avoid them like the plague for no good reason.


I actually agree having a preload scene is useful (I use them myself), but the fact you don't make your _app a singleton baffles me. At the very least, devs now have to press play from the preload scene to ensure their systems are running (this alone is horrendous), when in fact you could have the _app object on all scenes implemented as a singleton and the play button would work from anywhere. When the game is built/run from preload the additional _apps would be destroyed without any conflicts or problems.


Another horrible concept you've got here is telling devs to find references by using FindObjectOfType and then manually caching the reference in each script which needs it... JUST so you don't use a static instance. At least I HOPE you're expecting them to set them as cached references and not FindObjectOfType every time... or else we've got an even deeper issue. You are taking an incredibly valuable program$$anonymous$$g concept which is used widely, throwing it in the bin and giving them a sh*t sandwich in return.


I wouldn't of attacked this post if it wasn't for the factual way you wrote the posts. You may have helped thousands of people on these forums over the years, but I truly believe you've set every dev who read this post and took it to heart in a bad direction.

avatar image loconeko73 Tarodev · Feb 12 at 12:20 AM 1
Share

Hey @Tarodev , thanks for writing this as I was about to write the same thing after seeing Fattie posts everywhere.

The pattern he describes is useful, but the dogmatic way he talks about it is totally off putting. There's a post where he just says, all caps "THERE IS NO OTHER WAY", which was almost enough to convince me that this is a terrible design (because, generally speaking, people who very strongly say there's no other way are pushing a narrative that is not strong enough to stand on its own)

One GameManager with a singleton that references other managers is fine, GetComponent in the constructor to cache the results is fine, but you can also have serialized fields and link to one object per manager, or make your "grid" (what a terrible name, by the way !) a component and use its Awake(). A persistent scene with DontDestroyOnLoad() is great, too.

Contrary to what some random zealot wants you to believe, there's more than one pattern and design solution to your Unity game issues.

Cheers

avatar image mirrorfish · Apr 09, 2014 at 11:59 AM 0
Share

Hey Fattie!

Thanks for the link, that's a great solution!

$$anonymous$$.

avatar image Xevoius · Apr 13, 2014 at 03:26 PM 0
Share

Fattie, here is what I believe you have been after.

Game Pre-loading Setup Configuration

1) Add all the persistent objects/components to a Pre-Game Loading Scene

2) Add the Grid and SceneAutoLoader scripts to the project - do not need to be attached to an object Grid Script: http://answers.unity3d.com/questions/663351/design-advice-power-up-system-static-variables.html#comment-684020 SceneAutoLoader: http://wiki.unity3d.com/index.php/SceneAutoLoader

3) $$anonymous$$ake sure this has been added to the Grid code:

 #if UNITY_EDITOR
 using UnityEditor;
 #endif
 ...
 //add this below component code
 #if UNITY_EDITOR
         Application.LoadLevel(System.IO.Path.GetFileNameWithoutExtension(EditorPrefs.GetString("SceneAutoLoader.PreviousScene")),true);
 #endif

4) $$anonymous$$ake sure and wrap the SceneAutoLoader code in this

 #if UNITY_EDITOR 
 ...
 #endif

5) Add the Pre-Game Loader persistent components to the Grid constructor code 6) Reference the Grid at least once in one of the persistent object Start() or Awake() to make sure constructor gets called 7) Add this to all persistent component scripts

 void Awake()
 {
      DontDestroyOnLoad(gameObject);
 }

8) Configure the ScreenAutoLoader File->Scene Autoload menu option to point to my Pre-Game Loading screen

9) $$anonymous$$ake sure all scenes required have been added to the build

10) Press Play

This automatically reloads the scene you are working on in the editor after the pre-game scene has been loaded.

I want to test the workflow a bit to make sure it is a working solution for me. Then I intend to put together a video on YouTube to give a step by step on how to set your bootstrap scene method up.

Let me know how it goes.

~Cheers

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

26 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

Related Questions

Damager Powerup issue - NullReferenceException: Object reference not set to an instance of an object 2 Answers

GIVING variables to another gameobject 2 Answers

Accessing other objects efficiently 1 Answer

Destroy(GetComponent(...)) not working 1 Answer

GetComponent(); in Awake cant be accessed in Update 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