- Home /
How to make NPCs check the time?
Hi, I am trying to create a 2d game with a town in which some NPCs have a schedule. Just like Skyrim, the town is a scene and interiors are separate scenes, like tavern is one scene etc. I tried to learn the logic through some research and found some information about it. People say that you need to make the NPC check the time and do its actions according to it. So how am I supposed to make the NPC check the time of day?
I mean, how can I create the "thing" that acts as the "time" and make all NPCs look at it before being where they are supposed to be and do their routine actions?
Answer by Romano · May 22, 2019 at 12:54 AM
There's a few ways you could do this but I would use a coroutine to do it. That's the thing that acts as the time. It's like a function you can make repeatedly loop through a set amount of time and trigger events at set intervals. Imagine a game where 24 hours last just 24 minutes, you could set it up the coroutine like this:
public IEnumerator DayCoroutine()
{
// The timer
float elapsedTime = 0;
// 24 minutes expressed in seconds
float twentyFourMinsInSeconds = 60 * 24;
// 7 minutes in seconds
float sevenAM = 60 * 7;
// 9 minutes in seconds
float nineAM = 60 * 9;
// 18 minutes in seconds
float sixPM = 60 * 18;
// 22 minutes in seconds
float tenPM = 60 * 22;
bool wokeUp = false;
bool wentToWork = false;
bool wentHome = false;
bool wentToSleep = false;
// Loop forever
while (true)
{
// Reset the timer to zero
elapsedTime = 0;
// Reset the bools for a new day
wokeUp = false;
wentToWork = false;
wentHome = false;
wentToSleep = false;
while (elapsedTime < twentyFourMinsInSeconds)
{
if (wokeUp == false && elapsedTime > sevenAM)
{
// A function that wakes your character up
WakeUp();
// Set the bool to true so we can stop checking this.
wokeUp = true;
}
else if (wentToWork == false && elapsedTime > nineAM)
{
// A function that wakes your character up
GoToWork();
// Set the bool to true so we can stop checking this.
wokeUp = true;
}
else if (/* not come home by 6 pm then come home */)
else if (/* not asleep by 10 pm then go to sleep */)
// Progress the coroutine to the next frame.
yield return null;
}
yield return null;
}
And you can trigger the coroutine from the Start function like this:
void Start()
{
StartCoroutine(DayCoroutine();
}
That's not the tidiest example, but basically something along those lines should work.
Thank you very much for your answer. It helped me get the logic better.
In addition, do you think that it can be done via behaviour trees? like third party asset-plugins?
I've never used anything like that, but I guess it depends on the complexity of your project. Something that uses the time to trigger functions is relatively straight forward. An alternative approach would be to add the timer to the NPC and time how long they have been in an area/doing a task for.
So the NPC script would look more like:
WakeUp()
(Wait for 2 hours using a coroutine)
GoToWork()
(Wait for 8 hours or for another source to tell the coroutine to stop - e.g. the NPC can't continue to work because the building has burnt down)
GoHome()
Generally I avoid third party assets unless I really need them, because they often come with their own complexities and other things to learn. The state machines in the mecanim animator in Unity can be used for things like this, where the NPC animation or set of animations will loop until something external tells it otherwise or you can use a State$$anonymous$$achineBehaviour script to control behaviour.
I really like this tutorial as an introduction to how to use State$$anonymous$$achineBehaviours:
Your answer
Follow this Question
Related Questions
Cycle Through Array of Enemies 1 Answer
Physics behaves more strangely with Time? Bouncing and Sliding Objects 2 Answers
Animator/Behaviour I want to get all the transitions of a state 0 Answers
A.I That tracks the player then resets 1 Answer
Am I using Behavior Designer correctly to control the AI of my character? 0 Answers