最新方法:
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform
, Input.mousePosition, canvas.worldCamera, out pos); 这个方法能直接返回鼠标在UGUI上的相对坐标,如果为手机的话将Input.mousePosition换成Input.GetTouch(),通过这个方法实现图标位置跟随鼠标位置移动的方式直接简化为:
RectTransformUtility.ScreenPointToLocalPointInRectangle
(canvas.transform as RectTransform, Input.mousePosition, canvas.worldCamera, out pos)
rectTransform.anchoredPosition = pos;//这里的rectTransform直接传入想随着鼠标动的图标的rectTransform 另一种使用方式为判断鼠标位置相对于图标的相对位置,直接改变上面方法的第一个参数,改为想要判断的图标的rectTransform就可以
RectTransformUtility.ScreenPointToLocalPointInRectangle
(mainImage.rectTransform, Input.mousePosition, canvas.worldCamera, out pos) 通过这种方式获得的UI相对位置坐标可以直接用以下方式判断是否处于该UI触碰范围中
if (mainRect.rect.Contains(pos))
针对UGUI自动适配之后会出现问题经过多次优化,直接上代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class GameManager
{
//单例
#region 单例
private static GameManager main;
public static GameManager Main
{
get
{
if (main == null)
{
main = new GameManager();
}
return main;
}
}
#endregion
//全局变量
#region 全局变量z
#endregion
//手游端操作框架
#region 手机游戏Touch适配
public bool canchange = true;
private bool forif;
//返回两个手指开始点击屏幕
public bool GetDoubleClick()
{
forif = true;
if (SystemInfo.deviceType == DeviceType.Desktop)
{
forif = false;
}
else
{
if (Input.touchCount <= 1)
{
forif = false;
}
else
{
forif = Input.GetTouch(1).phase == TouchPhase.Began;
}
}
return forif;
}
//返回两个手指持续点击屏幕
public bool GetDoubleClickAlways()
{
forif = true;
if (SystemInfo.deviceType == DeviceType.Desktop)
{
forif = false;
}
else
{
if (Input.touchCount <= 1)
{
forif = false;
}
}
return forif;
}
//返回两个手指中的一个手指离开屏幕
public bool GetDoubleClickUp()
{
if (SystemInfo.deviceType == DeviceType.Desktop)
{
forif = false;
}
else
{
if (Input.touchCount <= 1)
{
forif = false;
}
else
{
forif = Input.GetTouch(0).phase == TouchPhase.Ended ||Input.GetTouch(1).phase == TouchPhase.Ended;
}
}
return forif;
}
//返回是否按下鼠标左键或手指开始点击屏幕
public bool GetClick()
{
if (SystemInfo.deviceType == DeviceType.Desktop)
{
forif = Input.GetMouseButtonDown(0);
}
else
{
if (Input.touchCount <= 0)
{
forif = false;
}
else
{
forif = Input.GetTouch(0).phase == TouchPhase.Began;
}
}
return forif;
}
//判断鼠标持续按下或手指是否持续点击屏幕
public bool GetClickAlways()
{
if (SystemInfo.deviceType == DeviceType.Desktop)
{
forif = Input.GetMouseButton(0);
}
else
{
if (Input.touchCount <= 0)
{
forif = false;
}
else
{
forif = true;
}
}
return forif;
}
//判断松开鼠标左键或手指离开屏幕
public bool GetClickUp()
{
if (SystemInfo.deviceType == DeviceType.Desktop)
{
forif = Input.GetMouseButtonUp(0);
}
else
{
if (Input.touchCount <= 0)
{
forif = false;
}
else
{
forif = Input.GetTouch(0).phase == TouchPhase.Ended;
}
}
return forif;
}
private Vector3 pos;
//获得经过适配调整的鼠标或手指坐标
public Vector3 GetPos()
{
if (SystemInfo.deviceType == DeviceType.Desktop)
{
return GetMousePos();
}
else
{
return GetHandPos();
}
}
//获得未经过适配调整的鼠标或手指坐标
public Vector3 GetNumPos()
{
if (SystemInfo.deviceType == DeviceType.Desktop)
{
return Input.mousePosition;
}
else
{
if (Input.touchCount > 0)
{
return Input.GetTouch(0).position;
}
else
{
return Vector3.zero;
}
}
}
public bool ClickLeftScreen()
{
if (GetClickAlways())
{
if (GetNumPos().x < Screen.width * 0.5f)
{
return true;
}
}
return false;
}
public bool ClickRightScreen()
{
if (GetClickAlways())
{
if (GetNumPos().x > Screen.width * 0.5f)
{
return true;
}
}
return false;
}
private Vector3 GetMousePos()
{
if ((float) Screen.width / Screen.height < 1080.0f / 1920.0f)
{
pos.x = Input.mousePosition.x / Screen.width * 1080.0f;
pos.y = Input.mousePosition.y / Screen.width * 1080.0f;
pos.z = 0;
}
else
{
pos.x = Input.mousePosition.x / Screen.height * 1920.0f;
pos.y = Input.mousePosition.y / Screen.height * 1920.0f;
pos.z = 0;
}
return pos;
}
private Vector3 GetHandPos()
{
if ((float) Screen.width / Screen.height < 1080.0f / 1920.0f)
{
//竖屏
pos.x = Input.GetTouch(0).position.x / Screen.width * 1080.0f;
pos.y = Input.GetTouch(0).position.y / Screen.width * 1080.0f;
pos.z = 0;
}
else
{
//横屏
pos.x = Input.GetTouch(0).position.x / Screen.height * 1920.0f;
pos.y = Input.GetTouch(0).position.y / Screen.height * 1920.0f;
pos.z = 0;
}
return pos;
}
private PointerEventData pointerEventData;
private GraphicRaycaster gr;
List<RaycastResult> results = new List<RaycastResult>();
/// <summary>
/// 获取鼠标或手指在哪个UI上。
/// </summary>
/// <param name="examisin">用来判断是否在自己身上的UI</param>
/// <param name="getAll">传入true判断所有点击的UI,传入false判断最上层UI</param>
/// <param name="vv"> 传入参数则改为判断某个固定点而不是鼠标或手指位置 </param>
/// <returns>返回点是否在传入的UI上</returns>
public bool GetTouch(GameObject examisin, bool getAll = false, Vector2? vv = null)
{
gr = examisin.transform.root.GetComponent<GraphicRaycaster>();
pointerEventData = new PointerEventData(EventSystem.current);
if (vv == null)
{
pointerEventData.position = GetNumPos();
}
else
{
pointerEventData.position = (Vector2) vv;
}
results.Clear();
gr.Raycast(pointerEventData, results);
if (results.Count != 0)
{
if (getAll)
{
foreach (RaycastResult result in results)
{
if (result.gameObject.name == examisin.name)
{
return true;
}
}
return false;
}
if (results[0].gameObject.name == examisin.name)
{
return true;
}
if (results[0].gameObject.name == "miss")
{
for (int i = 0; i < results.Count; i++)
{
if (results[i].gameObject.name == "miss")
{
continue;
}
if (results[i].gameObject.name == examisin.name)
{
return true;
}
else
{
return false;
}
}
}
}
return false;
}
public GameObject GetCanvasTouch(GameObject canvas)
{
return GetCanvasTouch(canvas, GetNumPos());
}
public GameObject GetCanvasTouch(GameObject canvas , Vector2 vector2)
{
// if(!GetClickAlways()){return null;}
gr = canvas.transform.GetComponent<GraphicRaycaster>();
pointerEventData = new PointerEventData(EventSystem.current);
pointerEventData.position = vector2;
pointerEventData.pressPosition = vector2;
results.Clear();
gr.Raycast(pointerEventData, results);
if(results.Count>0){return results[0].gameObject;} return null;
}
public bool GetTouchAnything(GameObject examisin, Vector2? vv = null)
{
gr = examisin.transform.root.GetComponent<GraphicRaycaster>();
pointerEventData = new PointerEventData(EventSystem.current);
if (vv == null)
{
pointerEventData.position = GetNumPos();
}
else
{
pointerEventData.position = (Vector2) vv;
}
results.Clear();
gr.Raycast(pointerEventData, results);
if (results.Count != 0)
{
return true;
}
return false;
}
// 播放龙骨动画
// private GameObject gameanim;
//
// public void AnimPlay(ref UnityArmatureComponent anim, string name, int playertime = 0)
// {
// gameanim = GameObject.Instantiate(anim.gameObject, anim.transform.parent);
// gameanim.name = anim.gameObject.name;
// gameanim.transform.SetSiblingIndex(anim.transform.GetSiblingIndex());
// GameObject.Destroy(anim.gameObject);
// anim = gameanim.GetComponent<UnityArmatureComponent>();
// anim.animation.Play(name, playertime);
// }
#endregion
}
一个简单单例,注意的是下面获取位置是只适用于UGUI是自适应模式并且有自动适应宽高屏代码的,自适应宽高屏在这里: Unity学习笔记:ScreenAudoChange UGUI分辨率自适应_努力长头发的程序猿的博客-CSDN博客
版权声明:本文为qq_39332021原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。