Unity摇杆+键鼠控制位移、旋转

1、位移

首先我们找到两张图片,一个大圆一个小圆,像这样:

结构是这样的:

然后,新建一个场景,用胶囊去做玩家,摄像机在胶囊下,并且在场景中放两个cube作为参照物

像这样搭好后,我们编写脚本,用ScrollRect去实现摇杆,新建ScrollCircle.cs脚本,继承ScrollRect:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class ScrollCircle : ScrollRect
{
    float radius = 0;
    public Vector2 output;
    void Start()
    {
        output = new Vector2();
        radius = (transform as RectTransform).rect.size.x * 0.5f;
    }

    public override void OnDrag(PointerEventData eventData)
    {
        base.OnDrag(eventData);
        Vector2 pos = content.anchoredPosition;
        if (pos.magnitude > radius)
        {
            pos = pos.normalized * radius;
            SetContentAnchoredPosition(pos);
        }
    }
    public override void OnEndDrag(PointerEventData eventData)
    {
        base.OnEndDrag(eventData);
        content.localPosition = Vector3.zero;
        
    }
    void Update()
    {
        output = content.localPosition / radius;
    }

   
}

编写完后,将脚本挂在交互区,然后参数按这样设置:

设置完后我们运行场景,会发现摇杆已经做好了,同时,我们开始编写位移等脚本,位移脚本也很简单,只需要把ScrollCircle里的output值拿到就行,新建脚本MoveScript.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

public class MoveScript : MonoBehaviour
{
    public ScrollCircle scroll;  
    public Transform Player;  
    public float MoveSpeed = 10f; 
    public Vector3 MoveVec3;
    private float horizontal;
    private float vertical;
    void Update()
    {
        if (Input.touchCount == 0)
        {
            // 键盘输入
            horizontal = Input.GetAxis("Horizontal");
            vertical = Input.GetAxis("Vertical");
        }
        else
        {
            scroll.gameObject.SetActive(true);
            // 摇杆输入
            horizontal = scroll.output.x;
            vertical = scroll.output.y;
        }
        Vector3 moveVector = new Vector3(horizontal, 0f, vertical) * MoveSpeed * Time.deltaTime;
        Player.Translate(moveVector);
    }
}

将位移MoveScript脚本挂在Player上,并且像我这样设置

这时候运行场景会发现摇杆没用,其实这不是摇杆没用,只是我们脚本写了限制条件,只有手指才能触发摇杆,如果有不需要这个判定的可以删除

但是这时候我们又想测试怎么办,很简单,我们找到game下拉框,选择Simulator

窗口就会变成这样:

然后选择你想测试的机型

选择好后再运行场景,会发现我们的摇杆有用了,还记得我们的MoveScript脚本吗,里面我们写了两个交互,一个是摇杆,一个是键盘控制,当我们的视图选择了Simulator后,能够生效的只有摇杆,因为这个是模拟手机的过程,当我们视图选择Game后,我们则回到了键盘控制,这时按下wasd才会生效

2、旋转

新建RotateScript脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class RotateScript : MonoBehaviour
{
    public float rotationSpeed = 1f;
    private Vector2 lastTouchPosition;
    [SerializeField] ScrollCircle ScrollCircle;
    private void Update()
    {

        if (Input.touchCount == 0)
        {
            //鼠标的旋转
        }
        else
        {
            Rotaes2();
        }
    }
    /// <summary>
    /// 摇杆旋转
    /// </summary>
    void Rotaes()
    {
        float x = ScrollCircle.output.x;
        float xRotationAngle = x * 50 * Time.deltaTime;
        Vector3 xRotationAxis = transform.up;
        transform.Rotate(xRotationAxis, xRotationAngle, Space.World);
    }

    /// <summary>
    /// 手指旋转
    /// </summary>
    void Rotaes2()
    {
        Touch touch;
        if (Input.touchCount == 1)
        {
            touch = Input.GetTouch(0);
        }
        else
        {
            touch = Input.GetTouch(Input.touchCount - 1);
        }
        if (touch.phase == TouchPhase.Began)
        {
            lastTouchPosition = touch.position;
        }
        else if (touch.phase == TouchPhase.Moved)
        {
            Vector2 delta = touch.position - lastTouchPosition;
            transform.Rotate(Vector3.up, delta.x * rotationSpeed, Space.World);
            lastTouchPosition = touch.position;
        }
    }
}

然后我们将脚本拖给Player

运行场景时,我们成功了,修改场景,将摇杆复制一份出来,作为旋转的摇杆:

打开RotateScript脚本,将方法修改一下

然后把旋转摇杆拖给RotateScript脚本

运行场景,我们的摇杆也有用了,这两者的共存本文暂时不写,因为涉及UI交互的判定,需要根据实际情况去修改

