Unity的滑动控制相机跟随和第三人称视角三

news2024/12/24 21:19:17

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

  • 第三人称相机优化
  • 介绍
  • 讲解
  • 拖动事件
  • 相机逻辑
  • 人物移动逻辑
  • 总结

第三人称相机优化

Unity第三人称相机视角一
Unity第三人称相机视角二

介绍

之前相机视角讲过了两篇文章了,但是都是自动旋转视角,今天来了新需求,自动视角的时候,人没办法看全场上所有的景象,所以可以自己控制相机的视口方向,说白了就是做一个拖拽事件,再根据拖动的大小来控制相机视口旋转量,这样就完成了相机的可控视口旋转。
请添加图片描述

讲解

我上面的那个Gif可以看到,我创建了一个有拖动事件的UI,开始拖拽,拖拽中,结束拖拽。
在开始的时候我们采集他的开始拖拽点,然后在拖拽中进行插值运算计算进行镜头的左右旋转。
这个Gif里面我代码也加入了原来的人物中心点的位移,比如偏左一点或者偏右一点又或者是在正中心,这里我所使用的是Dotween这个插件,这里按键Q是切换镜头,ERT是镜头左侧,右侧,正中心的设置按键。

拖动事件

这里创建了一个UI来继承拖拽事件,可以把这个UI的透明通道调整到看不到的程度,我这里是为了大家方便看到我没有设置为0。

在这里插入图片描述MoveTouch.cs

using UnityEngine;
using UnityEngine.EventSystems;

public class MoveTouchTest : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    /// <summary>
    /// 跟随相机
    /// </summary>
    public FollowCameraTest followCameraTest;
     
    /// <summary>
    /// 是否在拖拽中
    /// </summary>
    public bool IsDrag = false;

    /// <summary>
    /// 开始位置
    /// </summary>
    private float startPosX;

    /// <summary>
    /// 旋转的角度
    /// </summary>
    public float angle = 1;

    public void OnBeginDrag(PointerEventData eventData)
    {
        IsDrag = true;
        startPosX = eventData.position.x;
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (!followCameraTest.IsHasBall) return;

        if (!IsDrag) return;
 
        followCameraTest.transform.localEulerAngles += new Vector3(0, (eventData.position.x - startPosX) * angle, 0);

        startPosX = eventData.position.x;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        IsDrag = false;
    }
    private void OnEnable()
    {
        IsDrag = false;
    }

    private void OnDisable()
    {
        IsDrag = false;
    }
}

相机逻辑

我用电脑测试的所以下面代码加了个鼠标滚轮控制镜头的旋转。

FollowCameraTest .cs

using DG.Tweening;
using Unity.VisualScripting;
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;

    public float angle = 5;

    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)
        {
        	//这里我用的电脑方便测试加了一个滚轮的方式去旋转镜头,需要可以打开 不需要就不用管
        	//float mouseWheel = Input.GetAxis("Mouse ScrollWheel");
            //transform.localEulerAngles += mouseWheel * angle * Vector3.up;
        }
        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 rotateSpeed = 5f;

    public FollowCameraTest followCamera;

    void Update()
    {
        Vector3 moveDir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
        moveDir = RotateRound(moveDir, Vector3.zero, Vector3.up, followCamera.transform.localEulerAngles.y);

        if (followCamera.IsHasBall)
        {
            transform.position += moveDir * moveSpeed * Time.deltaTime;

            transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(moveDir), rotateSpeed);
        }
        else
        {
            if (moveDir == Vector3.zero) return;
            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;
    }
}

总结

对比之前自动旋转的,这个版我觉着会更舒服一些,因为这个版的镜头更加可控制一些,但是这个也会让你操作变得复杂,无疑增加了一种操作负担。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FPGA高端项目:FPGA基于GS2971的SDI视频接收+HLS多路视频融合叠加,提供1套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收转HDMI输出应用本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放Video Mixer多路视频拼接应用本方案的SDI接收OSD动态字符叠加…

Day23:安全开发-PHP应用后台模块SessionCookieToken身份验证唯一性

目录 具体安全知识点 身份验证-Cookie使用 身份验证-Session使用 唯一性判断-Token使用 总结 源码 思维导图 PHP知识点&#xff1a; 功能&#xff1a;新闻列表&#xff0c;会员中心&#xff0c;资源下载&#xff0c;留言版&#xff0c;后台模块&#xff0c;模版引用&…

Java 拦截器Interceptor详解

1、拦截器概念 先看一下 3、代码示例 4、使用类解读 5、使用注解解读 6、与filter区别 7、优化策略 8、常见问题分析 学海无涯苦作舟&#xff01;&#xff01;&#xff01;

无尘擦拭布:保持清洁,确保品质

在现代工业和科技领域中&#xff0c;保持工作环境的清洁和设备的无尘是至关重要的。无尘布作为一种重要的清洁工具&#xff0c;在这一领域发挥着不可或缺的作用。它具有一系列优秀的特性&#xff0c;使其成为各种行业中的*选之一。 优秀的除尘效果与防静电功能 首先&#xff0…

Jupyter Notebook使用教程——从Anaconda环境构建到Markdown、LaTex语法介绍

0. 前言 按照国际惯例&#xff0c;首先声明&#xff1a;本文只是我自己学习的理解&#xff0c;虽然参考了他人的宝贵见解及成果&#xff0c;但是内容可能存在不准确的地方。如果发现文中错误&#xff0c;希望批评指正&#xff0c;共同进步。 你是否在视频教程或说明文档或Githu…

