using { /Fortnite.com/Devices } using { /Fortnite.com/Characters } using { /UnrealEngine.com/Temporary/SpatialMath } using { /Verse.org/Simulation } # This is our device class. Think of it as the "brain" of the trap. spyglass_trap_device := class(concrete creative_device): # @editable variables appear in the device settings in UEFN. # Threshold: How precise the "looking" needs to be. # 0.95 = very precise (narrow cone), 0.5 = wide angle. @editable LookThreshold: float = 0.95 # The location we want players to look at. # We will set this via code to a fixed point in the sky. TargetLocation: vector3 = vector3(0.0, 0.0, 1000.0) # This function runs automatically when the game starts. OnBegin(): void = # Infinite loop! This keeps checking forever. loop: # Get all players currently in the game. # GetPlayers() returns a list of all active players. players := Self.GetPlayspace().GetPlayers() for player in players: # Get the character model for this player. # Not all players might have a character loaded yet, so we check. if (character := player.GetFortCharacter()): # 1. Get where the player's camera is. view_location := character.GetViewLocation() # 2. Get the direction the player is facing. # GetViewRotation() gives us the angle. # We convert that angle into a direction vector (an arrow). view_direction := character.GetViewRotation().GetForwardVector() # 3. Calculate the direction FROM the player TO the target. # Vector subtraction: Target - Player = Direction to Target. to_target := TargetLocation - view_location # Normalize turns that long arrow into a standard-length arrow (length 1). # This ensures distance doesn't mess up our angle check. to_target := Normalize(to_target) # 4. The Magic Math: Dot Product. # Dot product of two normalized vectors tells us how aligned they are. alignment := Dot(view_direction, to_target) # 5. Check if aligned enough. if alignment > LookThreshold: # BINGO! They are looking at the spot. # Let's make a sound or visual effect. # For simplicity, we'll just print to the debug log. Print("Player is staring at the target!") # Optional: Add your trap trigger here! # e.g., SpawnEffectAtLocation(...) # Small pause so we don't crash the game with 1000 checks per second. # 0.1 seconds = 10 checks per second. Smooth enough. await Delay(0.1)