Unity的相机跟随和第三人称视角二

Unity的相机跟随和第三人称视角二

展示

我录的视频上可能看不太出来,但是其实今天的这个方法比原来写的那个方法更简便并且死角更少一些。

这里我也做了两个人物偏移的视角,按Q是原来的两个相机模式切换,按E、R、T是人物在相机中心的偏移。


介绍

之前讲过一个第三人称的相机镜头,今天想把原来的镜头改一下。之前测试的时候发现了原来相机的镜头移动是有点问题的,虽然都是平滑的移动但是其实不是环形移动。
Unity的相机跟随和第三人称视角一

第一篇的相机的移动我下面举个例子大家看一下,这里虽然都是平滑的移动,但是还是有差距的。

第一篇文章中相机的平滑大家可以看到其实是A->B->C->D->A都是直接取的两个点进行平滑的移动,并且在移动的过程中相机还要进行旋转,所以说实际上移动的并不是球型移动(用我第一篇的相机你会发现有的时候视角切换的时候很难看清楚人有的时候)。后面我会讲一个更简单一点的相机移动和旋转跟随人物。

第二种相机模式远离

这种相机其实就是让相机一直缓慢的跟着人物,然后旋转的话是直接调整玩家的旋转。下面我在画图说明一下。

这种方式其实就是按照这个球型来进行移动和旋转,这样就避免了一些相机的死角问题。

这里的搭建跟第一种搭建其实是一样的

代码

这里我直接上代码了,原理也很简单,比之前写的那个镜头移动的还要更简单一些。

FollowCameraTest.cs

csharp 复制代码
using DG.Tweening;
using UnityEngine;

public class FollowCameraTest : MonoBehaviour
{
    public Transform target; // 要跟随的目标对象
    public Transform football; // 其次要跟随的目标
    public Vector3 camPosOffset = new Vector3(0, 1.5f, -5);   // 相机与目标之间的距离偏移量
    public Vector3 camEulerOffset = new Vector3(6, 0, 0);   // 相机与目标之间的距离偏移量
    public float smoothSpeed = 0.05f; // 相机跟随平滑度
    public float rotateSpeed = 0.08f; // 相机旋转平滑度
    public float fov = 45;
    public bool IsHasBall = true;

    public Camera m_cam;
    public float moveTime = 1f;

    private void Start()
    {
        m_cam.transform.localPosition = camPosOffset;
        m_cam.transform.localEulerAngles = camEulerOffset;
        transform.position = target.transform.position;
        m_cam.fieldOfView = fov;
    }


    public void LateUpdate()
    {
        if (target == null) return;
        if (Input.GetKeyDown(KeyCode.Q)) 
        {
            IsHasBall = !IsHasBall;
        }
        if (Input.GetKeyDown(KeyCode.E)) 
        {
            if (m_cam != null) m_cam.transform.DOLocalMoveX(-1, moveTime);
        }
        if (Input.GetKeyDown(KeyCode.R))
        {
            if (m_cam != null) m_cam.transform.DOLocalMoveX(1, moveTime);
        }
        if (Input.GetKeyDown(KeyCode.T))
        {
            if (m_cam != null) m_cam.transform.DOLocalMoveX(0, moveTime);
        }
        //相机缓动过程
        transform.position = Vector3.Lerp(transform.position, target.transform.position, smoothSpeed);

        if (IsHasBall)
        {

            transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(target.transform.forward), rotateSpeed);
        }
        else
        {
            Vector3 tar = ((target.position + football.position) * 0.5f - target.transform.position).normalized;
            tar.y = 0;
            transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(tar), rotateSpeed);
        }
    }
}

RoleCtrlTest.cs

csharp 复制代码
using UnityEngine;

public class RoleCtrlTest : MonoBehaviour
{
    public float moveSpeed = 5f; // 人物移动速度
    public float rotationSpeed = 180f; // 人物转向速度

    public float rotateSpeed = 5f;

    public FollowCameraTest followCamera;

    void Update()
    {

        if (followCamera.IsHasBall)
        {
            // 获取玩家的输入
            float moveHorizontal = Input.GetAxis("Horizontal");
            if (moveHorizontal == 0)
            {
            }
            else if (moveHorizontal > 0)
            {
                transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime);
            }
            else if (moveHorizontal < 0)
            {
                transform.Rotate(Vector3.up, -rotationSpeed * Time.deltaTime);
            }

            if (Input.GetAxis("Vertical") > 0)
            {
                transform.position += followCamera.transform.forward * moveSpeed * Time.deltaTime;
            }
        }
        else
        {
            Vector3 moveDir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            if (moveDir == Vector3.zero) return;
            moveDir = RotateRound(moveDir, Vector3.zero, Vector3.up, followCamera.transform.localEulerAngles.y);
            transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(moveDir), rotateSpeed);
            transform.position += transform.forward * moveSpeed * Time.deltaTime;
        }
    }

    protected Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
    {
        Vector3 point = Quaternion.AngleAxis(angle, axis) * (position - center);
        Vector3 resultVec3 = center + point;
        return resultVec3;
    }
}

总结

这种方式比原来的代码量还要少,并且死角也少了很多。

如果大家还有什么好的想法可以跟我探讨,感谢大家的支持!

相关推荐
虾球xz7 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
red_redemption12 小时前
自由学习记录(23)
学习·unity·lua·ab包
/**书香门第*/16 小时前
Cocos creator 3.8 支持的动画 7
学习·游戏·游戏引擎·游戏程序·cocos2d
向宇it1 天前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
Heaphaestus,RC1 天前
【Unity3D】获取 GameObject 的完整层级结构
unity·c#
芋芋qwq1 天前
Unity UI射线检测 道具拖拽
ui·unity·游戏引擎
tealcwu1 天前
【Unity服务】关于Unity LevelPlay的基本情况
unity·游戏引擎
大眼睛姑娘1 天前
Unity3d场景童话梦幻卡通Q版城镇建筑植物山石3D模型游戏美术素材
unity·游戏美术
鹿野素材屋2 天前
Unity Dots下的动画合批工具:GPU ECS Animation Baker
unity·游戏引擎
小春熙子2 天前
Unity图形学之着色器之间传递参数
unity·游戏引擎·技术美术·着色器