You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity虚拟摇杆控制角色移动适配相机旋转问题排查

问题分析与修复方案

先帮你拆解两个尝试代码里的问题,以及给出正确的实现方式:

第一个代码片段的问题(速度异常+逻辑优化点)

你的核心思路是对的——根据相机旋转角度修正移动方向,但有两个细节没处理好,会引发速度异常:

  1. 未归一化输入方向:当摇杆推到对角线位置时,inputDirection的模长会大于1(比如x=1,z=1时,模长是√2≈1.414),这会让角色移动速度超出你设置的speed值,看起来比预期快很多。
  2. 在Update中处理刚体移动:Unity的物理更新是在FixedUpdate中进行的,在Update里直接修改Rigidbody.velocity会导致物理行为不稳定,尤其是帧率波动时。

第二个代码片段的致命错误

这段代码的问题非常明显,直接导致了移动速度爆炸:

var Direction = transform.position += new Vector3(xMovement, 0f,zMovement);
Vector3 newDir = MainCam.transform.TransformDirection(Direction);
transform.position += new Vector3(newDir.x, 0f,newDir.z) * speed * Time.deltaTime;
  • transform.position += ...是直接修改角色位置,然后把这个世界位置坐标传给TransformDirection——这个方法的作用是把局部空间的方向向量转换为世界空间方向,你传入一个超大的位置值,会得到一个极其巨大的方向向量,再乘以speed和时间,瞬间让角色位置飞到无限远,导致Unity失去响应。

修正后的完整代码

下面是整合了正确逻辑的代码,解决了方向适配和速度异常的问题:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using EasyJoystick;

public class NewJoystick : MonoBehaviour
{
    [SerializeField] private float speed;
    [SerializeField] private Joystick1 joystick;
    [SerializeField] private Camera mainCam;
    private Rigidbody rb;
    private Transform cameraTransform;

    void Awake()
    {
        rb = GetComponent<Rigidbody>();
        cameraTransform = mainCam.transform;
    }

    // 刚体移动放在FixedUpdate中处理,保证物理行为稳定
    void FixedUpdate()
    {
        float xMovement = joystick.Horizontal();
        float zMovement = joystick.Vertical();

        Vector3 inputDirection = new Vector3(xMovement, 0, zMovement);
        
        // 归一化输入方向,避免对角线速度过快
        if (inputDirection.magnitude > 1f)
        {
            inputDirection.Normalize();
        }

        // 获取相机的水平旋转(忽略Y轴,只保留水平方向的旋转)
        Quaternion cameraHorizontalRot = Quaternion.Euler(0, cameraTransform.eulerAngles.y, 0);
        // 将输入方向转换为相机朝向的世界空间方向
        Vector3 moveDirection = cameraHorizontalRot * inputDirection;

        // 设置刚体速度,这里不需要Time.deltaTime,因为velocity本身是基于物理时间步长的
        rb.velocity = new Vector3(moveDirection.x * speed, rb.velocity.y, moveDirection.z * speed);
    }
}

关键说明

  1. 归一化输入方向:确保无论摇杆推到哪个方向,角色的移动速度都是你设置的speed值,不会出现对角线加速的情况。
  2. 使用FixedUpdate处理刚体:让物理更新和Unity的物理引擎同步,避免帧率波动带来的移动不稳定。
  3. 简化相机旋转计算:直接用相机的Y轴欧拉角创建旋转四元数,比计算SignedAngle更简洁高效,逻辑也更清晰。
  4. 保留刚体的Y轴速度:如果你的角色有跳跃或下落需求,不要覆盖Y轴的速度,否则会破坏重力等物理效果。

内容的提问来源于stack exchange,提问作者Luke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 22:38:14