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

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

  • 展示
  • 介绍
  • 第二种相机模式远离
  • 代码
  • 总结

展示

我录的视频上可能看不太出来,但是其实今天的这个方法比原来写的那个方法更简便并且死角更少一些。
这里我也做了两个人物偏移的视角,按Q是原来的两个相机模式切换,按E、R、T是人物在相机中心的偏移。

请添加图片描述
请添加图片描述

介绍

之前讲过一个第三人称的相机镜头,今天想把原来的镜头改一下。之前测试的时候发现了原来相机的镜头移动是有点问题的,虽然都是平滑的移动但是其实不是环形移动。
Unity的相机跟随和第三人称视角一
第一篇的相机的移动我下面举个例子大家看一下,这里虽然都是平滑的移动,但是还是有差距的。
第一篇文章中相机的平滑大家可以看到其实是A->B->C->D->A都是直接取的两个点进行平滑的移动,并且在移动的过程中相机还要进行旋转,所以说实际上移动的并不是球型移动(用我第一篇的相机你会发现有的时候视角切换的时候很难看清楚人有的时候)。后面我会讲一个更简单一点的相机移动和旋转跟随人物。
在这里插入图片描述

第二种相机模式远离

这种相机其实就是让相机一直缓慢的跟着人物,然后旋转的话是直接调整玩家的旋转。下面我在画图说明一下。
这种方式其实就是按照这个球型来进行移动和旋转,这样就避免了一些相机的死角问题。

这里的搭建跟第一种搭建其实是一样的
在这里插入图片描述
在这里插入图片描述

代码

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

FollowCameraTest.cs

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

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

总结

这种方式比原来的代码量还要少,并且死角也少了很多。
如果大家还有什么好的想法可以跟我探讨,感谢大家的支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/435599.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

内容管理平台用这几个就够了,简单又好用

对于大多数企业和自由职业者来说&#xff0c;选择合适的内容管理平台已经成为一种必备的技能。良好的内容管理平台可以赋能你的团队&#xff0c;让你们更好地协作、管理和分享内容。不管你是要发布博客文章&#xff0c;还是需要管理复杂的项目文档&#xff0c;都可以通过内容管…

解读Linux文件目录权限:srw-rw----

在Linux系统中&#xff0c;文件或目录的权限由10个字符表示&#xff0c;分为四段&#xff1a; 第一个字符&#xff1a;表示文件类型。d代表目录&#xff0c;-代表普通文件&#xff0c;l代表符号链接&#xff0c;s代表套接字&#xff08;socket&#xff09;&#xff0c;c代表字符…

以太网帧格式

以太网帧格式 以太网帧格式前导码&#xff08;Preamble&#xff09;帧起始界定符&#xff08;SFD&#xff0c;Start Frame Delimiter&#xff09;以太网帧头目的MAC地址源MAC地址长度/类型 数据段帧检验序列&#xff08;FCS&#xff0c;Frame Check Sequence&#xff09;帧间隙…

Linux 文件操作命令

1 文件与目录操作 cd /home 进入 ‘/home’ 目录 cd .. 返回上一级目录cd ../.. 返回上两级目录cd - 返回上次所在目录cp file1 file2 将file1复制为file2cp -a dir1 dir2 复制一个目录 cp -a /tmp/dir1 . 复制一个…

网络安全审计是什么意思?与等保测评有什么区别?

网络安全审计和等保测评在信息安全领域中都是非常重要的环节。但不少人对于这两者是傻傻分不清楚&#xff0c;今天我们就来简单聊聊网络安全审计是什么意思&#xff1f;与等保测评有什么区别&#xff1f; 网络安全审计是什么意思&#xff1f; 网络安全审计是通过对网络系统和网…

selenium鼠标操作实战

鼠标操作实战 鼠标单击操作 click()内置鼠标操作包ActionChains鼠标双击操作double_click()鼠标右击操作context_click()鼠标指针悬浮操作move_to_element(ele)鼠标拖动操作drag_and_drop(source, target)其他鼠标操作汇总 鼠标单击操作 click() from selenium import webdriv…

MySQL存储过程2——if、case、while、repeat、loop、cursor、handler

1、if用作条件判断 1.1、语法结构 IF 条件1 THEN... ELSEIF 条件2 THEN... ELSE... END IF; 在if条件判断的结构中&#xff0c;Else if结构可以有多个&#xff0c;也可以没有。Else结构可以有&#xff0c;也可以没有 1.2、示例 根据定义的分数score变量&#xff0c;判断当…

openssl调试记录

openssl不能直接解密16进制密文&#xff0c;需要把密文转化成base64格式才能解密 调试记录如下&#xff1a;

搭建SpringBoot项目——开发环境搭建开发环境搭建

