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

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

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

摄像机移动至碰撞点处

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

    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.xdnf.cn/news/147762.html

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

相关文章

FOC程序cubemx配置-ADC配置

具体配置步骤大家参考&#xff1a;这篇文章 我配置后用keil5自带的仿真工具查看引脚波形&#xff0c;在这里写一下遇到的问题。 1、波形仿真的时候出现 Unknown Signal&#xff1a;参考 这篇文章 2、生成的波形并不完全互补。 PS&#xff1a;出现以上这种情况时&#xff0…

使用Visual Studio调试排查Windows系统程序audiodg.exe频繁弹出报错

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…

多线程基础篇(多线程案例)

文章目录 多线程案例1、单例模式1&#xff09;饿汉模式2&#xff09;懒汉模式3&#xff09;线程安全吗&#xff1f;&#xff1f;4&#xff09;解决懒汉模式线程安全问题5&#xff09;解决懒汉模式内存可见性问题 2、阻塞队列1) 阻塞队列是什么&#xff1f;2) 生产者消费者模型1…

操作系统原理-习题汇总

临近毕业&#xff0c;整理一下过去各科习题及资料等&#xff0c;以下为操作系统原理的习题汇总&#xff0c;若需要查找题目&#xff0c;推荐CtrlF或commandF进行全篇快捷查找。 操作系统原理 作业第一次作业选择题简答题 第二次作业选择题简答题 第三次作业选择题简答题 第四次…

Oracle - 多区间按权重取值逻辑

啰嗦: 其实很早就遇到过类似问题&#xff0c;也设想过&#xff0c;不过一致没实际业务需求&#xff0c;也就耽搁了&#xff1b;最近有业务提到了&#xff0c;和同事讨论&#xff0c;各有想法&#xff0c;所以先把逻辑整理出来&#xff0c;希望有更好更优的解决方案&#xff1b;…

CSS鼠标指针表

(机翻)搬运自:cursor - CSS: Cascading Style Sheets | MDN (mozilla.org) 类型Keyword演示注释全局autoUA将基于当前上下文来确定要显示的光标。例如&#xff0c;相当于悬停文本时的文本。default 依赖于平台的默认光标。通常是箭头。none不会渲染光标。链接&状态contex…

Spring的注解开发-注解方式整合MyBatis代码实现

之前使用xml方式整合了MyBatis&#xff0c;文章导航&#xff1a;Spring整合第三方框架-MyBatis整合Spring实现-CSDN博客 现在使用注解的方式无非是就是将xml标签替换为注解&#xff0c;将xml配置文件替换为配置类而已。 非自定义配置类 package com.example.Configure;import c…

yolov5检测cs2中的目标

环境介绍 系统&#xff1a;Windows11 显卡&#xff1a;4070ti cuda:11.8 配置环境 python环境 安装python的虚拟环境anaconda。Free Download | Anaconda 成功安装后可以按Win键搜索anaconda&#xff0c;可以看到桌面版和命令行版本&#xff0c;我们这里直接用命令行版本…

spring-boot入门之如何利用idea创建一个spring-boot项目

1.创建流程&#xff01;&#xff01;&#xff01; 选择新建项目&#xff0c;这里我们需要注意是基于maven建立的和java版本和jdk版本要对应 这里我们是基于web项目创建的记得选择这个框架。 2.测试程序 编写hello测试类 我们需要通过程序的入口进行启动程序。idea已经为我们自…

C++算法 —— 动态规划(7)两个数组的dp

文章目录 1、动规思路简介2、最长公共子序列3、不相交的线4、不同的子序列5、通配符匹配6、正则表达式匹配7、交错字符串8、两个字符串的最小ASCII删除和9、最长重复子数组 每一种算法都最好看完第一篇再去找要看的博客&#xff0c;因为这样会帮你梳理好思路&#xff0c;看接下…

vue项目开发环境工具-node

最近在开始接触做vue框架的前端项目&#xff0c;以前用的前端比如html&#xff0c;js&#xff0c;css等都是比较原生的&#xff0c;写好后直接浏览器打开就行。但vue跟java一样是需要编译的&#xff0c;和微信小程序类似。今天就先记录一下vue的开发运行搭建。所需工具如下 nod…

【MySQL】MySQL 官方安装包形式

MySQL 官方提供3种包&#xff1a; 1. 源码包 mysql-5.7.42.tar.gz mysql-5.7.42-aarch64.tar.gz http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.34.tar.gz http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.42.tar.gz需要用户根据自己的CPU架构选择对应的…

vue3+ts创建前端blog项目

vue3创建blog项目 cmd创建Manually select featuresChoose Vue versionUse class-style component syntax? (Y/n)Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n)Use history mode for router?Pick a CSS pre…

Python之函数、模块、包库

函数、模块、包库基础概念和作用 A、函数 减少代码重复 将复杂问题代码分解成简单模块 提高代码可读性 复用老代码 """ 函数 """# 定义一个函数 def my_fuvtion():# 函数执行部分print(这是一个函数)# 定义带有参数的函数 def say_hello(n…

码科速送同城跑腿小程序 v3.2.8+用户端+接单端 安装测试教程

码科速送同城跑腿V3.2.8版本包含骑手端用户端小程序&#xff01;骑手端码科跑腿快速发单&#xff0c;码科速送同城跑腿小程序是一款专用于同城跑腿小程序源码&#xff0c;播播资源针对这系统安装后感觉配置比较折腾人&#xff0c;不过正常使用后基本没发现什么BUG。本版本并非开…

摄影后期图像编辑软件Lightroom Classic 2023 mac中文特点介绍

Lightroom Classic 2023 mac是一款图像处理软件&#xff0c;是数字摄影后期制作的重要工具之一&#xff0c;lrc2023 mac适合数字摄影后期制作、摄影师、设计师等专业人士使用。 Lightroom Classic 2023 mac软件特点 高效的图像管理&#xff1a;Lightroom Classic提供了强大的图…

JUC——并发编程—第四部分

理解JMM Volatile是Java虚拟机提供的轻量级的同步机制。有三大特性。 1.保证可见性 2.不保证原子性 3.禁止指令重排 定义:Java内存模型&#xff0c;是一个概念。 关于JMM的一些同步的约定: 1、线程解锁前&#xff0c;必须把共享变量立刻刷回主存. 2、线程加锁前&#x…

【AI视野·今日Robot 机器人论文速览 第四十三期】Thu, 28 Sep 2023

AI视野今日CS.Robotics 机器人学论文速览 Thu, 28 Sep 2023 Totally 37 papers &#x1f449;上期速览✈更多精彩请移步主页 Interesting: &#x1f4da;****触觉力控学习策略,基于触觉的主动推理与力控用于小孔插入任务。提出了姿态控制与插入控制双策略模型。 (from 东京大学…

HTML开篇之安装VSvode(用记事本编辑HTML)

文章目录 前端开篇开篇知识点讲解1.HTML 结构1.1认识 HTML 标签1.2HTML 文件基本结构1.3标签层次结构1.4快速生成代码框架1.5用记事本写HTML1.6前端开发工具1.7下载vscode 及使用教学 大家好&#xff0c;我是晓星航。今天为大家带来的是 HTML 相关的讲解&#xff01;&#x1f6…

redis的简单使用

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