接下来我们把鼠标旋转给补上,修改RotateScript脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class RotateScript : MonoBehaviour
{
    public float rotationSpeed = 1f;
    private Vector2 lastTouchPosition;
    [SerializeField] ScrollCircle ScrollCircle;
    private void Update()
    {

        if (Input.touchCount == 0)
        {
            //鼠标的旋转
            MouseRotate();
        }
        else
        {
            Rotaes();
        }
    }
    void MouseRotate()
    {
        if (Input.GetMouseButton(0))
        {
            float mouseX = Input.GetAxis("Mouse X");
            float mouseY = Input.GetAxis("Mouse Y");
            float xRotationAngle = mouseX * rotationSpeed;
            float yRotationAngle = mouseY * rotationSpeed;
            transform.Rotate(Vector3.up, xRotationAngle, Space.World);
            transform.Rotate(Vector3.right, -yRotationAngle, Space.Self);
        }
    }
    /// <summary>
    /// 摇杆旋转
    /// </summary>
    void Rotaes()
    {
        float x = ScrollCircle.output.x;
        float xRotationAngle = x * 50 * Time.deltaTime;
        Vector3 xRotationAxis = transform.up;
        transform.Rotate(xRotationAxis, xRotationAngle, Space.World);
    }

    /// <summary>
    /// 手指旋转
    /// </summary>
    void Rotaes2()
    {
        Touch touch;
        if (Input.touchCount == 1)
        {
            touch = Input.GetTouch(0);
        }
        else
        {
            touch = Input.GetTouch(Input.touchCount - 1);
        }
        if (touch.phase == TouchPhase.Began)
        {
            lastTouchPosition = touch.position;
        }
        else if (touch.phase == TouchPhase.Moved)
        {
            Vector2 delta = touch.position - lastTouchPosition;
            transform.Rotate(Vector3.up, delta.x * rotationSpeed, Space.World);
            lastTouchPosition = touch.position;
        }
    }
}

 回到场景中,将视图切换为Game,运行

至此,本文结束,我们下次见! 

  • 9
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Unity 中实现摇杆可以通过自定义 UI 组件来实现。以下是一个简单的摇杆实现的代码示例: 1. 首先创建一个新的 UI 组件,将该组件命名为 `Joystick`。 2. 在 `Joystick` 组件中创建两个子对象,分别命名为 `Background` 和 `Handle`。 3. 为 `Background` 对象添加一个 `Image` 组件,用于显示摇杆的背景图像。并调整该组件的大小、颜色和透明度等属性。 4. 为 `Handle` 对象添加一个 `Image` 组件,用于显示摇杆的操纵杆图像。并调整该组件的大小、颜色和透明度等属性。 5. 在 `Joystick` 组件中创建一个新的脚本文件,将该文件命名为 `JoystickController`。 6. 在 `JoystickController` 脚本中定义以下变量: ```csharp using UnityEngine; using UnityEngine.EventSystems; public class JoystickController : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler { [SerializeField] private RectTransform joystickBackground; [SerializeField] private RectTransform joystickHandle; private Vector2 joystickDirection = Vector2.zero; private float joystickRadius; public Vector2 JoystickDirection { get { return joystickDirection; } } void Start() { joystickRadius = joystickBackground.rect.width / 2f; } public void OnDrag(PointerEventData eventData) { Vector2 joystickPosition = Vector2.zero; RectTransformUtility.ScreenPointToLocalPointInRectangle(joystickBackground, eventData.position, eventData.pressEventCamera, out joystickPosition); joystickPosition.x = joystickPosition.x / joystickRadius; joystickPosition.y = joystickPosition.y / joystickRadius; joystickDirection = joystickPosition.magnitude > 1f ? joystickPosition.normalized : joystickPosition; joystickHandle.anchoredPosition = new Vector2(joystickDirection.x * joystickRadius, joystickDirection.y * joystickRadius); } public void OnPointerDown(PointerEventData eventData) { OnDrag(eventData); } public void OnPointerUp(PointerEventData eventData) { joystickDirection = Vector2.zero; joystickHandle.anchoredPosition = Vector2.zero; } } ``` 在该代码中,我们首先定义了两个私有变量 `joystickBackground` 和 `joystickHandle`,分别用于存储摇杆背景和操纵杆的 `RectTransform` 组件。并定义了一个私有变量 `joystickDirection`,用于存储摇杆的方向向量。 我们还定义了一个公共属性 `JoystickDirection`,用于获取摇杆的方向向量。 在 `Start` 方法中,我们计算出摇杆背景的半径(即操纵杆可以移动的最大半径)。 在 `OnDrag` 方法中,我们使用 `RectTransformUtility.ScreenPointToLocalPointInRectangle` 方法将屏幕坐标转换为本地坐标,并根据摇杆背景的半径计算出操纵杆的位置。然后,我们将操纵杆的位置向量归一化,并将其赋值给 `joystickDirection` 变量。最后,我们将操纵杆的位置设置为摇杆背景的局部坐标。 在 `OnPointerDown` 方法中,我们调用 `OnDrag` 方法来处理摇杆的拖动事件。 在 `OnPointerUp` 方法中,我们将 `joystickDirection` 变量重置为零向量,并将操纵杆的位置设置为原点,实现摇杆的复位操作。 7. 将 `JoystickController` 脚本挂载到 `Joystick` 组件上,并将 `joystickBackground` 和 `joystickHandle` 变量分别绑定到 `Background` 和 `Handle` 对象的 `RectTransform` 组件上。 8. 在需要使用摇杆的地方,可以通过以下代码来获取摇杆的方向向量: ```csharp using UnityEngine; public class PlayerController : MonoBehaviour { [SerializeField] private JoystickController joystick; [SerializeField] private float speed; void Update() { Vector2 direction = joystick.JoystickDirection; transform.Translate(new Vector3(direction.x, 0f, direction.y) * speed * Time.deltaTime); } } ``` 在该代码中,我们首先定义了一个私有变量 `joystick`,用于存储摇杆的 `JoystickController` 组件。并定义了一个公共变量 `speed`,用于控制玩家移动的速度。 在 `Update` 方法中,我们获取摇杆的方向向量,并使用该向量来控制玩家的移动方向和速度。具体来说,我们将摇杆的方向向量的 `x` 和 `y` 值分别作为玩家在水平和垂直方向上的移动速度。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

故渊9527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值