ejs模版引擎使用

ejs express渲染页面需要借助ejs官网传送门使用流程 安装ejs引擎 npm i ejs -S 在app.js入口文件里面设置模版引擎和目录 const path require(path)// 设置项目里面模版存放位置app.set(views, path.join(__dirname, views))// 设置模版引擎app.set(view engine, ejs)在项…

重学SpringBoot3-路径匹配机制

重学SpringBoot3-路径匹配机制 AntPathMatcherPathPatternParser 和 PathPattern演示AntPathMatcher 示例PathPattern 示例性能和精确度的提升 选择使用哪一种 在 Spring Framework 5.3 及 Spring Boot 2.4 之后&#xff0c;引入了一种新的路径匹配机制&#xff0c;这一变化在 …

Buildroot 之一 详解源码及架构

在之前的博文中,我们学习了直接通过 Makefile 手动来进行构建 U-Boot 和 Linux Kernel 等,其实,目前存在多种嵌入式 Linux 环境的构建工具,其中,Buildroot 就是被广泛应用的一种。今天就来详细学习一个 Buildroot 这个自动化构建工具。 Buildroot Buildroot 是一个运行于…

福派斯课堂:怎样选择品质比较好的猫粮?

亲爱的猫友们&#xff0c;我们都知道&#xff0c;猫咪的健康离不开好的饮食&#xff0c;而猫粮作为它们日常的主食&#xff0c;选择一款品质优良的猫粮就显得尤为重要了。那么&#xff0c;如何选择品质比较好的猫粮呢&#xff1f;今天&#xff0c;就让我来给大家支支招吧&#…

PaddlePaddle框架安装

提示&#xff1a;可在python环境中进行安装&#xff0c;避免环境污染&#xff0c;创建命令conda create -n xxx_name python3.9,激活conda activate xxx_name 第一步&#xff1a;查看计算机平台版本 在窗口输入查看命令&#xff0c;查看CUDA的版本 nvidia-smi 二、根据以下条件…

Redis主从架构和管道Lua(一)

Redis主从架构 架构 Redis主从工作原理 如果为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个PSYNC命令给master请求复制数据。master受到PSYNC命令&#xff0c;会在后台进行数据持久化通过bgsave生成最新的 RDB快照文件&#xff0c;持久化期间…

Linux之线程控制

目录 一、POSIX线程库 二、线程的创建 三、线程等待 四、线程终止 五、分离线程 六、线程ID&#xff1a;pthread_t 1、获取线程ID 2、pthread_t 七、线程局部存储&#xff1a;__thread 一、POSIX线程库 由于Linux下的线程并没有独立特有的结构&#xff0c;所以Linux并…

[Mac软件]Adobe Illustrator 2024 28.3 intel/M1/M2/M3矢量图制作软件

应用介绍 Adobe Illustrator 是行业标准的矢量图形应用程序&#xff0c;可以为印刷、网络、视频和移动设备创建logos、图标、绘图、排版和插图。数以百万计的设计师和艺术家使用Illustrator CC创作&#xff0c;从网页图标和产品包装到书籍插图和广告牌。 绘制任意大小的标志 拥…

C++进阶之路---多态(一)

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、多态的概念 1.概念 多态的概念&#xff1a;通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为…

[gic]-linux和optee的中断处理流程举例(gicv3举例)

目录 环境配置:说明:举例1、当cpu处于REE&#xff0c;来了一个非安全中断2、当cpu处于TEE&#xff0c;来了一个安全中断3、当cpu处于TEE&#xff0c;来了一个非安全中断4、当cpu处于REE&#xff0c;来了一个安全中断答疑 推荐 本文转自 周贺贺&#xff0c;baron&#xff0c;代码…

ROS2从入门到精通0-2:ROS2简介、对比ROS1与详细安装流程

目录 0 专栏介绍1 什么是机器人操作系统&#xff1f;2 ROS的发展历程3 ROS2与ROS1的区别4 ROS2安装4.1 基本安装4.2 测试ROS24.2.1 测试一&#xff1a;发布者与订阅者4.2.2 测试二&#xff1a;海龟仿真器 5 常见问题 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌…

凌鲨开发容器架构

开发容器是基于docker的快速开发搭建方案&#xff0c;在开发容器里面集成了asdf包管理系统和code server ide服务。 这个项目是开源的。 开发容器启动流程 #mermaid-svg-VJYq3izhUZRJA4Eq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fil…

java之mybatis

准备工作 上面4步骤 XML映射文件 动态SQL

git分布式管理-头歌实验冲突处理、忽略文件

一、解决冲突 任务描述 在团队协作开发过程中&#xff0c;可能你和团队中的其他成员&#xff0c;都修改了某个文件的某一部分内容&#xff0c;且其他成员已将该修改推送到了远程仓库。这样当你需要合并他的代码的时候&#xff0c;可能就会在内容上出现冲突&#xff0c;这个时候…

vue之性能优化

1.路由懒加载 所谓路由懒加载&#xff0c;其实就是路由通过import动态引入&#xff0c;而不是在文件最上面一个个全部引入&#xff0c;因为JS执行的时候会优先执行引入的文件&#xff0c;如果一次性引入过多&#xff0c;则会增加处理时长。 2.图片懒加载 图片在网页加载过程…