using UnityEngine;
using UnityEditor;
public class SaveLocalTransInfo : EditorWindow
{
static float m_explodeTime = 1.0f;
static float m_resetTime = 1.0f;
[MenuItem("ExplodeMgr/OpenExplodeTimePanel #`")]
static void OpenExplodeTimePanel()
{
var win = EditorWindow.GetWindow<SaveLocalTransInfo>();
win.minSize = new Vector2(340, 110);
//EditorGUILayout.LabelField("ExplodeTime", EditorStyles.boldLabel);
}
void OnGUI()
{
m_explodeTime = EditorGUILayout.FloatField("ExplodeTime:", m_explodeTime);
m_resetTime = EditorGUILayout.FloatField("ResetTime:", m_resetTime);
}
[MenuItem("ExplodeMgr/SaveOriInfo #1")]
static void SaveOriInfo()
{
GameObject obj = Selection.activeGameObject;
foreach (var it in obj.transform.GetComponentsInChildren<Transform>())
{
DoExplode childExplode;
if (it.transform.GetComponent<DoExplode>() == null)
{
childExplode = it.gameObject.AddComponent<DoExplode>();
}
else
{
childExplode = it.gameObject.GetComponent<DoExplode>();
}
childExplode.m_oriPos = it.transform.localPosition;
childExplode.m_oriRotate = it.transform.localEulerAngles;
childExplode.m_oriScale = it.transform.localScale;
childExplode.m_resetTime = m_resetTime;
}
}
[MenuItem("ExplodeMgr/SaveToInfo #2")]
static void SaveToInfo()
{
GameObject obj = Selection.activeGameObject;
foreach (var it in obj.transform.GetComponentsInChildren<Transform>())
{
DoExplode childExplode;
if (it.transform.GetComponent<DoExplode>() == null)
{
childExplode = it.gameObject.AddComponent<DoExplode>();
}
else
{
childExplode = it.gameObject.GetComponent<DoExplode>();
}
childExplode.m_toPos = it.transform.localPosition;
childExplode.m_toRotate = it.transform.localEulerAngles;
childExplode.m_toScale = it.transform.localScale;
childExplode.m_explodeTime = m_explodeTime;
}
}
[MenuItem("ExplodeMgr/DoExplode #3")]
static void DoExplode()
{
if (Application.isPlaying)
{
NotificationCenter.Get().ObjDispatchEvent(KEventKey.m_evExplode);
}
else
{
GameObject obj = Selection.activeGameObject;
foreach (var it in obj.transform.GetComponentsInChildren<Transform>())
{
DoExplode childExplode;
if (it.transform.GetComponent<DoExplode>() == null)
{
return;
}
else
{
childExplode = it.gameObject.GetComponent<DoExplode>();
it.transform.localPosition = childExplode.m_toPos;
it.transform.localEulerAngles = childExplode.m_toRotate;
it.transform.localScale = childExplode.m_toScale;
m_resetTime = childExplode.m_resetTime;
}
}
}
}
[MenuItem("ExplodeMgr/DoReset #4")]
static void DoReset()
{
if (Application.isPlaying)
{
NotificationCenter.Get().ObjDispatchEvent(KEventKey.m_evReset);
}
else
{
GameObject obj = Selection.activeGameObject;
foreach (var it in obj.transform.GetComponentsInChildren<Transform>())
{
DoExplode childExplode;
if (it.transform.GetComponent<DoExplode>() == null)
{
return;
}
else
{
childExplode = it.gameObject.GetComponent<DoExplode>();
it.transform.localPosition= childExplode.m_oriPos;
it.transform.localEulerAngles= childExplode.m_oriRotate;
it.transform.localScale = childExplode.m_oriScale;
m_resetTime = childExplode.m_resetTime;
}
}
}
}
}
#Notification
using UnityEngine;
using System.Collections.Generic;
public class Notification
{
/// <summary>
/// 通知发送者
/// </summary>
public GameObject sender;
/// <summary>
/// 通知内容
/// 备注:在发送消息时需要装箱、解析消息时需要拆箱
/// </summary>
public object param;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="param"></param>
public Notification(object param,GameObject sender = null)
{
this.sender = sender;
this.param = param;
}
/// <summary>
/// 实现ToString方法
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format("sender={0},param={1}", this.sender, this.param);
}
}
public class NotificationCenter {
/// <summary>
/// 通知中心单例
/// </summary>
private static NotificationCenter instance = null;
public delegate void OnNotification(Notification notific);
public static NotificationCenter Get()
{
if (instance == null)
{
instance = new NotificationCenter();
return instance;
}
return instance;
}
//实现一对多的消息
private Dictionary<string, Dictionary<GameObject, OnNotification>> m_dicEvent
= new Dictionary<string, Dictionary<GameObject, OnNotification>>();
public void ObjAddEventListener(string eventKey, GameObject obj,OnNotification eventListener)
{
if (!m_dicEvent.ContainsKey(eventKey))
{
Dictionary<GameObject, OnNotification> dic = new Dictionary<GameObject, OnNotification>();
dic[obj] = eventListener;
m_dicEvent[eventKey] = dic;
}
else
{
m_dicEvent[eventKey][obj] = eventListener;
}
}
public void ObjRemoveEventListener(string eventKey,GameObject obj)
{
if (!m_dicEvent.ContainsKey(eventKey))
return;
m_dicEvent[eventKey].Remove(obj);
}
public void ObjDispatchEvent(string eventKey, object param = null,GameObject sender = null)
{
if (!m_dicEvent.ContainsKey(eventKey))
return;
List<GameObject> listRemoveKey = new List<GameObject>();
List<OnNotification> listNoti = new List<OnNotification>();
lock (m_dicEvent)
{
foreach (var it in m_dicEvent[eventKey])
{
if (it.Key != null)
{
listNoti.Add(it.Value);
}
else
{
listRemoveKey.Add(it.Key);
}
}
//删除已经Destory的GameObject
for (int i = 0; i < listRemoveKey.Count; i++)
{
m_dicEvent[eventKey].Remove(listRemoveKey[i]);
}
for ( int i = 0; i < listNoti.Count; i++)
{
listNoti[i](new Notification(param, sender));
}
}
}
/// <summary>
/// 是否存在指定事件的监听器
/// </summary>
public bool HasEventListener(string eventKey)
{
return m_dicEvent.ContainsKey(eventKey);
}
}
#KEventKey
using UnityEngine;
using System.Collections;
public class KEventKey : MonoBehaviour
{
static public string m_evExplode = "m_evExplode";
static public string m_evReset = "m_evReset";
}
#DoExplode
using UnityEngine;
using System.Collections;
public class DoExplode : MonoBehaviour
{
public float m_explodeTime = 1.0f;
public float m_resetTime = 1.0f;
public Vector3 m_oriPos;
public Vector3 m_oriRotate = Vector3.zero;
public Vector3 m_oriScale = new Vector3(1, 1, 1);
public Vector3 m_toPos;
public Vector3 m_toRotate = Vector3.zero;
public Vector3 m_toScale = new Vector3(1, 1, 1);
private WaitForEndOfFrame _waitTime = new WaitForEndOfFrame();
// Use this for initialization
void Start()
{
NotificationCenter.Get().ObjAddEventListener(KEventKey.m_evExplode, gameObject, OnEventExplode);
NotificationCenter.Get().ObjAddEventListener(KEventKey.m_evReset, gameObject, OnEventReset);
}
private void OnDestroy()
{
NotificationCenter.Get().ObjRemoveEventListener(KEventKey.m_evExplode, gameObject);
NotificationCenter.Get().ObjRemoveEventListener(KEventKey.m_evReset, gameObject);
}
void OnEventReset(Notification notific)
{
DoReset();
}
void OnEventExplode(Notification notific)
{
DoOpen();
}
public void DoOpen()
{
if (_isMoving || _isRotating || _isScaling)
{
return;
}
StartCoroutine(IEMove(m_toPos, m_explodeTime));
StartCoroutine(IERotate(m_toRotate, m_explodeTime));
StartCoroutine(IEScale(m_toScale, m_explodeTime));
}
public void DoReset()
{
if (_isMoving || _isRotating || _isScaling)
{
return;
}
StartCoroutine(IEMove(m_oriPos, m_explodeTime));
StartCoroutine(IERotate(m_oriRotate, m_explodeTime));
StartCoroutine(IEScale(m_oriScale, m_explodeTime));
}
private bool _isMoving = false;
IEnumerator IEMove(Vector3 endPos,float durationTime)
{
if (_isMoving)
{
yield return null;
}
else
{
_isMoving = true;
float speed = 0;
Vector3 startpos = transform.localPosition;
while (transform.localPosition != endPos)
{
transform.localPosition = Vector3.Lerp(startpos, endPos, speed);
yield return _waitTime;
speed += Time.deltaTime/durationTime;
}
_isMoving = false;
}
}
private bool _isRotating = false;
IEnumerator IERotate(Vector3 endRot, float durationTime)
{
if (_isRotating)
{
yield return null;
}
else
{
_isRotating = true;
float speed = 0;
Vector3 startRot = transform.localEulerAngles;
while (transform.localEulerAngles != endRot)
{
transform.localEulerAngles = Vector3.Lerp(startRot, endRot, speed);
yield return _waitTime;
speed += Time.deltaTime / durationTime;
}
_isRotating = false;
}
}
private bool _isScaling = false;
IEnumerator IEScale(Vector3 endScale, float durationTime)
{
if (_isScaling)
{
yield return null;
}
else
{
_isScaling = true;
float speed = 0;
Vector3 startScale = transform.localScale;
while (transform.localScale != endScale)
{
transform.localScale = Vector3.Lerp(startScale, endScale, speed);
yield return _waitTime;
speed += Time.deltaTime / durationTime;
}
_isScaling = false;
}
}
}