一:矩形镂空功能
1、新建一个场景,创建两个按钮,一个Image
2、导入shader,创建两个材质,将两个shader拖到两个材质上。将材质拖动到Image组件的Material上。
3、创建脚本RectGuide,创建一个方法Guide(参数:Canvas(为了将世界转换屏幕坐标提供需要的Camera,target(要镂空的组件)),测试一下
- GetWorldCorners:在世界空间中得到计算的矩形的角。参数角的数组
- WorldToScreenPoint参数:camera(通过canvas传入),vector3(世界坐标)
using Sytem.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class RectGuide : MonoBehaviour { private Material material; // 材质 private Vector3 center; // 镂空区域的中心 private float width; // 镂空区域的宽 private float height; // 镂空区域的高 private RectTransform target;// 要显示的目标,通过目标计算镂空区域的中心,宽高 public Vector3[] targetCorners = new Vector3[4];//存储要镂空组件的四个角的数组 // 引导 public void Guide(Canvas canvas, RectTransform target) { this.target = target; // 将传进来的目标组件赋值给target // 获取中心点 // GetWorldCorners:在世界空间中得到计算的矩形的角。参数角的数组 target.GetWorldCorners(targetCorners); // 讲四个角的世界坐标转为屏幕坐标 for (int i = 0; i < targetCorners.Length; i++) { // WorldToScreenPoint参数:camera(通过canvas传入),vector3(世界坐标) targetCorners[i]=RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, targetCorners[i]); } } private void Update() { Guide(GameObject.Find("Canvas").GetComponent<Canvas>(),GameObject.Find("Button").GetComponent<RectTransform>()); } }
问题:shader的坐标的原点是中心,而转换的屏幕坐标的原点是左下角,所以需要转化
4、RectTransformUtility.ScreenPointToLocalPointInRectangle:屏幕坐标转换为局部坐标
参数:
- RectTransform rect ------转换为谁的局部坐标
- Vector2 screenPoint ------要转换的屏幕坐标
- Camera cam, ------相机
- out Vector2 localPoint ---- 输出的局部坐标
// 讲四个角的世界坐标转为屏幕坐标 for (int i = 0; i < targetCorners.Length; i++) { // WorldToScreenPoint参数:camera(通过canvas传入),vector3(世界坐标) targetCorners[i]=RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, targetCorners[i]); // 屏幕坐标转换为局部坐标 //out的是vector2类型,事先声明 Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), targetCorners[i], canvas.worldCamera, out localPoint); targetCorners[i] = localPoint; }
5、将上述代码封装成一个方法,完整的为:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class RectGuide : MonoBehaviour { private Material material; // 材质 private Vector3 center; // 镂空区域的中心 private float width; // 镂空区域的宽 private float height; // 镂空区域的高 private RectTransform target;// 要显示的目标,通过目标计算镂空区域的中心,宽高 public Vector3[] targetCorners = new Vector3[4];//存储要镂空组件的四个角的数组 // 引导 public void Guide(Canvas canvas, RectTransform target) { this.target = target; // 将传进来的目标组件赋值给target // 获取中心点 // GetWorldCorners:在世界空间中得到计算的矩形的角。参数角的数组 target.GetWorldCorners(targetCorners); // 讲四个角的世界坐标转为局部坐标坐标 for (int i = 0; i < targetCorners.Length; i++) { targetCorners[i] = WorldToScreenPoint(canvas, targetCorners[i]); } } //private void Update() //{ // Guide(GameObject.Find("Canvas").GetComponent<Canvas>(),GameObject.Find("Button").GetComponent<RectTransform>()); //} public Vector2 WorldToScreenPoint(Canvas canvas,Vector3 world) { //把世界坐标转化为屏幕坐标 Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, world); // 屏幕坐标转换为局部坐标 //out的是vector2类型,事先声明 Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), screenPoint, canvas.worldCamera, out localPoint); return localPoint; } }
6、由获取到的镂空矩形四个角的局部坐标,计算镂空区域的中心点,赋值给material材质,在赋值之前,要对声明的材质变量,赋值
给材质赋值的时候要用它实际的名字_Center,而不是显示的名字Center
private void Start() { // 获取材质 material = transform.GetComponent<Image>().material; //如果没有获取到材质,就抛出异常 if(material == null) { throw new System.Exception("为获取到材质"); } }
//计算中心点 center.x = targetCorners[0].x + (targetCorners[3].x - targetCorners[0].x) / 2; center.y = targetCorners[0].y + (targetCorners[1].y - targetCorners[0].y) / 2; //设置材质的中心点 material.SetVector("_Center", center);
完整代码:改动组件的值,镂空区域的中心点能够跟随移动
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class RectGuide : MonoBehaviour { private Material material; // 材质 private Vector3 center; // 镂空区域的中心 private float width; // 镂空区域的宽 private float height; // 镂空区域的高 private RectTransform target;// 要显示的目标,通过目标计算镂空区域的中心,宽高 public Vector3[] targetCorners = new Vector3[4];//存储要镂空组件的四个角的数组 private void Start() { // 获取材质 material = transform.GetComponent<Image>().material; //如果没有获取到材质,就抛出异常 if(material == null) { throw new System.Exception("为获取到材质"); } } // 引导 public void Guide(Canvas canvas, RectTransform target) { this.target = target; // 将传进来的目标组件赋值给target // 获取中心点 // GetWorldCorners:在世界空间中得到计算的矩形的角。参数角的数组 target.GetWorldCorners(targetCorners); // 讲四个角的世界坐标转为局部坐标坐标 for (int i = 0; i < targetCorners.Length; i++) { targetCorners[i] = WorldToScreenPoint(canvas, targetCorners[i]); } //计算中心点 center.x = targetCorners[0].x + (targetCorners[3].x - targetCorners[0].x) / 2; center.y = targetCorners[0].y + (targetCorners[1].y - targetCorners[0].y) / 2; //设置材质的中心点 material.SetVector("_Center", center); } public Vector2 WorldToScreenPoint(Canvas canvas,Vector3 world) { //把世界坐标转化为屏幕坐标 Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, world); // 屏幕坐标转换为局部坐标 //out的是vector2类型,事先声明 Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), screenPoint, canvas.worldCamera, out localPoint); return localPoint; } private void Update() { Guide(GameObject.Find("Canvas").GetComponent<Canvas>(), GameObject.Find("Button").GetComponent<RectTransform>()); } }
7、计算镂空区域的宽和高
// 计算宽高 width = targetCorners[3].x - targetCorners[0].x; height = targetCorners[1].y - targetCorners[0].y; //设置材质的宽高 material.SetFloat("_SliderX", width); material.SetFloat("_SliderY", height);
这个后运行,宽高会比实际的大,所以将获得的宽高/2
// 计算宽高 width = (targetCorners[3].x - targetCorners[0].x)/2; height = (targetCorners[1].y - targetCorners[0].y)/2; //设置材质的宽高 material.SetFloat("_SliderX", width); material.SetFloat("_SliderY", height);
到此完成的效果就是,镂空区域能够能随button组件移动,宽高、中心都会跟随button组件,但是还不能点击,并且也不能有动画
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class RectGuide : MonoBehaviour { private Material material; // 材质 private Vector3 center; // 镂空区域的中心 private float width; // 镂空区域的宽 private float height; // 镂空区域的高 private RectTransform target;// 要显示的目标,通过目标计算镂空区域的中心,宽高 private Vector3[] targetCorners = new Vector3[4];//存储要镂空组件的四个角的数组 private void Start() { // 获取材质 material = transform.GetComponent<Image>().material; //如果没有获取到材质,就抛出异常 if (material == null) { throw new System.Exception("为获取到材质"); } } // 引导 public void Guide(Canvas canvas, RectTransform target) { this.target = target; // 将传进来的目标组件赋值给target // 获取中心点 // GetWorldCorners:在世界空间中得到计算的矩形的角。参数角的数组 target.GetWorldCorners(targetCorners); // 讲四个角的世界坐标转为局部坐标坐标 for (int i = 0; i < targetCorners.Length; i++) { targetCorners[i] = WorldToScreenPoint(canvas, targetCorners[i]); } //计算中心点 center.x = targetCorners[0].x + (targetCorners[3].x - targetCorners[0].x) / 2; center.y = targetCorners[0].y + (targetCorners[1].y - targetCorners[0].y) / 2; //设置材质的中心点 material.SetVector("_Center", center); // 计算宽高 width = (targetCorners[3].x - targetCorners[0].x)/2; height = (targetCorners[1].y - targetCorners[0].y)/2; //设置材质的宽高 material.SetFloat("_SliderX", width); material.SetFloat("_SliderY", height); } public Vector2 WorldToScreenPoint(Canvas canvas, Vector3 world) { //把世界坐标转化为屏幕坐标 Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, world); // 屏幕坐标转换为局部坐标 //out的是vector2类型,事先声明 Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), screenPoint, canvas.worldCamera, out localPoint); return localPoint; } private void Update() { Guide(GameObject.Find("Canvas").GetComponent<Canvas>(), GameObject.Find("Button").GetComponent<RectTransform>()); } }
二、圆形镂空
圆形和矩形大部分代码都是一样的,就是矩形要计算宽高,而圆形要计算半径,所以可以创建一个基类GuideBase。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class GuideBase : MonoBehaviour { // 将私有的变量,变成protect,这样才可以继承 protected Material material; // 材质 protected Vector3 center; // 镂空区域的中心 protected RectTransform target;// 要显示的目标,通过目标计算镂空区域的中心,宽高 protected Vector3[] targetCorners = new Vector3[4];//存储要镂空组件的四个角的数组 protected virtual void Start() { // 获取材质 material = transform.GetComponent<Image>().material; //如果没有获取到材质,就抛出异常 if (material == null) { throw new System.Exception("为获取到材质"); } } // 引导 public virtual void Guide(Canvas canvas, RectTransform target) { this.target = target; // 将传进来的目标组件赋值给target // 获取中心点 // GetWorldCorners:在世界空间中得到计算的矩形的角。参数角的数组 target.GetWorldCorners(targetCorners); // 讲四个角的世界坐标转为局部坐标坐标 for (int i = 0; i < targetCorners.Length; i++) { targetCorners[i] = WorldToScreenPoint(canvas, targetCorners[i]); } //计算中心点 center.x = targetCorners[0].x + (targetCorners[3].x - targetCorners[0].x) / 2; center.y = targetCorners[0].y + (targetCorners[1].y - targetCorners[0].y) / 2; //设置材质的中心点 material.SetVector("_Center", center); } // 功能性的方法,不需要重写,所以不需要创建成虚方法 public Vector2 WorldToScreenPoint(Canvas canvas, Vector3 world) { //把世界坐标转化为屏幕坐标 Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, world); // 屏幕坐标转换为局部坐标 //out的是vector2类型,事先声明 Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), screenPoint, canvas.worldCamera, out localPoint); return localPoint; } }
继承GuideBase后的RectGuide脚本
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class RectGuide : GuideBase { private float width; // 镂空区域的宽 private float height; // 镂空区域的高 // 引导 public override void Guide(Canvas canvas, RectTransform target) { //调用下base,中的方法 base.Guide(canvas,target); // 中心点的计算在base.Guide(canvas,target)有了, // 计算宽高 width = (targetCorners[3].x - targetCorners[0].x)/2; height = (targetCorners[1].y - targetCorners[0].y)/2; //设置材质的宽高 material.SetFloat("_SliderX", width); material.SetFloat("_SliderY", height); } private void Update() { Guide(GameObject.Find("Canvas").GetComponent<Canvas>(), GameObject.Find("Button").GetComponent<RectTransform>()); } }
继承GuideBase后的CircleGuide脚本
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CircleGuide : GuideBase { private float r; // 镂空区域圆形的半径 public override void Guide(Canvas canvas, RectTransform target) { base.Guide(canvas, target); float width = (targetCorners[3].x - targetCorners[0].x) / 2; float height = (targetCorners[1].y - targetCorners[0].y) / 2; //计算半径,宽/2的平方 + 高/2的平方,之后开方 r = Mathf.Sqrt(width * width + height * height); // 赋值给材质 material.SetFloat("_Slider", r); } // Update is called once per frame void Update() { Guide(GameObject.Find("Canvas").GetComponent<Canvas>(), GameObject.Find("Button").GetComponent<RectTransform>()); } }
将image的材质换成CircleMateri,将CircleGuide脚本挂载到Image上,运行。
三、新手引导的方法封装
1、在GuideBase中加上[RequireComponent(typeof(Image))],保证有image组件,而且移除不了。
材质的初始化,不在start中了。在Guide方法中(这点也没搞懂)
2、创建GuideController脚本
- 创建枚举,里面可以选择引导的类型(Rect或者Circle)
- 需要保证有CircleGuide、RectGuide组件(自己创建的矩形镂空和圆形镂空,在这里里面可以将update测试代码注释了)
- 创建变量包括(矩形引导脚本组件、圆形引导组件、矩形材质、圆形材质(根据情况,自己选择需要的材质,就不用自己手动拖到Image组件的Material上了),Image组件)
- 初始化,获得(引导页面)的圆形、矩形组件、image组件
- 创建方法Guide(参数:canvas\镂空组件\引导类型),在这里用switch
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; // 枚举,引导的类型 public enum GuideType { Rect, Circle } //组件:需要的组件将会自动被添加到game object(游戏物体)。上 [RequireComponent(typeof(CircleGuide))] [RequireComponent(typeof(RectGuide))] public class GuideController : MonoBehaviour { // private CircleGuide circleGuide; private RectGuide rectGuide; //材质不一样,所以创建两个材质 [SerializeField] private Material rectMat; [SerializeField] private Material circleMat; //需要image, private Image mask; // 在 private void Awake() { mask = transform.GetComponent<Image>(); if (rectMat==null || circleMat==null) { throw new System.Exception("材质未赋值"); } circleGuide = transform.GetComponent<CircleGuide>(); rectGuide = transform.GetComponent<RectGuide>(); } public void Guide(Canvas canvas,RectTransform target,GuideType guideType) { // TODO switch (guideType) { case GuideType.Rect: mask.material = rectMat; rectGuide.Guide(canvas, target); break; case GuideType.Circle: mask.material = circleMat; circleGuide.Guide(canvas, target); break; } } }
3、创建GuidePanel脚本
获取canvas、GuideController guideController、调用guideController中的Guide方法,传入参数,2秒后切换button_cir组件镂空
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GuidePanel : MonoBehaviour { GuideController guideController; Canvas canvas; private void Awake() { canvas = GetComponentInParent<Canvas>(); } // Start is called before the first frame update void Start() { guideController = GetComponent<GuideController>(); guideController.Guide(canvas, GameObject.Find("Button").GetComponent<RectTransform>(),GuideType.Rect); Invoke("test", 2); } void test() { guideController.Guide(canvas, GameObject.Find("Button_cir").GetComponent<RectTransform>(), GuideType.Circle); } // Update is called once per frame void Update() { } }
4、创建页面,将GuideController脚本、GuidePanel脚本挂上,记得更改image组件的大小、颜色、透明度。
四、事件渗透
问题:现在虽然镂空,但是按钮不能点击
1、给需要能点击的UI控件上绑定,实现一个接口ICanvasRaycastFilter
在方法IsRaycastLocationValid中判断当前点击的位置是否符合响应事件的条件,return true事件不能渗透,false能渗透
应用场景:
1.引导挖洞
2.ui事件触发,并且不影响下面的其他控件的事件响应
2、RectTransformUtility.RectangleContainsScreenPoint(target, sp);矩形区域包不包含鼠标点击的点
3、在GuideController脚本中改
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; // 枚举,引导的类型 public enum GuideType { Rect, Circle } //组件:需要的组件将会自动被添加到game object(游戏物体)。上 [RequireComponent(typeof(CircleGuide))] [RequireComponent(typeof(RectGuide))] public class GuideController : MonoBehaviour,ICanvasRaycastFilter { // private CircleGuide circleGuide; private RectGuide rectGuide; //材质不一样,所以创建两个材质 [SerializeField] private Material rectMat; [SerializeField] private Material circleMat; //需要image, private Image mask; private RectTransform target; // 在 private void Awake() { mask = transform.GetComponent<Image>(); if (rectMat==null || circleMat==null) { throw new System.Exception("材质未赋值"); } circleGuide = transform.GetComponent<CircleGuide>(); rectGuide = transform.GetComponent<RectGuide>(); } public void Guide(Canvas canvas,RectTransform target,GuideType guideType) { //引导的时候,将传入的target赋值 this.target = target; // TODO switch (guideType) { case GuideType.Rect: mask.material = rectMat; rectGuide.Guide(canvas, target); break; case GuideType.Circle: mask.material = circleMat; circleGuide.Guide(canvas, target); break; } } /// <summary> /// /// </summary> /// <param name="sp">鼠标点的点(屏幕坐标),看看在不在镂空区域,在就把事件渗透,不在拦截</param> /// <param name="eventCamera"></param> /// <returns></returns> public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera) { if (target==null) { return true; }//点击不了 // 看看鼠标点击在不在镂空区域 return !RectTransformUtility.RectangleContainsScreenPoint(target, sp); } }
五、完善优化
1、加动画,需要在GuideBase中写个Guide重载函数,矩形更改宽高,圆形更改半径,都不用在基类中写
//写个重载函数 public virtual void Guide(Canvas canvas, RectTransform target,float scale,float time) { }
2、找到子类,重写,在里面不用调用基类的方法,以圆形为例
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CircleGuide : GuideBase { private float r; // 镂空区域圆形的半径 private float scaleR; //变化之前的半径大小 private float timer; //计时器 private float time; // 时间 private bool isScaling; // 是否正在变化 //重写引导,没有动画 public override void Guide(Canvas canvas, RectTransform target) { base.Guide(canvas, target); float width = (targetCorners[3].x - targetCorners[0].x) / 2; float height = (targetCorners[1].y - targetCorners[0].y) / 2; //计算半径,宽/2的平方 + 高/2的平方,之后开方 r = Mathf.Sqrt(width * width + height * height); // 赋值给材质 material.SetFloat("_Slider", r); } //重写引导,有动画 public override void Guide(Canvas canvas, RectTransform target, float scale, float time) { //base.Guide(canvas, target, scale, time);不用调用因为是空的 this.Guide(canvas,target); scaleR = r * scale; this.material.SetFloat("_Slider", scaleR); this.time = time; isScaling = true; timer = 0; } private void Update() { if (isScaling) { // 每秒变化1/time,时间越短变化的就得越快 //deltaTime时间增量,保证不同帧率移动的是一样的 timer += Time.deltaTime * 1 / time; this.material.SetFloat("_Slider", Mathf.Lerp(scaleR, r, timer)); if(timer >= 1) { timer = 0; isScaling = false; } } } // Update is called once per frame //void Update() //{ // Guide(GameObject.Find("Canvas").GetComponent<Canvas>(), GameObject.Find("Button_cir").GetComponent<RectTransform>()); //} }
3、GuideController脚本中,创建重载函数
public void Guide(Canvas canvas, RectTransform target, GuideType guideType, float scale, float time) { //引导的时候,将传入的target赋值 this.target = target; // TODO switch (guideType) { case GuideType.Rect: mask.material = rectMat; rectGuide.Guide(canvas, target, scale, time); break; case GuideType.Circle: mask.material = circleMat; circleGuide.Guide(canvas, target, scale, time); break; } }
4、在GuidePanel,test中调用
void test() { //guideController.Guide(canvas, GameObject.Find("Button_cir").GetComponent<RectTransform>(), GuideType.Circle); guideController.Guide(canvas, GameObject.Find("Button_cir").GetComponent<RectTransform>(), GuideType.Circle,2,0.5f); }
5、矩形类似,可以用继承,但是我没有用,晕,直接按照circle格式写的,类似,到此RectGuide全部代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class RectGuide : GuideBase { private float width; // 镂空区域的宽 private float height; // 镂空区域的高 private float scaleW; //变化之前的宽 private float scaleH; //变化之前的高 private float timer; //计时器 private float time; // 时间 private bool isScaling; // 是否正在变化 // 引导 public override void Guide(Canvas canvas, RectTransform target) { //调用下base,中的方法 base.Guide(canvas,target); // 中心点的计算在base.Guide(canvas,target)有了, // 计算宽高 width = (targetCorners[3].x - targetCorners[0].x)/2; height = (targetCorners[1].y - targetCorners[0].y)/2; //设置材质的宽高 material.SetFloat("_SliderX", width); material.SetFloat("_SliderY", height); } //重写引导,有动画 public override void Guide(Canvas canvas, RectTransform target, float scale, float time) { //base.Guide(canvas, target, scale, time);不用调用因为是空的 this.Guide(canvas, target); scaleW = width * scale; scaleH = height * scale; this.material.SetFloat("_SliderX", scaleW); this.material.SetFloat("_SliderY", scaleH); this.time = time; isScaling = true; timer = 0; } private void Update() { if (isScaling) { // 每秒变化1/time,时间越短变化的就得越快 //deltaTime时间增量,保证不同帧率移动的是一样的 timer += Time.deltaTime * 1 / time; this.material.SetFloat("_SliderX", Mathf.Lerp(scaleW, width, timer)); this.material.SetFloat("_SliderY", Mathf.Lerp(scaleH, height, timer)); if (timer >= 1) { timer = 0; isScaling = false; } } } //private void Update() //{ // Guide(GameObject.Find("Canvas").GetComponent<Canvas>(), GameObject.Find("Button").GetComponent<RectTransform>()); //} }
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; // 枚举,引导的类型 public enum GuideType { Rect, Circle } //组件:需要的组件将会自动被添加到game object(游戏物体)。上 [RequireComponent(typeof(CircleGuide))] [RequireComponent(typeof(RectGuide))] public class GuideController : MonoBehaviour,ICanvasRaycastFilter { // private CircleGuide circleGuide; private RectGuide rectGuide; //材质不一样,所以创建两个材质 [SerializeField] private Material rectMat; [SerializeField] private Material circleMat; //需要image, private Image mask; private RectTransform target; // 在 private void Awake() { mask = transform.GetComponent<Image>(); if (rectMat==null || circleMat==null) { throw new System.Exception("材质未赋值"); } circleGuide = transform.GetComponent<CircleGuide>(); rectGuide = transform.GetComponent<RectGuide>(); } public void Guide(Canvas canvas, RectTransform target, GuideType guideType) { //引导的时候,将传入的target赋值 this.target = target; // TODO switch (guideType) { case GuideType.Rect: mask.material = rectMat; rectGuide.Guide(canvas, target); break; case GuideType.Circle: mask.material = circleMat; circleGuide.Guide(canvas, target); break; } } public void Guide(Canvas canvas, RectTransform target, GuideType guideType, float scale, float time) { //引导的时候,将传入的target赋值 this.target = target; // TODO switch (guideType) { case GuideType.Rect: mask.material = rectMat; rectGuide.Guide(canvas, target, scale, time); break; case GuideType.Circle: mask.material = circleMat; circleGuide.Guide(canvas, target, scale, time); break; } } /// <summary> /// /// </summary> /// <param name="sp">鼠标点的点(屏幕坐标),看看在不在镂空区域,在就把事件渗透,不在拦截</param> /// <param name="eventCamera"></param> /// <returns></returns> public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera) { if (target==null) { return true; }//点击不了 // 看看鼠标点击在不在镂空区域 return !RectTransformUtility.RectangleContainsScreenPoint(target, sp); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GuidePanel : MonoBehaviour { GuideController guideController; Canvas canvas; private void Awake() { canvas = GetComponentInParent<Canvas>(); } // Start is called before the first frame update void Start() { guideController = GetComponent<GuideController>(); //guideController.Guide(canvas, GameObject.Find("Button").GetComponent<RectTransform>(),GuideType.Rect); guideController.Guide(canvas, GameObject.Find("Button").GetComponent<RectTransform>(),GuideType.Rect,3,1.5f); Invoke("test", 2); } void test() { //guideController.Guide(canvas, GameObject.Find("Button_cir").GetComponent<RectTransform>(), GuideType.Circle); guideController.Guide(canvas, GameObject.Find("Button_cir").GetComponent<RectTransform>(), GuideType.Circle,3,1.0f); } // Update is called once per frame void Update() { } }
链接:https://pan.baidu.com/s/1BzGGotE8imnp1nYo9T4pAQ
提取码:uvf1
复制这段内容后打开百度网盘手机App,操作更方便哦