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

Unity移动端角色控制求助:UI按钮/摇杆实现移动与视角旋转

Unity移动端:UI按钮按住持续移动+摇杆控制角色/相机旋转方案

一、UI按钮实现按住持续移动

你之前的代码仅在点击瞬间触发移动,要实现按住持续行走,需通过按钮的按下/抬起事件标记状态,在帧循环里处理移动逻辑:

  1. 编写控制脚本,挂在角色物体上:
using UnityEngine;
using UnityEngine.UI;

public class ButtonMovement : MonoBehaviour
{
    public float moveSpeed = 5f;
    public Button moveForwardButton; // 在Inspector中拖入前进按钮
    private bool isMovingForward = false;

    void Start()
    {
        // 绑定按钮事件(也可在Inspector面板手动绑定)
        moveForwardButton.onPointerDown.AddListener(StartMovingForward);
        moveForwardButton.onPointerUp.AddListener(StopMovingForward);
        moveForwardButton.onPointerExit.AddListener(StopMovingForward); // 防止手指移出按钮后仍持续移动
    }

    void Update()
    {
        if (isMovingForward)
        {
            // 按角色自身前方向移动
            transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
        }
    }

    public void StartMovingForward()
    {
        isMovingForward = true;
    }

    public void StopMovingForward()
    {
        isMovingForward = false;
    }
}
  1. 手动绑定事件(可选):
    选中UI按钮,在Inspector的On Pointer Down()和On Pointer Up()面板中,拖拽角色物体到对象框,选择ButtonMovement脚本下的StartMovingForward和StopMovingForward方法。

二、摇杆控制角色移动(无需过时资源包)

用Unity内置UI系统自制摇杆,步骤如下:

  1. 创建摇杆UI:
  • 新建一个Image作为摇杆背景(圆形),再在其下方创建一个小Image作为摇杆节点(圆形),确保摇杆节点锚点在背景中心。
  1. 编写摇杆控制脚本,挂在摇杆背景上:
using UnityEngine;
using UnityEngine.EventSystems;

public class Joystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
    private RectTransform joystickBg;
    private RectTransform joystickHandle;
    public Vector2 inputDirection { get; private set; } = Vector2.zero;
    public float deadZone = 0.1f; // 死区,避免轻微触摸误触发

    void Awake()
    {
        joystickBg = GetComponent<RectTransform>();
        joystickHandle = transform.GetChild(0).GetComponent<RectTransform>();
    }

    public void OnDrag(PointerEventData eventData)
    {
        Vector2 localPoint;
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(joystickBg, eventData.position, eventData.pressEventCamera, out localPoint))
        {
            // 计算摇杆偏移比例
            localPoint.x = (localPoint.x / joystickBg.sizeDelta.x) * 2;
            localPoint.y = (localPoint.y / joystickBg.sizeDelta.y) * 2;

            inputDirection = new Vector2(localPoint.x, localPoint.y);
            // 限制摇杆范围在单位圆内
            inputDirection = inputDirection.magnitude > 1 ? inputDirection.normalized : inputDirection;

            // 应用死区
            if (inputDirection.magnitude < deadZone)
                inputDirection = Vector2.zero;

            // 更新摇杆节点位置
            joystickHandle.anchoredPosition = new Vector2(inputDirection.x * joystickBg.sizeDelta.x / 2, inputDirection.y * joystickBg.sizeDelta.y / 2);
        }
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        inputDirection = Vector2.zero;
        joystickHandle.anchoredPosition = Vector2.zero;
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        OnDrag(eventData);
    }
}
  1. 角色移动脚本(挂在角色上):
using UnityEngine;

public class JoystickMovement : MonoBehaviour
{
    public Joystick movementJoystick;
    public float moveSpeed = 5f;
    private Camera mainCamera;

    void Start()
    {
        mainCamera = Camera.main;
    }

    void Update()
    {
        if (movementJoystick.inputDirection.magnitude > 0)
        {
            // 将摇杆输入转换为相机视角下的世界空间方向
            Vector3 moveDir = mainCamera.transform.TransformDirection(new Vector3(movementJoystick.inputDirection.x, 0, movementJoystick.inputDirection.y));
            moveDir.y = 0; // 保持水平移动
            moveDir.Normalize();

            transform.Translate(moveDir * moveSpeed * Time.deltaTime, Space.World);
            // 可选:让角色朝向移动方向
            transform.rotation = Quaternion.LookRotation(moveDir);
        }
    }
}

三、摇杆控制相机视角环视

用另一个摇杆控制相机旋转,脚本示例(挂在相机父物体或直接挂在相机):

using UnityEngine;

public class CameraLook : MonoBehaviour
{
    public Joystick lookJoystick;
    public float lookSensitivity = 2f;
    private float xRotation = 0f; // 上下旋转角度,限制范围避免翻转

    void Update()
    {
        if (lookJoystick.inputDirection.magnitude > 0)
        {
            // 左右旋转:控制物体Y轴旋转
            transform.Rotate(Vector3.up * lookJoystick.inputDirection.x * lookSensitivity);

            // 上下旋转:控制相机X轴旋转,限制角度在-60到60度之间
            xRotation -= lookJoystick.inputDirection.y * lookSensitivity;
            xRotation = Mathf.Clamp(xRotation, -60f, 60f);
            Camera.main.transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
        }
    }
}

注意事项

  • 所有移动/旋转逻辑需乘以Time.deltaTime,保证不同帧率下速度一致。
  • 摇杆的deadZone可根据需求调整,优化触摸体验。
  • 若为第三人称视角,可在LateUpdate中添加相机平滑跟随角色的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 12:10:15