This guide presents a Room of Requirement Automatic Ambience blueprint mod for Hogwarts Legacy and describes how it works.
Beginners should read the previous tutorials before this one. They can be found here:
All the usual prerequisites apply at this point. I won't keep repeating them.
If you're a beginner and you haven't read the previous tutorials you should. You'll struggle to follow this one if you don't.
You can download the Level Blueprint (.umap file) using the link below.
Remember to rename it to MyRORAutoAmbience.umap (noting the uppercase letters) and put it in PhoenixUProj\Content\CustomContent\.
Download the Level Blueprint from here.
The Event Graph looks quite different to previous tutorials. The way this mod is going to work is as follows: as soon as the game is up and running it will called a Function called MyAmbienceSwitcher which will set the RoR ambience based on the in-game time of day. That Function will then set a timer running which will call MyAmbienceSwitcher again in 60 seconds' time. The signal that the game is “up and running” is called Curtain Raised in Unreal Engine. So our Event BeginPlay checks whether the curtain is down. If not, then the game is running and we can immediately call MyAmbienceSwitcher. But if it's down we must wait.
You might wonder why I call MyAmbienceSwitcher every 60 seconds. Game time runs 30 times faster than real time, so if the ambience changes every 6 hours of game-time that's every 12 minutes in real-time. Why not run MyAmbienceSwitcher every 12 minutes? Well, it's because the Function to change the ambience only works if you're in the RoR or fast-travelling to the RoR. Therefore, if you enter the RoR via the door, the ambience will be incorrect when you enter. It will only switch to the correct setting the next time MyAmbienceSwitcher is called. If that isn't for another 12 minutes then that's no good. But waiting a maximum of 60 seconds isn't so bad.
I have also replaced one of the Nodes in the Debug toggle logic from a simple Validated Get to a call to MyDebugGetWidget. This is a better approach because if the Validated Get failed the Debug Widget would simply not appear. Now it will attempt to create the Debug Widget before giving up.
There's one small change to the MyInitialize Function. I've added Get LightingIdentityMaster which we'll need later.
This Function does most of the work. It operates as follows:
Sequence Node sends execution along the upper path first, then the lower path.MyTimeToAmbientInt and MyIntToEsanctuaryIdentity, with Variables set to remember the outputs.MyAmbienceOkay is set to TRUE.MyAmbienceOkay is TRUE or not.TRUE then the ambience doesn't need to be set, so I just start a Timer to call MyAmbienceSwitcher again in 60 seconds.FALSE then the ambience is changed using a game Function called Set Identity and the Timer is set to repeat in 60 seconds. I suppose this could actually be set to 720 seconds (or 660 to be safe)… since we know that the ambience will be correct for the next 12 minutes no matter what… but I haven't thought about that so I'm not entirely sure… It's the things you don't anticipate that catch you out!In Blend Duration pin on the Set Identity Node it would make the ambience change gradually from one setting to the next over the course of 6 in-game hours. In other words the ambience would be constantly evolving from one to the next. Of course it's quite hard to see if this is actually working since it happens so slow. Time inside the game runs about 30 times faster than the real world, so one game-day is about 48 real-minutes. And 6 game-hours is 12 real-minutes (or 720 real-seconds). To allow you to see this slow change happen a bit faster I included a Variable called MyTestingSpeedup. By default this is set to 1.0 but if you set it to 48.0 then one game-day will pass in one real-minute, and 6 game-hours will pass in 15 real-seconds. So you can see things happen much more rapidly. I would also note that there is a mod called Tempus Imperium which speeds up the day-night cycle y changing an in-game Variable called SiumlationTimeFactorOverride from 1.0 to some other number. I have therefore attempted to adjust for this.
This Function converts the current in-game time to an Integer in the range 0 to 3. These represent the four ambience settings. The Function works as follows:
372 minutes not 12 minutes. I therefore Get MinuteOfTheDay and divide it by 60 to get a Float equivalent, with minutes as the integer part and seconds as the decimal fraction. So 6:12am will be 6.20 hours after midnight.MyTestingSpeedup to speed things up for testing (if it's set to a number > 1.0).Truncate this to get just the Integer part, which is the number of hours since midnight (plus one).Modulo mathematical function to ensure that the results always fall within the range 0 to 23. If our in-game time is currently 23:30, for example, this will become 24:30 after I've added an hour, which will be 24 in Integer terms. Modulo will convert that 24 to 0, which is what we want because 24:30 should actually be 00:30, so 0 for our purposes, not 24.Integers in the range 0 to 23 become Integers in the range 0 to 3.
The Set Identity Node requires us to set the ambience using an ESanctuaryIdentity Enum not an Integer so we need to convert our Integers. Here's how I did it:
And here's how I change them back (for the debug info that's currently disabled):
That's it!