zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    redis.conf 配置信息:读取及修改命令
    Redis 持久化
    webpack 中,module、chunk、bundle 的区别(待补充)
    对象属性的描述:writable、enumerable、configurable
    webpack 中,importloaders 配置项的含义
    vue cli 3 中,Lint on save 与 Lint and fix on commit 区别(待补充)
    使用 vue-cli-service inspect 来查看一个 Vue CLI 3 项目的 webpack 配置信息(包括:development、production)
    Eslint 能自动格式化代码,为什么还要用 Prettier?
    prettier-eslint 与 prettier-eslint-cli 区别
    032_nginx配置文件安全下载
  • 原文地址:https://www.cnblogs.com/jiangshuai52511/p/5439110.html
Copyright © 2011-2022 走看看