February 6, 2015 at 6:56 pm #6510ThomasGuest
First, great book. I literally waited months on developing parts of my game in order to do it with uGUI. Unfortunately, after it launched there wasn’t great documentation on how to utilize it. I was thrilled to see your book release a few days ago and immediately bought it. I read it in two sittings in a day. Your book made some very important light bulbs go off and now, I think, I finally get it.
FYI, I come from an enterprise C# windows forms background.
In chapter 6 you discuss the new Event system, something I am very interested in for my game. I love the publish/subscribe model found in many enterprise projects and thought I would have to build my own.
Your examples make sense and I’ve started implementing it, but maybe i’m misunderstanding what exactly the event system is for.
I have object A and object C. Object C is a container of A, so it cares a lot about what is going on with A, but I don’t want A to know anything about C. I want proper encapsulation where A just raises events for anyone who would care to listen. I want them loosely coupled so A can play well with a possible D and E should they come along.
I started implementing this but then I got to the line:
ExecuteEvents.Execute(droid, eventData, MyAlarmTriggerEvents.AlarmEventHandler);
Wait, what? I also searched up the Unity docs on ExecuteEvents.Execute and they all require a gameobject as a target.
So then I wonder, what the heck is the point of this stuff? If I must have a gameobject target for my custom event handler, if I must track what gameobjects recieve the event, I may as well just cast it to what I want and call the function I want directly and skip all this event stuff. In my case have A hold a reference to C and call functions for interesting events.
So my question to you is am I misunderstanding what the EventSystem is actually for, or is the right thing for my job but I just am using it wrong? Or should I just be using this:February 6, 2015 at 7:10 pm #6511
Thanks for your question Thomas
At it’s core, the Event system is just an Event manager, a central location where events are marshalled between objects and other events.
The GO in the example you highlight is the “Droid” object, sending the event data directly to that GO. Because the droi implements the “IAlarmHandler” interface, the Event system knows which method to call on the droid.
This means there is a complete disconnect between what calls the event and what receives it. This is important because it means we are not using reflection (Slow) or tight delegate reference (which breaks if you regularly destroy things)
There is no right or wrong answer whether it is right to use the Event System to solve certain issues. If you want to remove all SendMessage and Broadcast uses in your app/game then definitely.
For more complex scenarios, it’s a mix up to whether you want to invest the time to build the full linkage (Interface, UnityEvemt, Handler and so on) or just use a fixed reference.
The best idea is to throw a situation at me and I can walk you through whether the EventSystem and UnityEvent’s are a good fit for it.
The first job is knowing knowing how it works, the harder question is how to apply it effectively 😀
Simon (Darkside) Jackson
@SimonDarksideJFebruary 6, 2015 at 7:21 pm #6512ThomasGuest
Ok, so my situation is (I think) fairly simple.
I have a ShopItem and a ShopItemList (sorta like ListViewItem and ListView in winforms).
I have a snazzy ShopItem that I want to raise some events on, the most important is when it is selected. It already handles the click handler, updates itself to display appropriately, but the ShopItemList needs to know that it was selected BECAUSE if this is a single item select type list, then it needs to remove the selection from the previously selected item (if there was one) and now know this item was selected.
So I think there should be an event like ShopItemSelected and any other object that cares about those events can react to it. For instance, beyond the list container itself, if I have a detailed text description of said shop item it would care to know the selected one changed. Perhaps a button becomes active now that an item is selected. So I really do want a loosely coupled publish/subscribe model which I thought the EventSystem would give me but now I’m not so sure.
Thanks.February 6, 2015 at 7:49 pm #6513
Now that takes me back, I did an entire example on this in my previous book.
For this example, the best answer would be to have a static property on the ShopManager than controls the ShopItemList , to have a property called Selected that is a type of ShopItem.
Then ensure that each ShopItem has a reference back to the ShopManager when it is instantiated. Once the ShopItem receives the Click event, you set a bool in the ShopItem (selected) and also update the ShopManager SelectedItem property to the instance of the selected shop item. (I hope that makes sense)
This works so long as only one item in the shop can be selected at at a time. So in that case the event system would be an overkill.
Now, if you could have multiple selected items, you could extend the above example to have static “AddSelectedShopItem” and “RemoveSelectedShopItem” methods on the manager and have a private list in the manager for selected items.
If you really wanted to use the EventSystem, then keep it simple and just use the UnityEvent setup as shown in the “Working with events” section in ch 6.
Let me know how you get on and if need be I’ll whip you up an example
Simon (Darkside) Jackson
@SimonDarksideJFebruary 6, 2015 at 8:13 pm #6514ThomasGuest
I knew that is a way to do it, but as you know it is all tightly coupled. The shop item HAS to know about the shopmanager, the shopmanager HAS to know about shopitems. Tight coupling usually leads to breaking during refactoring, and often limits functionality later on. I’m not just interested in getting it work, i’m interested in getting it to work WELL. Also, I’m not just interested in solving this one problem, I am looking for a pattern/model to use for solving similar problems throughout my game. A generic event system seems to fit the bill.
Maybe I need to explain my situation better.
ShopItem, as the peon of the group, only knows about itself. It knows when it has been clicked. It can holler about it to anyone who is listening.
ShopList is a reusable generic scrollable control. It is a container for shopItems. It cares to listen if a shopitem is selected or unselected so it can tell other shopitems to deselect themselves.
BuyButton doesn’t care about lists or items, but it does care if something is selected (enable) or unselected (disable). It would like to listen to yells from Shop Item.
According to my implementation of Chapter 6’s example this morning it seems to me that the publishing object (ShopItem) has to maintain it’s own list of subscribers (ShopList, BuyButton) to tell them an event occurred. ExecuteEvents.Execute() requires a gameobject target. If I have to maintain a list of gameobject targets for the event, this is the least useful event system I have ever had the pleasure of programming with. Every other one I’ve used is decoupled.
I fully accept an answer “Ya, it’s not really designed for that.” Trouble is I don’t know what I don’t know, so maybe it is the right solution if I just persevere with it or had some missing piece of info.
I wrote to ask you because:
- You seem like a nice guy
- You make some good Hitchikers references
- You know more about the event system than I
🙂February 13, 2015 at 12:36 pm #6577
I’ve not forgotten you, just been pulled this way and the other. Desperately trying to put a sample together for you, but this is what is in my head.
There is no truly disconnected way (yet) with the event system to raise alerts and have them captured by components listening for them. It would cause too much of a performance hit with each component searching for events.
So the only solution right now is to have a single manager who manages events and can notify subscribers. I did something similar with the Conversation manager singleton in book one, the premise simply is:
- Have a Singleton manager registered in the scene (either adding it’self on first call or placed)
- The manager would be the target by any class wanting to “raise” an event (The Game object in the EventSystem.Execute(<manager>, etc
- Items wishing to be notified of a certain event would subscribe to the manager on Awake, being populated in to a subscriber list
- When an event occurs, the manager walks through the subscriber list and notifies everyone.
With the event system, you can build your own interface and event type so as not to interfere with other Unity events, further specialising (or generalising depending on your needs and data)
This loosely couple system wouldn’t have the same drawbacks as the tightly coupled Group -> Item linkage I described earlier and allows ANY object to subscribe for “Selected Inventory item” events
(also make sure there is an unsubscribe option as well :D)
How does that sound?
Simon (Darkside) Jackson
- The forum ‘Unity 3D UI Essentials’ is closed to new topics and replies.