🔦 光线投射(Raycast)#

#bs.raycast:help

Cast rays to detect block and entity hits, with voxel-accurate collisions.

“现实只有在诗歌之光的照耀下才会展现自己。”

—乔治·布拉克(Georges Braque)

寻找简单的用例?

如果你只想检测实体正在看什么(瞄准的方块、瞄准的实体、击中点),视图模块 提供了简化包装器,处理常见情况。

它是如何工作的?

此模块使用 体素遍历 算法。射线从一块边界步进到下一块,而不是在固定间隔检查点,确保每个方块都被检查而无需冗余操作。


🔧 函数#

你可以在下方找到此模块中的所有可用函数。


运行#

#bs.raycast:run {with:{}}

在执行位置发射一条射线并检查它的碰撞情况。

输入:

执行 at <entity>positioned <x> <y> <z> rotated <rot>:射线的原点

函数宏

  • 参数

    • with:射线输入数据

      • blocks:射线是否在方块处停止(默认:true)

        可以是 碰撞箱提供器(例如 function #bs.hitbox:callback/get_block_collision)。

      • entities:射线是否在实体处停止(默认:false)

        可以是选择器标签(通常通过 /tag 分配),出于性能考虑,更推荐使用。

      • ignored_blocks:要忽略的方块(默认值:#bs.hitbox:intangible

      • ignored_entities:要忽略的实体类型(默认值:#bs.hitbox:intangible

        不适用于具有自定义碰撞箱的实体。

      • max_distance:射线最大传播距离(默认值:16.0)

      • on_targeted_block:以目标方块为 at 位置运行的回调(坐标已对齐)。

      • on_targeted_entity:对目标实体执行 asat 的回调。

      • on_entry_point:对射线进入形状的点执行 at 的回调。

        对于复杂形状和穿透,可能每个方块运行多次。

      • on_exit_point:对射线离开形状的点执行 at 的回调。

        对于复杂形状和穿透,可能每个方块运行多次。

      • piercing:射线可穿过的方块或实体(默认值:0)。

        • blocks: blocks to track independently from entities (default: 0)

        • entities: entities to track independently from blocks (default: 0)

Lambda 函数:

记分板 $raycast.entry_distance bs.lambda:从原点到进入点的距离(×1000)

记分板 $raycast.exit_distance bs.lambda:从原点到退出点的距离(×1000)

记分板 $raycast.prev_entry_distance bs.lambda:上一次击中的进入距离(×1000)

记分板 $raycast.prev_exit_distance bs.lambda:上一次击中的退出距离(×1000)

记分板 $raycast.hit_face bs.lambda:边界框的进入面,5 为东,4 为西,3 为南,2 为北,1 为顶部,0 为底部

记分板 $raycast.hit_flag bs.lambda:相交边界框的标志,-1 表示实体

Score $raycast.piercing bs.lambda:剩余可穿过的方块或实体数量。

记分板 $raycast.entry_point.[x,y,z] bs.lambda:相对于方块或实体的进入点(×1000)

记分板 $raycast.exit_point.[x,y,z] bs.lambda:相对于方块或实体的退出点(×1000)

记分板 $raycast.targeted_block.[x,y,z] bs.lambda:目标方块的坐标

输出:

返回值:射线是否与碰撞箱发生碰撞(1 或 0)。

什么是边界框?

边界框是一个矩形框,环绕物体(或物体的一部分),用于检测其位置和接触对象。例如,楼梯使用两个边界框:一个用于下台阶,一个用于上台阶。

自定义碰撞箱

Bookshelf 支持多种 hitbox types 以实现精确控制。方块可使用自定义 hitbox providers。实体支持 dynamicbakedcustom 类型。

贡献者:Aksiome


🎓 使用方法#

基础射线投射#

最简单的情况下,射线检测检查你前方是否有物体,并返回 1(击中)或 0(未击中):

# Check if there's a block within 10 blocks in front of you
execute anchored eyes positioned ^ ^ ^ store result score #hit bs.data run function #bs.raycast:run {with:{max_distance:10}}

默认情况下,射线检测方块但不检测实体。返回值告诉你是否发生了碰撞。


使用回调#

回调允许你在射线击中物体时运行命令。有四种回调类型:

回调

运行位置

用例

on_targeted_block

对齐的方块位置

放置/破坏方块,检查方块类型

on_targeted_entity

实体位置(as & at)

伤害、标记或与实体交互

on_entry_point

射线进入的精确点

生成粒子,精确击中效果

on_exit_point

射线退出的精确点

穿透效果,出口伤

示例:在射线击中方块的确切位置生成粒子

execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{on_entry_point:"particle minecraft:flame ~ ~ ~"}}

配置检测#

默认情况下,射线检测方块但不检测实体。你可以使用 blocksentities 参数更改此设置。

Blocks 接受 true(默认)、falsehitbox provider

# Ignore blocks entirely
execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{blocks:false,entities:true,on_targeted_entity:"say Hit!"}}

Entities 接受 truefalse(默认)或一个实体标签来筛选可被击中的实体。

# Detect all entities
execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{entities:true,on_targeted_entity:"say I was hit!"}}

