摄像机旋转,视距调节,第一/第三人称控制器可切换

这篇博客详细介绍了如何在Unity3D中创建一个第一人称控制器,包括玩家的移动、旋转、跳跃以及相机的跟随和旋转。同时,还实现了一个防止相机穿模的功能,确保相机在移动时不穿过场景中的物体。此外,博客还涵盖了相机视野缩放和第一、第三人称视角切换的实现。
摘要由CSDN通过智能技术生成

摄像机位置自己看着摆放

Camera 跟随player

MainCameraModeilocationRecord 是空物体放在MaiCamera 同一位置

head 是头部放在你认为的第一人称视角的地方

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 玩家控制器 
/// </summary>
public class PlayerController : MonoBehaviour
{
    [Header("切换第一人称")]
    [Tooltip("切换第一人称时为true")]
    public bool FirstPersonExchange = false;
    [Tooltip("记录摄像机第三人称的位置")]
    public Transform MainCameraModelLocationRecord;
    [Tooltip("第一人称摄像机的位置")]
    public Transform Head;

    [Header("玩家的移动和旋转参数")]
    [Tooltip("走路速度")]
    public float WalkingSpeed = 3;
    [Tooltip("跑步速度")]
    public float RunningSpeed = 5;

    [Header("玩家的自身旋转和位置")]
    [Tooltip("玩家自身旋转速度")]
    public float PlayerRotationSpeed = 10;
    [Tooltip("人物位置")]
    public Transform PlayerModelsTransform;
    [Tooltip("位置输入")]
    private Vector3 _moveDirection = Vector3.zero;

    [Header("重力和跳跃的参数")]
    [Tooltip("是否接地")]
    public bool GroundCheck ;
    [Tooltip("重力")]
    public float Gravity = -15f;
    [Tooltip("跳跃的力")]
    public float JunpHeiqht = 5;

    [Header("相机的旋转参数")]
    [Tooltip("相机旋转速度")]
    public float CameraRotationSpeed = 2;
    [Tooltip("第三人称向上下看的范围")]
    public float CameraRotationX = 30;
    [Tooltip("第一人称向上下看的范围")]
    public float FirstPersonCameraRotationX = 45;

    [Header("相机的位置信息")]
    [Tooltip("相机的父物体")]
    public GameObject CameraFather;
    [Tooltip("相机的模型")]
    public GameObject MainCameraModel;

    [Header("相机视野大小")]
    [Tooltip("视野最大值")]
    public float MaxFieldOfView = 100;
    [Tooltip("视野最小值")]
    public float MinFieldOfView = 10;


    [Tooltip("判断是否按下键盘按键")]
    private bool _isKeyboard = false;

    [Tooltip("穿模物体储存")]
    private    List<MeshRenderer> _mesList = new List<MeshRenderer>();
    [Tooltip("是否开启第三人称")]
    private bool _isViewingAngleSwitching = false;
    [Tooltip("不跳跃时Y的值")]
    private float _Dontjump = 0;
    [Tooltip("角色控制器")]
    private CharacterController _characterController;
    void Start()
    {
        _characterController = transform.GetComponent<CharacterController>();

    }

    void Update()
    {
        Move();
        CameraRotation();
        Zoom();
        if (!FirstPersonExchange)
            CameraOcclusion();
    }
    /// <summary>
    /// 相机不穿模
    /// </summary>
    private void CameraOcclusion()
    {

        Vector3 CameraPointing = transform.position - MainCameraModel.transform.position;//相机到人物的向量
        Ray CameraRay = new Ray(MainCameraModel.transform.position, CameraPointing);
        RaycastHit hitInfo;
        if (Physics.Raycast(CameraRay, out hitInfo))
        {

            if (hitInfo.collider.tag != "Player")
            {
                _mesList.Add(hitInfo.collider.gameObject.GetComponent<MeshRenderer>());
                hitInfo.collider.gameObject.GetComponent<MeshRenderer>().enabled = false;

            }
            else
            {
                foreach (var item in _mesList)
                {
                    item.enabled = true;
                }
                _mesList.Clear();
            }

        }

    }

