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);//广播相应的事件,此时监听此事件的所有物体都将触发相应方法
}
}
}
}
运行时,我为两个足球添加了相应脚本则在运行时,无需绑定对象,即可使两个足球通过手指滑动屏幕同时进行旋转
- Unity广播快速学习
- Unity 广播和发送消息
- nrf52 - 快速广播与慢速广播
- unity学习之Unity3D 脚本常用方法快速参考
- Unity学习(九)Bresenham快速画直线算法
- Unity(三):快速入门
- Unity快速入门总纲
- Android学习--广播机制
- BroadcastReceiver 广播学习笔记
- Android广播学习笔记
- MulticastSocket 广播学习
- android学习之广播
- 【学习笔记】自定义广播
- Android广播机制学习
- Android广播的学习
- Android 广播学习总结
- 广播的学习初学者
- 广播--android学习
- linux进程通信之消息队列
- Zookeeper的基本概念和基础使用
- 【英语句式】写论文中值得参考的语法、句式
- socket can error write: No buffer space available
- OpenCV图像旋转,指定填充背景颜色边界颜色
- Unity广播快速学习
- impdp 报错 ora-31640
- 《jQuery技术内幕》
- echarts3改动
- Python网络爬虫与信息提取-Day12-Re(正则表达式)库入门
- jsp错误
- C语言怎样提取一个数的十位个位百位千位
- 安装、配置和测试Asterisk过程中遇到的问题及解决方法
- 正确使用日志的10个技巧