Unity

Events in Unity: event delegates and Unity events

What is an Event?

An Event can be defined as a function pointer. It notifies its subscriber of an incident. It means that it stores the pointer to a method which will be invoked when the “event” happens. As you can see from the definition, pointers are at the heart of the event system. So, the question is how is it type safe. After all, pointers are not considered a type safe way of calling a method.

The answer is Events in C# use delegates to point to a method. The type safety is guaranteed by the use of delegates. A delegate only allows storing a pointer to a method if the target method satisfies the method signature of the delegate. This will guarantee that the event will not call illegal methods when invoked. Events in .NET are based on the Publisher-Subscriber model.

C# event delegates (cite from the .net library)

A delegate is a type that represents references to methods with a particular parameter list and return type. When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type. You can invoke (or call) the method through the delegate instance. Delegates are used to pass methods as arguments to other methods. Event handlers are nothing more than methods that are invoked through delegates. You create a custom method, and a class such as a windows control can call your method when a certain event occurs. (source)

Unity events (cite from the Unity manual)

UnityEvents are a way of allowing user driven callback to be persisted from edit time to run time without the need for additional programming and script configuration. UnityEvents are useful for a number of things: Content driven callbacks, decoupling systems, persistent callbacks, preconfigured call events. UnityEvents can be added to any MonoBehaviour and are executed from code like a standard .net delegate. When a UnityEvent is added to a MonoBehaviour it appears in the Inspector and persistent callbacks can be added. UnityEvents have similar limitations to standard delegates. That is, they hold references to the element that is the target and this stops the target being garbage collected. If you have a UnityEngine.Object as the target and the native representation disappears the callback will not be invoked. (source)

First impression

It seems Unity events are some kind of hidden, not obvious feature added when they implemented the new UI system (in 4.6? need source on this…). At first glance it seems Unity events are easier to implement and has nice added features, you can for example see the subscribers which you can’t with delegates.

Performance

Performance wise delegate events are way faster than Unity events. Using a little program I invoked 10000000 events both using delegates and Unity events, the results are shown below. Does this matter? That will depend on the application itself I guess.
ScreenHunter_288 Apr. 28 15.55

C# event Implementation

The basic steps to creating an event is:
1. [publisher script] create a delegate.
2. [publisher script] create an event based on the delegate.
3. [publisher script] create an event publisher method.
4. [listener script] create an event listener method.
5. [listener script] add the listener method to the event.
6. [publisher script] raise the event and pray =p

1. An example delegate would be:
public delegate void ButtonPressEventHandler(object source, EventArgs e);
You can create your own event arguments which inherit from EventArgs but that is optional.

2. You then create an event based on the just created delegate:
public event ButtonPressEventHandler ButtonPressed;

3. Then you create a event publisher method. The C# convention is that the method has to be protected and virtual, and the name has to be “On” + the event name. In this case our method would become: protected virtual void OnButtonPressed() { ButtonPressed(); }

4. An event listener (or subscriber) will have the same naming as the publisher. In our case that would be: public void OnButtonPressed(object source, EventArgs e) { //do something } 

5. We then “subscribe” by adding the method itself to the event: ButtonPressed += OnButtonPressed; Now when an button press event is raised this method (OnButtonPressed) will be notified.

6. Raising an event can be done by calling the event publisher OnButtonPressed()

using UnityEngine;
using System;
 
public class Publisher : Singleton<Publisher>
{
    //-- delegate --//
    public delegate void ButtonPressEventHandler(object source, EventArgs e);
    //-- event based on delegate --//
    public event ButtonPressEventHandler ButtonPressed;
 
    void Start()
    {
        //-- raise the event --//
        Debug.Log("Broadcasting button press event...");
        OnButtonPressed();
    }
 
    //-- event publisher (broadcaster) --//
    protected virtual void OnButtonPressed()
    {
 
        ButtonPressed(this, EventArgs.Empty);
    }
}
using UnityEngine;
using System;
 
public class Subscriber : MonoBehaviour
{
    void Start()
    {
        //-- subscribe to event --//
        Publisher.Instance.ButtonPressed += OnButtonPressed;
    }
 
    //-- event listener method --//
    public void OnButtonPressed(object source, EventArgs e)
    {
        Debug.Log("Button press event registered!");
    }
}
other, Unity

Unity is working on a new input system!

Finally after so many years Unity has decided to improve the current input system!

The new input system will consist of two parts. The low-level part is integrated into the C++ core of Unity. The high-level part is implemented in managed (C#) code that will be open-source in the same way as e.g. the UI system.

Our development process for the new input system is to design and implement large parts of the high level system first. Initially this is based on top of the current input system that already exists in Unity. For now, we call this the input system prototype. Later, once the new low-level core is more mature, we’ll change the high-level part to be based on the new low-level system.

This means that the current high-level system (the prototype) lacks specific features that depend on the new low-level core, such as robust registration of connected and disconnected input devices while the game is running. However, many features of the design can already be used and tested, and this is particularly what we want early feedback on.

(full original article with prototype download links etc)

 

Pigeon shit

[ Pigeon shit ] Unity data persistence – serialization

After looking at the found options I decided to go with serialization and if feasible google play services. This because serialization basically supports everything and is easy to implement. You just have to make sure all the data that you want to save has the serialize tag like so:

[System.Serializable]
public class GameData { 
//all data goes here
//
}

And then you can save the data with a function like this:

using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public void Save(GameData data){
   BinaryFormatter bf = new BinaryFormatter();
   FileStream file = File.Create(Application.persistentDataPath + “/gamedata.gd”);
   bf.Serialize(file, data);
   file.Close();
}

Pigeon shit

[ Pigeon shit ] Unity data persistence

Hello there, been a while..
I have been working on the data persistence of the game, the choice was made to do local storage and if feasible online storage (in the cloud~). After a short research I had found the following possiblities:

Playerprefs
The most easy and standard used solution. Playerpres supports:

get/set floats
get/set ints (booleans are possible if you convert them to integers ea 0-1).
get/set strings

– Writing / reading  XML / JSON formats
I don’t think I’ll pick this one, the format is very human readable and players could mess with it to cheat.

Serialization
With this we can write and read whole classes with nested classes etc in them and is safer than XML/JSON because it’s less readable. Serialization supports:

custom non abstract classes with [Serializable] attribute.
custom structs with [Serializable] attribute. (Added in Unity 4.5)
references to objects that derive from UnityEngine.Object
primitive data types (int, float, double, bool, string, etc.)
array of a fieldtype we can serialize
List<T> of a fieldtype we can serialize

Google play games services API
this can be used to do the online-cloud storage of our game data so the players data is linked with their play store account and his/her progress is linked on multiple devices.
Have to look more into this in the future when we integrate google play.