• 【Unity2022】Unity实现手机游戏操控摇杆(实现操控轮盘)


    运行效果预览

    首先展示一下本文章实现的效果:
    在这里插入图片描述

    创建物体

    创建两个UI图像,一个用于表示背景,作为父物体,命名为JoyStick,一个表示摇杆,命名为Center。
    在这里插入图片描述
    背景图像选择一个圆,最好加点半透明的属性,最终完成图如下图所示。
    在这里插入图片描述

    脚本

    创建一个脚本,命名为Joystick,然后将脚本挂载到JoyStick物体上,我们将通过这个脚本来实现摇杆。

    获取RectTransform

    我们首先需要在Awake() 方法中,获取摇杆背景的 RectTransform 组件和手柄的RectTransfomr组件。

    background = GetComponent<RectTransform>();
    handle = transform.GetChild(0).GetComponent<RectTransform>(); // 摇杆手柄是背景的子元素
    
    • 1
    • 2

    background 变量保存了背景的 RectTransform 组件,handle 变量保存了摇杆手柄的 RectTransform 组件。

    处理玩家拖动事件

    接下来,编写一个方法,用于处理拖动事件,代码如下所示。

    public void OnDrag(PointerEventData eventData)
    {
        Vector2 touchPosition = Vector2.zero;
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(background, eventData.position, eventData.pressEventCamera, out touchPosition))
        {
            // 获取触摸位置相对于摇杆背景的百分比
            touchPosition.x = (touchPosition.x / background.sizeDelta.x)*2;
            touchPosition.y = (touchPosition.y / background.sizeDelta.y)*2;
            touchPosition = (touchPosition.magnitude > 1f) ? touchPosition.normalized : touchPosition;
            
            // 更新摇杆手柄的位置
            handle.anchoredPosition = new Vector2(touchPosition.x * (background.sizeDelta.x / 2), touchPosition.y * (background.sizeDelta.y / 2));
            // 更新输入方向
            inputDirection = touchPosition;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    OnDrag(PointerEventData eventData) 方法用于处理拖动事件。在该方法中,首先通过 RectTransformUtility.ScreenPointToLocalPointInRectangle() 方法将触摸位置从屏幕坐标系转换为摇杆背景的本地坐标系。然后将触摸位置转换成相对于摇杆背景的百分比,这样摇杆手柄就能够根据触摸位置的百分比调整自己的位置。最后更新输入方向变量。

    完整代码

    using UnityEngine;
    using UnityEngine.EventSystems;
    
    public class Joystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
    {
        private RectTransform background; // 摇杆背景
        private RectTransform handle; // 摇杆手柄
    
        private Vector2 inputDirection; // 输入方向
    
        private void Awake()
        {
            background = GetComponent<RectTransform>();
            handle = transform.GetChild(0).GetComponent<RectTransform>(); // 摇杆手柄是背景的子元素
        }
    
        public void OnDrag(PointerEventData eventData)
        {
            Vector2 touchPosition = Vector2.zero;
            if (RectTransformUtility.ScreenPointToLocalPointInRectangle(background, eventData.position, eventData.pressEventCamera, out touchPosition))
            {
                // 获取触摸位置相对于摇杆背景的百分比
                touchPosition.x = (touchPosition.x / background.sizeDelta.x)*2;
                touchPosition.y = (touchPosition.y / background.sizeDelta.y)*2;
                touchPosition = (touchPosition.magnitude > 1f) ? touchPosition.normalized : touchPosition;
                
                // 更新摇杆手柄的位置
                handle.anchoredPosition = new Vector2(touchPosition.x * (background.sizeDelta.x / 2), touchPosition.y * (background.sizeDelta.y / 2));
                // 更新输入方向
                inputDirection = touchPosition;
            }
        }
    
        public void OnPointerDown(PointerEventData eventData)
        {
            OnDrag(eventData);
        }
    
        public void OnPointerUp(PointerEventData eventData)
        {
            // 重置摇杆位置和输入方向
            handle.anchoredPosition = Vector2.zero;
            inputDirection = Vector2.zero;
        }
    
        // 返回输入方向
        public Vector2 GetInputDirection()
        {
            return inputDirection;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    获取输入

    接下来就可以在其他所需获取输入的地方调用我们的GetInputDirection方法,来获取玩家的输入了,具体示例代码如下所示;

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Player : Ball
    {
        public Joystick joystick;
        // Start is called before the first frame update
        protected override void Start()
        {
            base.Start();
            GameObject canvas = GameObject.FindGameObjectWithTag("UI");
            joystick = canvas.transform.Find("Input/JoyStick").GetComponent<Joystick>();
        }
    // Update is called once per frame
    void Update()
        {
            Vector2 joystickInput=joystick.GetInputDirection();
            Move(new Vector3(joystickInput.x,joystickInput.y,transform.position.z));
            //Debug.Log(Weight);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    运行

    运行程序,效果如下所示:
    在这里插入图片描述

    其他文章

    Unity实现在两个物体之间连出一条线

    Unity如何生成随机数

  • 相关阅读:
    IDEA Debug过程中使用Drop Frame或Reset Frame实现操作回退
    AI计算机视觉进阶项目(一)——带口罩识别检测(3)
    浏览器本地存储
    目标检测——Faster RCNN系列算法原理介绍
    Docker发布简单springboot项目
    好记性不如烂笔头(ubuntu的samba的配置)
    vite + react 基本项目搭建
    你与网站建立的链接并非完全安全?建议全站开启https
    1个程序员单干之:怎样给我的升讯威在线客服系统编写堪比 MSDN 的用户手册
    java面试(八)
  • 原文地址:https://blog.csdn.net/weixin_44499065/article/details/133553928