# Detect only entities with a specific tag (better performance)
execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{entities:"my_tag",on_targeted_entity:"say I was hit!"}}

小技巧

使用标签选择器(entities:"my_tag")比 entities:true 性能更好,因为它缩小了要检查的实体范围。


筛选目标#

使用 ignored_blocksignored_entities 指定射线应跳过的目标:

# Ignore glass blocks
execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{ignored_blocks:"#c:glass_blocks",on_targeted_block:"setblock ~ ~ ~ stone"}}

# Ignore specific entity types
execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{entities:true,ignored_entities:"#bs.hitbox:intangible",on_targeted_entity:"say Hit!"}}

默认值:

  • ignored_blocks#bs.hitbox:intangible(无法物理交互的方块)

  • ignored_entities#bs.hitbox:intangible(不充当物理障碍的实体)


穿透#

默认情况下,射线在第一次碰撞时停止。使用 piercing 让射线穿过多个目标:

# Pass through up to 3 blocks before stopping
execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{piercing:3,on_entry_point:"particle minecraft:flame ~ ~ ~"}}

你还可以分别跟踪方块和实体:

# Pass through 2 blocks but stop at first entity
execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{entities:true,piercing:{blocks:2,entities:0},on_entry_point:"particle minecraft:flame ~ ~ ~"}}

Lambda 分数#

Lambda 分数提供关于碰撞的详细信息,仅在回调内部可用。请参阅上面的函数参考以获取完整列表。

常见用例:

  • $raycast.entry_distance - 击中点距离射线原点的距离

  • $raycast.entry_point.[x,y,z] - 相对于目标的精确击中位置

  • $raycast.hit_face - 击中的面(0=底部,1=顶部,2=北,3=南,4=西,5=东)

  • $raycast.hit_flag - 击中的碰撞箱形状(取决于提供者,实体为 -1

重要

位置分数(entry_pointexit_point)有不同的参考点:

  • 方块:相对于对齐的方块位置

  • 实体:相对于实体的位置


碰撞箱提供者#

碰撞箱提供者控制射线检测使用的方块形状。默认只检测实心碰撞形状,但你可以使用其他提供者检测流体等形状。

# Detect both solid blocks and fluids
execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{blocks:"function #bs.hitbox:callback/get_block_shape_with_fluid",ignored_blocks:"#air"}}

提供者可以定义具有不同标志的多个形状。当发生这种情况时:

  • on_targeted_block 每个方块运行一次,$raycast.hit_flag 组合所有相交的形状

  • on_entry_pointon_exit_point 每个形状运行一次,$raycast.hit_flag 设置为该形状的标志

例如,流体提供者对固体使用 1,对流体使用 2。含水的方块可能触发入口/出口回调两次(带有标志 12),而 on_targeted_block 一次带有标志 3


💬 这对你有帮助吗?

欢迎在下方留下你的问题和反馈!