Unity实现在镜子间反射光柱

一、最终效果:

二、代码来源及思路

unity-raycast-reflection/Assets/RaycastReflection.cs at master · Loafwad/unity-raycast-reflection · GitHub

在GitHub找到了现成的,效果很好,稍微改了一点来满足我的需求,并加上了注释理解,代码如下

using System.Collections;
using System.Collections.Generic;
//using UnityEditor.EditorTools;
using UnityEngine;

public class MirrorReflection : MonoBehaviour
{
    //挂在发射光线的物体上
    [Tooltip("光线反射次数")]
    public int refelections;
    [Tooltip("光线最大长度")]
    public float maxLength;
    /// <summary>
    /// 通过这个transform旋转后的up来决定射线方向
    /// </summary>
    [Tooltip("光线射出的方向")]
    public Transform direction;
    
    LineRenderer lineRenderer;
    Ray ray;
    RaycastHit hit;
    

    void Awake()
    {
        lineRenderer =GetComponent<LineRenderer>();    
    }
    void Update()
    {
        //ray在这为初始光线的起点和方向
        ray = new Ray(transform.position,direction.up);
        
        //设定初始光线起点
        lineRenderer.positionCount=1;
        lineRenderer.SetPosition(0,transform.position);
        
        //定义剩余长度
        float remainingLength = maxLength;

        //反射
        for(int i=0;i<refelections;i++){
            //如果打到物体
            if(Physics.Raycast(ray.origin,ray.direction,out hit,remainingLength)){
                //光线击中物体
                lineRenderer.positionCount+=1;
                lineRenderer.SetPosition(lineRenderer.positionCount-1,hit.point);//设置末端点位置
                remainingLength-=Vector3.Distance(ray.origin,hit.point);//更新剩余光线长度
                

                //如果打到的物体不是镜子,则不继续发生折射
                if(hit.collider.tag!="Mirror"){
                    break;
                }

                //将Ray更新成折射后的射线
                ray=new Ray(hit.point,Vector3.Reflect(ray.direction,hit.normal));
            }
            //如果没打到任何东西
            else if(i==refelections-1){
                //则在设定长度的末端生成一个端点
                lineRenderer.positionCount+=1;
                lineRenderer.SetPosition(lineRenderer.positionCount-1,ray.origin+ray.direction*remainingLength);
            }
        }
    }
}

思路: 该脚本挂在光源物体上(发射光柱的物体,即光柱起点物体),给光源物体加上一个子物体法平面用于调节光柱方向。

围绕Vector3的reflect方法确定所需参数,利用unity提供的Ray类型在代码中确定光柱的起点和方向,LineRenderer渲染实际光柱

ray建立入射光线的起点以及入射方向,使用Raycast方法(它有很好的特性:能获取被射点的法线normal向量)得到入射点的法线向量,即可完成光线入射

而如果入射物体是镜子,则可以发生反射。更新ray的起点为入射点,方向为使用reflect方法计算得出的反射方向向量。

如果入射物体不是镜子,则不计算反射光线,也不更新ray,仅在最后一次循环时更新光柱末端点

写在update里起到每帧都会重新发射一次光线的作用

for循环决定了一帧内一共能反射多少次(通过refelections来控制数量)

三、场景搭建步骤

1、创建一个发射光线的物体,我这里创了一个球体来代表光源

2、给光源添加LineRenderer组件,size改成0,线的材质可以根据自己需求改,我这里用默认材质

3、再在光源物体下创建一个法平面子物体(作用是决定光源物体发射的光线的方向)

个人认为直接创建一个平面物体在下面好一些,调方向的时候很直观

调好方向后关掉MeshRenderer(自带的collider可以移除掉)

PS.为什么不直接转光源物体来决定方向?LineRenderer不会跟着物体转

5、给光源物体挂上MirrorRefelection脚本,设定好需要的反射次数,光柱总长度,以及挂上直接设置的法平面

4、创建一个带“mirror”tag的镜子,我这里创建了一个平面来当作镜子,并且设置了一个镜子材质

注意:ray要想成功打到物体要求那个物体必须有collider才能检测到,因此使用自定义模型时一定要记住添加碰撞体(并且meshcollider的话要求勾选convex)

