为Unity用手机操作UGUI制作一套操作方法

60 篇文章 2 订阅
9 篇文章 1 订阅

市面上最常见的就是EasyTouch,不过现在下不到了而且也没学会,所以自己研究出来一套方式来应对手机端操作UGUI,应该和EasyTouch类似(没怎么用过EasyTouch)

实现了点击事件,拖拽功能,松开事件,放在固定点的事件,四个最常用的功能

应用这篇文章里的内容用上了前面获取手机端操作的代码:https://blog.csdn.net/qq_39332021/article/details/106625199

首先是大脚本TakeEvent

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public abstract class TakeEvent: MonoBehaviour
{
    public List<MovePos> movepos = new List<MovePos>();
    protected bool move , movetopos;
    protected Vector3 oldpos , handoldpos,way;
    protected RectTransform moverect;
    protected GameObject g;
    //制作的时候设定的屏幕长宽,子类可以改,和Canvas上的属性一起动
    protected Vector2 screensetsize = new Vector2(1080.0f,1920.0f);

    public void Setmove(RectTransform moveobject)
    {
        move = true;
        moverect = moveobject;
        oldpos = moveobject.anchoredPosition;
        handoldpos = GameManager.Main.GetPos();
    }
    
    public void SetmoveToPos(RectTransform moveobject)
    {
        Setmove(moveobject);
        movetopos = true;
    }

    protected GameObject GetMovePos(Vector2 v)
    {
        if ((float)Screen.width / Screen.height < screensetsize.x / screensetsize.y)
        {
            //竖屏
            v.x = v.x/screensetsize.x*Screen.width + Screen.width / 2.0f;
            v.y = v.y/(screensetsize.x/Screen.width*Screen.height)*Screen.height + Screen.height / 2.0f;
        }
        else
        {
            //横屏
            v.x = v.x/(screensetsize.y*Screen.width/Screen.height)*Screen.width + Screen.width / 2.0f;
            v.y = v.y/screensetsize.y*Screen.height + Screen.height / 2.0f;
        }
        foreach (MovePos m in movepos)
        {
            g = m.GetIsPos(v);
            if (g)
            {
                return g;
            }
        }
        return null;
    }

    public abstract void SetClick(GameObject click);
    public abstract void SetClickOver(GameObject click);

    public abstract void MoveEnd(RectTransform click);
    public abstract void FatherUpdate();

    private void Update()
    {
        Move();
        FatherUpdate();
    }

    protected virtual void Move()
    {
        if (move)
        {
            way = GameManager.Main.GetPos() - handoldpos;
            moverect.anchoredPosition = oldpos + way;
            if (GameManager.Main.GetClickUp())
            {
                move = false;
                if (movetopos)
                {
                    MoveEnd(moverect);
                    movetopos = false;
                }
            }
        }
    }
}

一个抽象类,自己写一个脚本继承TakeEvent放到场景里,然后抽象方法里随便写点啥就可以用了,里面的四个抽象方法分别是点击触发事件,点击结束事件,拖拽结束事件,跟Update,继承了就不要写Update了不然会把父类的Update替换掉。前面三个抽象方法的参数都是被点击的物体,拖拽结束事件是被拖拽的物体。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public abstract class GetHand : MonoBehaviour
{
    protected RectTransform rect;

    protected TakeEvent takeEvent;
    // Start is called before the first frame update
    void Start()
    {
        rect = gameObject.GetComponent<RectTransform>();
        takeEvent = GameObject.FindObjectOfType<TakeEvent>();
        start();
    }

    protected abstract void start();
    
    
    protected bool GetTouch()
    {
        PointerEventData pointerEventData = new PointerEventData(EventSystem.current);
        if (SystemInfo.deviceType == DeviceType.Desktop)
        {
            pointerEventData.position = GameManager.Main.GetMousePos();
        }
        else
        {
            pointerEventData.position = GameManager.Main.GetHandPos();
        }
        GraphicRaycaster gr = gameObject.transform.parent.GetComponent<GraphicRaycaster>();
        List<RaycastResult> results = new List<RaycastResult>();
        gr.Raycast(pointerEventData, results);
        if (results.Count != 0)
        {
            if (results[0].gameObject.name == gameObject.name)
            {
                return true;
            }
        }
        return false;
    }
    
    protected bool GetTouch(Vector2 v)
    {
        PointerEventData pointerEventData = new PointerEventData(EventSystem.current);
        pointerEventData.position = v;
        GraphicRaycaster gr = gameObject.transform.parent.GetComponent<GraphicRaycaster>();
        List<RaycastResult> results = new List<RaycastResult>();
        gr.Raycast(pointerEventData, results);
        if (results.Count != 0)
        {
            if (results[0].gameObject.name == gameObject.name)
            {
                return true;
            }
        }
        return false;
    }
}

又是一个抽象类,但是这个不用管,这个是用来别的工具类需要继承的,主要实现了判断手指鼠标或者某个点在不在自己的身上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class GetClick : GetHand
{

    protected override void start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        if (GameManager.Main.GetClick())
        {
            if (GetTouch())
            {
                takeEvent.SetClick(gameObject);
            }
        }
    }
}

直接把这个脚本挂在场景中的物体上,如果挂载的物体被点击了直接调用TakeEvent里面的抽象事件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class GetClickOver : GetHand
{

    protected override void start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
        if (GameManager.Main.GetClickUp())
        {
            if (GetTouch())
            {
                takeEvent.SetClickOver(gameObject);
            }
        }
    }
}

和上一个一样,这个获取的是抬起

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;


public class GetMove : GetHand
{

    protected override void start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        if (GameManager.Main.GetClick())
        {
            if (GetTouch())
            {
                takeEvent.Setmove(rect);
            }
        }
    }
}

这个脚本挂在场景上被挂载的物体可以被鼠标或者手直接拖动,不过仅仅只是能拖动,没别的功能

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class GetMoveToPos : GetHand
{
    protected override void start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        if (GameManager.Main.GetClick())
        {
            if (GetTouch())
            {
                takeEvent.SetmoveToPos(rect);
            }
        }
    }

}

这个和上面功能一样,但是不同的是拖动结束后会调用一次TakeEvent里面的MoveEnd方法,可以用来判断是否将物体拖到了某个位置上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class MovePos : GetHand
{
    protected override void start()
    {
        takeEvent.movepos.Add(this);
    }

    public GameObject GetIsPos(Vector2 v)
    {
        if (GetTouch(v))
        {
            return gameObject;
        }
        else
        {
            return null;
        }
    }
}

挂在被拖到的位置上,这个要和拖拽的物体分别放在两个画布上,不然会重叠不能判断,继承TakeEvent的代码在MoveEnd直接调用GetMovePos()参数传click.anchoredPosotion就能返回物体被拖拽到了哪个物体上

 

就这么几个功能,记住不动的背景,动的物体,尽量分开放到多个Canvas上     动的物体和被拖到的位置  必须分开放

功能是通过物体的名字判断的,尽量让场景能点的能拖得都不要重名,不然会出BUG

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值