unity Camera第一人称移动

简介: 第一人称视角移动模拟通过检测用户键盘和鼠标输入,实现场景中的位置移动和视角旋转。位置移动基于W、A、S、D键控制相机前后左右移动,视角旋转通过鼠标控制上下左右观察,避免翻转并限制旋转角度。代码使用Unity的Input类和Transform方法实现这些功能,确保流畅的第一人称体验。

基本原理概述

第一人称视角移动模拟的是玩家以自身视角在场景中移动和观察的体验。主要包含两个核心部分:
位置移动:根据用户的输入(如 W、A、S、D 键),在三维空间中改变相机的位置,实现前后左右移动。
视角旋转:根据鼠标的移动,改变相机的旋转角度,实现上下左右观察。

具体实现原理和步骤

  1. 位置移动
    输入检测:通过Input类检测用户的按键输入。在 Unity 中,可以使用Input.GetAxis方法获取水平(Horizontal)和垂直(Vertical)方向的输入值,这些输入值通常是由键盘的 W、A、S、D 键或方向键控制的。
    移动计算:根据输入值和移动速度,计算相机在当前帧需要移动的距离。移动方向通常基于相机的本地坐标系,即前后移动沿着相机的 Z 轴,左右移动沿着相机的 X 轴。
    位置更新:将计算得到的移动距离添加到相机的当前位置上,使用transform.Translate方法实现相机位置的更新。
  2. 视角旋转
    鼠标输入检测:使用Input.GetAxis方法获取鼠标的水平(Mouse X)和垂直(Mouse Y)移动值。
    旋转计算:根据鼠标的移动值和旋转速度,计算相机在当前帧需要旋转的角度。通常,鼠标的水平移动控制相机绕 Y 轴旋转(左右观察),垂直移动控制相机绕 X 轴旋转(上下观察)。
    旋转限制:为了避免相机在上下观察时出现翻转的情况,需要对相机绕 X 轴的旋转角度进行限制,通常将其限制在一个合理的范围内(如 -90° 到 90°)。
    旋转更新:使用transform.Rotate或直接修改transform.eulerAngles来更新相机的旋转角度。

代码如下:

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