5、运行,可以多复制几个镜子验证效果

这样看效果还比较差,需要调节LineRenderer的参数

这样就发现圆润多了

但是我们会发现悬空了,悬空的原因是平面的collider比较大,不贴合平面本身

所以自己建一个boxcollider调整一下位置就好啦

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

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

相关文章

快速理清 Attention 注意力和 Encoder, Decoder 概念

之前一直以为 Attention 和 RNN 没关系是凭空蹦出来的新概念&#xff1b;以为 Transformer, Encoder, Decoder 这几个概念是绑在一起的。并不尽然。 Encoder 和 Decoder RNN 里就有 Encoder Decoder 的概念。其中&#xff0c;encoder 接受用户输入&#xff0c;写入 hidden stat…

达梦数据库系列之Mysql项目迁移为达梦项目

达梦数据库系列之Mysql项目迁移为达梦项目 1 达梦数据库安装及MySql数据迁移2 SpringBoot项目迁移2.1 驱动包引入2.2 驱动类配置2.3 数据源配置2.4 flowable迁移2.4.1 异常问题2.4.2 解决 3 迁移常见问题3.1 不是 GROUP BY 表达式3.1.1 dm.ini 开启Mysql兼容模式3.1.2 修改动态…

第5章 使用OSSEC进行监控(网络安全防御实战--蓝军武器库)

网络安全防御实战--蓝军武器库是2020年出版的&#xff0c;已经过去3年时间了&#xff0c;最近利用闲暇时间&#xff0c;抓紧吸收&#xff0c;总的来说&#xff0c;第5章开始进入主机安全&#xff08;HIDS&#xff09;领域了&#xff0c;2022年的时候有幸做过终端安全一段时间&a…

【文献阅读】The Efficiency Spectrum of Large Language Models: An Algorithmic Survey

这篇文章发表于2024年4月 摘要 大语言模型&#xff08;LLMs&#xff09;的快速发展推动了多个领域的变革&#xff0c;重塑了通用人工智能的格局。然而&#xff0c;这些模型不断增长的计算和内存需求带来了巨大挑战&#xff0c;阻碍了学术研究和实际应用。为解决这些问题&…

毕业项目推荐:基于yolov8/yolov5/yolo11的暴力行为检测识别系统(python+卷积神经网络)

文章目录 概要一、整体资源介绍技术要点功能展示&#xff1a;功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出&#xff08;xls格式&#xff09;功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…

MySQL面试01

MySQL 索引的最左原则 &#x1f370; 最左原则本质 ͟͟͞͞( •̀д•́) 想象复合索引是电话号码簿&#xff01; 索引 (a,b,c) 的排列顺序&#xff1a; 先按a排序 → a相同按b排序 → 最后按c排序 生效场景三连&#xff1a; 1️⃣ WHERE a1 ✅ 2️⃣ WHERE a1 AND b2 ✅ 3️…

【Linux】【网络】UDP打洞-->不同子网下的客户端和服务器通信(未成功版)

【Linux】【网络】UDP打洞–>不同子网下的客户端和服务器通信&#xff08;未成功版&#xff09; 上次说基于UDP的打洞程序改了五版一直没有成功&#xff0c;要写一下问题所在&#xff0c;但是我后续又查询了一些资料&#xff0c;成功实现了&#xff0c;这次先写一下未成功的…

unity学习63,第2个小游戏:用fungus做一个简单对话游戏

目录 1 目标用fungus做一个简单的剧情对话游戏 1.1 先创建一个新的3D项目 1.2 fungus是什么 1.2.1 怎么获得 1.2 在AssetStore里搜索fungus (插件类)--千万别买收费的错的&#xff01; 1.3 fungus的官网 1.3.1 官网给的3个下载链接&#xff0c;unity的果然已经失效了 …

前后分离文件上传案例,前端HTML,后端Net6开发的webapi(完整源代码)下载

文件上传功能在项目开发中非常实用&#xff0c;本案例前端用HTML页面的form表单实现&#xff0c;后端用Net6实现。 前后分离文件上传案例&#xff0c;前端HTML&#xff0c;后端Net6&#xff08;完整源代码&#xff09; 下载链接https://download.csdn.net/download/luckyext/9…

