unity2022版本 实现手机虚拟操作杆

news2024/11/18 4:31:54

简介

在许多移动游戏中,虚拟操纵杆是一个重要的用户界面元素,用于控制角色或物体的移动。本文将介绍如何在Unity中实现虚拟操纵杆,提供了一段用于移动控制的代码。我们将讨论不同类型的虚拟操纵杆,如固定和跟随,以及如何在实际游戏中使用这些操纵杆。

界面节点设置

1. 添加一个Canvas节点

首先,我们需要创建一个画布节点,这是我们整个界面的基础。这个节点将允许我们绘制和排列其他元素。

2. 在Canvas节点下添加一个Panel节点

接下来,我们将在Canvas节点下创建一个Panel节点。这个Panel节点将充当容器,用于组织和管理我们的界面元素。

3. 在Panel节点下添加两个Image节点

在Panel节点中,我们将添加两个Image节点。这两个Image节点具有不同的用途:

a. 背景节点:第一个Image节点将用作背景,为整个界面提供背景图像或颜色。

b. 操作按钮节点:第二个Image节点将用于显示操作按钮或其他交互元素。

4. 结构示意图:

你可以使用以下结构示意图来更清晰地展示节点的层次关系:

UiCanvas (画布)
│
└─ Joystick (面板)
   │
   ├─ Bg(背景)
   │
   └─ Btn(操作按钮)

截图可以这样:

脚本编写

简要说明:

因为编写的是虚拟操作杆 需要添加三个事件:

触摸开始(Pointer Down),拖动(Drag),触摸结束(Pointer Up)

在触摸开始记录拖动的一些起始坐标。

在拖动中移动操作按钮节点如果是操作角色移动这里就可以操作移动角色

在触摸结束的时候重置坐标

  1. PointerDown方法:描述PointerDown方法,它处理当玩家触摸操纵杆时的行为。根据操纵杆类型(固定或跟随),它设置操纵杆的初始位置。

  2. Drag方法:详细解释Drag方法,这是当玩家拖动操纵杆时执行的代码。说明如何计算操纵杆输入的方向,以及如何限制操纵杆的移动范围。

  3. PointerUp方法:描述PointerUp方法,用于当玩家释放操纵杆时重置相关变量和位置,同时停止玩家的移动。

在初始化引用的时候可以传入参数(JoystickType)控制虚拟操作杆是固定的还是跟随触摸点的

完整的脚本如下:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class MovementJoystick : MonoBehaviour
{
    // 枚举类型,用于指定操纵杆的类型
    public enum JoystickType
    {
        FIXED,    // 固定类型的操纵杆
        FOLLOW    // 跟随类型的操纵杆
    }

    // 对操纵杆和其背景对象的引用
    public GameObject joystick;  // 操纵杆对象
    public GameObject joystickBG;  // 操纵杆背景对象

    // 存储当前操纵杆的输入值作为一个二维向量
    public Vector2 joystickVec;

    // 指定操纵杆的类型(固定或跟随)
    public JoystickType joystickType = JoystickType.FIXED;

    // 触摸操纵杆时的位置
    private Vector2 joystickTouchPos;

    // 操纵杆背景的原始位置
    private Vector2 joystickOriginalPos;

    // 操纵杆背景的半径,根据屏幕宽度计算而来
    private float joystickRadius;

    // 初始化
    void Start()
    {
        // 初始化操纵杆背景的原始位置
        joystickOriginalPos = joystickBG.transform.position;

        // 根据屏幕宽度计算操纵杆背景的半径
        joystickRadius = joystickBG.GetComponent<RectTransform>().sizeDelta.y * Screen.width / 800 / 2;
    }

    // 当玩家按下操纵杆时调用
    public void PointerDown()
    {
        if (joystickType == JoystickType.FIXED)
        {
            // 对于固定操纵杆,将触摸位置设置为操纵杆背景的原始位置
            joystickTouchPos = joystickOriginalPos;
        }
        else if (joystickType == JoystickType.FOLLOW)
        {
            // 对于跟随操纵杆,将操纵杆及其背景设置为触摸位置
            joystick.transform.position = Input.mousePosition;
            joystickBG.transform.position = Input.mousePosition;
            joystickTouchPos = Input.mousePosition;
        }
    }

    // 当玩家拖动操纵杆时调用
    public void Drag(BaseEventData baseEventData)
    {
        // 将基本事件数据强制转换为PointerEventData
        PointerEventData pointerEventData = (PointerEventData)baseEventData;

        // 获取当前拖动位置
        Vector2 dragPos = pointerEventData.position;

        // 计算操纵杆输入的方向
        joystickVec = (dragPos - joystickTouchPos).normalized;

        // 计算当前位置与触摸位置之间的距离
        float joystickDist = Vector2.Distance(dragPos, joystickTouchPos);

        // 限制操纵杆在指定半径范围内移动
        if (joystickDist < joystickRadius)
        {
            joystick.transform.position = joystickTouchPos + joystickVec * joystickDist;
        }
        else
        {
            joystick.transform.position = joystickTouchPos + joystickVec * joystickRadius;
        }

        // 根据操纵杆输入设置玩家的移动方向
        // HHSJ.Main.instance.PlayerEx.GetComponent<HHSJ.Player>().moveDir = dragPos - joystickTouchPos;
    }

    // 当玩家释放操纵杆时调用
    public void PointerUp()
    {
        // 重置操纵杆输入和位置到初始值
        joystickVec = Vector2.zero;
        joystick.transform.position = joystickOriginalPos;
        joystickBG.transform.position = joystickOriginalPos;

        // 将玩家的移动方向重置为零
        // HHSJ.Main.instance.PlayerEx.GetComponent<HHSJ.Player>().moveDir = Vector3.zero;
    }

    // 可以在这里添加其他方法和FixedUpdate以实现特定功能
}

