using { /Fortnite.com/AI } using { /Fortnite.com/Characters } using { /Fortnite.com/Game } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/SpatialMath } using { /UnrealEngine.com/Temporary/Diagnostics } # CUSTOM NPC BEHAVIOR — teach a villager to flee when hurt. # # An npc_behavior is a Verse class that rides ON TOP of an NPC's built-in brain. # You attach it to an NPC Character Definition; OnBegin runs the moment the # character is simulating. Unlike a creative_device, an npc_behavior gets a # handle to its OWN character through GetAgent[] / GetFortCharacter[], then drives # it with the navigatable and focus interfaces. # # This villager stands still until something damages them — then it sprints away # from the attacker and keeps its eyes locked on the threat the whole time. fleeing_villager := class(npc_behavior): # How far to run when spooked (centimeters). FleeDistance : float = 1200.0 # OnBegin runs when the NPC enters the simulation. Wire up its damaged event. OnBegin() : void = if: Agent := GetAgent[] Character := Agent.GetFortCharacter[] then: Character.DamagedEvent().Subscribe(OnDamaged) Print("Villager is on patrol duty... nervously.") # When hit, run directly away from the instigator and stare them down. OnDamaged(Result : damage_result) : void = if: Agent := GetAgent[] Character := Agent.GetFortCharacter[] Navigatable := Character.GetNavigatable[] Focus := Character.GetFocusInterface[] Attacker := agent[Result.Instigator?] AttackerChar := Attacker.GetFortCharacter[] then: MyPos := Character.GetTransform().Translation ThreatPos := AttackerChar.GetTransform().Translation # Direction pointing FROM the threat TO us, normalized, then pushed out. Away := (MyPos - ThreatPos) FleePoint := MyPos + Away * FleeDistance Target := MakeNavigationTarget(FleePoint) Print("Villager spooked — fleeing!") # Keep looking at the attacker while we run (focus never completes # on its own, so spawn it as its own fiber). spawn{ Focus.MaintainFocus(Attacker) } spawn{ RunAway(Navigatable, Target) } # Sprint to the flee point; report whether we made it. RunAway(Navigatable : navigatable, Target : navigation_target) : void = Navigatable.SetMovementSpeedMultiplier(2.0) Result := Navigatable.NavigateTo(Target, ?MovementType := movement_type.Running) if (Result = navigation_result.Reached): Print("Villager reached safety.") else: Print("Villager's escape was blocked!")