    /// <summary>
    /// 运动
    /// </summary>
    private void Move()
    {

        WalkingSpeed = Input.GetKey(KeyCode.LeftShift) ? RunningSpeed : 2.0f;//加速
        if (GroundCheck)//跳跃
        { 
            _Dontjump = Input.GetKeyDown(KeyCode.Space) ? JunpHeiqht : _Dontjump;
            GroundCheck = false;
        }
        if (_characterController.isGrounded)
        {
            GroundCheck = true;
        }
        float _hprizontal = Input.GetAxis("Horizontal");
        float _vertical = Input.GetAxis("Vertical");

        _moveDirection = new Vector3(_hprizontal * WalkingSpeed, _Dontjump, _vertical * WalkingSpeed);
        _moveDirection = transform.TransformDirection(_moveDirection);

        _Dontjump += Gravity * Time.deltaTime;//重力
        _characterController.Move(_moveDirection * Time.deltaTime);

        Vector3 _movement = Vector3.zero;
        _movement = transform.forward * _vertical + transform.right * _hprizontal;
        _isKeyboard = _movement == Vector3.zero ? _isKeyboard : true;//判断是否有按键输入
        if (_isKeyboard && !FirstPersonExchange)//人物自身旋转
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, CameraFather.transform.rotation, 0.15f);
            Quaternion PlayerModelsRotation = Quaternion.LookRotation(_movement);
            PlayerModelsTransform.rotation = Quaternion.Lerp(PlayerModelsTransform.rotation, PlayerModelsRotation, Time.deltaTime * PlayerRotationSpeed);
            _isKeyboard = false;
        }

        if (FirstPersonExchange)//第一人称相机位置
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, CameraFather.transform.rotation, 0.15f);
            PlayerModelsTransform.rotation = transform.rotation;
            MainCameraModel.transform.position = Head.position;
            _isViewingAngleSwitching = true;
        }

        else if (_isViewingAngleSwitching)//第三人称相机位置
        {
            MainCameraModel.transform.position = MainCameraModelLocationRecord.position;
            MainCameraModel.transform.rotation = MainCameraModelLocationRecord.rotation;
            _isViewingAngleSwitching = false;
        }

    }
    /// <summary>
    /// 相机旋转
    /// </summary>
    private void CameraRotation()
    {
        CameraRotationX = FirstPersonExchange ? FirstPersonCameraRotationX : 30;//第一和第三人称角度切换

        CameraFather.transform.position = transform.position;//相机跟随
        if (Input.GetMouseButton(1))
        {
            float cameraX = Input.GetAxis("Mouse X");
            float cameraY = Input.GetAxis("Mouse Y");
            if (cameraX != 0)//相机x轴旋转
            {
                CameraFather.transform.Rotate(Vector3.up, cameraX * 120 * CameraRotationSpeed * Time.deltaTime);
                if (FirstPersonExchange)
                    transform.Rotate(Vector3.up, cameraX * 120 * CameraRotationSpeed * Time.deltaTime);
            }
            if (cameraY != 0)//相机Y轴旋转
            {
                MainCameraModel.transform.Rotate(Vector3.left, cameraY * 120 * CameraRotationSpeed * Time.deltaTime);
            }

            if (Vector3.Angle(CameraFather.transform.forward, MainCameraModel.transform.forward) > CameraRotationX)//上下视角约束
            {
                MainCameraModel.transform.Rotate(Vector3.left, -cameraY * 120 * CameraRotationSpeed * Time.deltaTime);
            }


        }

    }
    /// <summary>
    /// 视距选择
    /// </summary>
    private void Zoom()
    {
        float camerazoom = Input.GetAxis("Mouse ScrollWheel");//鼠标滑轮
        if (camerazoom < 0)
        {
            if (Camera.main.fieldOfView <= MaxFieldOfView)
            {
                Camera.main.fieldOfView += 2;
            }
            if (Camera.main.orthographicSize <= 20)
            {
                Camera.main.orthographicSize += 0.5f;
            }
        }
        if (camerazoom > 0)
        {
            if (Camera.main.fieldOfView >= MinFieldOfView)
            {
                Camera.main.fieldOfView -= 2;
            }
            if (Camera.main.orthographicSize >= 5)
            {
                Camera.main.orthographicSize -= 0.5f;
            }
        }
    }
}
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值