大致效果如下:

社交:

QQ群:859055710 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1082276.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

lv8 嵌入式开发-网络编程开发 16 多路复用poll函数

目录 1 多路复用的多种实现方式 2 poll 2.1 poll 函数应用 3 epoll 函数族&#xff08;效率最高&#xff09; 3.1 epoll_create 创建epoll句柄 3.2 epoll_ctl epoll句柄控制接口 3.3 epoll_wait 等待 epoll 文件描述符上的 I/O 事件 3.4 epoll 函数应用 1 多路复用的多…

数据结构学习笔记——数据结构概论

目录 一、数据与数据元素二、数据类型和抽象数据类型三、数据结构的定义&#xff08;一&#xff09;逻辑结构&#xff08;二&#xff09;存储结构&#xff08;物理结构&#xff09;1、顺序存储结构2、链式存储结构3、索引存储结构4、散列存储结构 &#xff08;三&#xff09;数…

Python 自定义包和模块随机生成6位验证码(详解版)

一、新建一个包&#xff08;两种方法&#xff09; 方法一&#xff1a;先新建一个空目录命名为"小功能包"&#xff0c;然后在新建的目录下新建一个空__init__.py&#xff08;目的是声明当前目录是一个包&#xff09; 方法二&#xff1a;直接在PyCharm用鼠标依次点击F…

【Unity】【VR】如何让Distance Grab抓取物品时限制物品的Rotation

【背景】 遇到这样的场景,希望抓取Canvas时,Canvas不会沿Z轴旋转。 【问题】 发现Freeze Canvas的Rigid Body没有用。 【分析】 应该是RigidBody的限制仅在物理互动下生效,抓取可能不属于物理互动(比如碰撞),所以不生效。 【思路】 还是得写脚本挂载在Interacta…

LeetCode 69.x的平方

LeetCode 69.x的平方 思路&#xff1a; 二分查找。从1到x进行二分查找&#xff0c;每次判断mid的平方是否<x&#xff0c; 如果是&#xff0c;则更新ansmid&#xff0c;并缩小区间&#xff1b; 如果不是&#xff0c;则缩小区间&#xff1b; 最后则找到最接近的ans&#xff0…

数字IC/FPGA面试题目合集解析(一)

数字IC/FPGA面试题目合集解析&#xff08;一&#xff09; 题目概述题目1&#xff0c;计算题2&#xff0c;计算题3&#xff0c;选择题 答案与解析1&#xff0c;计算题2&#xff0c;计算题3&#xff0c;选择题 题目概述 1&#xff0c;计算题&#xff1a;计算该触发器等效的建立保…

AI项目十五:PP-Humanseg训练及onnxruntime部署

