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 ronronmx · May 16, 2012 at 07:00 AM · debugmanagergamecontrollerfsm

Stop everything on first error + state machine

Let me explain, I have a FSM called "GameStates" which basically sets up a bunch of things and then switches to the correct state. I also have many scripts which rely on it, for example, the state machine sends a message to my Managers class, which in turn caches everything I need and then tells the state machine when it's done, and the state machine moves on.

All the scripts that rely on it are caching their own things on start, by accessing my Managers class and getting its components/cached scripts and objects.

But what I am currently doing in all these scripts is this, which I don't like much:

 private Transform player;
 private Camera playerCam;
 
 void Start () 
 {
     if( !GameStates.initDone )
     {
         Debug.LogWarning("Initialization failed! Disabling " + this);
         this.enabled = false;
         return;
     }
     else
     {
         // Do what I need
         player = Managers.PC.transform;
         playerCam = Managers.Cameras.PlayerCam;
         etc...
     }
 }

This works fine, but I hate having to add the check for successful initialization in every scripts that depend on it.

Is there another way I can 'stop' everything from only one main class, like my GameStates class? I'm not sure I'm doing this very efficiently, and it can also introduce a lot more user errors then if only one script took care of stopping everything that needs to be stopped.

Any suggestion is greatly appreciated as always, thanks for your time guys!

Stephane

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 whydoidoit · May 16, 2012 at 07:53 AM 0
Share

Could your state machine not call an initialization method in each object it manages and then you'd put your Start() code in there ins$$anonymous$$d?

Or perhaps this is more of a subscription model. In that case you could define an public static event in the state machine class and subscribe to it.

$$anonymous$$y state machines work rather like this second - I have a class called StatefulBehaviour which is derived from $$anonymous$$onoBehaviour and does all of the event subscription stuff - then it sends an Initialized() message. All of my classes that rely on this then derive from StatefulBehaviour rather than $$anonymous$$onoBehaviour.

avatar image asafsitner · May 16, 2012 at 10:32 AM 0
Share

Why not broadcast a message to everything from your FS$$anonymous$$?

avatar image ronronmx · May 17, 2012 at 06:52 AM 0
Share

whydoidoit, thanks for the suggestion. When you talk about a subscription model, and subscribing to a public static event, what do you mean exactly? Could you give a small example? I use events in some of my scripts, but nothing fancy yet...

asafsitner, I like your idea as well, I already do this for my $$anonymous$$anagers class so I might as well try and do it for other classes as well.

Thanks for your help guys!

1 Reply

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

Answer by whydoidoit · May 17, 2012 at 11:42 AM

So you have two choices listed here, by far the simplest is to take asafsitner's BroadcastMessage concept when your initialisation is complete. This is a slow method, but you don't really care as this happens only once. The event model is fast and works well if you need components to react to changes in your state machine on a regular basis.

Unity doesn't have a "root" scene object, so it turns out that you should probably use a loop and SendMessage something like this:

Add Linq to your usings:

 using Systen.Linq;

The when you've initialized

 foreach(var go in GameObject.FindObjectsOfType(typeof(GameObject))
      .Cast<GameObject>())
 {
     go.SendMessage("StateMachineInitialized",
           null, SendMessageOptions.DontRequireReceiver);
 }

In each object you can now optionally add a void StateMachineInitialized() method to do what you need to do on initialization, like enabling things.

If you wanted to use events then to your state machine you would add some event definitions, in this case Initialized. I'm guess you have one master statemachine, if you had multiple this would be more tricky.

 public class SomeStateMachine
 {
      public static event Action Initialized = delegate {};

      void Start()
      {
           // Some kind of initialization

           Initialized();
      }
 }

Your other objects subscribe to this event:

 public class SomeOtherBehaviour : MonoBehaviour
 {
     void Awake()
     {
           SomeStateMachine.Initialized += MethodCalledAfterInitialization;
     }

     void MethodCalledAfterInitialization()
     {
           // enable or whatever
 
           SomeStateMachine.Initialized -= MethodCalledAfterInitialization;
     }
 }

You could have events for states changing etc.

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 ronronmx · May 17, 2012 at 05:06 PM 0
Share

$$anonymous$$ike, thanks a lot for the examples above, they are very helpful and exactly what I needed to see in order to understand both options!

One quick question though, I'm using "CSharp$$anonymous$$essenger Extended" from the wiki for all my events and broadcasts, and from the looks of it and how you use it, it already does subscribing to events internally...is this correct or am I completely wrong?

Either way, I like option 2 better, so I'm gonna try it out :)

Thanks for your help!

avatar image ronronmx · May 18, 2012 at 05:03 PM 0
Share

After looking into it a little more, i found out that the "CSharp$$anonymous$$essenger Extended" event system does use a subscription model for all its events so it works out great, just like solution 2 above.

Thanks for the help guys!

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

6 People are following this question.

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

Related Questions

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

poly and vertex counting at runtime 6 Answers

Gun Manager only working once 1 Answer

Using Update() or Coroutine for this problem? 2 Answers

Is there a way to have debug code compiled out for a final build? 5 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