圆形遮罩镂空处理脚本:
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
///
public class CircleGuidance : MonoBehaviour
{
public static CircleGuidance instance;
///
public Image target;
///
private Vector3[] corners = new Vector3[];
///
private Vector4 center;
///
private float radius;
///
private Material material;
///
private float currentRadius;
///
private float shrinkTime = 0.5f;
///
private GuidanceEventPenetrate eventPenetrate;
private void Awake()
{
instance = this;
}
public void Init(Image target)
{
this.target = target;
eventPenetrate = GetComponent
if (eventPenetrate != null)
{
eventPenetrate.SetTargetImage(target);
}
Canvas canvas = GameObject.Find("Canvas").GetComponent
/// <summary>
/// 世界坐标转换为画布坐标
/// </summary>
/// <param name="canvas">画布</param>
/// <param name="world">世界坐标</param>
/// <returns></returns>
private Vector2 WorldToCanvasPos(Canvas canvas, Vector3 world)
{
Vector2 position;
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, world, canvas.GetComponent<Camera>(), out position);
return position;
}
}
矩形遮罩镂空处理脚本:
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
///
public class RectGuidance : MonoBehaviour
{
public static RectGuidance instance;
///
public Image target;
///
private Vector3[] corners = new Vector3[];
///
private Vector4 center;
///
private float targetOffsetX = ;
///
private float targetOffsetY = ;
///
private Material material;
///
private float currentOffsetX = 0f;
///
private float currentOffsetY = 0f;
///
private float shrinkTime = 0.5f;
///
private GuidanceEventPenetrate eventPenetrate;
private void Awake()
{
instance = this;
}
public void Init(Image target)
{
this.target = target;
eventPenetrate = GetComponent<GuidanceEventPenetrate>();
if (eventPenetrate != null)
{
eventPenetrate.SetTargetImage(target);
}
Canvas canvas = GameObject.Find("Canvas").GetComponent<Canvas>();
//获取高亮区域的四个顶点的世界坐标
target.rectTransform.GetWorldCorners(corners);
//计算高亮显示区域在画布中的范围
targetOffsetX = Vector2.Distance(WorldToCanvasPos(canvas, corners\[\]), WorldToCanvasPos(canvas, corners\[\])) / 2f;
targetOffsetY = Vector2.Distance(WorldToCanvasPos(canvas, corners\[\]), WorldToCanvasPos(canvas, corners\[\])) / 2f;
//计算高亮显示区域的中心
float x = corners\[\].x + ((corners\[\].x - corners\[\].x) / );
float y = corners\[\].y + ((corners\[\].y - corners\[\].y) / );
Vector3 centerWorld = new Vector3(x, y, );
Vector2 center = WorldToCanvasPos(canvas, centerWorld);
//设置遮罩材质中的中心变量
Vector4 centerMat = new Vector4(center.x, center.y, , );
material = GetComponent<Image>().material;
material.SetVector("\_Center", centerMat);
//计算当前高亮显示区域的半径
RectTransform canRectTransform = canvas.transform as RectTransform;
if (canRectTransform != null)
{
//获取画布区域的四个顶点
canRectTransform.GetWorldCorners(corners);
//计算偏移初始值
for (int i = ; i < corners.Length; i++)
{
if (i % == )
{
currentOffsetX = Mathf.Max(Vector3.Distance(WorldToCanvasPos(canvas, corners\[i\]), center), currentOffsetX);
}
else
{
currentOffsetY = Mathf.Max(Vector3.Distance(WorldToCanvasPos(canvas, corners\[i\]), center), currentOffsetY);
}
}
}
//设置遮罩材质中当前偏移的变量
material.SetFloat("\_SliderX", currentOffsetX);
material.SetFloat("\_SliderY", currentOffsetY);
}
/// <summary>
/// 收缩速度
/// </summary>
private float shrinkVelocityX = 0f;
private float shrinkVelocityY = 0f;
private void Update()
{
//从当前偏移量到目标偏移量差值显示收缩动画
float valueX = Mathf.SmoothDamp(currentOffsetX, targetOffsetX, ref shrinkVelocityX, shrinkTime);
float valueY = Mathf.SmoothDamp(currentOffsetY, targetOffsetY, ref shrinkVelocityY, shrinkTime);
if (!Mathf.Approximately(valueX, currentOffsetX))
{
currentOffsetX = valueX;
material.SetFloat("\_SliderX", currentOffsetX);
}
if (!Mathf.Approximately(valueY, currentOffsetY))
{
currentOffsetY = valueY;
material.SetFloat("\_SliderY", currentOffsetY);
}
}
/// <summary>
/// 世界坐标转换为画布坐标
/// </summary>
/// <param name="canvas">画布</param>
/// <param name="world">世界坐标</param>
/// <returns></returns>
private Vector2 WorldToCanvasPos(Canvas canvas, Vector3 world)
{
Vector2 position;
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, world, canvas.GetComponent<Camera>(), out position);
return position;
}
}
新手引导管理脚本,通过此脚本管理遮罩跟引导步骤,动态添加按钮点击事件等:
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
///
public class GuideManagers : MonoBehaviour
{
///
public List
///
private int currentIndex = ;
///
private bool isFinish = false;
///
private GameObject maskPrefabs;
///
public void Next()
{
if (isFinish || currentIndex > guideList.Count)
{
return;
}
//注销上一步按钮点击事件
if (currentIndex != && guideList[currentIndex - ].go.GetComponent
{
EventTriggerListener.GetListener(guideList[currentIndex - ].go).onClick -= null;
}
if (maskPrefabs == null)
{
maskPrefabs = Instantiate(Resources.Load<GameObject>("RectGuidance\_Panel"), this.transform);
}
//初始化遮罩
maskPrefabs.GetComponent<RectGuidance>().Init(guideList\[currentIndex\].go.GetComponent<Image>()); ;
currentIndex++;
//给当前按钮添加点击事件
if (currentIndex < guideList.Count)
{
EventTriggerListener.GetListener(guideList\[currentIndex - \].go).onClick += (go) =>
{
Next();
};
}
//最后一个按钮点击事件处理
else if (currentIndex == guideList.Count)
{
EventTriggerListener.GetListener(guideList\[currentIndex - \].go).onClick += (go) =>
{
maskPrefabs.gameObject.SetActive(false);
//注销最后一个按钮的点击事件
EventTriggerListener.GetListener(guideList\[currentIndex - \].go).onClick -= null;
};
isFinish = true;
}
}
}
///
[Serializable]
public class GuideUIList
{
///
public GameObject go;
public GuideUIList(GameObject go)
{
this.go = go;
}
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章