unity2022版本 实现手机虚拟操作杆
简介
在许多移动游戏中,虚拟操纵杆是一个重要的用户界面元素,用于控制角色或物体的移动。本文将介绍如何在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)
在触摸开始记录拖动的一些起始坐标。
在拖动中移动操作按钮节点如果是操作角色移动这里就可以操作移动角色
在触摸结束的时候重置坐标
-
PointerDown方法:描述PointerDown方法,它处理当玩家触摸操纵杆时的行为。根据操纵杆类型(固定或跟随),它设置操纵杆的初始位置。
-
Drag方法:详细解释Drag方法,这是当玩家拖动操纵杆时执行的代码。说明如何计算操纵杆输入的方向,以及如何限制操纵杆的移动范围。
-
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){// 将基本事件数据强制转换为PointerEventDataPointerEventData 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
相关文章:

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

『GitHub Actions』部署静态博客指南
前言 之前博主是使用的 Jenkins 实现 vuepress 博客的自动部署与持续交付,但是因为现在迁移服务器到海外,并且服务器配置降低。现在经常出现服务器的 Jenkins 构建过程中 CPU 占用率过高,导致服务器卡死 然后我想的话既然只是部署静态博客&…...
WPF Datagrid Header数据绑定,表头复选框实现全选、全否、部分选中,根据条目动态变化
制作一个根表头为CheckBox可全选、全不选的列表,且可根据条目自动调整CheckBox的状态(选中、不选、部分选中)。 本来是想用DataGrid做一个CheckBox的列用于勾选其中的某些行,当时做出来之后想着添加一个全选、全否的功能。做两个…...
Tensorflow2 中对模型进行编译,不同loss函数的选择下输入数据格式需求变化
一、tf2中常用的损失函数介绍 在 TensorFlow 2 中,编译模型时可以选择不同的损失函数来定义模型的目标函数。不同的损失函数适用于不同的问题类型和模型架构。下面是几种常见的损失函数以及它们的作用和适用场景: 1.均方误差(Mean Squared …...
【python】基础语法(三)--异常、模块、包
异常 代码中出现的报错问题,可能会导致整个代码的停止,为了避免这种情况,有了捕获异常操作; 捕获异常 提前预知可能出错的代码,做好准备,避免因bug导致整个项目停止; try:可能出…...

XGBoost+LR融合
1、背景简介 xgboostlr模型融合方法用于分类或者回归的思想最早由facebook在广告ctr预测中提出,其论文Practical Lessons from Predicting Clicks on Ads at Facebook有对其进行阐述。在这篇论文中他们提出了一种将xgboost作为feature transform的方法。大概的思想…...

leetcode:1929. 数组串联(python3解法)
难度:简单 给你一个长度为 n 的整数数组 nums 。请你构建一个长度为 2n 的答案数组 ans ,数组下标 从 0 开始计数 ,对于所有 0 < i < n 的 i ,满足下述所有要求: ans[i] nums[i]ans[i n] nums[i] 具体而言&am…...
Epoch和episodes的区别
“Epoch” 和 “episode” 是两个不同的概念,通常在不同领域中使用。 Epoch(周期): Epoch 是一个在机器学习和深度学习中常用的术语,通常用于表示训练数据集中的一个完整遍历。在每个 epoch 中,整个训练数据…...

漏洞复现--华测监测预警系统2.2任意文件读取
免责声明: 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…...

数据结构 - 6(优先级队列(堆)13000字详解)
一:堆 1.1 堆的基本概念 堆分为两种:大堆和小堆。它们之间的区别在于元素在堆中的排列顺序和访问方式。 大堆(Max Heap): 在大堆中,父节点的值比它的子节点的值要大。也就是说,堆的根节点是堆…...

Js高级技巧—拖放
拖放基本功能实现 拖放是一种非常流行的用户界面模式。它的概念很简单:点击某个对象,并按住鼠标按钮不放,将 鼠标移动到另一个区域,然后释放鼠标按钮将对象“放”在这里。拖放功能也流行到了 Web 上,成为 了一些更传统…...

ELF和静态链接:为什么程序无法同时在Linux和Windows下运行?
目录 疑问 编译、链接和装载:拆解程序执行 ELF 格式和链接:理解链接过程 小结 疑问 既然我们的程序最终都被变成了一条条机器码去执行,那为什么同一个程序,在同一台计算机上,在 Linux 下可以运行,而在…...

【爬虫实战】python微博热搜榜Top50
一.最终效果 二.项目代码 2.1 新建项目 本文使用scrapy分布式、多线程爬虫框架编写的高性能爬虫,因此新建、运行scrapy项目3步骤: 1.新建项目: scrapy startproject weibo_hot 2.新建 spider: scrapy genspider hot_search "weibo.com" 3…...

【网络基础】——传输层
目录 前言 传输层 端口号 端口号范围划分 知名端口号 进程与端口号的关系 netstat UDP协议 UDP协议位置 UDP协议格式 UDP协议特点 面向数据报 UDP缓冲区 UDP的使用注意事项 基于UDP的应用层协议 TCP协议 TCP简介 TCP协议格式 确认应答机制&#…...

删除字符串特定的字符(fF)C语言
代码: #include <stdio.h> void funDel(char *str) {int i, j;for (i j 0; str[i] ! \0; i)if (str[i] ! f && str[i] ! F)str[j] str[i];str[j] \0; }int main() {char str[100];printf("请输入一个字符串:");gets(str);pr…...
C++入门(1):命名空间,IO流 输入输出,缺省参数
一、命名空间 1.1 命名空间的作用: 避免标识符命名冲突 1.2 命名空间定义: 关键字:namespace namespace test {// 命名空间内可以定义变量/函数/类型int a 10;int Add(int x, int y){return x y;}struct Stack{int* a;int top;int …...
Go 语言面试题(三):并发编程
文章目录 Q1 无缓冲的 channel 和 有缓冲的 channel 的区别?Q2 什么是协程泄露(Goroutine Leak)?Q3 Go 可以限制运行时操作系统线程的数量吗? Q1 无缓冲的 channel 和 有缓冲的 channel 的区别? 对于无缓冲的 channel,…...

Linux - make命令 和 makefile
make命令和 makefile 如果之前用过 vim 的话,应该会对 vim 又爱又恨吧,刚开始使用感觉非常的别扭,因为这种编写代码的方式,和在 windows 当中用图形化界面的方式编写代码的方式差别是不是很大。当你把vim 用熟悉的之后࿰…...

FPGA复习(功耗)
减小功耗 就得减小电流 电流和CF有关( C: 电容(被门数目和布线长度影响) F:时钟频率) 方法大纲 减小功耗:1 时钟控制 2输入控制 3减小供电电压 4双沿触发器 5修改终端 同步数字电路降低动态功耗:动态禁止…...

element ui el-table表格复选框,弹框关闭取消打勾选择
//弹框表格复选框清空 this.$nextTick(()>{this.$refs.table.clearSelection();})<el-table ref"table" v-loading"crud.loading" :header-cell-style"{ color: #FFF, background: #333 }":cell-style"{ color: #FFF, background: #3…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...

麒麟系统使用-进行.NET开发
文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...