利用Adobe Acrobat 实现PPT中图片分辨率的提升

1. 下载适用于 Windows 的 64 位 Acrobat 注册方式参考&#xff1a;https://ca.whu.edu.cn/knowledge.html?type1 2. 将ppt中需要提高分辨率的图片复制粘贴到新建的pptx问价中&#xff0c;然后执行“文件—>导出---->创建PDF、XPS文档” 3. 我们会发现保存下来的distrib…

自学微信小程序的第十二天

DAY12 1、腾讯地图SDK是一套为开发者提供多种地理位置服务的工具,可以使开发者在自己的应用中加入地图相关功能,轻松访问腾讯地图服务和数据,更好地实现微信小程序的地图功能。 表49:search()方法的常用选项 选项 类型 说明 keyword string POI搜索关键词,默认周边搜索 l…

海南自贸港的数字先锋:树莓集团的战略布局解析

海南自贸港凭借其独特的政策优势和地理条件&#xff0c;成为了数字产业发展的热土。树莓集团敏锐地捕捉到这一机遇&#xff0c;在此展开了全面而深远的战略布局。 在基础设施建设方面&#xff0c;树莓集团投入大量资金&#xff0c;建设了先进的数据中心。这些数据中心配备了顶…

MySQL -操作

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【暂无】 欢迎点赞&#x1f44d;收藏⭐关注❤️ 文章目录 创建数据库格式编码集 操控数据库查看数据库修改数据库删除数据库备份与还原 部分表操作创建表查看表修改表 我的版本号&#xff1a;8.0.41-0ubuntu0.22.04.1 创…

ubuntu20系统下conda虚拟环境下安装文件存储位置

在 Conda 虚拟环境中执行 pip install 安装软件后&#xff0c;安装的文件会存储在该虚拟环境专属的 site-packages 目录中。具体路径取决于你激活的 Conda 环境路径。以下是定位步骤&#xff1a; 1. 确认 Conda 虚拟环境的安装路径 查看所有环境&#xff1a; conda info --env…

Blazor-路由模板(上)

Blazor 的路由模板是定义应用中不同页面或组件访问路径的一种方式。通过路由模板&#xff0c;你可以管理应用程序的导航结构&#xff0c;支持基本路由、参数路由、子路由和区域路由等功能。 我们为访问组件使用page 指令指定路由 URL page "/demoPage" <h3>&l…

OpenObserve开源高性能云原生平台本地部署与远程监控数据攻略

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;人工智能教程 文章目录 前言1. 安装Docker2. 创建并启动OpenObserve容器3. 本地访问测试4. 公网访问本地部署的OpenObserve4.1 内网穿透工具安装…

鸿蒙HarmonyOS-Navagation基本用法

Navagation基本用法 Navigation组件是路由导航的根视图容器&#xff0c;一般作为Page页面的根容器使用&#xff0c;其内部默认包含了标题栏&#xff0c;内容栏和公工具栏&#xff0c;其中内容区默认首页显示导航内容&#xff08;Navigation的子组件&#xff09;或非首页显示&am…

相控阵扫盲

下图展示天线增益 在仰角为0度的情况下随着方位角的变化而变化。需要注意到的是在天线视轴方向上的高增益主瓣上还有几个低增益旁瓣 阵列因子乘以新的阵元方向图会形成指向性更强的波速

CDefView::_OnFSNotify函数分析

进入CDefView::_OnFSNotify函数时状态栏 _UpdateStatusBar函数之后增加一个对象&#xff0c;变成7个对象。 LRESULT CDefView::_OnFSNotify(LONG lNotification, LPCITEMIDLIST* ppidl) { LPITEMIDLIST pidl; LPCITEMIDLIST pidlItem; // we may be registered for no…

人工智能之数学基础:矩阵的秩

本文重点 矩阵的秩,作为矩阵理论中的一个核心概念,是连接矩阵性质与应用的重要桥梁。本文我们将学习矩阵秩的概念,通过矩阵的秩可以判断矩阵是否可逆等等,所以矩阵的秩是非常重要的一个概念。 矩阵秩的概念 秩定义为矩阵A的线性独立的行(或列)的最大数目。也就是说,如…