Forum rules - please read before posting.

loop in NPC actions

Hello, I'm new to the forum and game development. I'm stuck at a point, and if someone could help me, it would be greatly appreciated. I'm trying to bring NPCs to life.

I've set up some NPCs to follow predetermined paths in the OnStart event, but I'm not satisfied with it. The first issue I'm facing is that when I talk to them, they stop to chat and don't resume their paths afterward. The second issue is that I feel restricted in controlling the characters' movements.

I've considered creating a system based on in-game hours or moments of the day, and I've read some posts in this forum about it. This involves creating a global variable for the time of day.

My problem is that I don't see how I can create a loop "within" the NPCs that constantly monitors the variable and performs different actions based on its value. Additionally, I want them to recover their intended actions if they get interrupted mid-path, and if they stopped for something like talking, I want them to resume their stroll.

Furthermore, I'd like to make them talk in the middle of their paths, and if I get ambitious, create interactions between them. How do I set up this loop within the NPC? Does it have to involve pure programming, or can it be done with AC (Adventure Creator)?

I've tried inserting an ActionList that I execute within the NPC from OnStart, but the game freezes until the action is complete, and if it stops, it doesn't recover.

Comments

  • If you just want the NPC to resume the path it was previously following, there is an AC action that does just that. You just have to run it after the conversation is over.

    But if you want the NPCs to follow a schedule, this is fairly complicated to do, especially depending on how closely you want the NPCs do adhere to the schedule, and how important continuity is to your game. For example, AC's Remember NPC scripts are useful if you want the NPCs to stay where they were when the player last left the scene, but if you want them to keep "existing" and doing stuff even when the player isn't in the scene, you can't rely on them.

    It's fairly simple to create a custscene that teleports NPCs around when you enter the scene, depending on the time of day. It's also not hard to have an actionlist that fires off whenever the time changes, and runs actions the NPCs are supposed to do at those times. If an NPC is supposed to go from point A to point B at 2pm, then you just need run an action to do that.

    But things get complicated really fast if, for example, you want to account for the times an NPC would be walking from point A to point B when you enter the scene. Say it takes 1 in-game hour for an NPC to walk that path. If the NPC is teleported to point A when you enter the scene between 8am and 2pm, and to point B when you enter the scene between 3pm and 7pm, what happens when you enter the scene between 2pm and 3pm (say, at 2:15pm)? Do you want the level of granularity where the NPC is placed at the exact point along the path where they would be if the player had been in the scene when the action would had been run at 2pm (in this case, 1/4 of the way)? And what happens if the player interrupts the NPC, leaves the scene, and then returns? You CAN take all of that into account with some scripting, but it's definitely not trivial, and it might not be worth the effort depending on what you want to accomplish with your game.

    Tldr; I'm afraid there is no simple solution here, particularly when you still don't know where you want your game to go. If you are just experimenting, go ahead and try building this type of logic from scratch! It's fun (and extremely frustrating at times). It will give you a good idea of the amount of work you need to do for those features, and it will help you understand the limitations you need to design your game within.

  • Hello,

    Even though in my game there's only one scene and the characters don't care about the time of day when they move, I want them to feel alive, and your suggestions have given me something to think about. A simple solution to what you mentioned could be something like this:

    I want an NPC to leave home for work and take 1 hour to arrive. I would program the following:

    If it's 8 AM and the NPC is at home, move the character to work.
    If it's later than 8 AM and the NPC is at home, teleport them to work.
    With this, the only thing that might happen oddly is if the scene loads a little after 8 AM and the NPC isn't at work yet, but within 1 hour of gameplay, they will appear, skipping the walk. Depending on the game mechanics, this could be perfectly acceptable.

    On the other hand, I still think that the most logical way to control the behavior of an NPC is to have a loop running in the NPC's own body that tells them what to do at each moment. However, this loop should interact well with the other types of iterations that AC has, such as when the player talks to them.

    I've been conducting some tests and noticed some odd behaviors with "Character: Move along path." I've added a 2-second pause between nodes. If I talk to the NPC while they are in the pause, or if I trigger a "Stop Moving" just before starting the conversation, the NPC will leave. This doesn't happen if I catch them in the middle of the walk between nodes. Another issue I've observed is that if I start a conversation with an NPC who is in the middle of a path, the NPC won't stop until the Player is in the position where they were when clicked, sometimes resulting in conversations happening at a considerable distance.

  • I think the first thing you should keep in mind is that there is no such thing as a "loop running in the NPC's own body". You can have an actionlist that you choose to use only to deal with actions related to a specific NPC, but there's nothing except your design choice linking it to the NPC's "body".

    The issue here seems to be that you have simultaneous actionlists running contradictory actions. You're quite right that your looping actionlist doesn't interact well with the actionlist you've assigned to the NPC's hotspot; but this is down to the way you've set them up. You have to remember that when coding game logic (either via C# or the visual scripting AC provides), everything is very literal. AC actions are essentially code snippets that you chain together, and they will do exactly what they say they will. So if you want an NPC's hotspot interaction to play well with another actionlist you're already running, you need to account for that in the logic. You could, for example, (1) check if an actionlist is running, (2) if it is, pause it, (3) run the conversation, (4) resume the paused actionlist.

    Another issue I've observed is that if I start a conversation with an NPC who is in the middle of a path, the NPC won't stop until the Player is in the position where they were when clicked, sometimes resulting in conversations happening at a considerable distance.

    If you want the NPC's hotspot interaction to run immediately, you can change the "Player Action" setting from "Walk to" to "Do Nothing". This will trigger the interaction immediately, and then you can use it to (for example), stop the NPC, tell the player to walk up to them, or simply start the conversation immediately.

    But in a different gameplay situation, you may find that you want the player to chase the NPC before triggering the conversation. Just so you know: the reason the player is only going up to the position where the NPC was when the interaction was triggered is that your pathfinding update time is 0. If you wanted the interaction to be triggered only when the player actually reached the NPC, you'd need to change this setting under AC Game Editor > Settings > Movement. This is a global setting that applies to all players and NPCs, but for this particular issue, only the player's pathfinding update time is relevant. It means that every x seconds, the player's path will be recalculated to take the NPC's new position into account.

    And if for whatever reason you don't want to change the global setting, you can change the pathfinding update time of specific characters by attaching this script to them:

        using System.Collections;
        using System.Collections.Generic;
        using UnityEngine;
        using AC;
    
        public class CustomPathfindingUpdateTime : MonoBehaviour
        {
    
            public float pathfindUpdateFrequency = 0;
    
            void Start()
            {
                this.GetComponent<Char>().PathfindUpdateFrequency = pathfindUpdateFrequency;        
            }
    
        } 
    

    As you can see, AC is extremely flexible and capable of getting the results you want. But this flexibility also means that you need to tell it exactly what to do.

  • Welcome to the community, @moral3jo.

    There's a fair bit to unpack here, but it seems to me like it essentially boils down to two main areas:

    1. Moving NPC characters on their own accord when left to their own devices
    2. Temporarily pausing this behaviour when interacting with the Player

    As @Rairun says, things can get very complex very quickly, so I'd recommend starting small - perhaps in a smaller, testing, scene - to figure out the right approach for you. There's a few top-level design ways to approach this kind of behaviour, but I'll try to offer my thoughts and suggestions as to how I'd try to go about it.

    There are a couple of ways to move NPCs around the scene, doing different things as they reach certain points.

    One is to run the Character: Move along Path Action, to move them along a pre-designed Path that runs Cutscenes when they reach certain Nodes. This is best for a "mini-schedule", where an NPC moves e.g. around a kitchen, stopping at the various stations and playing an animation there.

    The other is to run the Character: Move to point Action, that moves them to a specific place in the scene, and then running additional tasks in the same list. This is best run when you don't know where the NPC is to begin with - as they'll make use of dynamic pathfinding to reach their destination. Placing this in an ActionList whose When running Action is set to Run In Background will prevent the Actions from blocking regular gameplay for the Player.

    What you might have success with is using a combination of both of the above: for each "main" part of their schedule (i.e. at home, in the office), create a Cutscene/ActionList that first runs Character: Move to point to get them in the right location, and then run Character: Move along Path to move them on a Path in that location that then runs various Node cutscenes along the way.

    It'd then be a case of having a "master" ActionList for each NPC that then decides which of the above Cutscenes to run, based on the current time.

    You wouldn't typically have this "master" ActionList evaluate the time of day every frame - instead you'd be better off doing so every X seconds, or only when the "Time of day" variable has changed.

    For example, you could use the Engine: Wait Action, then run your evaluation logic, and then loop back to the Engine: Wait to restart it. To run an ActionList when the scene begins, attach the ActionList Starter component, and check Run on scene start?.

    So far as interacting with the Player goes, the Character: Move along Path Action's Stop moving / Resume Last Set Path commands, and ActionList: Pause or resume will help here - manually stopping the NPC at the start of an Interaction, and moving them again afterwards.

    What you might need to also do is introduce a separate "Is busy" variable that you can attach to the NPC via the Variables component, which you can set to True when talking to the Player, and then check for in their "master" ActionList to prevent it taking effect during this time. Variables like this could be useful in other ways - e.g. keeping track of which location they're in / which schedule they're running.

    Again, I'd recommend playing in a smaller test scene to figure out the best approach. Scripting, and use of AC's Event Runner component / Events Editor, may also need to play a part - but it's best to start small and see where such things are needed as you build up complexity.

  • Wow, a thousand thanks.
    The proof of concept I made is working well for me. I created a variable "timer" that increases from 1 to 12 every 10 seconds and associated it with a global variable. Then, I linked an ActionList to the update of the "timer" variable, where I will run in parallel the ActionLists stored within each NPC. Inside the NPC, I simply have logic asking for the time, and based on the time, it performs different actions. Everything seems to be working well; I also adjusted the pathfinding, and now the player correctly pursues the NPCs.

    I miss one thing that I'm not sure if it can be done automatically.
    In the dialogues, I would appreciate an option that displays the player's chosen option automatically without having to create it.

    I have Playmaker on my radar, which I already purchased and might be a good option for NPC routines.
    And the Dialogue System is also intriguing, but I need to look closely to see if it would significantly speed up the dialogue creation process, which is a bit cumbersome for me as I'm focusing heavily on the conversational aspect of my game.

  • I created a variable "timer" that increases from 1 to 12 every 10 seconds and associated it with a global variable.

    If it's working, you may wish to leave as-is - but AC does have a dedicated Timer system you can access with the Variable: Set Timer Action.

    Everything seems to be working well; I also adjusted the pathfinding

    One thing that occured to me while writing the above is that the Character: Move to point Action should behave differently if the Marker you're moving to has a Paths component attached. I'll extend this in the next update to provide the option to move to e.g. the nearest node on that Path if so - which should help in the moving to "schedule area" logic I mentioned, since you could then run it even if the NPC was already there as they could then just move to their nearest Path point.

    In the dialogues, I would appreciate an option that displays the player's chosen option automatically without having to create it.

    You might be able to sort something out through custom scripting, but I suspect it'd be more trouble than its worth. Though the dedicated Speech Action is necessary, it allows for all the goodies that come with it, i.e. audio options, animation, etc.

    If you're making a dialogue-heavy game, though, Dialogue System is certainly a good choice. It's an excellent tool and enjoys a robust integration thanks to its developer, Tony.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.