最近刚好公司安排了一个封装不规则UI脚本的任务,作为一个刚过实习期的游戏小白本能反应是问度娘,但是找了很多文章,因为本身代码水平一般,很多文章所用的代码水平对我而言严重超纲,直到我看到了一篇宏哥的一篇文章[UnityUI]不规则图片的点击响应_宏哥的博客-CSDN博客。以下代码也是我按照这篇文章最后的内容自己推展了一点,代码逻辑比较简单,可能不是很严谨,欢迎大佬们指正。
演示效果如下:
代码部分如下:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEditor;
public class IrregularUI : MonoBehaviour
{
#region 字段声明
public bool AlwaysIn = true;
public bool draggable = false;
public Image image;
public PolygonCollider2D polygonCollider2D;
private bool MouseDownInArea;
private bool MouseAlwaysInArea;
private bool IsDrag = false;
public UnityEvent OnClick;
public UnityEvent OnDragStart;
public UnityEvent OnDragEnd;
#endregion
#region 生命周期
void Start()
{
InitData();
InitEvent();
InitModule();
}
// Update is called once per frame
void Update()
{
MouseInArea();
if (AlwaysIn)
AlwaysInArea();
if (draggable && MouseDownInArea)
StartDrag();
if (IsDrag && !MouseDownInArea)
EndDrag();
}
#endregion
#region 初始化数据
private void InitData()
{
MouseAlwaysInArea = true;
MouseDownInArea = false;
}
private void InitEvent()
{
OnClick = new UnityEvent();
OnDragStart = new UnityEvent();
OnDragStart = new UnityEvent();
OnClick.AddListener(OnClickedEvent);
}
private void InitModule()
{
if (image == null)
image = GetComponent<Image>();
if (polygonCollider2D == null)
polygonCollider2D = GetComponent<PolygonCollider2D>();
}
#endregion
#region 私有方法
private void AlwaysInArea() //鼠标按下至抬起期间,鼠标移出区域不会触发OnClick
{
if (MouseDownInArea && !polygonCollider2D.OverlapPoint(Input.mousePosition))
MouseAlwaysInArea = false;
if (Input.GetMouseButtonUp(0))
MouseAlwaysInArea = true;
}
private void MouseInArea() //鼠标按下至抬起期间,鼠标移出区域也会触发OnClick
{
if (Input.GetMouseButtonDown(0)&& polygonCollider2D.OverlapPoint(Input.mousePosition))
MouseDownInArea = true;
if (Input.GetMouseButtonUp(0) && MouseDownInArea && MouseAlwaysInArea)
{
if (polygonCollider2D.OverlapPoint(Input.mousePosition))
OnClick.Invoke();
MouseDownInArea = false;
}
else if(Input.GetMouseButtonUp(0))
MouseDownInArea = false;
}
private void StartDrag()
{
IsDrag = true;
GetComponent<RectTransform>().position = Input.mousePosition;
OnDragStart.Invoke();
}
private void EndDrag()
{
IsDrag = false;
Vector3 pos = Input.mousePosition;
GetComponent<RectTransform>().position = pos;
}
#endregion
#region 公有方法
public bool GetButtonState() //获得当前鼠标状态
{
if (MouseDownInArea)
return true;
return false;
}
public bool DragState()
{
return IsDrag;
}
#endregion
#region 测试用临时方法
private void OnClickedEvent()
{
Log.Info("点击");
}
#endregion
参考另一位大佬文章UGUI中几种不规则按钮的实现方式 - 知乎 (zhihu.com),封装了一个组件,添加起来方便一点。
public class IrregularUIHelper //自动添加组件
{
[MenuItem("GameObject/UI/IrregularUI")]
public static void CreateIrregularUI()
{
var goRoot = Selection.activeGameObject;
if (goRoot == null)
return;
var polygon = new GameObject("IrregularUI");
var iUI = polygon.AddComponent<IrregularUI>();
var p2D = polygon.AddComponent<PolygonCollider2D>();
var image = polygon.AddComponent<Image>();
iUI.polygonCollider2D = p2D;
iUI.image = image;
polygon.transform.SetParent(goRoot.transform, false);
polygon.transform.SetAsLastSibling();
}
}
具体操作如下:
1、添加如上脚本
2、Hierachy界面创建IrregularUI物体(也可以直接在GameObject上直接添加,不过要手动添加Image和polygon collider 2d组件)
3、然后配置该GameObject的Inspector界面的Image和polygon collider 2d组件即可(如果是本身AddComponent添加的组件,在运行时会自动绑定其他两个组件:image和polygon collider 2d,也可以手动绑定,直接将装载该组建的GameObject拖拽到对应的位置即可)
AlwaysIn: 鼠标按下至抬起期间,鼠标移出区域是否会触发OnClick
Draggable:当前GameObject是否可拖动
初入游戏行业,技能积累比较少,欢迎各位大佬指正批评,也希望可以与大家有更多游戏开发上面的交流。