若该文为原创文章&#xff0c;转载请注明原文出处。 关于PP-Humanseg是在正点原子的3568开发板AI测试例子里看到的&#xff0c;目的也是想自己训练并部署&#xff0c;这里记录一下训练和在onnxruntime部署运行的全过程&#xff0c;会转成ONNX&#xff0c;至于部署到rk3568上&a…

Leetcode刷题详解——移动零

题目链接&#xff1a;移动零 题目描述&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出…

深度学习自学笔记十三:unet网络详解和环境配置

一、unet网络详解 UNet&#xff08;全名为 U-Net&#xff09;是一种深度学习架构&#xff0c;最初由Olaf Ronneberger、Philipp Fischer和Thomas Brox于2015年提出&#xff0c;用于图像分割任务。该网络的名称来源于其U形状的架构&#xff0c;该架构使得网络在编码和解码过程中…

Linux查看本机IP地址

Linux查看本机IP地址 命令 ipconfig可能会遇到的问题 Command ‘ifconfig’ not found, but can be installed with: Command ifconfig not found, but can be installed with:sudo apt install net-tools解决办法 安装net-tools再执行ipconfig 安装网络工具 sudo apt i…

Java-集合框架

文章目录 摘要CollectionCollection集合遍历Iterator迭代器增强for循环 排序 ListArrayListLinkedListVector SetHashSet Map小结 摘要 Java的集合框架提供了一组用于存储、管理和操作数据的类和接口。这个框架提供了各种数据结构&#xff0c;如列表、集合、队列和映射&#x…

sqoop 脚本密码管理

1&#xff1a;背景 生产上很多sqoop脚本的密码都是铭文&#xff0c;很不安全&#xff0c;找了一些帖子&#xff0c;自己尝试了下&#xff0c;记录下细节&#xff0c;使用的方式是将密码存在hdfs上然后在脚本里用别名来替代。 2&#xff1a;正文 第一步&#xff1a;创建密码对…

分类预测 | MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输入分类预测

分类预测 | MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输入分类预测 目录 分类预测 | MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输入分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输…

小迈物联网网关对接串口服务器[Modbus RTU]

很多工控现场&#xff0c;方案中会使用串口服务器采集Modbus RTU的设备&#xff0c;这种情况下一般会在PC机上装上串口服务器厂家的软件来进行数据采集。如果现场不需要PC机&#xff0c;而是通过网关将数据传输到软件平台&#xff0c;如何实现呢&#xff1f; 本文简要介绍小迈网…

记录用命令行将项目打包成war包

记录用命令行将项目打包成war包 找到项目的pom.xml 在当前路径下进入cmd 输入命令 mvn clean package 发现报错了 Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project MMS: Error assembling WAR: webxml attribute is req…

编程助手成为编程高手,帮您正则调试

官方下载地址&#xff1a;安果移动 视频演示地址&#xff1a;编程助手-正则调试与面试题&#xff0c;升职加薪不是梦_哔哩哔哩_bilibili 编程助手成为编程高手&#xff0c;帮您正则调试 软件介绍版本号 1.0.2更新日期 2023-10-11 找工作不敢谈薪资&#xff1f;总觉得公司欠我…

【JVM】初步认识Java虚拟机

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 JVM 一、初识JVM1.1 什么是JVM1.2 JVM的功能…

C之fopen/fclose/fread/fwrite/flseek

一、C中文件操作简介 c中的文件操作大致和linux的文件操作类似&#xff0c;但是毕竟是不同的API&#xff0c;所以会有些差异。部分差异会在下面的案例中体验 二、fopen open的参数有两个一个是文件名&#xff0c;一个是模式选择&#xff0c;不同open函数&#xff0c;open中的模…

python - 第15章 GUI的最终选择 Tkinter

文章目录 tk1tk2tk3 添加图片tk4 图片作背景 tk1 import tkinter as tkapptk.Tk() app.title("这是标题") # 显示标题theLabeltk.Label(app,text窗口程序!) # 显示文本,图片,图标 theLabel.pack() # 自动调节组件尺寸app.mainloop()tk2 import tkinter as tkclas…

各省份12.5m地形数据

手机整理了全国各省份12.5m的地形数据&#xff0c;ALOS的。 另外也有全国30m的地形数据&#xff0c;可以去我的博客目录找&#xff0c;以及各种模型数据均可在下面链接下载。 传送门&#xff1a;数据共享中心