
动态手电筒
一个轻量级的玩家手电筒系统(指令,尚未制作模型),通过动态光源实体模拟向前照射的光束。
查看大图手电筒
为 Hytale 制作的小型插件实验,用于在未来的项目中实现玩家手电筒效果。
目前手电筒并非渲染为真正的投射光束,而是通过追踪玩家视角方向、在世界中寻找撞击点,并在这些命中位置周围生成小型动态光源实体来模拟的。这就是为什么可以看到它表现为向前投射的光束。
我还需要为手电筒创建一个模型。
当前思路
目前我尚不清楚如何正确实现,因此当前实现采用了一种更实用的变通方法:
- 读取玩家头部方向
- 追踪一条中心射线加上一圈额外射线
- 检测已加载世界区块中附近的命中点
- 选取有代表性的命中位置
- 在这些位置生成/更新动态光源实体
这样得到的结果更像是伪造的投射手电筒撞击效果,而非真正的渲染级手电筒。
工作原理
该插件分为几个简单的部分:
Main注册命令和刻循环系统FlashlightCommand启用、禁用或切换手电筒FlashlightTickSystem每隔数刻更新活跃的手电筒玩家FlashlightService包含主要逻辑FlashlightConeMath包含用于光束采样的数学辅助函数
运行时流程
当玩家执行命令时:
- 切换玩家手电筒状态
- 插件在世界线程上同步该玩家
- 手电筒激活期间,每隔数刻重新计算光束
光束近似
光束近似使用以下方式:
- 一条中心射线
- 围绕其周围的一圈射线
服务程序会将这些射线向前追踪,直到它们在已加载的区块中命中非空气方块。
从这些结果中:
- 如果存在中心命中点,则保留该点
- 将圆圈命中点合并为一个加权次要命中点
- 在这些位置生成或更新一个或多个动态光源实体
为什么使用动态光源实体
我选择使用生成的实体 + DynamicLight,因为目前我还没有合适的方法来完全按照我想要的方式渲染手电筒。
主要问题在于,我真正想要的是更接近以下效果的东西:
- 一个真正的表面投影
- 或者一个可见的锥形/光束效果
- 或者基于着色器的叠加/后期处理效果
配置
该插件支持一个 config.json 文件来设置手电筒的主要参数。
配置文件存储在插件数据目录中,首次加载时如果不存在则会自动创建。
它用于在不重新编译插件的情况下调整主要数值,例如:
- 调试渲染标志
- 撞击光源启用/禁用
- 玩家附着光源数值
- 光束范围和光束角度
- 射线步长
- 撞击背面偏移
- 圆圈射线数量
- 调试绘制设置
如果文件缺失,插件会自动写入一个默认文件。 如果文件已存在,插件则从中加载数值。
示例:
{
"debugDrawBeam": false,
"debugShowHitPoint": false,
"enableImpactLight": true,
"playerLightRadius": 0,
"playerLightRed": 0,
"playerLightGreen": 0,
"playerLightBlue": 0,
"minEffectiveHitDistance": 2.0,
"centerLightRadius": 5,
"sideLightRadius": 2,
"maxImpactLights": 10,
"beamRange": 50.0,
"beamHalfAngleDeg": 10.0,
"rayStep": 0.08,
"impactBackOffset": 0.15,
"beamRingRays": 10,
"debugDrawDurationSeconds": 0.12,
"debugLineWidth": 0.02,
"debugFade": false
}
激活手电筒的命令
/flashlight
/flashlight on
/flashlight off
正在加载版本记录…


正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。