I’m having an issue getting baked lighting working with static lights in child actors or scene components. My game worlds are built from large modular rooms with each room being its own blueprint. I have a light fixture that I re-use a lot within different rooms so I would like to be able to use child actors so I only have to modify one blueprint to change the lighting, but I’m finding that child actors dont properly contribute to baked lighting. I thought maybe putting the lights in a scene component instead might get around the issue, but I’m finding that these have the exact same behavior. The really strange thing is that it seems like sometimes the lights do get baked but I still get the warning about needing to rebuild lighting. On the other hand sometimes the static lights in either the child actor or scene component suddenly start acting like dynamic lights.
Is there a proper way to have a single source of truth for static lights without either having to manually place both the fixture mesh and the light over and over within a blueprint, or without having to decouple the light fixtures from the rooms and manually place the light blueprints in the world?
Forgot to mention that I’m using UE 4.27 and a C++ project.
The only thing I can say here, is that child actors won’t work. That’s because child actors are actually spawned as standalone actors at runtime, so static lighting has no chance
I think it should be possible to get them working as components though, although I have a feeling that might be more tricky with 5 than it was with 4.
A quick rummage around, and I’m feeling that if you’re spawning the blueprints, this might not be possible… Placing, yes.
EDIT: What about using level instances instead of BPs? I think that’s a better shot…
I probably should have specified I’m using UE 4.27, oops, I’ll add that to the main post. Also none of my blueprints are spawned, they’re placed in the level. I’m hoping theres a better way to incorporate basically a blueprint within a blueprint without SpawnActorFromClass that will allow static lighting.
Child actors will always been spawned, even if the blueprint has been placed.
I don’t know if it’s possible. Placing the BP, then building light, yes. But if the BP can be place in any orientation, how can the light be ok? I guess within the bounds of the BP maybe…
I think I may have a workaround solution. Its kinda stupid but I think it will work. I already use the UE python integration to help with world building, I’m thinking I can actually split my light fixtures up so that theres a BP for just the fixture as well as a BP for just the light source. I think I should be able to get all instances of the fixture BP in python, then all I have to do is spawn a light source at each fixture. That way the lights will be placed in editor rather than at run time and the static lighting should bake properly. I already know that lights placed bake properly so I think this will work, the only thing I’m not sure of is if I can actually do it in python. Ideally it would be great to have a native C++ implementation that I can run straight from the editor but I have no idea if thats possible yet.
My theory worked! The script takes quite a while to run since I have a lot of lights in my worlds, but it was really simple to write and works perfectly! This script runs on the currently open level, so I don’t know how it will work with world composition, for that I might have to have it open each level in a given folder and run for each level, but for single levels it works fantastic as is.
import json
import random
import sys, getopt
from enum import Enum
# https://docs.unrealengine.com/4.27/en-US/PythonAPI/class/EditorLevelLibrary.html
# The class we want to find and replace. These will populate even if they're child actors inside of blueprints so we dont have to do
# a lot of work to find them all in the open level. These dont get removed, but are set to be hidden in game and editor only so we
# dont have overlapping objects. They could be anything really but in my case they look the same so I can properly place them.
fixture_class = unreal.EditorAssetLibrary.load_blueprint_class('/Game/CeilingLight_Office_High_Fixture.CeilingLight_Office_High_Fixture')
# The class we want to place on top of the fixtures.
source_class = unreal.EditorAssetLibrary.load_blueprint_class('/Game/CeilingLight_Office_High.CeilingLight_Office_High')
all_actors = unreal.EditorLevelLibrary.get_all_level_actors()
for actor in all_actors:
if actor.get_class() == source_class:
unreal.EditorLevelLibrary.destroy_actor(actor)
all_actors = unreal.EditorLevelLibrary.get_all_level_actors()
with unreal.ScopedSlowTask(len(all_actors), "Placing lights") as slow_task:
slow_task.make_dialog(True) # Makes the dialog visible, if it isn't already
for actor in all_actors:
if actor.get_class() == fixture_class:
pos = actor.get_actor_location()
rot = actor.get_actor_rotation()
unreal.EditorLevelLibrary.spawn_actor_from_class(source_class, pos, rot)
if slow_task.should_cancel(): # True if the user has pressed Cancel in the UI
unreal.log_error("Lighting fixup canceled")
break
slow_task.enter_progress_frame(1)