UnityVR--组件2--Rigidbody--移动控制

    移动的方式有transform.Translate()、rigidbody.velocity()、rigidbody.MovePosition()等多种。本篇使用rigidbody的方式,并向着相机朝向的方向控制移动。也就是继上一篇“第三人称相机控制”,相机随鼠标点击而旋转位置之后,我们让主角小人朝向相机看向的方向移动(越来越接近商业游戏的界面了)。

  本篇用到的API有:Rigidbody.MovePosition、rigidbody.MoveRotation、Vector3.Set、Vector3.Normalize、Camera.main、Vector3.RotateTowards、Vector3.RotateTowards、Mathf.Approximately、Camera.main   最终效果如下:


目录

  1. Rigidbody的作用

  2. 实现Rigidbody移动的过程分析

  3. 实现旋转的过程分析

  4. 脚本实现HeroMove


  1. Rigidbody的作用

  (1)Rigidbody组件:Rigidbody的重要性不用多说了,本专栏前面的文章已经多次使用和提及,凡是GameObject需要涉及物理力的影响,都需要添加此组件,并且大部分情况下需要配合Collider碰撞器使用。

   上图是Rigidbody组件的参数解释,详见官方手册Rigidbody 

  以及笔记【Untiy学习笔记】Rigidbody组件及其常用函数_一白梦人的博客

    (2)Rigidbody类:类中提供了关于重力、阻力、速度、移动、质量等与物理相关的方法。在本篇中,我们使用的是其中的  rigidbody.MovePosition()位置移动方法、 rigidbody.MoveRotation()旋转方法

  其他方法可以参照笔记:第十章 Rigidbody类

  2. 实现Rigidbody移动的过程分析

  (1)第一步:在初始化时使用GetComponent拿到挂在主角身上的Rigidbody组件;

rb=GetComponent<Rigidbody>();

  (2)第二步:获取键盘输入的横向坐标和纵向坐标(由W、A、S、D提供);

moveInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));

   这个Input.GetAxis中的坐标名字(Horizental和Vertical),是通过InputManager设置的,这些按键触发获取水平方向的值的改变:

(3)第三步:坐标转换。第二步得到的是X、Y方向的坐标,而实际在unity空间中移动的方向是X、Z方向,因此,使用Vector3.set方法将(X,Y,0)转换成(X,0,Y),并使用Vector3..Normalize()方法单位化此向量,得到移动的方向;

movement.Set(moveInput.x, 0, moveInput.y);
movement.Normalize();

  (4)第四步:Rigidbody.MovePosition实现移动

rb.MovePosition(rb.position + movement * moveSpeed * Time.DeltaTime);

  3. 实现旋转的过程分析

  (1)第一步:使用Mathf.Approximately(近似值)判断是否有横向和纵向的输入改变(键盘控制方向);

Mathf.Approximately(moveInput.x, 0);
Mathf.Approximately(moveInput.y, 0);

  Mathf类有很多有用且有趣的API,使设计的过程更加快捷,之后我们还会用到很多。

  (2)第二步:如果收到了键盘控制方向的命令,那就改变一下小人移动的方向,让它乘上主相机的方向,这里使用了一个四元数与三维向量相乘,它的几何意义是表示这个向量按照这个四元数进行旋转之后得到的新的向量。

movement = Quaternion.Euler(0, Camera.main.transform.eulerAngles.y, 0) * movement;

    然后用Vector3.RotateTowards()方法控制,将当前小人朝向的方向(transform.forwad)向目标前方旋转;

Vector3 lookForward = Vector3.RotateTowards(transform.forward, movement, rotateSpeed * Time.fixedDeltaTime, 360);

*Vector3 RotateTowards(当前向量, 目标向量,每次移动的最大角度(弧度),最大移动弧度):从当前角度向目标角度旋转,并且在旋转中控制增量,类似于球形插值。

   (3)第三步:使用Quaternion.LookRotation来改变朝向;

targetRotation = Quaternion.LookRotation(lookForward);

 *Quaternion.LookRotation(Vector3):官方文档翻译过来的解释就是“创建一个旋转,沿着forward(z轴)并且头部沿着upwards(y轴)的约束注视。也就是建立一个旋转,使z轴朝向view y轴朝向up”。看着就很迷……

  通过实验可以基本了解,这个意思就是将物体的前方(forward)按照传入的这个三维向量旋转,最终结果是这个物体看向传入的这个向量,最后返回一个旋转角度。详见解释:Quaternion.LookRotation实现原理_刺子的博客

(4)第四步:使用Rigidbody.MoveRotation()实现旋转。

