Unity广播快速学习

来源:互联网 发布:百度一下淘宝男裤 编辑:程序博客网 时间:2024/06/11 04:07

通过广播进制可以使脚本在与多个物体互动时不需要一一的将其绑定在脚本中,只需要通过监听方法即可轻松实现.

1

首先导入Messenger这个C#脚本,可以在Unity社区中找到

 Messenger.cs v1.0 by Magnus Wolffelt, magnus.wolffelt@gmail.com

 Version 1.4 by Julie Iaccarino, biscuitWizard @ github.com

Inspired by and based on Rod Hyde's Messenger:

http://www.unifycommunity.com/wiki/index.php?title=CSharpMessenger

如下为Messenger的代码,将其拷入

 using System;
using System.Collections.Generic;
using System.Linq;
 
public enum MessengerMode {
DONT_REQUIRE_LISTENER,
REQUIRE_LISTENER,
}
 
static internal class MessengerInternal {
readonly public static Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();
static public readonly MessengerMode DEFAULT_MODE = MessengerMode.REQUIRE_LISTENER;
 
  static public void AddListener(string eventType, Delegate callback) {
MessengerInternal.OnListenerAdding(eventType, callback);
eventTable[eventType] = Delegate.Combine(eventTable[eventType], callback);
}
 
static public void RemoveListener(string eventType, Delegate handler) {
MessengerInternal.OnListenerRemoving(eventType, handler);
eventTable[eventType] = Delegate.Remove(eventTable[eventType], handler);
MessengerInternal.OnListenerRemoved(eventType);
}
 
static public T[] GetInvocationList<T>(string eventType) {
Delegate d;
if(eventTable.TryGetValue(eventType, out d)) {
if(d != null) {
return d.GetInvocationList().Cast<T>().ToArray();
} else {
throw MessengerInternal.CreateBroadcastSignatureException(eventType);
}
}
return null;
}
 
static public void OnListenerAdding(string eventType, Delegate listenerBeingAdded) {
if (!eventTable.ContainsKey(eventType)) {
eventTable.Add(eventType, null);
}
 
var d = eventTable[eventType];
if (d != null && d.GetType() != listenerBeingAdded.GetType()) {
throw new ListenerException(string.Format("Attempting to add listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being added has type {2}", eventType, d.GetType().Name, listenerBeingAdded.GetType().Name));
}
}
 
static public void OnListenerRemoving(string eventType, Delegate listenerBeingRemoved) {
if (eventTable.ContainsKey(eventType)) {
var d = eventTable[eventType];
 
if (d == null) {
throw new ListenerException(string.Format("Attempting to remove listener with for event type {0} but current listener is null.", eventType));
} else if (d.GetType() != listenerBeingRemoved.GetType()) {
throw new ListenerException(string.Format("Attempting to remove listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being removed has type {2}", eventType, d.GetType().Name, listenerBeingRemoved.GetType().Name));
}
} else {
throw new ListenerException(string.Format("Attempting to remove listener for type {0} but Messenger doesn't know about this event type.", eventType));
}
}
 
static public void OnListenerRemoved(string eventType) {
if (eventTable[eventType] == null) {
eventTable.Remove(eventType);
}
}
 
static public void OnBroadcasting(string eventType, MessengerMode mode) {
if (mode == MessengerMode.REQUIRE_LISTENER && !eventTable.ContainsKey(eventType)) {
throw new MessengerInternal.BroadcastException(string.Format("Broadcasting message {0} but no listener found.", eventType));
}
}
 
static public BroadcastException CreateBroadcastSignatureException(string eventType) {
return new BroadcastException(string.Format("Broadcasting message {0} but listeners have a different signature than the broadcaster.", eventType));
}
 
public class BroadcastException : Exception {
public BroadcastException(string msg)
: base(msg) {
}
}
 
public class ListenerException : Exception {
public ListenerException(string msg)
: base(msg) {
}
}
}
 
// No parameters
static public class Messenger { 
static public void AddListener(string eventType, Action handler) {
MessengerInternal.AddListener(eventType, handler);
}
 
static public void AddListener<TReturn>(string eventType, Func<TReturn> handler) {
MessengerInternal.AddListener(eventType, handler);
}
 
static public void RemoveListener(string eventType, Action handler) {
MessengerInternal.RemoveListener(eventType, handler);
}
 
static public void RemoveListener<TReturn>(string eventType, Func<TReturn> handler) {
MessengerInternal.RemoveListener(eventType, handler);
}
 
static public void Broadcast(string eventType) {
Broadcast(eventType, MessengerInternal.DEFAULT_MODE);
}
 
static public void Broadcast<TReturn>(string eventType, Action<TReturn> returnCall) {
Broadcast(eventType, returnCall, MessengerInternal.DEFAULT_MODE);
}
 
