二.Unity中使用虚拟摇杆来控制角色移动

news2024/11/7 15:25:34

上一篇中我们完成了不借助第三方插件实现手游的虚拟摇杆,现在借助这个虚拟摇杆来实现控制角色的移动。

虚拟摇杆实际上就给角色输出方向,类似于键盘的WSAD,也是一个二维坐标,也就是(-1,1)的范围,将摇杆的方向进行归一化传递给角色即可,创建一个名为PlayerManager的脚本,通过Character组件来控制角色的移动。这里在上一篇文章在一. Unity实现虚拟摇杆及屏幕自适应功能,讲述过了,这里拖拽的时候将位移的向量归一化后传递给角色,松手的时候归0.

 mUIEvtListener.OnPointerUpEvent += (eventData =>
            {
                mPointImg.transform.localPosition = mDefaultPos;
                mPointImg.SetActiveState(false);
                mDirImg.transform.localPosition = mDefaultPos;
                PlayerManager.Instance.SetPlayerDir(Vector2.zero);
            });
            mUIEvtListener.OnDragFunc += (eventData =>
            {
                Vector2 dir = eventData.position - mStartPos;
                float length = dir.magnitude;
                PlayerManager.Instance.SetPlayerDir(dir.normalized);
                if (length > mTouchMaxDir)
                {
                    Vector2 clampDir = Vector2.ClampMagnitude(dir, mTouchMaxDir);
                    mPointImg.transform.position = mStartPos + clampDir;
                }
                else
                {
                    mPointImg.transform.position = eventData.position;
                }
            });

在PlayerManager中就是一些常规操作,设置方向,这里用了一个Vector2.SignedAngle的API,其作用就是返回传入向量和目标向量之间的角度,我们设定的目标向量是(0,1)也就是二维向量的正前方,下面画了一张图,应该会很清楚。其中为什么要+mCamTrans.eulerAngles.y,是因为相机是倾斜的照着角色,摄像机于角色之间有一个相对角度,是为了能够确保玩家的移动方向与摄像机视角一致,不论摄像机朝哪个方向,玩家的输入都能按照当前摄像机的视角调整角色的朝向。

在这里插入图片描述

 public class PlayerManager : Component<PlayerManager>
    {
        private const float TouchSpeed = 5;
        private CharacterController mCC;
        private Animator mAnim;
        private Vector2 mDir;
        private Transform mCamTrans;
        private Vector3 mOffset;
        private float mCurAnimSpeed;
        private float mTargerAnimSpeed;
        private const float AccelerSpeed = 5;
        public override void IStart()
        {
            base.IStart();
            mCC = GetComponent<CharacterController>();
            mAnim = GetComponentInChildren<Animator>();
            mCamTrans = Camera.main.transform;
            mOffset = transform.position - mCamTrans.transform.position;
        }

        public override void IUpdate()
        {
            base.IUpdate();
            if (mDir != Vector2.zero)
            {
                SetDir();
                SetMove();
                SetCamera();
            }
        
        }
        /// <summary>
        /// 通过摇杆控制玩家方向
        /// </summary>
        /// <param name="dir"></param>
        public void SetPlayerDir(Vector2 dir)
        {
            if (dir != Vector2.zero)
            {
                mDir = dir;
                SetAnimSpeed(1);
            }
            else
            {
                mDir = Vector2.zero;
                SetAnimSpeed(0);
            }
        }

        private void SetDir()
        {
            float angle = Vector2.SignedAngle(mDir, new Vector2(0, 1)) + mCamTrans.eulerAngles.y;
            transform.eulerAngles = new Vector3(0, angle, 0);
        }

        private void SetMove()
        {
            mCC.Move(transform.forward * Time.deltaTime * TouchSpeed);
        }

        private void SetCamera()
        {
            mCamTrans.transform.position = transform.position - mOffset;
        }
  
    }
}