rb.MoveRotation(targetRotation);

  4. 脚本实现HeroMove

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//对象:主角Hero(需要加载Rigidbody)
//作用:使用RigidBody控制物体移动
//主角的移动方向是主相机的朝向
public class HeroMove : MonoBehaviour
{
    private Rigidbody rb;
    private Vector2 movementInput; //获取横向或纵向的命令坐标
    private Vector3 movement; //移动的坐标位置(将之前的二维坐标转成这里的三维)
    public float moveSpeed = 2f;
    private float rotateSpeed = 3;
    private Quaternion targetRotation;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {   //RigidBody属于物理层调用,主要在FixedUpdate()中
        
        movementInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
        //获取Hero横向和纵向移动的坐标,这个输入由键盘决定
        movement.Set(movementInput.x, 0, movementInput.y); //将获取到的坐标转到三维向量中
        movement.Normalize();   //并且将这个三维向量单位化,得到移动的方向

        //检查横向和纵向是否有输入
        bool hInput = !Mathf.Approximately(movementInput.x, 0);
        bool vInput = !Mathf.Approximately(movementInput.y, 0);

        if(hInput || vInput)
        {   //如果有移动命令,同时还可以获取主相机的旋转位置,获得其绕Y轴的旋转方向
            movement = Quaternion.Euler(0, Camera.main.transform.eulerAngles.y, 0) * movement;
            //四元数和向量相乘可以表示这个向量按照这个四元数进行旋转之后得到的新的向量。
        }

        Vector3 lookForward = Vector3.RotateTowards(transform.forward, movement, rotateSpeed * Time.fixedDeltaTime,360);
        //RotateTowards从当前方向向目标方向旋转
        //这里是Hero的正前方向着目标方向movement旋转,旋转的度数(rotateSpeed * Time.fixedDeltaTime),每次移动的最大角度
        //返回值为transform.forward+每次移动的最大角度
        //当这个值超过movement时,返回movement

        targetRotation = Quaternion.LookRotation(lookForward);//物体的z轴与lookForward对齐
        //得到Hero的Rotation值:targetRotation
        //这个方法配合transform.rotation = Quaternion.LookRotation()使用

        rb.MovePosition(rb.position + movement * speed * Time.fixedDeltaTime);
        //先获取当前位置rb.position,然后使用MovePosition方法移动到目标位置

        rb.MoveRotation(targetRotation);  //实现旋转
    }
}

  补充:1. 加了刚体组件和碰撞器的主角,碰到其他碰撞器很容易摔倒,可以在刚体组件中约束它的X、Z轴不产生旋转

  2. 上一篇的相机跟随,为了让相机移动发生在主角移动之后,特地将相机的移动写在LateUpdate()中,而主角移动因为用到了物理系统的更新,就写在FixedUpdate()中。但它们两个的更新频率是不同的,一个根据逻辑帧的频率,一个是根据真实世界的时间频率,所以这样写会出现移动时卡顿的现象。

  解决办法:将相机跟随也写到FixedUpdate()中。  那么该如何确定哪个脚本先执行呢?可以到Edit->ProjectSetting->ScriptExecutionOrder当中调整执行顺序

  以上为使用Rigidbody组件实现移动的方法,另外在“管理阶层Managers”栏目中,将控制的方式修改为使用新版InputSystem和事件发送来实现,详见EventManager--事件中心3新版InputSystem

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity中实现VR手柄控制移动可以通过以下步骤来完成: 1. 获取手柄输入:首先,你需要获取VR手柄的输入信号。根据你使用的手柄品牌和插件,你可以使用相关的API或插件提供的函数来获取手柄的按键和轴向输入。 2. 设置移动逻辑:在获取手柄输入后,你可以编写代码来处理移动逻辑。你可以使用手柄的摇杆或轨迹球等输入设备来控制移动方向和速度。 3. 应用移动力:根据你的需求,你可以使用Unity中的物理引擎或自定义的移动逻辑来应用力来实现移动效果。例如,你可以使用Rigidbody组件来添加力、速度或位移来控制物体的移动。 4. 更新移动状态:在每一帧更新中,你需要持续地根据手柄输入更新移动状态。这可以通过在Update()函数中获取手柄输入并更新物体的位置或速度来实现。 以下是一个简单的示例代码,展示了如何使用手柄的摇杆输入来控制一个物体的移动: ```csharp using UnityEngine; public class VRMovement : MonoBehaviour { public float moveSpeed = 3f; public Transform vrCamera; public Transform character; private CharacterController characterController; void Start() { characterController = character.GetComponent<CharacterController>(); } void Update() { float moveHorizontal = Input.GetAxis("Horizontal"); float moveVertical = Input.GetAxis("Vertical"); Vector3 moveDirection = new Vector3(moveHorizontal, 0f, moveVertical); moveDirection = vrCamera.TransformDirection(moveDirection); moveDirection.y = 0f; moveDirection.Normalize(); characterController.Move(moveDirection * moveSpeed * Time.deltaTime); } } ``` 在这个示例中,我们使用了Unity的Input类来获取手柄的摇杆输入。然后,我们将输入转换为相对于摄像机的方向,并将其应用于角色控制器的移动。 这只是一个简单的示例,你可以根据自己的需求进行进一步的定制和扩展。希望这可以帮助你开始在Unity中实现VR手柄控制移动

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值