  static public void Broadcast(string eventType, MessengerMode mode) {
MessengerInternal.OnBroadcasting(eventType, mode);
var invocationList = MessengerInternal.GetInvocationList<Action>(eventType);
 
foreach(var callback in invocationList)
callback.Invoke();
}
 
static public void Broadcast<TReturn>(string eventType, Action<TReturn> returnCall, MessengerMode mode) {
MessengerInternal.OnBroadcasting(eventType, mode);
var invocationList = MessengerInternal.GetInvocationList<Func<TReturn>>(eventType);
 
foreach(var result in invocationList.Select(del => del.Invoke()).Cast<TReturn>()) {
returnCall.Invoke(result);
}
}
}
 
// One parameter
static public class Messenger<T> {
static public void AddListener(string eventType, Action<T> handler) {
MessengerInternal.AddListener(eventType, handler);
}
 
static public void AddListener<TReturn>(string eventType, Func<T, TReturn> handler) {
MessengerInternal.AddListener(eventType, handler);
}
 
static public void RemoveListener(string eventType, Action<T> handler) {
MessengerInternal.RemoveListener(eventType, handler);
}
 
static public void RemoveListener<TReturn>(string eventType, Func<T, TReturn> handler) {
MessengerInternal.RemoveListener(eventType, handler);
}
 
static public void Broadcast(string eventType, T arg1) {
Broadcast(eventType, arg1, MessengerInternal.DEFAULT_MODE);
}
 
static public void Broadcast<TReturn>(string eventType, T arg1, Action<TReturn> returnCall) {
Broadcast(eventType, arg1, returnCall, MessengerInternal.DEFAULT_MODE);
}
 
static public void Broadcast(string eventType, T arg1, MessengerMode mode) {
MessengerInternal.OnBroadcasting(eventType, mode);
var invocationList = MessengerInternal.GetInvocationList<Action<T>>(eventType);
 
foreach(var callback in invocationList)
callback.Invoke(arg1);
}
 
static public void Broadcast<TReturn>(string eventType, T arg1, Action<TReturn> returnCall, MessengerMode mode) {
MessengerInternal.OnBroadcasting(eventType, mode);
var invocationList = MessengerInternal.GetInvocationList<Func<T, TReturn>>(eventType);
 
foreach(var result in invocationList.Select(del => del.Invoke(arg1)).Cast<TReturn>()) {
returnCall.Invoke(result);
}
}
}
 
 
// Two parameters
static public class Messenger<T, U> { 
static public void AddListener(string eventType, Action<T, U> handler) {
MessengerInternal.AddListener(eventType, handler);
}
 
static public void AddListener<TReturn>(string eventType, Func<T, U, TReturn> handler) {
MessengerInternal.AddListener(eventType, handler);
}
 
static public void RemoveListener(string eventType, Action<T, U> handler) {
MessengerInternal.RemoveListener(eventType, handler);
}
 
static public void RemoveListener<TReturn>(string eventType, Func<T, U, TReturn> handler) {
MessengerInternal.RemoveListener(eventType, handler);
}
 
static public void Broadcast(string eventType, T arg1, U arg2) {
Broadcast(eventType, arg1, arg2, MessengerInternal.DEFAULT_MODE);
}
 
static public void Broadcast<TReturn>(string eventType, T arg1, U arg2, Action<TReturn> returnCall) {
Broadcast(eventType, arg1, arg2, returnCall, MessengerInternal.DEFAULT_MODE);
}
 
static public void Broadcast(string eventType, T arg1, U arg2, MessengerMode mode) {
MessengerInternal.OnBroadcasting(eventType, mode);
var invocationList = MessengerInternal.GetInvocationList<Action<T, U>>(eventType);
 
foreach(var callback in invocationList)
callback.Invoke(arg1, arg2);
}
 
static public void Broadcast<TReturn>(string eventType, T arg1, U arg2, Action<TReturn> returnCall, MessengerMode mode) {
MessengerInternal.OnBroadcasting(eventType, mode);
var invocationList = MessengerInternal.GetInvocationList<Func<T, U, TReturn>>(eventType);
 
foreach(var result in invocationList.Select(del => del.Invoke(arg1, arg2)).Cast<TReturn>()) {
returnCall.Invoke(result);
}
}
}
 
 
// Three parameters
static public class Messenger<T, U, V> { 
static public void AddListener(string eventType, Action<T, U, V> handler) {
MessengerInternal.AddListener(eventType, handler);
}
 
static public void AddListener<TReturn>(string eventType, Func<T, U, V, TReturn> handler) {
MessengerInternal.AddListener(eventType, handler);
}
 
static public void RemoveListener(string eventType, Action<T, U, V> handler) {
MessengerInternal.RemoveListener(eventType, handler);
}
 
static public void RemoveListener<TReturn>(string eventType, Func<T, U, V, TReturn> handler) {
MessengerInternal.RemoveListener(eventType, handler);
}
 
static public void Broadcast(string eventType, T arg1, U arg2, V arg3) {
Broadcast(eventType, arg1, arg2, arg3, MessengerInternal.DEFAULT_MODE);
}
 
static public void Broadcast<TReturn>(string eventType, T arg1, U arg2, V arg3, Action<TReturn> returnCall) {
Broadcast(eventType, arg1, arg2, arg3, returnCall, MessengerInternal.DEFAULT_MODE);
}
 
static public void Broadcast(string eventType, T arg1, U arg2, V arg3, MessengerMode mode) {
MessengerInternal.OnBroadcasting(eventType, mode);
var invocationList = MessengerInternal.GetInvocationList<Action<T, U, V>>(eventType);
 
foreach(var callback in invocationList)
callback.Invoke(arg1, arg2, arg3);
}
 
static public void Broadcast<TReturn>(string eventType, T arg1, U arg2, V arg3, Action<TReturn> returnCall, MessengerMode mode) {
MessengerInternal.OnBroadcasting(eventType, mode);
var invocationList = MessengerInternal.GetInvocationList<Func<T, U, V, TReturn>>(eventType);
 
foreach(var result in invocationList.Select(del => del.Invoke(arg1, arg2, arg3)).Cast<TReturn>()) {
returnCall.Invoke(result);
}
}
}