在这里插入图片描述
最后简单设置一下角色的动画,将Idle和Run进行一个简单的混合,通过插值的形式,让当前的Speed以平缓的过渡到目标值。

   public class PlayerManager : Component<PlayerManager>
    {
        private float mCurAnimSpeed;
        private float mTargerAnimSpeed;
        private const float AccelerSpeed = 5;
       
        public override void IUpdate()
        {
            base.IUpdate();
            if (mDir != Vector2.zero)
            {
                SetDir();
                SetMove();
                SetCamera();
            }
            if (mCurAnimSpeed != mTargerAnimSpeed)
            {
                UpdateAnimFixed();
            }
        }
        private void SetAnimSpeed(float speed)
        {
            mTargerAnimSpeed = speed;
        }

        private void UpdateAnimFixed()
        {
            if (Mathf.Abs(mCurAnimSpeed - mTargerAnimSpeed) > AccelerSpeed)
            {
                mCurAnimSpeed = AccelerSpeed;
            }
            else if(mCurAnimSpeed > mTargerAnimSpeed)
            {
                mCurAnimSpeed -= Time.deltaTime * AccelerSpeed;
            }
            else if(mCurAnimSpeed< mTargerAnimSpeed)
            {
                mCurAnimSpeed += Time.deltaTime * AccelerSpeed;
            }
            mAnim.SetFloat("Speed",mCurAnimSpeed);
        }
     }

测试运行结果如下:
在这里插入图片描述

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

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

相关文章

Windows与Linux下 SDL2的第一个窗口程序

Windows效果和Linux效果如下&#xff1a; 下面是代码&#xff1a; #include <stdio.h> #include "SDL.h"int main(int argc, char* argv[]) { // 初始化SDL视频子系统if (SDL_Init(SDL_INIT_VIDEO) ! 0){// 如果初始化失败&#xff0c;打印错误信息printf(&…

HPA自动扩缩容和命名空间资源限制

目录 HPA概念 安装HPA的依赖环境 安装metrics-server 手动扩缩容 自动扩缩容 yaml文件 创建HPA 自动扩容 自动缩容 命名空间资源限制 HPA概念 HPA是针对pod的数量进行自动扩缩容。&#xff08;是针对控制器deployment、replicaset、StatefulSet创建的pod&#xff0…

TS接口、泛型、自定义类型

这里记录下typescript中接口、泛型和自定义类型的使用 接口定义 // 定义一个接口,用来限制Teacher的属性 export interface Teacher {name: string;age: number;gender: string; }export type teacherList Teacher[];// 一个自定义类型 export type Teachers Array<Teach…

【UE5 C++课程系列笔记】02——创建C++类的三种方式

目录 一、从UE编辑器中创建 引用头文件报错的两种解决方式 &#xff08;1&#xff09;方式1 &#xff08;2&#xff09;方式2 二、在文件夹中直接创建 三、在Visual Studio中创建 一、从UE编辑器中创建 在UE编辑器中选择“Tools-》New C Class” 这里新建的类的父类选择…

Gitlab 中几种不同的认证机制(Access Tokens,SSH Keys,Deploy Tokens,Deploy Keys)

前言 公司主要使用 Go 语言做项目&#xff0c;有一些 Gitlab 私有仓库需要引用&#xff0c;在做 CI 时&#xff0c;要自行配置权限以获取代码。 最近发现各个项目组在做 CI 遇到仓库权限问题时的解决方式不尽相同&#xff0c;有用 Project Token 的&#xff0c;有用 Deploy K…

【python】OpenCV—Augmented Reality Using Aruco Markers

文章目录 1、任务描述2、Aruco Markers3、代码实现4、更多例子展示5、涉及到的库cv2.findHomography 6、参考 1、任务描述 借助 Aruco Markers&#xff0c;替换墙面上画面中的内容 2、Aruco Markers OpenCV 中的 aruco 模块共有 25 个预定义的标记字典。字典中的所有标记包含…

新代机床采集数据

新代集團1995年成立於台灣新竹,事業版圖遍布全球,以台灣為中心向外發展,據點橫跨歐洲、美洲、亞洲三大洲。新代長期深耕於機床控制器的軟體及硬體技術研發,專注於運動控制領域,目前已成為亞太市場中深具影響力的控制器領導品牌之一。主營產品包括:機床數控系統、伺服驅動…

Java虚拟机 - 高级篇

一、GraalVM 1. 什么是GraalVM 2. GraalVM的两种运行模式 &#xff08;1&#xff09;JIT即时编译模式 &#xff08;2&#xff09;AOT提前编译模式 3. 应用场景 4. 参数优化和故障诊断 二、新一代的GC 1. 垃圾回收器的技术演进 2. Shenandoah GC 测试代码&#xff1a; /** C…

