Black Soul learns from project production 3: Camera Collisions

1. Correct some stiffness of the camera

  • Problems with the camera
    ① There is a little tad jittery, because we use lerp, we should use smooth tamp
    ② When the character walks along the wall, the camera can see that he has run into the wall
    insert image description here
  • Correction
    ① Fix the jittery first: the method is to modify the camera Handler
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 cameraTransformPosition;
        
        //用于摄像头碰撞的bit位
        private LayerMask ignoreLayers;
        private Vector3 cameraFollowVelocity = Vector3.zero;


        public static CameraHandler singleton;

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

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

        public float cameraSphereRadius = 0.2f;
        public float cameraCollisionOffset = 0.2f;
        public float minimumCollisionOffset = 0.2f;

        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);
            Vector3 targetPosition = Vector3.SmoothDamp
                (myTransform.position, targetTransform.position, ref cameraFollowVelocity,delta / followSpeed);
            myTransform.position = targetPosition;

            //调整摄像头碰撞
            HandleCameraCollisions(delta);
        }

        //这个函数去掌握摄像头的旋转
        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;
        }


        private void HandleCameraCollisions(float delta)
        {
    
    
            targetPosition = defaultPosition;
            RaycastHit hit;
            Vector3 direction = cameraTransform.position - cameraPivotTransform.position;
            direction.Normalize();

            if(Physics.SphereCast
                (cameraPivotTransform.position,cameraSphereRadius,direction,out hit,
                Mathf.Abs(targetPosition),ignoreLayers))
            {
    
    
                float dis = Vector3.Distance(cameraPivotTransform.position, hit.point);
                targetPosition = -(dis - cameraCollisionOffset);
            }

            if(Mathf.Abs(targetPosition) < minimumCollisionOffset)
            {
    
    
                targetPosition = -minimumCollisionOffset;
            }

            cameraTransformPosition.z = Mathf.Lerp(cameraTransform.localPosition.z, targetPosition, delta / 0.2f);
            cameraTransform.localPosition = cameraTransformPosition;
        }

    }

}

2. Write camera collision detection function

        private void HandleCameraCollisions(float delta)
        {
    
    
            targetPosition = defaultPosition;
            RaycastHit hit;
            Vector3 direction = cameraTransform.position - cameraPivotTransform.position;
            direction.Normalize();

            if(Physics.SphereCast
                (cameraPivotTransform.position,cameraSphereRadius,direction,out hit,
                Mathf.Abs(targetPosition),ignoreLayers))
            {
    
    
                float dis = Vector3.Distance(cameraPivotTransform.position, hit.point);
                targetPosition = -(dis - cameraCollisionOffset);
            }

            if(Mathf.Abs(targetPosition) < minimumCollisionOffset)
            {
    
    
                targetPosition = -minimumCollisionOffset;
            }

            cameraTransformPosition.z = Mathf.Lerp(cameraTransform.localPosition.z, targetPosition, delta / 0.2f);
            cameraTransform.localPosition = cameraTransformPosition;
        }

3. Make adjustments for the new functions of the camera

①Adjust camera Holder and Camera Pivot Layer to Controller.
②Main Camera should be set to default.
insert image description here

Guess you like

Origin blog.csdn.net/weixin_43679037/article/details/127662358