Unity关于手游端摇杆移动、摇杆按钮冲突问题

Unity关于手游端摇杆移动、摇杆按钮冲突问题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、摇杆移动问题

1.问题重现

①摇杆移动时,通过控制角色的刚体运动。
②当摇杆移动到游戏区域外松开时,后面对摇杆进行操作无响应。
③使用的是Drag事件来写的拖动逻辑。

2、解决

解决思路:摇杆控制角色移动时,不能通过控制角色的刚体移动,而要通过改变角色的位置来移动。

(有BUG)刚体移动代码如下(hor、ver为获取了摇杆移动的方向,判断设置了区间-1,1):

 	direction.x = hor;
	direction.y = ver * 0.7f;
	
	rig.velocity = direction * moveSpeed * 50 * Time.deltaTime;
        if (rig.velocity.x >= 0.05)
        {
            transform.rotation = new Quaternion(0, 0, 0, 0);
        }
        else if (rig.velocity.x <= -0.05)
        {
            transform.rotation = new Quaternion(0, 180, 0, 0);
        }

(可用)使用Translate的移动代码如下:

        direction.x = hor;
        direction.y = ver * 0.7f;
        player.transform.Translate(direction*moveSpeed*Time.deltaTime);

(可用)最后附上完整代码:

   private float moveSpeed;//移动速度
    private Vector2 direction;//移动方向
    private PlayerBehaviour behaviour;//角色行为
  //  public Transform Yingzi;//影子

    public Transform big; //摇杆背景
    public Transform small;//摇杆中心
    private float radius = 250;//摇杆半径

    private Vector2 moveCenter;//移动中心
    private Vector2 mouseToCenterVect;//鼠标移动到中心的向量
    private float mouseToCenterDistance;//鼠标到中心点的距离
    private float hor;//获取水平方向
    private float ver;//获取垂直方向
    public Transform player;//主角

// Start is called before the first frame update
    void Start()
    {
        behaviour = player.GetComponent<PlayerBehaviour>();
    }
    /// <summary>
    /// 开始拖动时
    /// </summary>
    public void Begin(BaseEventData data)
    {
        //移动中心点赋值
        moveCenter = big.position;
    }


    /// <summary>
    /// 拖动中
    /// </summary>
    /// <param name="_">UI事件数据</param>
    public void OnDrag(BaseEventData _)
    {
        //中心点到触摸点的向量赋值
        mouseToCenterVect = (Vector2)Input.mousePosition - moveCenter;
        //中心点到触摸点的距离计算
        mouseToCenterDistance = Mathf.Clamp(mouseToCenterVect.magnitude, 0, 250);
        //根据距离来判断摇杆中心的位置
        if (mouseToCenterDistance < radius)
        {
            //若是距离小于最大半径,这里取向量的归一值,就是模为1的向量,乘上中心到触摸点的距离,这个就是摇杆中心应该移动的方向和距离,并且移动是在移动中心的基础上,所以加上移动中心的坐标
            small.position = mouseToCenterVect.normalized * mouseToCenterDistance + moveCenter;
        }
        else
        {
            //同上,不过就是限定了移动的最大距离
            small.position = mouseToCenterVect.normalized * radius + moveCenter;
        }
        //摇杆中心的X - 移动中心的x就是水平的变化值,这里 /100 控制_hor在(-1,,1)之间
        hor = (small.position.x - moveCenter.x) / 250;
        //摇杆中心的Y - 移动中心的Y就是垂直的变化值,这里 /100 控制_hor在(-1,,1)之间
        ver = (small.position.y - moveCenter.y) / 250;
    }


    /// <summary>
    /// 结束时
    /// </summary>
    public void End(BaseEventData data)
    {
        PointerEventData _ = data as PointerEventData;
        if (_ == null)
            return;

        //水平移动值归零
        hor = 0;
        //垂直移动值归零
        ver = 0;

        small.localPosition = big.localPosition;
    }
     void Update()
    {
        moveSpeed = behaviour.Speed;
         direction.x = hor;
        direction.y = ver * 0.7f; 
    }

	private void FixedUpdate()
    {
        player.transform.Translate(direction*moveSpeed*Time.deltaTime);
    }

代码详细参考:https://blog.csdn.net/Mr_Sun88/article/details/84680361

(tips:需要添加Event Trigger组件,并添加Begin Drag、Drag、End Drag)
在这里插入图片描述

二、摇杆按钮冲突问题

1.问题重现

导到手机上后:
①摇杆的拖动区域
②左手拖动摇杆时,右手按下按钮,摇杆会往右边移动。

2.解决

解决思路:使用Drag事件所使用到的Input.mousePosition(鼠标位置)不适用于手游的使用,而应该使用多点触控来控制摇杆。

