05 SendingReceivingMessages - project-SIMPLE/simple.toolchain GitHub Wiki

Sending and receiving messages from/to GAMA/Unity

Link to the example model: LinkToUnity/Models/Code Examples/Send Receive Messages.gaml

The SIMPLE toolkit allows to send a message from GAMA to Unity and a message from Unity to GAMA.

Sending a message from GAMA to Unity

Sending a message from GAMA to Unity requires to use the action send_message of the Unity_linker agent. The message should be a map (key: name of the attribute; value: value of this attribute). The name of the attribute should be the same as the variable in the serialized class in Unity (c# script)

For example, to send a message to a all the players that contains the current cycle of the simulation, we can use:

do send_message players: unity_player as list mes: ["cycle":: cycle];

In Unity, a serialized class in Unity has to be defined to serialize (decrypt) the message:

[System.Serializable]

public class GAMAMessage
{
    public int cycle;

    public static GAMAMessage CreateFromJSON(string jsonString)
    {
        return JsonUtility.FromJson<GAMAMessage>(jsonString);
    }

}

Then the message can be received in the SimulationManager class:

public class SendReceiveMessageExample : SimulationManager
{

 GAMAMessage message = null;

//allow to serialize the message as GAMAMessage object
protected override void ManageOtherMessages(string content)
 {
     message = GAMAMessage.CreateFromJSON(content);
 }

//action activated at the end of the update phase (every frame)
 protected override void OtherUpdate()
 {
     // if a message was received, display in the console the content of the message
     if (message != null)
        {
            Debug.Log("received from GAMA: cycle " + message.cycle);
            message = null;
        }
     }
}

Sending a message from Unity to GAMA

The principle is to call from Unity an action defined in the Unity Linker.

For example, we define in GAMA, in the unity_linker species a new action called "receive_message" that just display in the console the id of the player sending the message and the content of it:

species unity_linker parent: abstract_unity_linker {
	//action that will be called by the Unity player to send a message to the GAMA simulation
	action receive_message (string id, string mes) {
		write "Player " + id + " send the message: " + mes;
	}
}

Then, in the SimulationManager of Unity, we ask the unity_linker to call this action with the corresponding arguments:

protected override void OtherUpdate()
 {

     if (IsGameState(GameState.GAME))
     {
        string mes = "A message from Unity at time: " + Time.time;
         //call the action "receive_message" from the unity_linker agent with two arguments: the id of the player and a message
         Dictionary<string, string> args = new Dictionary<string, string> {
         {"id",ConnectionManager.Instance.getUseMiddleware() ? ConnectionManager.Instance.GetConnectionId()  : ("\"" + ConnectionManager.Instance.GetConnectionId() +  "\"") },
         {"mes",  mes }};

            Debug.Log("sent to GAMA: " + mes);
         ConnectionManager.Instance.SendExecutableAsk("receive_message", args);
     }
}
⚠️ **GitHub.com Fallback** ⚠️