黑魂向project制作学习二:Camera Handler(主摄像头跟随人物且旋转)

一、创建摄像头控制器对象(Create the camera handler object)

①创建Camera Holder这个emptyobj,在其下面再创建Camera Pivot, 把主摄像头拖到Camera Pivot下面
在这里插入图片描述
②右键创建脚本CameraHandler.cs
在这里插入图片描述

二、给摄像头控制器对象写脚本 (SCRIPTING the camera handler object)

1)cameraHandler.cs

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

namespace SG
{
    
    
    public class CameraHandler : MonoBehaviour
    {
    
    
        //摄像头即将要到达的坐标
        public Transform targetTransform;

        //摄像头真正的实时坐标
        public Transform cameraTransform;

        //this is how camera is going to turn on a swivel(转向),make camera rotate,rotate around the pivot
        //让摄像机绕pivot旋转的坐标
        public Transform cameraPivotTransform;

        //人物坐标
        private Transform myTransform;

        //摄像头的坐标
        private Vector3 cameraTrasnformPositon;
        
        //用于摄像头碰撞的bit位
        private LayerMask ignoreLayers;

        public static CameraHandler singleton;

        //初始化默认值
        public float lookSpeed = 0.1f;
        public float followSpeed = 0.1f; 
        public float pivotSpeed = 0.03f;

        //默认摄像头的z轴坐标
        private float defaultPosition; 
        private float lookAngle;
        private float pivotAngle;
        public float minimimPivot = -35;
        public float maximumPivot = 35;



        public void Awake()
        {
    
    
            singleton = this;
            //Application.targetFrameRate = 60;

            //自己坐标就是人物的坐标
            myTransform = transform;
            defaultPosition = cameraTransform.localPosition.z;
            //下节课将更多摄像头和环境忽略的layer碰撞
            ignoreLayers = ~(1 << 8 | 1 << 9 | 1 << 10);
        }

        //will be used on update, 意味着每帧都会调用,让摄像头去跟随targettransform的top position(z轴顶部位置),也就是让摄像头跟着人走 
        public void FollowTarget(float delta)
        {
    
    
            Vector3 targetPosition = Vector3.Lerp(myTransform.position, targetTransform.position, delta / followSpeed);
            myTransform.position = targetPosition;

        }

        //这个函数去掌握摄像头的旋转
        public void HandlerCameraRotation(float delta,float mouseXInput,float mouseYInput)
        {
    
    
            //这样摄像头就会处在两个pivot之间,不能走更高或更低
            lookAngle += (mouseXInput * lookSpeed) / delta;
            pivotAngle -= (mouseYInput * pivotSpeed) / delta;
            //这会让摄像头卡在两个pivot角度之前,不能更高或更低(总体70°)
            pivotAngle = Mathf.Clamp(pivotAngle, minimimPivot, maximumPivot);

            Vector3 rotation = Vector3.zero;
            rotation.y = lookAngle;
            Quaternion targetRotation = Quaternion.Euler(rotation);
            myTransform.rotation = targetRotation;

            rotation = Vector3.zero;
            rotation.x = pivotAngle;

            targetRotation = Quaternion.Euler(rotation);
            cameraPivotTransform.localRotation = targetRotation;
        }

    }

}

2)InputHandler.cs

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

namespace SG
{
    
    
    public class InputHandler : MonoBehaviour
    {
    
    
        public float horizontal;
        public float vertical;
        public float moveAmount;
        public float mouseX;
        public float mouseY;

        //人物移动键盘监听的管理器
        PlayerControls inputActions;
        CameraHandler cameraHandler;

        //移动输入
        Vector2 movementInput;
        //摄像头输入
        Vector2 cameraInput;
         
        private void Awake()
        {
    
    
            cameraHandler = CameraHandler.singleton;
        }

        private void FixedUpdate()
        {
    
    
            float delta = Time.fixedDeltaTime;

            if (cameraHandler != null)
            {
    
    
                cameraHandler.FollowTarget(delta);
                cameraHandler.HandlerCameraRotation(delta,mouseX,mouseY);
            }
        }

        public void OnEnable()
        {
    
    
            //①初始化单例和单例对应的回调函数
            //获取键盘的输入数据,从2D坐标数据读进来
            if (inputActions == null)
            {
    
    
                inputActions = new PlayerControls();
                inputActions.PlayerMovement.Movement.performed += inputActions => movementInput = inputActions.ReadValue<Vector2>();
                inputActions.PlayerMovement.Camera.performed += i => cameraInput = i.ReadValue<Vector2>();
            }

            //②初始化这个输入资源库
            inputActions.Enable();
        }

        private void OnDisable()
        {
    
    
            //回收输入资源库对应数据 
            inputActions.Disable();
        }

        //这里应该是每帧去调用,转进来应该是时间?
        public void TickInput(float delta)
        {
    
    
            MoveInput(delta);
        }

        //这里应该是每帧去调用,转进来应该是时间?
        private void MoveInput(float delta)
        {
    
    
            //记录水平垂直移动值,并计算移动值
            horizontal = movementInput.x;
            vertical = movementInput.y;
            moveAmount = Mathf.Clamp01(Mathf.Abs(horizontal) + Mathf.Abs(vertical));
            mouseX = cameraInput.x;
            mouseY = cameraInput.y;
        }
    }
}

3)给脚本赋参数

在这里插入图片描述

4)拖动主摄像头(Main Camera)到合适位置

在这里插入图片描述

三、修正一个输入bug(non-stop spin 不停旋转)

点击PlayerControls,改变Camera的Action Type为Pass Through,且Control Type为Vector 2

在这里插入图片描述

四、修正一个移动bug(行走不断升高)

在这里插入图片描述

  • 解决办法
    在这里插入图片描述

五、其他可能遇到的bug(other possible bugs you may have encountered)

1)问题一:console信息报错

  • 问题:
    当把脚本放入到Script文件夹时,会有Console信息报错
  • 解决办法
    把在外面的旧cs代码文件删除,重新加载一遍就好了
  • 复现
    在这里插入图片描述

2)摄像头不跟着人走

  • 解决办法
    在CameraHolder的Inspector部件重新挂载脚本(删掉后重新挂载)
    在这里插入图片描述

六、英文

①joystick n. (电脑游戏的)游戏杆,操纵杆,控制杆; (飞机的)操纵杆;

猜你喜欢

转载自blog.csdn.net/weixin_43679037/article/details/127624679