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

Posted 冰冷的希望

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity 第一人称角色控制器手机虚拟双摇杆相关的知识,希望对你有一定的参考价值。

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,然后给变量赋一下值,如下截图

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

UnityPico手柄摇杆控制第一人称移动和旋转

【Unity】【Pico】手柄摇杆控制第一人称移动和旋转

背景:开发影院系统

环境:Unity2021.3、PicoNeo3ProEye

描述:已经在Unity项目中实现第一人称WASD移动和鼠标旋转(代码见我的其他博文)

需求:希望项目在Pico一体机运行时可以通过手柄摇杆控制(unityxr的基础配置见我的其他博文)

解决

  1. Locomotion System
    • XR Origin
  2. Continuous Move Provider(Action-based)
    • System
    • Move Speed:注意速度过小会导致看起来没有移动
    • RightHandMoveAction(right loco move):个人采用右手柄实现移动
  3. Continuous Turn Provider(Action-based)
    • System
    • LeftHandTurnAction(left loco turn):个人采用左手柄实现移旋转

如有帮助,麻烦动动手指点一下赞,感谢!

以上是关于unity 第一人称角色控制器手机虚拟双摇杆的主要内容,如果未能解决你的问题,请参考以下文章

游戏开发实战Unity手游第一人称视角,双摇杆控制,FPS射击游戏Demo(教程 | 含Demo工程源码)

unity虚拟摇杆

UnityPico手柄摇杆控制第一人称移动和旋转

unity第一人称控制器脚步声在哪

unity人物第一人称视角制作角色身体遮挡主镜头去掉方法,用VFX自制子弹拖尾效果。

Unity中的虚拟摇杆,用于触屏游戏的角色移动控制