├── .gitattributes ├── .gitignore ├── README.md ├── lib └── UnityEngine.dll └── src ├── UnityEventAggregator.sln └── UnityEventAggregator ├── BaseClass.cs ├── EventAggregator.cs ├── Extensions.cs ├── IListener.cs ├── Properties └── AssemblyInfo.cs └── UnityEventAggregator.csproj /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/obj/ 2 | **/bin/ 3 | *.suo 4 | *.csproj.user 5 | *.vshost.exe.* 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Unity Event Aggregator 2 | ====================== 3 | 4 | Event aggregation in Unity made easy! Decouple your GameObjects for simpler and cleaner code. 5 | 6 | #### Why Should I Care? 7 | [Look at how gross this is.](https://docs.unity3d.com/410/Documentation/ScriptReference/index.Accessing_Other_Game_Objects.html) Disgusting, huh? Now what if there was an easy way to send messages to other game objects in Unity3D without coupling everything to hell or using skittles magic? 8 | 9 | #### That way is here. 10 | Just drop [the .dll](https://github.com/EricFreeman/UnityEventAggregator/releases/tag/v1.0.0.0) into your existing Unity project and get started. Messages must be a class. 11 | 12 | To start listening to events, your MonoBehaviour must also inherit from `IListener<(message)>`. This will create the handler for the message. 13 | 14 | Make sure you register and unregister with the `EventAggregator` in your MonoBehaviour's `Start` and `OnDestroy` methods. I'll probably create a base class to inherit from that will do this automatically for you...when I'm feeling less lazy. 15 | 16 | ## Download 17 | [v1.0.0.0 Download](https://github.com/EricFreeman/UnityEventAggregator/releases/tag/v1.0.0.0) 18 | 19 | ## Example Usage 20 | https://github.com/EricFreeman/1800ContactsEndlessRunner/blob/master/src/Assets/Scripts/UI/Score.cs 21 | -------------------------------------------------------------------------------- /lib/UnityEngine.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EricFreeman/UnityEventAggregator/62a473dec2b61fd46b8fe6598a683ba3da91f0f5/lib/UnityEngine.dll -------------------------------------------------------------------------------- /src/UnityEventAggregator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityEventAggregator", "UnityEventAggregator\UnityEventAggregator.csproj", "{B4CEC7B5-0CA8-4FAE-BFBD-1226710608CE}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B4CEC7B5-0CA8-4FAE-BFBD-1226710608CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B4CEC7B5-0CA8-4FAE-BFBD-1226710608CE}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B4CEC7B5-0CA8-4FAE-BFBD-1226710608CE}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B4CEC7B5-0CA8-4FAE-BFBD-1226710608CE}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/UnityEventAggregator/BaseClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using UnityEngine; 5 | 6 | namespace UnityEventAggregator 7 | { 8 | public class BaseClass : MonoBehaviour 9 | { 10 | private Type[] _typeCache; 11 | 12 | void Start() 13 | { 14 | GetListenerTypes().Each(x => EventAggregator.Register(this, x)); 15 | } 16 | 17 | void OnDestroy() 18 | { 19 | GetListenerTypes().Each(x => EventAggregator.UnRegister(this, x)); 20 | } 21 | 22 | IEnumerable GetListenerTypes() 23 | { 24 | if (_typeCache != null) return _typeCache; 25 | 26 | var types = GetType() 27 | .GetInterfaces() 28 | .Where(x => x.IsGenericType) 29 | .Where(x => x.GetGenericTypeDefinition() == typeof(IListener<>)) 30 | .Select(x => x.GetGenericArguments()) 31 | .First(); 32 | 33 | _typeCache = types; 34 | 35 | return types; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/UnityEventAggregator/EventAggregator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using UnityEngine; 6 | 7 | namespace UnityEventAggregator 8 | { 9 | public static class EventAggregator 10 | { 11 | private static readonly Dictionary> _cache = new Dictionary>(); 12 | 13 | /// 14 | /// Register the game object to listen for events of type T. 15 | /// 16 | /// The type of event being listened for. 17 | /// 18 | public static void Register(this object obj) 19 | { 20 | if (!_cache.ContainsKey(typeof(T))) _cache[typeof(T)] = new List(); 21 | _cache[typeof(T)].Add(obj); 22 | } 23 | 24 | /// 25 | /// Removes the registration for listening to events of type T. 26 | /// 27 | /// The type of event to no longer listen for. 28 | /// 29 | public static void UnRegister(this object obj) 30 | { 31 | if (!_cache.ContainsKey(typeof(T))) return; 32 | _cache[typeof(T)].Remove(obj); 33 | } 34 | 35 | /// 36 | /// Register the game object to listen for events of type T. 37 | /// 38 | /// The type of event being listened for. 39 | /// 40 | /// 41 | public static void Register(object obj, Type listener) 42 | { 43 | if (!_cache.ContainsKey(listener)) 44 | _cache[listener] = new List(); 45 | 46 | _cache[listener].Add(obj); 47 | } 48 | 49 | /// 50 | /// Removes the registration for listening to events of type T. 51 | /// 52 | /// The type of event to no longer listen for. 53 | /// 54 | /// 55 | public static void UnRegister(object obj, Type listener) 56 | { 57 | if (!_cache.ContainsKey(listener)) return; 58 | _cache[listener].Remove(obj); 59 | } 60 | 61 | /// 62 | /// Notifies all listeners of event type T. 63 | /// 64 | /// The type of event being notified. 65 | /// 66 | public static void SendMessage(T message) 67 | { 68 | if (!_cache.ContainsKey(message.GetType())) return; 69 | _cache[message.GetType()].Each(x => ((IListener)x).Handle(message)); 70 | } 71 | 72 | /// 73 | /// Creates the cache for objects that listen to each event 74 | /// 75 | /// Searches through all active GameObjects for those listening for event T and auto registers them. 76 | public static void UpdateCache() 77 | { 78 | var type = typeof(IListener); 79 | var list = new List(); 80 | 81 | // Get all types of IListener 82 | Assembly.GetExecutingAssembly() 83 | .GetTypes() 84 | .Where(x => x.GetInterfaces().Contains(type)) 85 | .Each(x => 86 | { 87 | // Add existing unity objects that listen for event 88 | GameObject.FindObjectsOfType() 89 | .Where(t => t.GetType() == x) 90 | .Each(list.Add); 91 | }); 92 | 93 | _cache[typeof(T)] = list; 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /src/UnityEventAggregator/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace UnityEventAggregator 5 | { 6 | public static class Extensions 7 | { 8 | public static void Each(this IEnumerable enumerable, Action action) 9 | { 10 | if (enumerable == null) return; 11 | foreach (var e in enumerable) 12 | action(e); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/UnityEventAggregator/IListener.cs: -------------------------------------------------------------------------------- 1 | namespace UnityEventAggregator 2 | { 3 | public interface IListener 4 | { 5 | void Handle(T message); 6 | } 7 | } -------------------------------------------------------------------------------- /src/UnityEventAggregator/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UnityEventAggregator")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Extend Health, Inc.")] 12 | [assembly: AssemblyProduct("UnityEventAggregator")] 13 | [assembly: AssemblyCopyright("Copyright © Extend Health, Inc. 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5661a2ca-83bf-4961-8bdc-2e524f43a03a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/UnityEventAggregator/UnityEventAggregator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B4CEC7B5-0CA8-4FAE-BFBD-1226710608CE} 8 | Library 9 | Properties 10 | UnityEventAggregator 11 | UnityEventAggregator 12 | v3.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | ..\..\lib\UnityEngine.dll 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | --------------------------------------------------------------------------------