简介 SpringBoot 是 Java 社区最有影响力之一的开源的Spring后端开发框架&#xff0c;也是企业级应用开发的首选技术&#xff0c;Spring Boot 拥有良好的技术基因&#xff0c;它是伴随着Spring 4 而产生的技术框架&#xff0c;在继承了 Spirng 框架所有优点的同时也为开发者带来…

scrapy 爬虫:多线程爬取去微博热搜排行榜数据信息,进入详情页面拿取第一条微博信息,保存到本地text文件、保存到excel

如果想要保存到excel中可以看我的这个爬虫 使用Scrapy 框架开启多进程爬取贝壳网数据保存到excel文件中&#xff0c;包括分页数据、详情页数据&#xff0c;新手保护期快来看&#xff01;&#xff01;仅供学习参考&#xff0c;别乱搞_爬取贝壳成交数据c端用户登录-CSDN博客 最终…

AI智商排名:Claude-3首次突破100

用挪威门萨&#xff08;智商测试题&#xff09;中 35 个问题对chatGPT等人工智能进行了测试&#xff1a; ChatGPT 对ChatGPT进行了两次挪威门萨测试&#xff0c;在 35 个问题中&#xff0c;它平均答对了 13 个&#xff0c;智商估计为 85。 测试方法 每个人工智能都接受了两次…

【b站咸虾米】1 Vue介绍 2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例

课程地址&#xff1a;【2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例】 https://www.bilibili.com/video/BV1pz4y1S7bC/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 感觉尚硅谷的Vue看完忘得差不多了&#xff0c;且之前学过咸虾米的unia…

Java agent技术的注入利用与避坑点

什么是Java agent技术&#xff1f; Java代理&#xff08;Java agent&#xff09;是一种Java技术&#xff0c;它允许开发人员在运行时以某种方式修改或增强Java应用程序的行为。Java代理通过在Java虚拟机&#xff08;JVM&#xff09;启动时以"代理"&#xff08;agent…

Redis(十七)分布式锁

文章目录 面试题分布式锁锁的种类分布式锁需要具备的条件和刚需分布式锁 案例nginx分布式微服务部署&#xff0c;单机锁问题分布式锁注意事项lock/unlocklua脚本自研版的redis分布式锁搞定lua脚本 可重入锁可重入锁种类可重入锁hset实现&#xff0c;对比setnx&#xff08;重要&…

react高阶组件:如何同时兼容class类组件和函数式组件。

场景&#xff1a; 每个页面都要实现分享功能&#xff0c;但是页面有些是用class类&#xff0c;有些又直接是函数式。 方案1&#xff1a; 写2套方法。各自引用。&#xff08;维护不太好&#xff0c;改要改2遍&#xff09; 方案2&#xff1a; 可以封一个 jsx的组件&#xff0c…

NLP:spacy库安装与zh_core_web_sm配置

到公司来第一个项目竟然是偏文本信息抽取与结构化的&#xff0c;&#xff08;也太高看我了┭┮﹏┭┮&#xff09; 反正给机会了就上吧&#xff0c;我就一臭实习的&#xff0c;怕个啥。配置了两天的环境&#xff0c;也踩了不少坑&#xff0c;我把我的经历给大家分享一下&#…

HarmonyOS NEXT应用开发案例集

概述 随着应用代码的复杂度提升&#xff0c;为了使应用有更好的可维护性和可扩展性&#xff0c;良好的应用架构设计变得尤为重要。本篇文章将介绍一个应用通用架构的设计思路&#xff0c;以减少模块间的耦合、提升团队开发效率&#xff0c;为开发者呈现一个清晰且结构化的开发…

【Tauri】(4):整合Tauri和actix-web做本地大模型应用开发,可以实现session 登陆接口,完成页面展示,进入聊天界面

1&#xff0c;视频地址 https://www.bilibili.com/video/BV1GJ4m1Y7Aj/ 【Tauri】&#xff08;4&#xff09;&#xff1a;整合Tauri和actix-web做本地大模型应用开发&#xff0c;可以实现session 登陆接口&#xff0c;完成页面展示&#xff0c;进入聊天界面 使用国内代理进行加…

【HTML】HTML基础7.3(自定义列表)

目录 标签 效果 代码 注意 标签 <dl> <dt>自定义标题</dt><dd>内容1</dd><dd>内容2</dd><dd>内容3</dd> 。。。。。。 </dl> 效果 代码 <dl><dt>蜘蛛侠系列</dt><dd>蜘蛛侠1</dd…

PyCharm Community Edition 2023.3.3,UI界面设置成旧版

File->Settings->Appearance & Behavior->New UI->Enable new UI(取消勾选)->重启PyCharm 旧版UI: 新版UI&#xff1a;