# 老鸟教你用指令实现BOSS血条指向效果

今天小编为大家带来我的世界自定义BOSS血条实现指向效果教程，想学的玩家别错过下面的精彩内容！

从图中我们可以看到当玩家指向盔甲架的时候，TARGET这个bossbar满了。当玩家朝向和玩家指向盔甲架的向量的夹角θ超过90°时，TARGET变红，并且夹角θ越大，TARGET的值越大。过程不受抬头/低头影响。（gif中由于鼠标抖动而造成有一点不稳定）

看着挺高端，其实原理超级简单。就是最基础的Vector Math：点积（dot product）

我们先上命令：

init.mcfunction [LOAD]

# Initialization

# Create bossbar

bossbar create bossbar:target "TARGET"

# Player's location (X,Z)

scoreboard objectives add pos_p_x dummy

scoreboard objectives add pos_p_z dummy

# Target's location (X,Z)

scoreboard objectives add pos_t_x dummy

scoreboard objectives add pos_t_z dummy

# Player-facing vector (X,Z)

scoreboard objectives add vec_yw_x dummy

scoreboard objectives add vec_yw_z dummy

# Target-to-player vector (X,Z)

scoreboard objectives add vec_nvt_x dummy

scoreboard objectives add vec_nvt_z dummy

# Current dot product

scoreboard objectives add int_dp_vt dummy

# Max dot product

scoreboard objectives add int_dp_mx dummy

# Caclation output flag (to current or to max)

scoreboard objectives add con_mx_bool dummy

# Temp score when calculating abs

scoreboard objectives add tmp_abs_swp dummy

bossbar_navigation.mcfunction [TICK]

# Calculation

# Set storage flag(to max or current)

# Max

scoreboard players set @a con_mx_bool 1

# Calculate

execute as @a at @s facing entity @e[tag=target,sort=nearest,limit=1] eyes run function bossbar:bossbar_dotproduct_calculation

# Store max

execute as @a store result bossbar bossbar:target max run scoreboard players get @s int_dp_mx

# Current

scoreboard players set @a con_mx_bool 0

# Calculate

execute as @a at @s run function bossbar:bossbar_dotproduct_calculation

# Set display

# Current equals or is greater than 0

execute as @a[scores={int_dp_vt=0..}] run function bossbar:bossbar_positive_display

# Current is less than 0

execute as @a[scores={int_dp_vt=..-1}] run function bossbar:bossbar_minus_display

# Glow the target so that player can identify them easily

execute as @a at @s run effect give @e[tag=target,sort=nearest,limit=1] minecraft:glowing 1

bossbar_dotproduct_calculation.mcfunction

# Reset Scoreboards

# Current case

execute if entity @s[scores={con_mx_bool=0}] run scoreboard players set @s int_dp_vt 0

# Max case

execute if entity @s[scores={con_mx_bool=1}] run scoreboard players set @s int_dp_mx 0

# Get player's location (X,Z)

execute store result score @s pos_p_x run data get entity @s Pos[0] 100

execute store result score @s pos_p_z run data get entity @s Pos[2] 100

# Get player's facing vector(have not been normalized)

# Summon length-marker

execute if entity @s[scores={con_mx_bool=0}] rotated ~ 0 run summon minecraft:area_effect_cloud ^ ^ ^1 {CustomName:"["p_dir"]"}

# Get length-marker's location

execute store result score @s pos_t_x run data get entity @e[name=p_dir,sort=nearest,limit=1] Pos[0] 100

execute store result score @s pos_t_z run data get entity @e[name=p_dir,sort=nearest,limit=1] Pos[2] 100

# Calculate the vector

scoreboard players operation @s vec_yw_x = @s pos_t_x

scoreboard players operation @s vec_yw_z = @s pos_t_z

execute run scoreboard players operation @s vec_yw_x -= @s pos_p_x

execute run scoreboard players operation @s vec_yw_z -= @s pos_p_z

