Hi there. How can I detect an entity that looks at the player?
I have a command that search for marker armor stands near the player. How can I make it so that the command will be executed only if the player is in front of them?
You could do this with raycasting, but I just thought of another smart way to go about doing this.
NOTE: The following commands are run by the armor stand (every tick).
First, we take the current yaw and pitch (so the rotation values of the player) and store those in a scoreboard:
scoreboard objectives add originalYaw dummy
scoreboard objectives add originalPitch dummy
execute store result score @s originalYaw run data get entity @s Rotation[0]
execute store result score @s originalPitch run data get entity @s Rotation[1]
Then we summon another invisible and marker armor stand at the position of the original armor stand like this:
We can now force this 'rotCheck' armor stand to face the player. When that is done we can take that armor stand's yaw and pitch, so the yaw and pitch necessary for it to be looking at the player:
execute as @e[tag=rotCheck] at @s facing entity @p eyes run tp @s ~ ~ ~ ~ ~
scoreboard objectives add goalYaw
scoreboard objectives add goalPitch
execute store result score @s goalYaw run data get entity @e[tag=rotCheck,limit=1] Rotation[0]
execute store result score @s goalPitch run data get entity @e[tag=rotCheck,limit=1] Rotation[1]
Finally we can subtract originalYaw from goalYaw and originalPitch from goalPitch. This might give us negative values, however, so we'll account for that and convert negative values to positive ones.
scoreboard objectives add distanceYaw
scoreboard objectives add distancePitch
execute store result score @s distanceYaw run scoreboard players operation @s originalYaw -= @s goalYaw
execute store result score @s distancePitch run scoreboard players operation @s originalPitch -= @s goalPitch
scoreboard objectives add Constants
scoreboard players set -1 Constants -1
execute if score @s distanceYaw matches ..0 run scoreboard players operation @s distanceYaw *= -1 Constants
execute if score @s distancePitch matches ..0 run scoreboard players operation @s distancePitch *= -1 Constants
After doing all that you have a positive value that indicates how many degrees of rotation the yaw and pitch of the player is from the degrees they would have when looking directly at the player. You can choose a range yourself and if the offset is within a small range you could assume they're pretty much looking at the player:
execute if score @s distanceYaw matches ..10 if score @s distancePitch matches ..10 run say I am pretty much looking at the nearest player!
All together you get this function that gets run by every armor stand every tick:
#Scoreboard objectives
scoreboard objectives add originalYaw dummy
scoreboard objectives add originalPitch dummy
scoreboard objectives add goalYaw
scoreboard objectives add goalPitch
scoreboard objectives add distanceYaw
scoreboard objectives add distancePitch
scoreboard objectives add Constants
scoreboard players set -1 Constants -1
#Store original yaw and pitch
execute store result score @s originalYaw run data get entity @s Rotation[0]
execute store result score @s originalPitch run data get entity @s Rotation[1]
#Summon armor stand, face it towards the player and store its yaw and pitch
summon minecraft:armor_stand ~ ~ ~ {Marker:1b,Invisible:1b,Tags:["rotCheck"]}
execute as @e[tag=rotCheck] at @s facing entity @p eyes run tp @s ~ ~ ~ ~ ~
execute store result score @s goalYaw run data get entity @e[tag=rotCheck,limit=1] Rotation[0]
execute store result score @s goalPitch run data get entity @e[tag=rotCheck,limit=1] Rotation[1]
#Compare the original and goal yaw and pitch and account for negative values
execute store result score @s distanceYaw run scoreboard players operation @s originalYaw -= @s goalYaw
execute store result score @s distancePitch run scoreboard players operation @s originalPitch -= @s goalPitch
execute if score @s distanceYaw matches ..0 run scoreboard players operation @s distanceYaw *= -1 Constants
execute if score @s distancePitch matches ..0 run scoreboard players operation @s distancePitch *= -1 Constants
#Check if the result is within range offset
execute if score @s distanceYaw matches ..10 if score @s distancePitch matches ..10 run say I am pretty much looking at the nearest player!
#Kill the armor stand you used to check the rotation
kill @e[tag=rotCheck]
Hi there. How can I detect an entity that looks at the player?
I have a command that search for marker armor stands near the player. How can I make it so that the command will be executed only if the player is in front of them?
You could do this with raycasting, but I just thought of another smart way to go about doing this.
NOTE: The following commands are run by the armor stand (every tick).
First, we take the current yaw and pitch (so the rotation values of the player) and store those in a scoreboard:
Then we summon another invisible and marker armor stand at the position of the original armor stand like this:
We can now force this 'rotCheck' armor stand to face the player. When that is done we can take that armor stand's yaw and pitch, so the yaw and pitch necessary for it to be looking at the player:
Finally we can subtract originalYaw from goalYaw and originalPitch from goalPitch. This might give us negative values, however, so we'll account for that and convert negative values to positive ones.
After doing all that you have a positive value that indicates how many degrees of rotation the yaw and pitch of the player is from the degrees they would have when looking directly at the player. You can choose a range yourself and if the offset is within a small range you could assume they're pretty much looking at the player:
All together you get this function that gets run by every armor stand every tick:
Hope this helps!
Command FAQ
Minecraft Randomizer DataPack (by Me)
Thank you very much for such a detailed answer! I'll test it when I get back to Minecraft.