基于体素场景的摄像机穿模处理

基于上一篇一种基于体素的射线检测
使用射线处理第三人称摄像头穿模问题

基于体素的第三人称摄像机拉近简单处理

摄像机移动至碰撞点处

简单的从角色身上发射一条射线到摄像机,中途遇到碰撞就把摄像机移动至该碰撞点

    public void UpdateDistance(float defaultDistance){Vector3 from = player.position;Vector3 to = cameraRoot.position;Vector3 forward = (to - from).normalized;Debug.DrawLine(from, to, Color.red);if (BlockPhysics.Raycast(BlockWorld.CurWorld, from, forward, (to - from).magnitude, out hitInfo)){distance = cameraRoot.InverseTransformPoint(hitInfo.point).z;}else{distance = 0;}curDistance = Mathf.Lerp(curDistance, distance, speed * Time.fixedDeltaTime);curDistance = Mathf.Clamp(curDistance, 0, defaultDistance);transform.localPosition = Vector3.forward * curDistance;}

可以明显看到摄像机一半在外面,一半在墙里面体验感非常差
在这里插入图片描述
可以通过检测摄像机近裁剪面的4个顶点是否在方块或体素内
如果有一个顶点产生碰撞,那么就把摄像机向前移动

    float GetDistance(float distance){int i = 0;int loop = 666;virtualCamera.localPosition = Vector3.forward * distance;var wrold = BlockWorld.CurWorld;while (loop-- > 0){UpdateNearClipPlane();for (i = 0; i < 4; i++){if (wrold.HasBlockCollider(Vector3Int.RoundToInt(corners[i])) || wrold.HasVoxelCollider(corners[i])){break;}}if (i == 4)break;distance += 0.25f;virtualCamera.localPosition = Vector3.forward * distance;}return distance;}

通过前移规避穿模问题
在这里插入图片描述
当然如果夹角非常小或者在一个狭窄的通道内,并不推荐拉近摄像头。
在这里插入图片描述
因为拉近已经不能解决问题。这种情况下推荐摄像机观察中心直接固定在方块中心。
从方块中心出发就不用担心角色过于靠近墙壁导致的拉近修复无效

完整代码