2接着创建一个名为GameEvent的脚本//定义了一些事件消息的常量,只定义常量

两边的命名需一致.

比如定义了两个事件,分别是攻击敌人的事件,以及屏幕触摸的事件

public static class GameEvent

{

public const string ENEMY_HIT = "ENEMY_HIT";

public const string SCREEN_TOUCH = "SCREEN_TOUCH";

}

然后比如我通过滑动屏幕自动使多个足球旋转,在各足球物体同时旋转则具体实现如下,其他同理

using UnityEngine;
using System.Collections;


public class football : MonoBehaviour {
    void Awake()
    {

    //添加监听器

        Messenger.AddListener(GameEvent.SCREEN_TOUCH, OnTouch);//左边第一个参数为监听的事件,右边为事件触发时调用的方法

       //所有监听了GameEvent中SCREEN_TOUCH事件的物体,被广播时都会使对应的函数触发
    }
    void OnDestroy()
    {
        //若对象被销毁时则移除监听器
        Messenger.RemoveListener(GameEvent.ENEMY_HIT, OnTouch);

    }

    public void OnTouch()//自己定义的方法,当进行相应事件的广播时则会触发该方法
    {
        this.transform.Rotate(Vector3.right, Input.GetAxis("Mouse Y"));//竖直旋转 绕X轴
        this.transform.Rotate(Vector3.up, -1 * Input.GetAxis("Mouse X"));//竖直旋转 绕X轴
    }
}

下面是广播方法的实现,

在摄像机里添加如下脚本

using UnityEngine;
using System.Collections;


public class TouchTest : MonoBehaviour {
    public GameObject ball; 
    void Update()

 {
     if (Input.touchCount ==1)
        {
            Touch t = Input.GetTouch(0);
            if (t.phase == TouchPhase.Moved)
            {
                Messenger.Broadcast(GameEvent.SCREEN_TOUCH);//广播相应的事件,此时监听此事件的所有物体都将触发相应方法
            }
        }

 }

}

运行时,我为两个足球添加了相应脚本则在运行时,无需绑定对象,即可使两个足球通过手指滑动屏幕同时进行旋转

原创粉丝点击