黑魂向project制作学习三:摄像头碰撞(Camera Collisions)

一、纠正摄像头的一些僵硬

  • 摄像头的问题
    ①有一点tad jittery ,因为是用了lerp,我们应该用smooth tamp
    ②当人物沿着墙边走,摄像头可以看出来已跑进墙体里面了
    在这里插入图片描述
  • 修正
    ①先修正jittery:方法就是修改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;
        }

    }

}

二、撰写摄像头碰撞检测函数

        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;
        }

三、为摄像头新功能做调整

①调整camera Holder和Camera Pivot的Layer为Controller
②Main Camera保持为default的就行
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值