UE5 Time of Day Blueprint System
This page is part of the documentaiton for my UE5 Time of Day Blueprint System

Time of Day Blueprint

UE5 Time of Day Blueprint System Version: 2.0

    What is the Time of Day Blueprint?

    Whenever this documentation mentions Time of Day Blueprint or BP_TimeOfDay this is a reference to the main blueprint BP_TimeOfDay in the Blueprints/ folder. This is the blueprint that handles tracking and reporting the current time in your level.

    Under most circumstances you will only need one BP_TimeOfDay in your level. The only time you would need to add another is if you wanted to track and progress 2 different timeframes.

    Now if you haven't done so yet, go ahead and navigate to the Blueprints/ folder and drop a copy of the Time of Day Blueprint into your level. You can easily identify it in the viewport by the "Time of Day" text that is shown in place of the default blueprint icon.

    Configuring Time in our Level

    When we want to configure how time works in our level we make changes to this instance of the Time of Day blueprint we placed in the level. Go ahead and select it in the viewport and navigate the details panel to the "Default" section. By default it should look something like this:

    Time of Day ModeTime Of Day Mode has two options: Custom Time and Real Life Time. Real life time will use the time from your computer, and custom time is if you want to specify a starting point or start from absolute 0.

    Custom Time

    This category contains all the options and settings related to using custom time. To see all the custom time settings click on it to expand the category. If you are using Real Life Time these settings have no effect and can be ignored.

    SecondsPerDay This is how many real life seconds are in one of our days. This is the value before any sort of speed multiplier is applied. In real life this value is 86400, one hour is 3600 seconds (the default value).
    SpeedMultiplier This is the default starting speed multiplier. Under most circumstances you will want to leave this at 1.0 (the default value). We will talk about the speed multiplier later in this chapter.
    StartingPoint The starting point lets you define when you want your custom time to start. Year, Day in Year, Hour in Day, and Minute in Hour are pretty self explanatory but the last one StartingDayNumberForceTo has 3 values, and this is how you can define what Day Number you want to appear for your starting day. You can start at 0, 1 by setting the value to either. You can also set the value to -1 which will use the calculated day based on your starting point. See the Setting a Starting point chapter for a little bit more information about this variable.
    Keep in mind if you are saving your time this starting point data is only used once. While developing, if you make changes to this starting point and you have an active save that you are using, your changes to this starting point will not be used or reflected in the current time. You will need to reset that save game using the "Reset Saved Time" button on the details panel if you want to use and account for your new starting point. I recommend figuring out your starting point before enabling and using the save option.

    SaveTime

    These settings are related to saving time.

    SaveAndLoadTime? To use the save time system make sure to set this to true. With this disabled every time you start your game you will start at your starting point. With this enabled your time on the next play will continue where it left off.
    AutoSaveFrequencyInSeconds This is how many real life seconds you want to elapse between saves of the time. If you want to manually control when saves happen, set this to 0 then call the SaveTime event on this blueprint when you are ready to save.
    SaveIdentifier This string is appended to the save game slot name (keep it alphanumeric). If you have time of day BP in two different levels the time can be shared between them by making sure this value matches on both of them.
    ManualLoad? This is disabled by default, and if enabled you can use it to have more control on when the system handles its load of the saved time. This way you can dynamically update the SaveIdentifier if you had multiple save game slots on your main menu, then manually load after making this update. If you set this to true you have to manually call LoadTime when you are ready to run the load process.
    ResetSavedTime This editor button with the label "Reset Saved Time" can be used whenever you want to delete your save game. This comes in handy if you make changes to your starting point and want it to reflect in your current game. Unfortunately I could not place this button inside the same folder as the other Save Time stuff, Unreal just would not let me. You can find it down at the end of the Default category of the details panel. This button has no impact on real time mode and will only do something if a save exists for the current SaveIdentifier. If you are dynamically setting this value you will need to either manually remove the save game slots (see the resetSavedTime function), or append your dynamic logic manually into the details panel and then click this button, then make sure to reset the save identifier to whatever it was without your manually added dynamic logic.

    Other Options

    NotifySpeedThis is the frequency, in seconds, that the system will check for updates to time and if needed send notifications and replicate updates. By default 0.1 should be a good balance between performance and efficiency in single player. For multiplayer you may want to raise this a little bit, maybe to .3 or .5.
    TickSpeedElapsed time is tracked using a throttled tick, the speed of the tick is throttled to the value of this variable. This value should always be less than or equal to your notify speed. This use of tick only runs on the server in multiplayer. By default 0.1 should be fine for most circumstances.
    MonthNamesAndDays If you want to change the month names, or number of days in each month this is where you would do so. This has no impact on real life time mode, and is only used with the Custom Time mode.
    RealtimeMonthsAndDays If for whatever reason you want to change the months and number of days in each month for the realtime mode you will want to edit this variable inside the blueprint. It can be found in the same section but is intentionally not exposed to the blueprint since it is not something you will most likely change per instance, and also as a measure to prevent accidentally editing this one instead of the one for custom time mode.
    DaysOfTheWeek If you want to change the names of the days of the week this is where you would change them. Keep in mind real life time uses this data as well. The order is also important, make sure your days are in order and start on the first day of your week.
    TimeOfDaySchedule This is used by both custom time and real time, and is how we decide at what points of our day does the actual "Time of Day" change. By default 3 Times of Day are included (Morning, Afternoon, Evening). To add more to this list edit the E_TimeOfDays enum in the Blueprints/Variables/Enums/ folder. For each time of day (the key), you can specify the start and end point for the schedule. You also want to make sure these are in order and that you have no gaps between times of day. You will be seeing "null" as a value when you are in a gap. If the time of day changes back and forth between two multiple times this means you have an overlap in your timing. By default the system will know that you mean next day when your end time is lower than your start time. All hour values are also in 24 hour format.
    MinutesPerHour If there are more or less minutes per hour in your world this is the variable you will want to change.
    HoursPerDay If there are more or less hours per day in your world this is the variable you will want to change.
    DatestampYearPrefix When getting the datestamp there is an option to include the year. If the year is included you may want to prefix it with some text like "Year #". This doesn't make much sense for real time mode, but if you are starting at year 1 it will look weird to the player to see just a 1 after the month day in the datestamp. This variable lets you add a prefix to this year value, but this is only used on the datestamp, it is not used when you just want to get the current year value.
    SendNewEventsOnBeginPlay If you set this to true event dispatchers will be sent on begin play for the current time. By default this is disabled, but if you are using the event dispatchers to control things in your level that you want to take effect on begin play and not until the next change is detected then you will want to make sure this is enabled. Keep in mind if your logic is not loaded before the Time of Day is loaded your end will not receive this event. If you use this you may need to also manually control when the time of day runs its begin play event so you know it only runs when your side is ready. If you need help with this you can reach out to me on discord or email.

    Get the Current Time

    To get the current date or time you need to get a reference to your level's BP_TimeOfDay. I created a global function called getTimeOfDayBP that you can call from anywhere to get the first time of day bp in your level.

    From this reference you can call any of these functions:

    Popular Get Functions

    getDatestamp Returns a formatted text with the current datestamp in the Format of "DayOfWeek, Month Day{suffix}". Has an option to also include the year.
    getTimestamp Returns a formatted text with the current timestamp in the format of 00:00. Has boolean input options to include seconds, as well as show AM/PM instead of 24hour.
    getTimestampFromSeconds Returns a timestamp just like getTimestamp but with the option of providing an input value for the starting seconds.
    getHourMinSec Returns the integer values of the current hour, minute and second. If you need at least 2 of these use this function, if you only need one of these values use the getSeconds, getMinute, or getHour functions instead.
    getHourMinSecFromDayPercent Returns the hour, minute and second values for a provided day percentage.
    getTimeOfDay Returns the current Time of Day based on the data you entered in the TimeOfDaySchedule variable during configuration.
    getTotals Returns the total counts for each data point. Seconds, Minutes, Hours, Days, Weeks, Months, Years.

    Second

    getSeconds Returns the current seconds. If you need just the seconds use this, but if you need the hour or minute as well use getHourMinSec instead for a slight efficiency boost. If you need total seconds use getSecondsTotal instead.
    getSecondsTotal Returns the total seconds tracked (single player and server in multiplayer) or elapsed (client in multiplayer). For multiplayer the Client uses SecondsElapsed which is the replicated value of SecondsTracked but at the update speed of NotifySpeed. This is a bandwidth management measure. For faster updates lower the NotifySpeed and TickSpeed at the cost of more bandwidth usage.
    getSecondsPerMinute Returns the number of seconds in a minute based on the current settings.
    getSecondsPerHour Returns the number of seconds in an hour based on the current settings.
    getSecondsPerDay Returns the value of SecondsPerDay which is what you set on the instance of the actor in your world.
    getSecondsPerWeek Returns the number of seconds per week based on the current settings.
    getSecondsPerYear Returns the number of seconds per year based on the current settings.

    Minute

    getMinute Returns the current minute. If you need just the minutes use this, but if you need the hour or seconds as well use getHourMinSec instead for a slight efficiency boost.
    getMinutesPerDay Returns the number of minutes per day based on current settings.

    Hour

    getHour Returns the current hour. If you need just the hour use this, but if you need the minutes or seconds as well use getHourMinSec instead for a slight efficiency boost.
    getHoursLeftInDay Returns the number of hours left in the current day (includes both full and partial). This is used internally to calculate the difference in two different times.

    Day

    getDayNumber Returns the current day number.
    getDayPercent Returns the current day's percentage complete.
    getDayInWeek Returns the current day number, and the name of the day in the week. For real life time mode this uses the formula provided by Farmer's Almanac.
    getDayInMonth Returns the current day number in the month.
    getDayInYear Returns the current day number in the year.
    getDaysPerWeek Returns the number of days per week based on the current configuration.
    getDaysPerYear Returns the number of days per year based on the current configuration.
    getDaysThisMonthReturns the number of days in the current month.

    Month

    getMonth Get data about the current month. Returns Month Name (text), Month Number (int), Month Start Day in Year (int), and Days in the Month (int).
    getMonthPercent The currently monthly progress based on completed days. Changes on a new day unless the input IncludeIntraday (boolean) is set to true, in which case it will also include the current day's progress in the percentage.
    getMonthsInYear This returns a count of months in the year, it is used internally but is still available to you if you need it.

    Year

    getYear Returns the current year (int).
    getYearPercent Returns the current year's percentage complete for the current point in time.

    Multiplier

    getSpeed Returns the current speed multiplier.

    Get notified when Time changes

    You can always get the time on demand using the functions provided in the last part of this chapter but if you want the Time of Day BP to notify your BPs when time is updated at different intervals you would bind into the provided event dispatchers instead.

    OnUpdateTime Called whenever time is updated. Does not provide any data, but can be used to tell your side when it is time to get the newest data from its Time of Day BP reference.
    OnNewMinute Called whenever a new minute is detected. Keep in mind if time in your level is moving really fast you will not get a call for every single minute. To help you keep your side in sync each call will provide you with the TotalMinutes. If you track this at your end you can compare to this incoming value to count how many minutes have passed since your last update. This event will also provide you with the currentMinute (in the hour), SecondsTracked (total), and current DayPercent.
    OnNewHour Called whenever a new hour is detected. Will provide the TotalHours and the CurrentHour (in the day). Like the minute if time is moving too fast you may not get a call every single hour, use the TotalHours value to sync with your side if there is something you have to account for every single hour.
    OnTimeOfDayChange Called whenever the time of day, based on your TimeOfDaySchedule, changes. Keep in mind if you jump time and skip over a time of day, the event for that time of day will not be called. Time has to actually progress through that point in the day to call this event.
    OnNewDay Called whenever a new day is detected. Will provide the TotalDays, DayInYear, DayOfWeekNumber, DayOfWeekName, DayInMonth, MonthPercent, and Datestamp.
    OnNewWeek Called whenever a new week is detected. Will provide the TotalWeeks.
    OnNewMonth Called whenever a new month is detected. Will provide the TotalMonths, the NewMonthName, NewMonthNumberInYear, MonthStartDayInYear, and DaysInMonth.
    OnNewYear Called whenever a new year is detected. Will provide the TotalYears.
    OnSpeedChange Called whenever the speed changes. Will provide the new Speed Multiplier as NewSpeed.
    Keep in mind if time is moving too fast in your level you may not get a call for every single interval, especially the lower end ones like minute and hour. Each of these calls will provide you with the current total count for that interval, you can use this value to keep your side in sync if this matters. For example, if you are restoring X health every minute, and you fast forward time to the point where your minutes are jumping by 5 at a time, you would only get a call every 5 instead of one, but if you compare the value of TotalMinutes on each call then calculate the difference since the previous call you would get the value of 5, which you can then use to increase this health value by 5x instead of 1x for that call.

    Change the Current Time

    If you want to change the starting time and date see the configuration section. If you want to change the time at runtime in Custom Time mode there are 3 events on the BP_TimeOfDay you can call. You can see examples of both of these events inside the demo player controller BP_TimeOfDayController found in the Demo/ folder.

    JumpTime Will jump ahead a specific amount of time. You can provide how many Seconds, Minutes, Hours, Days and Years. You can also provide negative values to jump backwards with this event.
    JumpToNext Will jump ahead to the next Hour and Minute you provide as inputs. If this time is in the future of the current day it will jump to that point, otherwise it will jump to the next day at this hour and minute. You can not jump backwards with this event.
    JumpToExactly Will jump to the exact point in time. You can provide the Second, Minute, Hour, Day (Number in year), and Year.
    By default manipulating time is disabled in Real Life Time mode. This includes changing the current time.

    Pause, Speed Up or Slow Down Time

    The fun doesn't stop with time travel, you can also Pause, Speed Up or Slow Down Time in Custom Time Mode. Keep in mind though this has no effect on the actual Pause Game or Time Dilation systems built into Unreal, these events are just for the time system, and everything hooked into its events.

    PauseTime Pause (or unpause if paused) time.
    SpeedUp Will increase the speed of time by +1.
    SlowDown Will decrease the speed of time by -1.
    ChangeSpeedBy Will increase or decrease the current speed of time by the value of the input Speed (float).
    ChangeSpeedTo Will set the speed multiplier to the exact value of the input Speed (float).

    The demo player controller BP_TimeOfDayController in the Demo/ folder has examples for these events.

    By default manipulating time is disabled in Real Life Time mode. This includes changing the speed of time.

    Using Multiple Time of Day BPs

    Under some circumstances you might have a need for more than one BP Time of Day in your level. For example if you wanted to progress time in multiple levels at the same time, but both are on unique timeframes.

    To do this you can just add multiple BPs to your level, and if you have Save Time enabled you will want to update the SaveIdentifier configuration variable so each one is unique. At no point is there a valid reason to have multiple TimeOfDay BPs in your level with the shared SaveIdentifier, this is going to cause a havoc of issues.

    To help you get a reference to the right time of day I have included a global function shortcut similar to the getTimeOfDayBP function that you can call anywhere. This one is called getTimeOfDayBPTagged which lets you also provide an actor tag. Then just make sure to give each of your BP time of days a unique actor tag that you would then use as an input when using the getTimeOfDayBPTagged function to find the right one.

    Keep in mind if you are using any of the included examples they will default to the first Time of Day BP detected, you may need to update them to also account for this actor tag so they know which time of day bp to get the correct time from.

    This documentation and asset version are new. If you encounter any bugs or if anything doesn't make sense, please let me know.