简单的爆炸

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;
        }
    }
}
上一篇:unity3d:网络模块优化:减少无用字段,降低字段精度,byte转vector3表示方向,心跳包优化,异步线程接收


下一篇:跳一跳Unity版(一)——基本功能实现