Skip to content

Instantly share code, notes, and snippets.

@jaburns
Last active November 16, 2015 22:11
Show Gist options
  • Save jaburns/d9c082c6c914da6dbd3a to your computer and use it in GitHub Desktop.
Save jaburns/d9c082c6c914da6dbd3a to your computer and use it in GitHub Desktop.
Type-safe implementation of Unity's SendMessage
using UnityEngine;
public class BumperZapper : MonoBehaviour
{
Rigidbody2D _rb;
void Awake()
{
_rb = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
if (Input.GetKey(KeyCode. LeftArrow)) _rb.AddForce(-Vector2.right);
if (Input.GetKey(KeyCode.RightArrow)) _rb.AddForce( Vector2.right);
if (Input.GetKey(KeyCode. UpArrow)) _rb.AddForce( Vector2.up);
if (Input.GetKey(KeyCode. DownArrow)) _rb.AddForce(-Vector2.up);
// Send the GetZapped messages to objects under the mouse.
var zapee = gameObjectUnderMouse();
if (zapee != null) {
// Message arguments are defined by populating the message type's fields.
zapee.SendTypedMessage(new Messages.GetZapped {
intensity = Random.value
});
}
}
void OnCollisionEnter2D(Collision2D col)
{
// Message types with no fields can be invoked with a type argument, like this:
col.gameObject.SendTypedMessage<Messages.GetBumped>();
}
static GameObject gameObjectUnderMouse()
{
var hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
return hit.collider != null ? hit.collider.gameObject : null;
}
}
static public class Messages
{
// Messages are defined as types. They may be structs or classes, and they
// do not require any member variables.
public struct GetBumped { }
public struct GetZapped {
public float intensity;
}
}
using UnityEngine;
// Scripts define which messages they respond to by implementing the Message<T> interface.
public class Receiver : MonoBehaviour
, Message<Messages.GetBumped>
, Message<Messages.GetZapped>
{
void Message<Messages.GetBumped>.Receive(Messages.GetBumped _)
{
transform.localScale = (Random.value + 0.5f) * Vector3.one;
}
void Message<Messages.GetZapped>.Receive(Messages.GetZapped messageData)
{
transform.position += (Random.value - 0.5f) * Vector3.one * messageData.intensity;
}
}
using UnityEngine;
public interface Message <T>
{
void Receive(T param);
}
static public class GameObject_SendTypedMessage
{
static public void SendTypedMessage <T> (this GameObject target, T param = default(T))
{
var targs = target.GetComponents(typeof(Message<T>));
foreach (var targ in targs) {
(targ as Message<T>).Receive(param);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment