【unity 】第一人称角色控制器手机虚拟双摇杆

2023-05-16

1.说明

第一人称角色控制器很常见,unity的标准资源包里也有,但试了一下,那个好像只有摇杆移动方向,无法使用摇杆进行视角旋转,所以我这里还是自己动手实现一个吧。制作两个虚拟摇杆,左边的控制前后左右的运动,右边的控制旋转视角方向。如下动图所示
在这里插入图片描述

2.制作摇杆

我们用图片制作一个摇杆。首先新建一个image,改名为JoyStick-move(创建 image会自动创建一个Canvas),表示一个控制移动的摇杆,再建一个 image 子组件,改名为ViewPort,表示摇杆外面的圈圈,然后再建一个image孙子组件,改名为Content,表示摇杆里面的小圈圈,所以JoyStick-move、ViewPort、Content都是image。然后再把JoyStick-move复制一份得到改名为JoyStick-rotate,表示一个控制视角的摇杆,结构如下
在这里插入图片描述
之后我们分别修改ViewPoint和Content的图片为摇杆应该有的样子,摇杆图片网上搜一下,或者自己用PS做一个 ,反正也就是两个圈圈。

我们可以给JoyStick-move添加一个ScrollRect组件就可以实现摇杆的拖拽效果了,但拖拽区域是一个矩形,我们最好改为圆形,所以我们可以写一个脚本ScrollCircle继承于ScrollRect

ScrollCircle.cs

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;
    // Start is called before the first frame update
    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);
        }
    }

    // Update is called once per frame
    void Update()
    {
        output = content.localPosition / radius;
    }
}

把ScrollCircle.cs拖给JoyStick-move,然后再把我们的ViewPort和Content对象分别拖给ScrollCircle.cs的Viewport和Content属性。不出意外的话就可以使用该摇杆了,自己调整好位置,大概截图(截图的箭头指向属性,但实际上要拖到属性右边的输入框)
在这里插入图片描述

3.第一人称角色控制器

老规矩,使用一个capsule当主角,首先创建一个空对象,改名为FPSPlayer,然后创建一个Capsule和 一个Camera当做FPSPlayer的子物体,结构如下
在这里插入图片描述
我们还需要给FPSPlayer增加一个CharacterController组件,这样才能更好地控制人物。
接下来要做的是写移动脚本和旋转视角的脚本,分别取名为MoveScript.cs和RotateScript.cs。内容如下

MoveScript.cs

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

public class MoveScript : MonoBehaviour
{

    public ScrollCircle scroll;  // 摇杆对象
    public CharacterController PlayerController;  // 角色控制器
    public float MoveSpeed = 10f; // 移动速度
    public Vector3 MoveVec3;
    private float horizontal;
    private float vertical;
    private float gravity = 9.8f;
    public float JumpSpeed = 15f;

    void Start()
    {
    }

    void Update()
    {

        if (PlayerController.isGrounded)
        {   
            // 键盘输入
            // horizontal = Input.GetAxis("Horizontal");
            // vertical = Input.GetAxis("Vertical");

            // 摇杆输入
            horizontal = scroll.output.x;
            vertical = scroll.output.y;

            MoveVec3 = (transform.forward * vertical + transform.right * horizontal) * MoveSpeed;

            //判断玩家是否按下空格键
            if (Input.GetAxis("Jump") == 1)
            {
                MoveVec3.y = MoveVec3.y + JumpSpeed;
            }
        }

        MoveVec3.y = MoveVec3.y - gravity * Time.deltaTime;
        PlayerController.Move(MoveVec3 * Time.deltaTime);
    }
}

RotateScript.cs

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

public class RotateScript : MonoBehaviour
{
    void Start()
    {
        // player = GameObject.Find("Capsule");
    }

    public ScrollCircle scroll; // 摇杆对象
    public Transform RotationTarget;  // 被旋转对象

    private float rotateX;
    private float rotateY;

    public float RotateSensitivity = 50f;

    public float xRotation;

    // Update is called once per frame
    void Update()
    {
        // 鼠标
        // rotateX = Input.GetAxis("Mouse X") * RotateSensitivity * Time.deltaTime;
        // rotateY = Input.GetAxis("Mouse Y") * RotateSensitivity * Time.deltaTime;

        // 摇杆
        rotateX = scroll.output.x * RotateSensitivity * Time.deltaTime;
        rotateY = scroll.output.y * RotateSensitivity * Time.deltaTime;

        xRotation = xRotation - rotateY;

        xRotation = Mathf.Clamp(xRotation, -90f, 90f);
        RotationTarget.Rotate(Vector3.up * rotateX);
        this.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
    }
}

把MoveScript.cs拖给FPSPlayer,把RotateScript.cs拖给Camera,然后给变量赋一下值,如下截图
在这里插入图片描述
在这里插入图片描述

不出意外的话现在已经可以使用摇杆控制了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【unity 】第一人称角色控制器手机虚拟双摇杆 的相关文章

随机推荐