back here -_-
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
"""
|
||||
FixTerraceLighting.py
|
||||
=====================
|
||||
For the Terrace level:
|
||||
1. Positions the RuinedCrypt_01_P Level Instance relative to PlayerStart
|
||||
2. Sets lighting to match RuinedCrypt's cool atmospheric tone
|
||||
3. Disables shadow casting on excess movable lights (fixes overlap warning)
|
||||
|
||||
How to run:
|
||||
File -> Execute Python Script -> select this file
|
||||
Terrace.umap must be open (tab should show "Terrace")
|
||||
"""
|
||||
|
||||
import unreal
|
||||
|
||||
USE_OPEN_LEVEL = True # Run against the currently open map
|
||||
|
||||
# How many units BELOW PlayerStart to place the RuinedCrypt ground
|
||||
# (keeps terrain hidden beneath the tower platform)
|
||||
RUIN_Z_OFFSET = -350.0
|
||||
|
||||
# RuinedCrypt scale — 0.7 = 70% of original size
|
||||
RUIN_SCALE = 0.7
|
||||
|
||||
# Atmospheric light color: cool blue-green to match RuinedCrypt's soft tone
|
||||
SUN_COLOR = unreal.LinearColor(0.65, 0.80, 0.90, 1.0) # cool / blue-white
|
||||
SUN_LUX = 8000.0 # low intensity for dusk/evening mood
|
||||
|
||||
SKY_INTENSITY = 1.2
|
||||
|
||||
FOG_DENSITY = 0.04 # subtle atmospheric fog
|
||||
FOG_FALLOFF = 0.25
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ helpers --
|
||||
|
||||
def _log(msg):
|
||||
unreal.log(f"[FixTerrace] {msg}")
|
||||
|
||||
def _warn(msg):
|
||||
unreal.log_warning(f"[FixTerrace] {msg}")
|
||||
|
||||
def _actors():
|
||||
sub = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
|
||||
return list(sub.get_all_level_actors())
|
||||
|
||||
def _of_class(cls):
|
||||
return [a for a in _actors() if a.get_class() == cls]
|
||||
|
||||
|
||||
# --------------------------------------------------------------- functions ---
|
||||
|
||||
def fix_ruinedcrypt_position():
|
||||
"""Aligns the RuinedCrypt Level Instance to the PlayerStart location."""
|
||||
all_actors = _actors()
|
||||
|
||||
# Find PlayerStart
|
||||
ps = next((a for a in all_actors if a.get_class() == unreal.PlayerStart), None)
|
||||
if ps is None:
|
||||
_warn("PlayerStart not found — skipping RuinedCrypt positioning.")
|
||||
return
|
||||
|
||||
ps_loc = ps.get_actor_location()
|
||||
_log(f"PlayerStart location: X={ps_loc.x:.0f} Y={ps_loc.y:.0f} Z={ps_loc.z:.0f}")
|
||||
|
||||
# Find RuinedCrypt Level Instance by label or class name
|
||||
ruin = None
|
||||
for a in all_actors:
|
||||
label = a.get_actor_label().lower()
|
||||
cls = a.get_class().get_name().lower()
|
||||
if "ruinedcrypt" in label or "ruined_crypt" in label or \
|
||||
("levelinstance" in cls and "ruined" in label):
|
||||
ruin = a
|
||||
break
|
||||
|
||||
if ruin is None:
|
||||
_warn("RuinedCrypt_01_P Level Instance not found. "
|
||||
"Check the actor label in the Outliner.")
|
||||
return
|
||||
|
||||
# New position: same X/Y as PlayerStart, Z offset downward
|
||||
new_loc = unreal.Vector(ps_loc.x, ps_loc.y, ps_loc.z + RUIN_Z_OFFSET)
|
||||
ruin.set_actor_location(new_loc, sweep=False, teleport=True)
|
||||
ruin.set_actor_scale3d(unreal.Vector(RUIN_SCALE, RUIN_SCALE, RUIN_SCALE))
|
||||
ruin.set_actor_rotation(unreal.Rotator(0.0, 0.0, 0.0), teleport_physics=True)
|
||||
|
||||
_log(f"RuinedCrypt positioned at Z={new_loc.z:.0f} Scale={RUIN_SCALE}")
|
||||
|
||||
|
||||
def fix_directional_light():
|
||||
"""Sets the DirectionalLight to a cool atmospheric color."""
|
||||
lights = _of_class(unreal.DirectionalLight)
|
||||
if not lights:
|
||||
_warn("DirectionalLight not found.")
|
||||
return
|
||||
|
||||
# Keep only the first one, remove duplicates
|
||||
keep = lights[0]
|
||||
for extra in lights[1:]:
|
||||
unreal.get_editor_subsystem(unreal.EditorActorSubsystem).destroy_actor(extra)
|
||||
_log(f"Removed {len(lights)-1} duplicate DirectionalLight(s).")
|
||||
|
||||
comp = keep.get_component_by_class(unreal.DirectionalLightComponent)
|
||||
if comp:
|
||||
comp.set_intensity(SUN_LUX)
|
||||
comp.set_light_color(SUN_COLOR)
|
||||
comp.set_atmosphere_sun_light(True)
|
||||
comp.set_cast_shadows(True)
|
||||
comp.set_mobility(unreal.ComponentMobility.STATIONARY)
|
||||
_log("DirectionalLight updated.")
|
||||
|
||||
|
||||
def fix_sky_light():
|
||||
"""Sets SkyLight intensity and removes duplicates."""
|
||||
skies = _of_class(unreal.SkyLight)
|
||||
if not skies:
|
||||
return
|
||||
keep = skies[0]
|
||||
for extra in skies[1:]:
|
||||
unreal.get_editor_subsystem(unreal.EditorActorSubsystem).destroy_actor(extra)
|
||||
|
||||
comp = keep.get_component_by_class(unreal.SkyLightComponent)
|
||||
if comp:
|
||||
comp.set_intensity(SKY_INTENSITY)
|
||||
comp.set_mobility(unreal.ComponentMobility.STATIONARY)
|
||||
_log("SkyLight updated.")
|
||||
|
||||
|
||||
def fix_fog():
|
||||
"""Configures subtle atmospheric height fog."""
|
||||
fogs = _of_class(unreal.ExponentialHeightFog)
|
||||
if not fogs:
|
||||
_warn("ExponentialHeightFog not found — skipping fog setup.")
|
||||
return
|
||||
comp = fogs[0].get_component_by_class(unreal.ExponentialHeightFogComponent)
|
||||
if comp:
|
||||
comp.set_fog_density(FOG_DENSITY)
|
||||
comp.set_fog_height_falloff(FOG_FALLOFF)
|
||||
comp.set_volumetric_fog(False)
|
||||
_log("Fog updated.")
|
||||
|
||||
|
||||
def disable_excess_movable_shadows():
|
||||
"""Disables shadow casting on movable PointLights and SpotLights
|
||||
to fix the TOO MANY OVERLAPPING SHADOWED MOVABLE LIGHTS warning."""
|
||||
all_actors = _actors()
|
||||
fixed = 0
|
||||
for a in all_actors:
|
||||
cls = a.get_class()
|
||||
if cls not in (unreal.PointLight, unreal.SpotLight):
|
||||
continue
|
||||
for comp_cls in (unreal.PointLightComponent, unreal.SpotLightComponent):
|
||||
comp = a.get_component_by_class(comp_cls)
|
||||
if comp and comp.get_mobility() == unreal.ComponentMobility.MOVABLE:
|
||||
comp.set_cast_shadows(False)
|
||||
fixed += 1
|
||||
if fixed:
|
||||
_log(f"Disabled shadow casting on {fixed} movable PointLight/SpotLight(s).")
|
||||
|
||||
|
||||
def save():
|
||||
world = unreal.get_editor_subsystem(
|
||||
unreal.UnrealEditorSubsystem).get_editor_world()
|
||||
if world:
|
||||
try:
|
||||
unreal.EditorLoadingAndSavingUtils.save_dirty_packages_with_confirmation(False)
|
||||
_log("Saved.")
|
||||
except Exception as e:
|
||||
_warn(f"Save error: {e}")
|
||||
|
||||
|
||||
# ------------------------------------------------------------------- main --
|
||||
|
||||
def run():
|
||||
_log("Starting...")
|
||||
fix_ruinedcrypt_position()
|
||||
fix_directional_light()
|
||||
fix_sky_light()
|
||||
fix_fog()
|
||||
disable_excess_movable_shadows()
|
||||
save()
|
||||
_log("Done. Move the camera in the Viewport to see the changes.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
Reference in New Issue
Block a user