先说摇杆的制作思路:
先显示一个大圆作为摇杆的底盘.
当手指按下显示一个小圆做摇杆, 拖动手指, 小圆跟着动 (把小圆限制在大圆的范围内)
得到手指与大圆的相对向量:
Vector2 v = (手指.Position - 大圆.Position).normalized;
再把这个向量给角色就完了.
当手指抬起时隐藏小圆.
不断推翻重来
我一开始用的是Input.mousePosition来做的, 完美运行.
Q: 手机有时候不能识别Mouse?
改成Touch: 用Input.touches[0]的TouchPhase.Began, TouchPhase.Moved, TouchPhase.Ended对应手指的按下, 滑动, 抬起.
Q: 我是要做多指触碰的, 一个Input.touches[0]怎么行?
那就遍历每个Touches的Position, 看哪个手指落在了摇杆上, 记录手指的fingerId, 然后和每个手指比较ID
Q: 我要10指触碰! 我要一边走路一边放技能一边买装备还一边拖动小地图!
那就…
重写 EventTrigger !
重写EventTrigger, 此脚本不用挂在场景中
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using DG.Tweening;
public class MyEvent : EventTrigger
{
//给物体添加本脚本调用这个方法
public static MyEvent Get(Transform obj)
{
if (obj == null)
{
Debug.LogError("没有找到MyEvent");
return null;
}
else
{
MyEvent lister = obj.GetComponent<MyEvent>();
if (lister == null)
{
lister = obj.gameObject.AddComponent<MyEvent>();
}
return lister;
}
}
//这里定义Action事件方法
public Action<GameObject, PointerEventData> MyBtnDown;
public Action<GameObject, PointerEventData> MyBtnDrag;
public Action<GameObject> MyBtnUp;
public Action<GameObject> MyBtnClick;
//下面开始重写
bool isBreathe = false; //防止连点用的
public override void OnPointerClick(PointerEventData eventData)
{
if (MyBtnClick != null && !isBreathe)
{
isBreathe = true;
MyBtnClick(gameObject);
//按钮呼吸效果
gameObject.transform.DOScale(1.1f, 0.2f).OnComplete(() =>
{
gameObject.transform.DOScale(1f, 0.2f).OnComplete(() => isBreathe = false );
});
}
}
public override void OnPointerDown(PointerEventData eventData)
{
if (MyBtnDown != null)
{
MyBtnDown(gameObject, eventData);
}
}
public override void OnDrag(PointerEventData eventData)
{
if (MyBtnDrag != null)
{
MyBtnDrag(gameObject, eventData);
}
}
public override void OnPointerUp(PointerEventData eventData)
{
if (MyBtnUp != null)
{
MyBtnUp(gameObject);
}
}
}
这个脚本挂在场景里, 这样就非常简单, 也不用射线也不用手指检测
using UnityEngine;
using UnityEngine.EventSystems;
public class UIMgr : MonoBehaviour
{
Transform rotPanel;
void Awake()
{
rotPanel = GameObject.Find("RotPanel").transform;
//给物体添加本脚本
MyEventTrigger rotEvent = MyEventTrigger.Get(rotPanel);
//添加要调用的Action
rotEvent.BtnDrag = RotPanelDrag;
}
private void RotPanelDrag(GameObject obj, PointerEventData eventData)
{
//这里我只用到了OnDrag方法, 用来控制相机旋转的
Camera.main.transform.RotateAround(Vector3.zero, Vector3.up, eventData.delta.x * cameraMoveSpeed * Time.deltaTime);
}
}
EventSystems的内部其实就是个AddListener的大集合;
即使只是个图片UI, 没有挂Button, 不能使用onClick.AddListener()方法, 也能响应点击事件;
↓改了一版, 用了泛型, 更灵活
using System;
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// 给按钮添加点击等脚本
/// </summary>
public class MyEvent : EventTrigger
{
/// <summary>
/// 给物体添加本脚本
/// </summary>
/// <param name="obj">给谁添加</param>
/// <returns></returns>
public static MyEvent Get<T>(T obj) where T : Component
{
if (null == obj)
{
Debug.LogError("没有找到: " + obj);
return null;
}
else
{
MyEvent trigger = obj.GetComponent<MyEvent>();
if (null == trigger)
{
trigger = obj.gameObject.AddComponent<MyEvent>();
}
return trigger;
}
}
/// <summary>
/// 移除本脚本
/// </summary>
/// <param name="obj"></param>
public static void Remove(Transform obj)
{
MyEvent trigger = obj.GetComponent<MyEvent>();
if (null == trigger)
{
return;
}
trigger.enabled = false;
}
public Action MyClick;
public Action MyDown;
public Action MyUp;
public Action<PointerEventData> MyDragStart;
public Action<PointerEventData> MyDrag;
public Action<PointerEventData> MyDragEnd;
public Action<PointerEventData> MyEnterObj;
public Action<PointerEventData> MyExitObj;
public override void OnPointerClick(PointerEventData eventData)
{
if (MyClick != null)
{
MyClick();
}
}
public override void OnPointerDown(PointerEventData eventData)
{
if (MyDown != null)
{
MyDown();
}
}
public override void OnPointerUp(PointerEventData eventData)
{
if (MyUp != null)
{
MyUp();
}
}
public override void OnBeginDrag(PointerEventData eventData)
{
if (MyDragStart != null)
{
MyDragStart(eventData);
}
}
public override void OnDrag(PointerEventData eventData)
{
if (MyDrag != null)
{
MyDrag(eventData);
}
}
public override void OnEndDrag(PointerEventData eventData)
{
if (MyDragEnd != null)
{
MyDragEnd(eventData);
}
}
}