• unity基础1-事件执行顺序、自定义事件


    事件执行顺序

    在unity中,我们通过添加脚本来控制物体的行为,那么搞清楚脚本中事件的执行顺序就十分重要。详情参见官方文档

    在这里插入图片描述
    最常用的几个生命周期函数是:
    部分代码片段来自 B 站麦扣老师的 3DRPG 课程的 playercontroller.cs 和 mousemanager.cs
    Awake
    例如,获取组件的引用

    	void Awake()
        {
            agent = GetComponent<NavMeshAgent>();
            anim = GetComponent<Animator>();
            characterStats = GetComponent<CharacterStats>();
            stopDistance = agent.stoppingDistance;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    或者把当前脚本绑定的游戏物体,标记为切换场景时不删除

    	protected override void Awake()
        {
            base.Awake();
            DontDestroyOnLoad(this);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    OnEnable
    为某些事件绑定处理函数

    	void OnEnable()
        {
            MouseManager.Instance.OnMouseClick += MoveToTarget;
            MouseManager.Instance.OnEnemyClick += EventAttack;
            GameManager.Instance.RegisterPlayer(characterStats);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Update
    处理游戏的输入、状态的切换等

    	void Update()
        {
            isDead = characterStats.CurrentHealth == 0;
            if (isDead)
            {
                GameManager.Instance.NotifyObservers();
            }
            SwitchAnimation();
            lastAttackTime -= Time.deltaTime;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    OnDisable
    为某些事件注销处理函数

    	void OnDisable()
        {
            MouseManager.Instance.OnMouseClick -= MoveToTarget;
            MouseManager.Instance.OnEnemyClick -= EventAttack;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    OnDestroy

    	protected virtual void OnDestory()
        {
            if (instance == this)
            {
                instance = null;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    自定义事件

    有时候我们需要在生命周期事件以外,自定义事件,例如,用一个图片代替鼠标时,从图片位置发射射线判断点击的物品,定义自己的鼠标点击事件处理不同的逻辑,需要事件名 OnMouseClick 和事件处理函数需要的参数类型 Vector3

    法一:继承 UnityEvent<T> 泛型类,定义自己的事件类,优点是可以编辑器在 inspector 窗口在添加事件处理函数,就像是 UI Button 按钮的点击事件一样
    在这里插入图片描述

    	using UnityEngine.Events;
    
    	[Serializable]
    	public class EventVector3 : UnityEvent<Vector3> { }
    
    • 1
    • 2
    • 3
    • 4

    声明自定义事件

    public class MouseManager : Singleton<MouseManager>
    {
        RaycastHit hitInfo;
        public EventVector3 OnMouseClick;
        // 或者直接使用 UnityEvent
        // public UnityEvent OnGameFinish;
        ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    法二:使用 Csharp 的委托 Action 定义自己的事件,优点是使用方便

    public class MouseManager : Singleton<MouseManager>
    {
        RaycastHit hitInfo;
        // public EventVector3 OnMouseClick;
        public event Action<Vector3> OnMouseClick;
        public event Action<GameObject> OnEnemyClick;
    	...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    绑定和移除事件处理函数

    	void OnEnable()
        {
            MouseManager.Instance.OnMouseClick += MoveToTarget;
            MouseManager.Instance.OnEnemyClick += EventAttack;
            GameManager.Instance.RegisterPlayer(characterStats);
        }
        void OnDisable()
        {
            MouseManager.Instance.OnMouseClick -= MoveToTarget;
            MouseManager.Instance.OnEnemyClick -= EventAttack;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    呼叫事件

    	void MouseControl()
        {
            if (Input.GetMouseButtonDown(0) && hitInfo.collider != null)
            {
                if (hitInfo.collider.gameObject.CompareTag("Ground"))
                {
                    OnMouseClick?.Invoke(hitInfo.point);
                }
                else if (hitInfo.collider.gameObject.CompareTag("Enemy"))
                {
                    OnEnemyClick?.Invoke(hitInfo.collider.gameObject);
                }
                else if (hitInfo.collider.gameObject.CompareTag("Attackable"))
                {
                    OnEnemyClick?.Invoke(hitInfo.collider.gameObject);
                }
                else if (hitInfo.collider.gameObject.CompareTag("Protal"))
                {
                    OnMouseClick?.Invoke(hitInfo.point);
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    剩余部分的代码,就是在 update 中发射射线

    	void Update()
        {
            SetCursorTexture();
            MouseControl();
        }
    
        void SetCursorTexture()
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hitInfo))
            {
                // 切换鼠标贴图
                switch (hitInfo.collider.gameObject.tag)
                {
                    case "Ground":
                        Cursor.SetCursor(target, new Vector2(16, 16), CursorMode.Auto);
                        break;
                    case "Enemy":
                        Cursor.SetCursor(attack, new Vector2(16, 16), CursorMode.Auto);
                        break;
                    case "Protal":
                        Cursor.SetCursor(doorway, new Vector2(16, 16), CursorMode.Auto);
                        break;
                    default:
                        Cursor.SetCursor(arrow, new Vector2(16, 16), CursorMode.Auto);
                        break;
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    [附源码]java毕业设计校园爱心支愿管理系统
    zk客户端连接关闭服务端,查看znode(重补早期的学习记录)
    如何将文本转换为向量?(方法三)
    Java学习笔记(十六)
    SpringMVC工作流程(八股速记)
    torch.expand()函数用法
    鼠标不动了怎么办?3招解决问题!
    Socket网络编程,网络原理基本概念
    20000字深度讲解 Python 数据可视化神器 Plotly
    基于SpringBoot的口腔保养管理系统
  • 原文地址:https://blog.csdn.net/qq_42534809/article/details/125440251