当前位置: 首页 > news >正文

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

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

虚拟摇杆实际上就给角色输出方向,类似于键盘的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.lryc.cn/news/442549.html

相关文章:

  • 基于SpringBoot的旅游管理系统
  • Linux套接字
  • 软件测试面试题(5)——二面(游戏测试)
  • C#基于SkiaSharp实现印章管理(8)
  • 信通院发布首个《大模型媒体生产与处理》标准,阿里云智能媒体服务作为业界首家“卓越级”通过
  • AI学习指南深度学习篇-Adam的Python实践
  • 08_React redux
  • 2024华为杯研究生数学建模竞赛(研赛)选题建议+初步分析
  • 001.从0开始实现线性回归(pytorch)
  • Relations Prediction for Knowledge Graph Completion using Large Language Models
  • 2024年中国研究生数学建模竞赛D题思路代码分析——大数据驱动的地理综合问题
  • 全国31省对外开放程度、经济发展水平、政府干预程度指标数据(2000-2022年)
  • 计算机网络传输层---课后综合题
  • 【homebrew安装】踩坑爬坑教程
  • 反游戏学(Reludology):概念、历史、现状与展望?(豆包AI版)
  • 【C/C++语言系列】实现单例模式
  • A. Make All Equal
  • 业务安全治理
  • HelpLook VS GitBook,在线文档管理工具对比
  • docker面经
  • Python 中的 Kombu 类库
  • safepoint是什么?有什么用?
  • axios相关知识点
  • LeetCode 面试经典150题 67.二进制求和
  • Dell PowerEdge 网络恢复笔记
  • Java面试——集合篇
  • 算法【双向广搜】
  • javascript检测数据类型的方法
  • 生信初学者教程(五):R语言基础
  • 深度学习计算