public class Player : MonoBehaviour {
    public GameObject CapsulePlayer, MainCamerahead;
    private float aixsX, aixsY, mouseScroll;
    private int moveSpeed;
    private int standardMoveSpeed = 600;
    private int runMoveSpeed = 1000;
    private int mouseScrollSpeed = 10;
    private float mouseScrolbackSpeed = 0.05f;
    private CharacterController charaControl;
    private Camera charaCam;
    public float mouseNumOne = 0, mouseNumTwo = 0;   
    public static bool chufa = false;
    void Awake()
    {
        charaControl = GetComponent<CharacterController>();
        charaCam = MainCamerahead.GetComponent<Camera>();
    }
    void Update()
    {
        aixsX = Input.GetAxis("Horizontal");
        aixsY = Input.GetAxis("Vertical");
        mouseScroll = Input.GetAxis("Mouse ScrollWheel");
        if (Input.GetKey(KeyCode.LeftShift))
        {
            moveSpeed = runMoveSpeed;
        }
        else
        {
            moveSpeed = standardMoveSpeed;
        }

        charaControl.SimpleMove(transform.forward * moveSpeed * aixsY * 0.02f + transform.right * moveSpeed * aixsX * 0.02f);

        /* ***********************镜头跟随鼠标移动的第一种方法**********************
        float mousex = Input.GetAxis("Mouse X") * 2f;
        float mousey = Input.GetAxis("Mouse Y") * 2f;
        if (mousex > 180)
        {
            mousex = 180;
        }
        else if (mousex < -180)
        {
            mousex = -180;
        }
        if (Mathf.Abs(mousey) < 120f)
        {
            MainCamerahead.transform.localRotation = charaCam.transform.localRotation * Quaternion.Euler(-mousey, 0, 0);
            CapsulePlayer.transform.localRotation = transform.localRotation * Quaternion.Euler(0, mousex, 0);
        }
      */

              //镜头跟随鼠标移动的第二种写法    (总之写法有很多,自己用着舒服就行)
          if (chufa )
        {
            mouseNumOne += Input.GetAxis("Mouse Y");
            mouseNumTwo += Input.GetAxis("Mouse X");
            if (mouseNumOne > 180)
            {
                mouseNumOne = 180;
            }
            else if (mouseNumOne < -180)
            {
                mouseNumOne = -180;
            }
            if (Mathf.Abs(mouseNumOne) < 90f)
            {
                MainCamerahead.transform.Rotate(new Vector3(-1 * Input.GetAxis("Mouse Y"), 0, 0));
                CapsulePlayer.transform.Rotate(0, 1.6f * Input.GetAxis("Mouse X"), 0);
            }
        }
        else
        {
           //鼠标滑动镜头跟着滑动
            if (Input.GetMouseButton(0))
            {
                mouseNumOne += Input.GetAxis("Mouse Y");
                mouseNumTwo += Input.GetAxis("Mouse X");
                if (mouseNumOne > 180)
                {
                    mouseNumOne = 180;
                }
                else if (mouseNumOne < -180)
                {
                    mouseNumOne = -180;
                }
                if (Mathf.Abs(mouseNumOne) < 90f)
                {
                    MainCamerahead.transform.Rotate(new Vector3(-1 * Input.GetAxis("Mouse Y"), 0, 0));
                    CapsulePlayer.transform.Rotate(0, 1.6f * Input.GetAxis("Mouse X"), 0);
                }
            }
        }


        //放大缩小功能

        if (charaCam.fieldOfView > 60)
        {
            charaCam.fieldOfView -= mouseScrolbackSpeed;
        }
        else if (charaCam.fieldOfView < 10)
        {
            charaCam.fieldOfView += mouseScrolbackSpeed;
        }
        else
        {
            charaCam.fieldOfView -= mouseScroll * mouseScrollSpeed;
        }
    }
}
相关文章
|
9月前
|
图形学
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
137 0
|
9月前
|
图形学
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇2(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇2(附项目源码)
171 0
|
9月前
|
定位技术 图形学 开发者
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)
252 0
|
编解码 图形学 Android开发
Unity环境下实现Camera高帧率RTMP推送
Unity下RTMP直播背景方面不再赘述,今天主要讨论的是,Unity环境下,如何实现Camera高帧率RTMP推送,这里提到的高帧率,不再局限于常规环境下的30帧,以VR头显为例,更高的帧率(比如50帧),体验会更好。
151 1
Unity环境下实现Camera高帧率RTMP推送
|
编译器 图形学 开发者
Unity例子——第一人称视角的角色控制器
Unity例子——第一人称视角的角色控制器
278 0
|
编解码 监控 vr&ar
Unity3D下如何采集camera场景数据并推送RTMP服务?
Unity3D是非常流行的游戏开发引擎,可以创建各种类型的3D和2D游戏或其他互动应用程序。常见使用场景如下:
171 1
|
数据采集 vr&ar 图形学
Windows平台Unity Camera场景实现轻量级RTSP服务和RTMP推送
随着VR技术在医疗、军事、农业、学校、景区、消防、公共安全、研学机构、展厅展馆,商场等场所普及,开发者对Unity平台下的直播体验提出了更高的要求。
133 0
|
数据采集 编解码 图形学
Unity实现Camera和Audio数据的低延迟RTMP推送技术探讨
关于Unity实现RTMP直播推送技术方案,之前零散的写过几篇介绍,得到了好多开发者的关注。以Android平台为例,目前视频这块,我们demo实现的是Camera数据的采集,然后编码投递到底层,如果设备没有性能瓶颈,可达到高帧率(60帧)均匀的RTMP推送效果。
121 0
|
数据采集 算法 数据可视化
Unity实现camera数据注入RMP推送或轻量级RTSP服务模块
Unity实现camera数据注入RMP推送或轻量级RTSP服务模块
147 0
|
图形学
Unity3D——第一人称FPS生存游戏(resident zombies)
Unity3D——第一人称FPS生存游戏(resident zombies)