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 FlowStateGames · Jan 14, 2013 at 03:33 PM · c#guihierarchybest practice

C# - GUI best practices: sending changed values to gui object

First, I do understand that there is no 'best'. However, I fear dropping into anti-patterns, and spaghetti code. All I'm looking for is a couple differing viewpoints with arguments to back the pattern (if necessary).

I'm making a very simple "baby's first GUI" for my current project. I'll have a score, an ammo count, and a couple other objects. It's a breakout game, and thus I'll need to send scoring information based on ball collisions, and ammo count changes based on actions taken within my paddle script.

I haven't structured my code in such a way that there is a 'scene manager' object, or any hierarchy like that.

My question is as to a successful pattern by which my GUI components can track these variables. The ideas I've had are:

  1. Create a public 'thePaddle' variable, same with the ball, and check member variables each frame.

  2. Attach the paddle and ball objects along with the GUI objects to some abstracted scene graph or scene manager.

  3. Have the paddle and ball kick off events like "scoreAdd(int pointsToAdd)" and so on.

The third option seems best to me. However, I've no idea how to hook up events in Unity, beyond utilizing the built-in ones such as OnCollisionEnter. If this is the 'best' method, could someone link me to the manual or a tutorial so that I could start learning from there? I do understand delegates and lambda notation, so that should help.

The second option really rubs me the wrong way, as I see Unity as more of a scripting environment than a traditional coding one, and want to avoid 'tall' hierarchies. The environment seems more suited to AOP than OOP in general.

The first option I see as a slippery slope leading to spaghetti code and possible errors.

Any help would be appreciated.

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

1 Reply

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

Answer by whydoidoit · Jan 14, 2013 at 03:44 PM

For me I would be going with option 1 and having the GUI update based on variables associated with the actual objects in question. If your GUI object needs access to these other items you would have two choices: a singleton pattern or actual game object references. I would normally choose the latter and associate the GUI item with the object using the inspector.

I do this for the sake of encapsulation and clarity as I would be defining the variables next to the things that use and update them and referencing from the component that reports on them.

I don't know what GUI you are thinking of using, but OnGUI would work the best that way as it does need to be updated every frame.

Presuming you are using some other GUI system that doesn't need the continual update then events to indicate a change would make sense - in that case I would still be associating the objects per my first point but would wire .NET events to the target objects in the Awake of the GUI components.

If you want to use an event pattern generally there are two ways:

SendMessage (which works very like OnCollisionEnter etc - calling a public or private method on another object or objects with up to one parameter). This can work well (especially Broadcast message and SendMessageUpwards which affect multiple objects) as there is no need for any wiring and coding time - however, it uses reflection and runs like a dog (up to 150x slower than a .NET delegate based event).

.NET events which require wiring and unwiring, but are very fast.

Score.cs

 public class Score : MonoBehaviour
 {
    public Paddle thePaddle;

    void Awake()
    {
        thePaddle.ScoreChanged += UpdateScore;
    }

    void OnDestroy()
    {
        thePaddle.ScoreChanged -= UpdateScore;
    }

    void UpdateScore()
    {
         var newScore = thePaddle.score;
         //Do something with it
    }
  }

Paddle.cs (part)

   public class Paddle : MonoBehaviour
   {
           public event Action ScoreChanged = delegate {};
           public int score;

           public void SomethingThatChangesScore() 
           {
                score += 10;
                ScoreChanged();
           }

   }
    
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 FlowStateGames · Jan 14, 2013 at 04:43 PM 0
Share

$$anonymous$$ike, I couldn't have asked for a better answer. Thanks so much. Also, thanks for unitygems... I've studied and restudied those many times.

One further question: my next task is to have multiplayer. Thus I'll be mirroring the gui events and objects for a second player. Would it make sense to create essentially a Plain Old Object which holds all scoring information for a player, and hook up the GUI object to this?

I'm starting to see a pattern where the objects that 'belong' to the player (their paddle, their ammo count, their score) have a common "Player" object which manages and handles player information (assu$$anonymous$$g I end up with profiles to save/load). Is this a common pattern, or would you prefer loose coupling wired through delegates?

avatar image whydoidoit · Jan 15, 2013 at 10:00 AM 0
Share

Yes that sounds like a good approach, though I haven't got a big issue with that object just being another $$anonymous$$onoBehaviour rather than a POCO object - it really depends on what you will do with it - certainly if you wanted to save and load that information then a POCO makes a lot of sense as they are easier to create than $$anonymous$$onoBehaviours (don't need to be associated with a GameObject and hence can be saved and loaded using BinaryFormatter etc).

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

9 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Distribute terrain in zones 3 Answers

Multiple Cars not working 1 Answer

I have some question about custom Hierarchy 0 Answers

How to get a pop-up window floating next to a gameobject? 1 Answer

Game Object enable for game mode selection on GUI 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