# Get target-to-player vector

# Get target's location

# Summon plainizer(X,Z)

execute run summon minecraft:area_effect_cloud ~ ~ ~ {CustomName:"["plainizer"]"}

# Correct the plainizer's location(Tx,Py,Tz)

execute store result entity @e[name=plainizer,sort=nearest,limit=1] Pos[0] double 1 run data get entity @e[tag=target,sort=nearest,limit=1] Pos[0]

execute store result entity @e[name=plainizer,sort=nearest,limit=1] Pos[1] double 1 run data get entity @s Pos[1]

execute store result entity @e[name=plainizer,sort=nearest,limit=1] Pos[2] double 1 run data get entity @e[tag=target,sort=nearest,limit=1] Pos[2]

# Summon length-marker

execute facing entity @e[name=plainizer,sort=nearest,limit=1] eyes run summon minecraft:area_effect_cloud ^ ^ ^1 {CustomName:"["tp_dir"]"}

# Get length-marker's location

execute store result score @s pos_t_x run data get entity @e[name=tp_dir,sort=nearest,limit=1] Pos[0] 100

execute store result score @s pos_t_z run data get entity @e[name=tp_dir,sort=nearest,limit=1] Pos[2] 100

# Calculate the vector

scoreboard players operation @s vec_nvt_x = @s pos_t_x

scoreboard players operation @s vec_nvt_z = @s pos_t_z

execute run scoreboard players operation @s vec_nvt_x -= @s pos_p_x

execute run scoreboard players operation @s vec_nvt_z -= @s pos_p_z

# Max case

execute if entity @s[scores={con_mx_bool=1}] run scoreboard players operation @s vec_yw_x = @s vec_nvt_x

execute if entity @s[scores={con_mx_bool=1}] run scoreboard players operation @s vec_yw_z = @s vec_nvt_z

# Dot Product

# Multiply the x and z of direction-vector to the x and z of target-to-player vector

execute run scoreboard players operation @s vec_nvt_x *= @s vec_yw_x

execute run scoreboard players operation @s vec_nvt_z *= @s vec_yw_z

# Add the result to output-scoreboards

# Current case

execute if entity @s[scores={con_mx_bool=0}] run scoreboard players operation @s int_dp_vt += @s vec_nvt_x

execute if entity @s[scores={con_mx_bool=0}] run scoreboard players operation @s int_dp_vt += @s vec_nvt_z

# Max case

execute if entity @s[scores={con_mx_bool=1}] run scoreboard players operation @s int_dp_mx += @s vec_nvt_x

execute if entity @s[scores={con_mx_bool=1}] run scoreboard players operation @s int_dp_mx += @s vec_nvt_z

※ 暂未想到办法简化第二个plainizer...感谢玄素dalao提供rotated思路

bossbar_positive_display.mcfunction

# Set color

bossbar set bossbar:target color white

# Write result to bossbar

execute store result bossbar bossbar:target value run scoreboard players get @s int_dp_vt

bossbar_minus_display.mcfunction

# Set color

bossbar set bossbar:target color red

# Get |int_dp_vt| by |int_dp_vt| = -int_dp_vt(int_dp_vt < 0) = int_dp_vt - 2 * int_dp_vt

scoreboard players operation @s tmp_abs_swp = @s int_dp_vt

scoreboard players operation @s int_dp_vt -= @s tmp_abs_swp

scoreboard players operation @s int_dp_vt -= @s tmp_abs_swp

# Write result to bossbar

execute store result bossbar bossbar:target value run scoreboard players get @s int_dp_vt

※ 以上所有文件都存在于bossbar命名空间内。请根据需要自行修改

※ [LOAD]为load.json内的function [TICK]为tick.json内的function

※ 注意，尽管我使用了@a，但是这个命令组只支持一个玩家。因为bossbar只有一个。

• 游戏大礼包
• 手游开测表

• 本月
• 最新

+更多

+更多