Ubuntu 20.04/22.04无法连接网络(网络图标丢失、找不到网卡)的解决方案

问题复述&#xff1a; Ubuntu 20.04无法连接到网络&#xff0c;网络连接图标丢失&#xff0c;网络设置中无网络设置选项。 解决方案 对于Ubuntu 20.04而言&#xff1a;逐条执行 sudo service network-manager stopsudo rm /var/lib/NetworkManager/NetworkManager.statesudo…

《深度学习》OpenCV轮廓检测 模版匹配 解析及实现

目录 一、模型匹配 1、什么是模型匹配 2、步骤 1&#xff09;提取模型的特征 2&#xff09;在图像中查找特征点 3&#xff09;进行特征匹配 4&#xff09;模型匹配 3、参数及用法 1、用法 2、参数 1&#xff09;image&#xff1a;待搜索对象 2&#xff09;templ&am…

利用AI驱动智能BI数据可视化-深度评测Amazon Quicksight(四)

简介 随着生成式人工智能的兴起&#xff0c;传统的 BI 报表功能已经无法满足用户对于自动化和智能化的需求&#xff0c;今天我们将介绍亚马逊云科技平台上的AI驱动数据可视化神器 – Quicksight&#xff0c;利用生成式AI的能力来加速业务决策&#xff0c;从而提高业务生产力。…

科技之光,照亮未来之路“2024南京国际人工智能展会”

全球科技产业的版图正以前所未有的速度重构&#xff0c;而位于中国东部沿海经济带的江浙沪地区&#xff0c;作为科技创新与产业升级的高地&#xff0c;始终站在这一浪潮的最前沿。2024年&#xff0c;这一区域的科技盛宴——“2024南京人工智能展会”即将在南京国际博览中心盛大…

基础的八股

JS this 全局&#xff1a;this指向window 函数&#xff1a;this指向window 对象&#xff1a;this指向调用它的 get、post的区别 1、写的地方不同&#xff1a;get在地址栏里 地址栏有多长就只能写多少、post在请求体里 没有上限 2、关于回退和刷新&#xff1a;get回退和刷新没问…

TCP、UDP、HTTPS、HTTP

前言 OSI七层网络 名称解释协议应用层定义了各种应用协议的数据规范 HTTP、HTTPS、SSL FTP、DNS TFTP、SMTP 表示层不同系统之间通信会话层断点续传传输层 一个电脑有许多端口&#xff0c;根据端口找到发送方与接收方 确保数据包完整性 TCP、UDP网络层 ARP协议&#xff1a;通过…

shopify主题布局layout

一、基本概念 Layout是Shopify主题中的基础结构&#xff0c;它决定了页面的整体框架和布局方式。通过Layout&#xff0c;可以统一管理和控制页面上的公共元素&#xff0c;如页眉&#xff08;Header&#xff09;、页脚&#xff08;Footer&#xff09;等&#xff0c;确保这些元素…

闯关leetcode——20. Valid Parentheses

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/valid-parentheses/description/ 内容 Given a string s containing just the characters ‘(’, ‘)’, ‘{’, ‘}’, ‘[’ and ‘]’, determine if the input string is valid. An input st…

批量采集电商商品详情数据接口(上货and数据分析价格库存监控等)

——在成长的路上&#xff0c;我们都是同行者。这篇关于电商API接口的文章&#xff0c;希望能帮助到您。期待与您继续分享更多API接口的知识&#xff0c;请记得关注Anzexi58哦&#xff01; 批量采集电商商品详情数据涉及到多个方面&#xff0c;包括商品的上货、价格监控、库存监…

机器学习--神经网络

神经网络 计算 神经网络非常简单&#xff0c;举个例子就理解了&#xff08;最后一层的那个写错了&#xff0c;应该是 a 1 ( 3 ) a^{(3)}_1 a1(3)​&#xff09;&#xff1a; n o t a t i o n notation notation&#xff1a; a j ( i ) a^{(i)}_j aj(i)​ 表示第 i i i 层的…

SprinBoot+Vue财务管理系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化&#xff0c;使其看起来更清晰&#xff0c;同时保持尺寸不变&#xff0c;通常涉及到图像处理技术如锐化、降噪、对比度增强…