Scene to scene script communication

Started by
5 comments, last by davejones 5 years, 9 months ago

I am trying to communicate between 2 scripts that are in 2 different scenes. I start of in the home scene and than press a button that takes me into the main scene. When I go into the main scene I want a list of GameObjects to be disabled and another set of GameObjects to be enabled. 

- start off in the home scene
- press a button that takes me to another scene (I can do this) 
- When I press button in home scene and enter main scene a list of gameobjects are disabled and another are enabled (struggling with this). 

 

 

Advertisement

I like global events for this type of thing, especially in Unity.  I often have a UI scene I load additively on top of other scenes and the buttons are all hooked up to global events.  Things in other scenes are listeners in these events and it all works well without objects in the UI scene having to know about objects in the game scene or vice versa.

The first thing I do is define structs (in C# this is nice since they're value types, they don't make garbage) to define the events, I'll have structs like EVUIStartButtonPressed or EVGamePlayerDied.  These structs not only define the presence of a type of event, but also all of the information about the event.  So EVGamePlayerDied will have at the minimum a reference to the player so any code listening to the event can tell which player died, or query the player object for information or something.

Then I have a template class that just looks something like this.  Again, this is C# and Unity, but it's a generic concept that can extend to any language or framework.


public static class Event<T> where T : struct
{
  private static event Action<T> ev;
  
  public static void Add(Action<T> action)
  {
  	ev += action;
  }
  
  public static void Remove(Action<T> action)
  {
    ev -= action;
  }
  
  public static void Invoke(T evData)
  {
    ev?.Invoke(evData);
  }
}

This is a templated static class, which means Event for each event struct type is a different type, and that any of those types can be referred to by any object in any scene.  This allows your UI code to call Event<EVUIGameStart>.Invoke(x) and your GameManger to call Event<EVUIGameStart>.Add(GameStart).  They don't have to know about each other, they just have to know about this common, generic event.  The only downside to this is that you need tiny scripts everywhere that just kind of hook things up to events.  It's not much of a problem, but it's annoying.

13 hours ago, gaxio said:

I like global events for this type of thing, especially in Unity.  I often have a UI scene I load additively on top of other scenes and the buttons are all hooked up to global events.  Things in other scenes are listeners in these events and it all works well without objects in the UI scene having to know about objects in the game scene or vice versa.

The first thing I do is define structs (in C# this is nice since they're value types, they don't make garbage) to define the events, I'll have structs like EVUIStartButtonPressed or EVGamePlayerDied.  These structs not only define the presence of a type of event, but also all of the information about the event.  So EVGamePlayerDied will have at the minimum a reference to the player so any code listening to the event can tell which player died, or query the player object for information or something.

Then I have a template class that just looks something like this.  Again, this is C# and Unity, but it's a generic concept that can extend to any language or framework.



public static class Event<T> where T : struct
{
  private static event Action<T> ev;
  
  public static void Add(Action<T> action)
  {
  	ev += action;
  }
  
  public static void Remove(Action<T> action)
  {
    ev -= action;
  }
  
  public static void Invoke(T evData)
  {
    ev?.Invoke(evData);
  }
}

This is a templated static class, which means Event for each event struct type is a different type, and that any of those types can be referred to by any object in any scene.  This allows your UI code to call Event<EVUIGameStart>.Invoke(x) and your GameManger to call Event<EVUIGameStart>.Add(GameStart).  They don't have to know about each other, they just have to know about this common, generic event.  The only downside to this is that you need tiny scripts everywhere that just kind of hook things up to events.  It's not much of a problem, but it's annoying.

Hi, thanks for your response. I will look into using your recommendations, despite not using structs often.  

In this scenarios, I think the best solution is to use something similar to the system recommended in this talk:
https://youtu.be/raQ3iHhE_Kk?t=27m33s

For me, this video was (and still is) pure gold, I highly recommend to you (and anyone reading) to watch it all.
The only downside in this event system is that in the implementation shown in the video, you can't store/pass data to the events and you are tied with the default single-argument UnityEvent, but I think it will not that difficult to write a bit of code that will do the job if needed.
The GIGANTIC pro is that you don't even have to touch any code to fire, receive and respond to an event.

6 hours ago, davejones said:

despite not using structs often

If you're unfamiliar with garbage collection and the difference between value types and reference types, this is something you should look into.  One of the most annoying things to deal with when doing gamedev with C# is the garbage collector.  Structs are value types, they make no garbage and I use them whenever possible.  If it makes sense to pass it by value, I use a struct.

https://gfycat.com/GlisteningUnselfishLeonberger

 


The media link attached gives an idea of what I am trying to achieve. The video shows panning movement around a specified area. It is not possible for the camera to move out of this specific area. There is a collision box used to ensure that the camera is bound within the area. This type of movement is what I am trying to add to the RTSCam script.
 
 

This topic is closed to new replies.

Advertisement