using UnityEngine;public class CameraOffset : MonoBehaviour
{public float speed = 10;Transform cameraRoot;Transform player;float distance;float curDistance;RaycastHit hitInfo;Camera mainCamera;Transform virtualCamera;Vector3[] corners = new Vector3[4];float width;float height;private void Start(){cameraRoot = transform.parent;player = GameObject.FindGameObjectWithTag("Player").transform;player = player.transform.Find("cameraFollow");mainCamera = Camera.main;virtualCamera = new GameObject("virtualCamera").transform;virtualCamera.transform.SetParent(mainCamera.transform.parent);virtualCamera.localPosition = Vector3.zero;virtualCamera.localRotation = Quaternion.identity;virtualCamera.localScale = Vector3.zero;float halfFOV = (mainCamera.fieldOfView * 0.5f) * Mathf.Deg2Rad;float aspect = mainCamera.aspect;height = mainCamera.nearClipPlane * Mathf.Tan(halfFOV);width = height * aspect;}private void OnDrawGizmos(){Gizmos.color = Color.red;Gizmos.DrawWireSphere(hitInfo.point, 0.1f);}public void UpdateDistance(float defaultDistance){Vector3 from = player.position;Vector3 to = cameraRoot.position;Vector3 forward = (to - from).normalized;Debug.DrawLine(from, to, Color.red);if (BlockPhysics.Raycast(BlockWorld.CurWorld, from, forward, (to - from).magnitude, out hitInfo)){distance = GetDistance(cameraRoot.InverseTransformPoint(hitInfo.point).z);}else{distance = 0;}curDistance = Mathf.Lerp(curDistance, distance, speed * Time.fixedDeltaTime);curDistance = Mathf.Clamp(curDistance, 0, defaultDistance);transform.localPosition = Vector3.forward * curDistance;}float GetDistance(float distance){int i = 0;int loop = 666;virtualCamera.localPosition = Vector3.forward * distance;var wrold = BlockWorld.CurWorld;while (loop-- > 0){UpdateNearClipPlane();for (i = 0; i < 4; i++){if (wrold.HasBlockCollider(Vector3Int.RoundToInt(corners[i])) || wrold.HasVoxelCollider(corners[i])){break;}}if (i == 4)break;distance += 0.25f;virtualCamera.localPosition = Vector3.forward * distance;}return distance;}void UpdateNearClipPlane(){corners[0] = virtualCamera.position - (virtualCamera.right * width);corners[0] += virtualCamera.up * height;corners[0] += virtualCamera.forward * mainCamera.nearClipPlane;corners[1] = virtualCamera.position + (virtualCamera.right * width);corners[1] += virtualCamera.up * height;corners[1] += virtualCamera.forward * mainCamera.nearClipPlane;corners[2] = virtualCamera.position - (virtualCamera.right * width);corners[2] -= virtualCamera.up * height;corners[2] += virtualCamera.forward * mainCamera.nearClipPlane;corners[3] = virtualCamera.position + (virtualCamera.right * width);corners[3] -= virtualCamera.up * height;corners[3] += virtualCamera.forward * mainCamera.nearClipPlane;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity实现设计模式——状态模式

Unity实现设计模式——状态模式 状态模式最核心的设计思路就是将对象的状态抽象出一个接口&#xff0c;然后根据它的不同状态封装其行为&#xff0c;这样就可以实现状态和行为的绑定&#xff0c;最终实现对象和状态的有效解耦。 在实际开发中一般用到FSM有限状态机的实现&…

Learning Invariant Representation for Unsupervised Image Restoration

Learning Invariant Representation for Unsupervised Image Restoration (Paper reading) Wenchao Du, Sichuan University, CVPR20, Cited:63, Code, Paper 1. 前言 近年来&#xff0c;跨域传输被应用于无监督图像恢复任务中。但是&#xff0c;直接应用已有的框架&#xf…

叶工好容6-自定义与扩展

本篇主要介绍扩展的本质以及CRD与Operator之间的区别&#xff0c;帮助大家理解相关的概念以及知道要进行扩展需要做哪些工作。 CRD&#xff08;CustomerResourceDefinition&#xff09; 自定义资源定义,代表某种自定义的配置或者独立运行的服务。 用户只定义了CRD没有任何意…

【Spring Cloud】深入探索统一网关 Gateway 的搭建,断言工厂,过滤器工厂,全局过滤器以及跨域问题

文章目录 前言为什么需要网关以及网关的作用网关的技术实现 一、Gateway 网关的搭建1.1 创建 Gateway 模块1.2 引入依赖1.3 配置网关1.4 验证网关是否搭建成功1.5 微服务结构分析 二、Gateway 断言工厂2.1 Spring 提供的断言工厂2.2 示例&#xff1a;设置断言工厂 三、Gateway …

从0手写两轮差速机器人urdf模型

文章目录 前言一、基本理论二、实现步骤1.创建一个机器人建模功能包2.使用圆柱体创建一个车体模型2.同理创建机器人其它构件3.机器人模型添加传感器 前言 最近为找到与自己课题应用场景相适应的机器人结构&#xff0c;对机器人建模方面的内容进行了了解和学习&#xff0c;计划…

【数组及指针经典笔试题解析】

1.数组和指针笔试题 题目1 int main(){int a[5] { 1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5};int * ptr (int * )(&a 1);printf("%d&#xff0c;%d"&#xff0c;*(a 1)&#xff0c;*(ptr - 1));return 0;}图文解析&#xff1a; int * ptr …

【JavaEE】JavaScript webAPI的基本知识

JavaScript Web API 文章目录 JavaScript Web APIwebAPI背景DOMDOM树 获取元素querySelectorquerySelectorAll 事件初识键盘事件onkeydownonkeypressonkeyup 操作元素获取/修改元素内容1.innerText2.innerHTML 获取/修改元素属性获取/修改表单元素属性获取/修改样式属性行内样式…

redis的简单使用

文章目录 环境安装与配置redis发布-订阅相关命令redis发布-订阅的客户端编程redis的订阅发布的例子 环境安装与配置 sudo apt-get install redis-server # ubuntu命令安装redis服务ubuntu通过上面命令安装完redis&#xff0c;会自动启动redis服务&#xff0c;通过ps命令确认&a…

用于YOLO格式分割的咖啡叶病害数据集。

下载链接&#xff1a;https://download.csdn.net/download/qq_40840797/88389334 数据集&#xff0c;一共1164张照片 随机选取几张照片及对应的目标标签 因为健康&#xff0c;所以标签为空

[BJDCTF2020]The mystery of ip

打开环境 点击flag&#xff0c;提示ip&#xff0c;这里确实就比较容易联想到x-forwarded-for 点击hint 这个好像没啥用 使用bp抓包 添加请求头 X-Forwarded-For:1 试一下 发现ip可控 后来查了发现 PHP可能存在Twig模版注入漏洞 参考https://www.cnblogs.com/zzjdbk/p/13…

【C语言】循环结构程序设计 (详细讲解)

前言&#xff1a;前面介绍了程序中常常用到的顺序结构和选择结构&#xff0c;但是只有这两种结构是不够的&#xff0c;还有用到循环结构(或者称为重复结构)。因为在日常生活中或是在程序所处理的问题中常常遇到需要重复处理的问题。 【卫卫卫的代码仓库】 【选择结构】 【专栏链…

HTML的相关知识

1.什么是HTML&#xff1f;基本语法 HTML: Hyper Text Markup Language &#xff08;超文本标记语言&#xff09; 超文本&#xff1f;超级文本&#xff0c;例如流媒体&#xff0c;声音、视频、图片等。 标记语言&#xff1f;这种语言是由大量的标签组成。HTML标签参考手…

【数据结构】堆的应用-----TopK问题

目录 一、前言 二、Top-k问题 &#x1f4a6;解法一&#xff1a;暴力排序 &#x1f4a6;解法二&#xff1a;建立N个数的堆 &#x1f4a6;解法三&#xff1a;建立K个数的堆&#xff08;最优解&#xff09; 三、完整代码和视图 四、共勉 一、前言 在之前的文章中&#xff…

React18入门(第一篇)——JSX、TSX语法详解

文章目录 一、JSX 语法简介二、和 HTML 标签的几点不同三、JSX 属性四、JSX 事件4.1 简单点击事件4.2 类型限制4.3 带参数&#xff0c;箭头函数 五、插入 JS 变量六、JSX 中使用条件判断七、循环 一、JSX 语法简介 JSX - 是 JS 的扩展&#xff0c;写在 JS 代码里面&#xff0c…

计算机算法分析与设计(4)---凸多边形的最优三角划分(含C++代码)

文章目录 一、概述1.1 概念说明1.2 与矩阵连乘对应关系1.3 递归定义 二、代码 一、概述 1.1 概念说明 1. 用多边形顶点的逆时针序列表示凸多边形&#xff0c;即P{V0, V1, … Vn-1, Vn}表示具有n1条边的凸多边形。 2. 若Vi和Vj是多边形上不相邻的两个顶点&#xff0c;则线段ViV…

SEO搜索引擎

利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名&#xff0c;吸引更多的用户访问网站&#xff0c;提高网站的访问量&#xff0c;提高网站的销售能力和宣传能力&#xff0c;从而提升网站的品牌效应 搜索引擎优化的技术手段 黑帽SEO 通过欺骗技术和滥用搜索算法来推销毫不…

Armv8/Armv9 Cache知识大纲分享--思维导图

关键词&#xff1a;cache学习、mmu学习、cache资料、mmu资料、arm资料、armv8资料、armv9资料、 trustzone视频、tee视频、ATF视频、secureboot视频、安全启动视频、selinux视频&#xff0c;cache视频、mmu视频&#xff0c;armv8视频、armv9视频、FF-A视频、密码学视频、RME/CC…

力扣:118. 杨辉三角(Python3)

题目&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官…

DS线性表之链表

前言 我们上一期介绍了顺序表&#xff0c;它的底层就是数组&#xff0c;我们也分别对顺序表的动态版本和静态版本进行了实现&#xff01;并且分析了顺序表的优缺点&#xff0c;优点是&#xff1a;尾插、尾删效率很高&#xff0c;其时间复杂度是O(1)&#xff1b;缺点是&#xff…

使用 ClassFinal 对 java class 文件进行加密防止反编译

ClassFinal 是一款 java class文件安全加密工具&#xff0c;支持直接加密 jar 包或 war 包&#xff0c;无需修改任何项目代码&#xff0c;兼容 spring-framework&#xff1b;可避免源码泄漏或字节码被反编译 特点 无需修改原项目代码&#xff0c;只要把编译好的jar/war包用本工…