Unity3D 自定義事件(事件偵聽與事件觸發)


先來看下效果圖,圖中點擊 Cube(EventDispatcher),Sphere(EventListener)以及 Capsule(EventListener)會做出相應的變化,例子中的對象相互之間沒有引用,也沒有父子關系。

Demo 事件觸發者(EventDispatcher)CubeObject.cs,掛載在 Cube 對象上

using UnityEngine;
using System.Collections;

public class CubeObject : MonoBehaviour 
{
    void Update()
    {
        if (Input.GetMouseButtonDown (0)) 
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit raycastHit = new RaycastHit();
            if(Physics.Raycast(ray, out raycastHit))
            {
                if(raycastHit.collider.gameObject.name == "Cube")
                {
                    // 觸發事件
                    ObjectEventDispatcher.dispatcher.dispatchEvent(new UEvent(EventTypeName.CUBE_CLICK, "cube"), this);
                }
            }
        }
    }
}

Demo 事件偵聽者(EventListener)CapsuleObject.cs,掛載在 Capsule 對象上

using UnityEngine;
using System.Collections;

public class CapsuleObject : MonoBehaviour 
{
    private float angle;
    private float targetAngle;
    private float currentVelocity;

    void Awake()
    {
        // 添加事件偵聽
        ObjectEventDispatcher.dispatcher.addEventListener (EventTypeName.CUBE_CLICK, OnClickHandler);
    }

    /// <summary>
    /// 事件回調函數
    /// </summary>
    /// <param name="uEvent">U event.</param>
    private void OnClickHandler(UEvent uEvent)
    {
        this.targetAngle = this.targetAngle == 90f ? 0f : 90f;

        this.StopCoroutine (this.RotationOperater ());
        this.StartCoroutine (this.RotationOperater());
    }

    IEnumerator RotationOperater()
    {
        while (this.angle != this.targetAngle) 
        {
            this.angle = Mathf.SmoothDampAngle (this.angle, this.targetAngle, ref currentVelocity, 0.5f);
            this.transform.rotation = Quaternion.AngleAxis(this.angle, Vector3.forward);

            if(Mathf.Abs(this.angle - this.targetAngle) <= 1) this.angle = this.targetAngle;

            yield return null;
        }
    }
}

Demo 事件偵聽者(EventListener)SphereObject.cs,掛載在 Sphere 對象上

using UnityEngine;
using System.Collections;

public class SphereObject : MonoBehaviour 
{
    private float position;
    private float targetPosition;
    private float currentVelocity;

    void Awake()
    {
        // 添加事件偵聽
        ObjectEventDispatcher.dispatcher.addEventListener (EventTypeName.CUBE_CLICK, OnClickHandler);
    }

    /// <summary>
    /// 事件回調函數
    /// </summary>
    /// <param name="uEvent">U event.</param>
    private void OnClickHandler(UEvent uEvent)
    {
        this.targetPosition = this.targetPosition == 2f ? -2f : 2f;
        
        this.StopCoroutine (this.PositionOperater ());
        this.StartCoroutine (this.PositionOperater());
    }
    
    IEnumerator PositionOperater()
    {
        while (this.position != this.targetPosition) 
        {
            this.position = Mathf.SmoothDamp (this.position, this.targetPosition, ref currentVelocity, 0.5f);
            this.transform.localPosition = new Vector3(this.transform.localPosition.x, this.position, this.transform.localPosition.z);
            
            if(Mathf.Abs(this.position - this.targetPosition) <= 0.1f) this.position = this.targetPosition;
            
            yield return null;
        }
    }
}

Demo 輔助類 EventTypeName.cs

using UnityEngine;
using System.Collections;

public class EventTypeName
{
    public const string CUBE_CLICK = "cube_click";
}

Demo 輔助類 ObjectEventDispatcher.cs

using UnityEngine;
using System.Collections;

public class ObjectEventDispatcher
{
    public static readonly UEventDispatcher dispatcher = new UEventDispatcher();
}

事件觸發器 UEventDispatcher.cs

using System;
using System.Collections.Generic;

public class UEventDispatcher
{
    protected Dictionary<string, UEventListener> eventListenerDict;

    public UEventDispatcher()
    {
        this.eventListenerDict = new Dictionary<string, UEventListener>();
    }

    /// <summary>
    /// 偵聽事件
    /// </summary>
    /// <param name="eventType">事件類別</param>
    /// <param name="callback">回調函數</param>
    public void addEventListener(string eventType, UEventListener.EventListenerDelegate callback)
    {
        if (!this.eventListenerDict.ContainsKey(eventType))
        {
            this.eventListenerDict.Add(eventType, new UEventListener());
        }
        this.eventListenerDict[eventType].OnEvent += callback;
    }

    /// <summary>
    /// 移除事件
    /// </summary>
    /// <param name="eventType">事件類別</param>
    /// <param name="callback">回調函數</param>
    public void removeEventListener(string eventType, UEventListener.EventListenerDelegate callback)
    {
        if (this.eventListenerDict.ContainsKey(eventType))
        {
            this.eventListenerDict[eventType].OnEvent -= callback;
        }
    }

    /// <summary>
    /// 發送事件
    /// </summary>
    /// <param name="evt">Evt.</param>
    /// <param name="gameObject">Game object.</param>
    public void dispatchEvent(UEvent evt, object gameObject)
    {
        UEventListener eventListener = eventListenerDict[evt.eventType];
        if (eventListener == null) return;

        evt.target = gameObject;
        eventListener.Excute(evt);
    }

    /// <summary>
    /// 是否存在事件
    /// </summary>
    /// <returns><c>true</c>, if listener was hased, <c>false</c> otherwise.</returns>
    /// <param name="eventType">Event type.</param>
    public bool hasListener(string eventType)
    {
        return this.eventListenerDict.ContainsKey(eventType);
    }
}

事件偵聽器 UEventListener.cs

using System;

public class UEventListener
{
    public UEventListener() { }

    public delegate void EventListenerDelegate(UEvent evt);
    public event EventListenerDelegate OnEvent;

    public void Excute(UEvent evt)
    {
        if (OnEvent != null)
        {
            this.OnEvent(evt);
        }
    }
}

事件參數 UEvent.cs

using System;

public class UEvent
{
    /// <summary>
    /// 事件類別
    /// </summary>
    public string eventType;

    /// <summary>
    /// 參數
    /// </summary>
    public object eventParams;

    /// <summary>
    /// 事件拋出者
    /// </summary>
    public object target;

    public UEvent(string eventType, object eventParams = null)
    {
        this.eventType = eventType;
        this.eventParams = eventParams;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM