Unity学习笔记:在GameManager里记录手游操作框架

最新方法:

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 版权协议,转载请附上原文出处链接和本声明。