Unity学习笔记(3)

目录

关于事件的一些零碎知识

 UI组件小知识

UnityAction和UnityEvent


关于事件的一些零碎知识
  • 在Unity中如按钮和Toggle等UI组件,事件中添加的方法会含有一些参数,这些参数在点击时会传递到事件所绑定的方法中作为形参。
    // 不使用匿名函数的写法:
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Events;
    using UnityEngine.UI;
    
    public class UITest : MonoBehaviour
    {
        public Toggle toggle;
        UnityAction<bool> action;
    
        private void Start()
        {
            action += work;
            toggle.onValueChanged.AddListener(action);
        }
    
        void work(bool para)
        {
            Debug.LogFormat("toggle = {0} selected = {1}", toggle.name, para);
        }
    }
    
    
    // 使用匿名函数写法:
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Events;
    using UnityEngine.UI;
    
    public class UITest : MonoBehaviour
    {
        public Toggle toggle;
    
        private void Start()
        {
            toggle.onValueChanged.AddListener((selected) =>
            {
                Debug.LogFormat("toggle = {0} selected = {1}", toggle.name, selected);
            });
        }
    }
    

  • 自定义UI及3D物体等的事件管理。
    // 当某个物体需要监听事件时,
    // 添加该脚本。
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Test : MonoBehaviour
    {
        private void Awake()
        {
            // 获取物体EventListener组件中的UnityAction,
            // 并添加需要监听的方法。
            EventListener.Get(gameObject).onClick = Work; 
        }
    
    
        // 函数需要符合UnityAction格式,这里就是UnityAction<GameObject>格式
        // GameObject类型参数。
        // 被监听的方法,可以自定义。
        void Work(GameObject go)
        {
            if(go == gameObject)
            {
                Debug.Log($"{gameObject.name}被点击");
            }
        }
    }
    
    
    // 工具代码,用于辅助上面的脚本。
    // 这个可以另外创建一个脚本,存放下面代码。
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Events;
    using UnityEngine.EventSystems;
    
    public class EventListener : EventTrigger
    {
        public UnityAction<GameObject> onClick;
    
        // 重写父类的方法,当UnityAction<GameObject>不为空时,
        // 进行调用其中的回调函数。
        public override void OnPointerClick(PointerEventData eventData)
        {
            base.OnPointerClick(eventData);
            
            if(onClick != null)
            {
                onClick(gameObject);
            }
        }
    
        // 返回go物体的EventListener组件引用,如果没有,就给go物体添加一个
        static public EventListener Get(GameObject go)
        {
            EventListener listener = go.GetComponent<EventListener>();
    
            if(listener == null)
            {
                listener = go.AddComponent<EventListener>();
            }
            return listener;
        }
    }
    
     

 

 UI组件小知识
  • 当Image的Anchors选择为全屏拉伸时,由于game界面的拉伸缩放,就会影响到Image的显示,通过添加Aspect Ratio Fitter组件,可以大程度解决问题。下面是Aspect Mode:
    • Width Controls Height:通过宽度来控制高度。
    • Height Controls Width:通过高度来控制宽度。
    • Fit In Parent:始终保持在屏幕上。它会在宽度失去比例后缩小贴图,始终保持贴图全部显示出现在屏幕上,代价就是两侧可能会漏出黑边。
    • Envelope Parent:通过裁剪方式保证两侧不漏出黑边,但是会裁剪额外的贴图信息。
  • 配置URP渲染管线下的UI摄像机。
    • 在Unity中,Windows->PackageManager中下载Universal RP资源包。
    • 在Unity中,Project面板下右键Create->Rendering->URP Asset,创建URP配置文件。
    • Edit->Project Settings->Graphics中,在Scriptable Render Pipeline Settings中选择配置的URP配置文件。
    • 在Hierarchy面板中创建Camera,将UICamera的Culling Mask选择为UI,表示这个摄像机只看UI层,Render Type选择为Overlay表示它需要叠在一个Base(基础)摄像机上。
    • 将MainCamera的Calling Mask设置为除UI层均可见,并且Render Type设置为Base,将UICamera添加到MainCamera的Stack中。
    • 再将Canvas组件的Render Mode设置为Screen Space-Camera表示使用屏幕空间的摄像机,在Render Camera中拖入刚创建的UI摄像机即可。
  • 在全局添加一个含有EventSystem组件的对象,运行后,就可以在面板中查看详细信息。便于调试。
UnityAction和UnityEvent
  • UnityAction是Unity自己实现的事件传递系统,就像C#里的委托和事件一样,它属于函数指针,可以把方法传递到另一个类中去执行。
  • UnityEvent则负责管理UnityAction,它提供了AddListener()、RemoveListener()和RemoveAllListeners()方法。
  • UnityAction只能调用自己,但是UnityEvent可以同时调用多个UnityAction。
  • using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Events;
    
    
    // 创建带两个参数(int,string)的事件类型
    public class MyEvent : UnityEvent<int, string> { }
    
    public class Test : MonoBehaviour
    {
        public UnityAction<int, string> action; // 相当于创建函数指针,理解为委托也行
    
        public MyEvent myEvent = new MyEvent();
    
        public void RunMyEvent(int a, string b)
        {
            Debug.LogFormat($"RunMyEvent{0}, {1}", a, b);
        }
    
        private void Start()
        {
            // 可以使用+=
            // 添加需要执行的方法
            action = RunMyEvent; 
    
            // myEvent事件监听action
            myEvent.AddListener(action);
        }
    
        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.A))
            {
                // 调用这个UnityAction中添加的方法
                action.Invoke(0, "按下A键");
            }
    
            if (Input.GetKeyDown(KeyCode.B))
            {
                // 会调用myEvent中监听的所有UnityAction
                myEvent.Invoke(100, "按下B键");
            }
        }
    }
    

 

 

  • 27
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值