"Error in NPC Behavior Script on NPC Setup" on NPC spawners with Verse's auto-generated NPC behavior script when stopping/playing a map.

Summary

All my NPC errors out by failing to load their agent/interfaces and do not move after reloading the map.

Please select what you are reporting on:

Creative

What Type of Bug are you experiencing?

Assets

Steps to Reproduce

1- Create Verse script > Create NPC behavior “new_npc_behavior” (not the basic)
2- Create a NPC Character Definition using this behavior and apply it to a NPC Spawner
3- Launch a session on the Fortnite client
4- In either the UEFN editor or inside the client: Stop the game to return to creative mode and restart it.

Expected Result

NPCs moving according to the their behavior script in both game loading.

Observed Result

NPCs moving normally in the 1st loading but failing to load their agent/interfaces on 2nd+ loading.

Platform(s)

Windows 10

Upload an image




Additional Notes

  • My map contain 2 NPCs: Jonesy who does nothing and the girl who moves randomly using Verse’s auto-generated script.
  • My screenshots show the NPC moving and printing normally and their error messages on 2nd loading. As well as the spawners’ configuration in the editor.
  • Here are the NPC’s onBegin function:

Jonesy ‘nothing’ :

    # This function runs when the NPC is spawned in the world and ready to follow a behavior.
    OnBegin<override>()<suspends>:void =

            if {
                # Get the Agent (the NPC).
                Agent := GetAgent[]
                
                # Gets the Fortnite Character interface, which gets you access to its gameplay data 
                # including its AI module for navigation and focus.
                Character := Agent.GetFortCharacter[]
                
                # Get the Navigatable Interface, this allows you to tell it to move.
                Navigatable := Character.GetNavigatable[]
                
                # Get the Focus Interface, this allows you to tell it to look at something or somewhere.
                Focus := Character.GetFocusInterface[]
            } then {
                loop {
                    PrintNPCB("Running loop.",
                        ?Duration := AIDebugDrawTime, 
                        ?TextColor := NamedColors.Green )
                    Focus.MaintainFocus(Agent)
                }
            } else {
            # If code falls here something failed when gathering the agent or its interfaces
                if(ShowAIDebug?):
                    PrintNPCB("Error in NPC Behavior Script on NPC Setup",
                        ?Duration := AIDebugDrawTime, 
                        ?TextColor := NamedColors.Red )
            }