多点触控代码如下:

 void Start()
    {
        Input.multiTouchEnabled = true;//开启多点触控
    }
    void Update()
    {
        if (Input.touchCount <= 0) //触摸点数量为0
            return;
        if (Input.touchCount >= 1)//触摸点数量不为0
        {
            //当触控为左边区域,左边控制虚拟摇杆从而控制player移动
            if (Input.GetTouch(0).position.x < Screen.width * 0.5f)
            {
                //只要有左边区域被触摸了,只获取第一次触摸的点
                if (Input.GetTouch(0).phase == TouchPhase.Began)
                {
                    //移动中心点赋值
                    moveCenter = big.position;
                }
                //第一次手指触摸移动
                if (Input.GetTouch(0).phase == TouchPhase.Moved)
                {

                        //中心点到触摸点的向量赋值
                        mouseToCenterVect = (Vector2)Input.GetTouch(0).position - moveCenter;
                        //中心点到触摸点的距离计算
                        mouseToCenterDistance = Mathf.Clamp(mouseToCenterVect.magnitude, 0, 250);
                        //根据距离来判断摇杆中心的位置
                        if (mouseToCenterDistance < radius)
                        {
                            //若是距离小于最大半径,这里取向量的归一值,就是模为1的向量,乘上中心到触摸点的距离,这个就是摇杆中心应该移动的方向和距离,并且移动是在移动中心的基础上,所以加上移动中心的坐标
                            small.position = mouseToCenterVect.normalized * mouseToCenterDistance + moveCenter;
                        }
                        else
                        {
                            //同上,不过就是限定了移动的最大距离
                            small.position = mouseToCenterVect.normalized * radius + moveCenter;
                        }
                        //摇杆中心的X - 移动中心的x就是水平的变化值,这里 /100 控制_hor在(-1,,1)之间
                        hor = (small.position.x - moveCenter.x) / 250;
                        //摇杆中心的Y - 移动中心的Y就是垂直的变化值,这里 /100 控制_hor在(-1,,1)之间
                        ver = (small.position.y - moveCenter.y) / 250;

                }

                //第一次手指触摸离开
                if (Input.GetTouch(0).phase == TouchPhase.Ended)
                {
                    //水平移动值归零
                    hor = 0;
                    //垂直移动值归零
                    ver = 0;

                    small.localPosition = big.localPosition;
                }
            }

        }   
    }

完整代码如下:

 private float moveSpeed;//移动速度
    private Vector2 direction;//移动方向
    private PlayerBehaviour behaviour;//角色行为
  //  public Transform Yingzi;//影子

    public Transform big; //摇杆背景
    public Transform small;//摇杆中心
    private float radius = 250;//摇杆半径

    private Vector2 moveCenter;//移动中心
    private Vector2 mouseToCenterVect;//鼠标移动到中心的向量
    private float mouseToCenterDistance;//鼠标到中心点的距离
    private float hor;//获取水平方向
    private float ver;//获取垂直方向
    public Transform player;//主角

 	void Start()
    {
        behaviour = player.GetComponent<PlayerBehaviour>();
        Input.multiTouchEnabled = true;
    }
 	void Update()
    {
        moveSpeed = behaviour.Speed;
        if (Input.touchCount <= 0)
            return;
        if (Input.touchCount >= 1)
        {
            //当触控为左边区域,左边控制虚拟摇杆从而控制player移动
            if (Input.GetTouch(0).position.x < Screen.width * 0.5f)
            {
                //只要有左边区域被触摸了,不管Input.touchCount等于多少,都会执行下面
                if (Input.GetTouch(0).phase == TouchPhase.Began)
                {
                    //移动中心点赋值
                    moveCenter = big.position;
                }
                //手指触摸移动
                if (Input.GetTouch(0).phase == TouchPhase.Moved)
                {

                        //中心点到触摸点的向量赋值
                        mouseToCenterVect = (Vector2)Input.GetTouch(0).position - moveCenter;
                        //中心点到触摸点的距离计算
                        mouseToCenterDistance = Mathf.Clamp(mouseToCenterVect.magnitude, 0, 250);
                        //根据距离来判断摇杆中心的位置
                        if (mouseToCenterDistance < radius)
                        {
                            //若是距离小于最大半径,这里取向量的归一值,就是模为1的向量,乘上中心到触摸点的距离,这个就是摇杆中心应该移动的方向和距离,并且移动是在移动中心的基础上,所以加上移动中心的坐标
                            small.position = mouseToCenterVect.normalized * mouseToCenterDistance + moveCenter;
                        }
                        else
                        {
                            //同上,不过就是限定了移动的最大距离
                            small.position = mouseToCenterVect.normalized * radius + moveCenter;
                        }
                        //摇杆中心的X - 移动中心的x就是水平的变化值,这里 /100 控制_hor在(-1,,1)之间
                        hor = (small.position.x - moveCenter.x) / 250;
                        //摇杆中心的Y - 移动中心的Y就是垂直的变化值,这里 /100 控制_hor在(-1,,1)之间
                        ver = (small.position.y - moveCenter.y) / 250;

                }

                //手指触摸离开
                if (Input.GetTouch(0).phase == TouchPhase.Ended)
                {
                    //水平移动值归零
                    hor = 0;
                    //垂直移动值归零
                    ver = 0;

                    small.localPosition = big.localPosition;
                }
            }

        }


        direction.x = hor;
        direction.y = ver * 0.7f;
        
    }

	 private void FixedUpdate()
    {
        player.transform.Translate(direction*moveSpeed*Time.deltaTime);
    }

代码详细参考:https://blog.csdn.net/qq_39745907/article/details/104010204
tips:这个不需要添加Event Trigger事件。


总结

以上就是本章要讲的内容,本文仅仅讲述了笔者在开发过程中遇到的问题,提供给遇到相同或者相似问问题的开发者参考,欢迎大佬下方评论。
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值