Girl auto-generated script:

    # This function runs when the NPC is spawned in the world and ready to follow a behavior.
    OnBegin<override>()<suspends>:void =

        if:
            # Get the Agent (the NPC).
            Agent := GetAgent[]

            # Gets the Fortnite Character interface, which gets you access to its gameplay data 
            # including its AI module for navigation and focus.
            Character := Agent.GetFortCharacter[]

            # Get the Navigatable Interface, this allows you to tell it to move.
            Navigatable := Character.GetNavigatable[]

            # Get the Focus Interface, this allows you to tell it to look at something or somewhere.
            Focus := Character.GetFocusInterface[]

        then:
            # TODO: Now that you have the Fortnite Character and the AI interfaces, replace this with your code 
            # for your desired movement, look at, and other behavior allowed by the AI module.
            if(ShowAIDebug?):
                Print(new_npc_behavior_message_module.OnBeginMessage(Agent), ?Duration := AIDebugDrawTime)

            # Save the position of your character which we'll use to generate more points to move to from.
            NPCSpawnPoint := Character.GetTransform().Translation

            loop:
                # Create a random offset from the spawn point to walk toward.
                GoToPoint := NPCSpawnPoint + vector3{X := GetRandomFloat(-DistanceFromSpawnPtToMove,DistanceFromSpawnPtToMove),
                                                     Y := GetRandomFloat(-DistanceFromSpawnPtToMove,DistanceFromSpawnPtToMove),
                                                     Z := 0.0 }
                
                if(ShowAIDebug?):
                    Print(new_npc_behavior_message_module.OnNavigateBeginMessage(Agent,GoToPoint.X,GoToPoint.Y,GoToPoint.Z), ?Duration := AIDebugDrawTime)

                # Create a navigation target from these two positions that the navigation interface can use.
                NavTargetStart := MakeNavigationTarget(GoToPoint)
                NavTargetEnd := MakeNavigationTarget(NPCSpawnPoint)
                
                # If the debug flag is enabled draw a box around the location the NPC is moving toward for visual
                # validation that it is where you expect.
                if(ShowAIDebug?):
                    DrawDebugLocation(GoToPoint)
            
                # Tell the navigation interface to walk to the location and store a navigation result for error checking.
                NavResultGoTo := Navigatable.NavigateTo(NavTargetStart, ?MovementType:=movement_types.Walking)
                
                # Check to see if something has interfered with the NPC reaching the intended location and print a
                # message to the output log.
                if (NavResultGoTo <> navigation_result.Reached):
                    if(ShowAIDebug?):
                        Print(new_npc_behavior_message_module.OnNavigateErrorMessage(Agent,GoToPoint.X,GoToPoint.Y,GoToPoint.Z), ?Duration := AIDebugDrawTime)
                else:
                    # Once it arrives at its location, wait for this duration in seconds
                    Navigatable.Wait(?Duration := MoveToWaitDuration)
                 
                # Draw more debug visuals to show the point the NPC will look at and move to.
                if(ShowAIDebug?):
                    DrawDebugLocation(NPCSpawnPoint)
                
                # Leveraging concurrency to wait until the NPC reaches its destination, while the calls to look back at its origin point 
                # and drawing a debug arrow never completes, continuing, ensures only the NavigateTo can win the race.
                NavResultGoToNext := race:
                    # Move back to its starting position.
                    Navigatable.NavigateTo(NavTargetEnd)

                    # Sets NPC to look at its previous position which will make it walk backwards. 
                    # This is meant to show the utility of the focus interface.
                    block:
                        Focus.MaintainFocus(GoToPoint)
                        navigation_result.Interrupted

                    block:
                        if(ShowAIDebug?):
                            DrawDebugLookAt(Character, GoToPoint) 
                        else:
                            Sleep(Inf)
                        navigation_result.Interrupted
                
                # Check again to see if something has interfered with the NPC reaching the intended location and
                # print a message to the output log.
                if (NavResultGoToNext <> navigation_result.Reached):
                    if(ShowAIDebug?):
                        Print(new_npc_behavior_message_module.OnNavigateErrorMessage(Agent,GoToPoint.X,GoToPoint.Y,GoToPoint.Z), ?Duration := AIDebugDrawTime)
                else:
                    # This tells the NPC to wait for this amount of time in seconds.
                    Navigatable.Wait(?Duration := MoveToWaitDuration)

                # End of loop, continue the patrol back to the point.
        else:
            # If code falls here something failed when gathering the agent or its interfaces
            if(ShowAIDebug?):
                PrintNPCB("Error in NPC Behavior Script on NPC Setup",
                        ?Duration := AIDebugDrawTime, 
                        ?TextColor := NamedColors.Red )

Yeah, GetAgent[] in npc_behavior seems broken after the last update. There’s a similar thread here: Verse AI Pathing broken after Round 1 in 33.30 - #8 by Flak

I found a bad workaround to get the agent by:

  1. Make an interface with a method signature of something like NagivateAgent(InAgent : agent)
  2. Inherit your interface in your custom npc_behavior
  3. Move your OnBegin logic to NavigateAgent
  4. Subscribe to your npc spawner device spawn event
  5. On spawn, get the agents behavior from the agent
  6. Cast the behavior to your interface
  7. Call NavigateAgent, passing in the agent from SpawnedEvent

Even with the agent though, NagivateTo still seems to be broken. :man_facepalming:

Edit: I just tested this morning though and navigation seems to be working again

1 Like