From 917fc4e16fa4b32faebcd180b7027c59dd007f38 Mon Sep 17 00:00:00 2001 From: Zeynep Kesim Date: Tue, 26 May 2026 23:18:32 +0300 Subject: [PATCH] Remove Python scripts (no longer needed) --- .../Content/Python/FixTerraceLighting.py | 186 ---------- .../Content/Python/README_SetupTerrace.txt | 36 -- .../Content/Python/SetupTerraceLevel.py | 350 ------------------ 3 files changed, 572 deletions(-) delete mode 100644 DrownedCityVR/Content/Python/FixTerraceLighting.py delete mode 100644 DrownedCityVR/Content/Python/README_SetupTerrace.txt delete mode 100644 DrownedCityVR/Content/Python/SetupTerraceLevel.py diff --git a/DrownedCityVR/Content/Python/FixTerraceLighting.py b/DrownedCityVR/Content/Python/FixTerraceLighting.py deleted file mode 100644 index f86897c..0000000 --- a/DrownedCityVR/Content/Python/FixTerraceLighting.py +++ /dev/null @@ -1,186 +0,0 @@ -""" -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() diff --git a/DrownedCityVR/Content/Python/README_SetupTerrace.txt b/DrownedCityVR/Content/Python/README_SetupTerrace.txt deleted file mode 100644 index 57c49c9..0000000 --- a/DrownedCityVR/Content/Python/README_SetupTerrace.txt +++ /dev/null @@ -1,36 +0,0 @@ -Terrace level setup script -========================== - -SetupTerraceLevel.py adds default lighting, fog, a scaled SM_Cube floor, and -PlayerStart to Content/VRTemplate/Maps/Terrace. It also removes duplicate -DirectionalLight / SkyLight actors and fixes exposure (white viewport fix). -Meshes such as rocks from LightingAndMainRocks are left untouched. - -Requirements ------------- -- Python Editor Script Plugin (enabled in DrownedCityVR.uproject) -- Editor Scripting Utilities -- Restart the editor after enabling plugins - -Run once --------- -1. Open the DrownedCityVR project. -2. File -> Execute Python Script -3. Select Content/Python/SetupTerraceLevel.py - -To run against whichever map is already open, set USE_OPEN_LEVEL = True at -the top of the script. - -Re-runs -------- -With SKIP_DUPLICATES = True, actors that are already present are left alone. - -Troubleshooting ---------------- -- "No module named unreal" -> enable the Python plugin and restart. -- "Mesh not found" -> confirm SM_Cube exists under LevelPrototyping/Meshes. -- Black viewport -> switch the view mode to Lit. - -Command line (optional) ------------------------ -UnrealEditor DrownedCityVR.uproject -ExecutePythonScript=".../SetupTerraceLevel.py" -unattended -nullrhi diff --git a/DrownedCityVR/Content/Python/SetupTerraceLevel.py b/DrownedCityVR/Content/Python/SetupTerraceLevel.py deleted file mode 100644 index fdb8dd2..0000000 --- a/DrownedCityVR/Content/Python/SetupTerraceLevel.py +++ /dev/null @@ -1,350 +0,0 @@ -"""Editor script for /Game/VRTemplate/Maps/Terrace. - -Builds baseline lighting, fog, floor, and PlayerStart. Also dedupes conflicting -lights (common after map duplicates) and clamps exposure for forward-shaded VR. - -File -> Execute Python Script, or run from the Output Log Cmd line. -""" - -import unreal - -TERRACE_MAP = "/Game/VRTemplate/Maps/Terrace" -USE_OPEN_LEVEL = False - -FLOOR_MESH = "/Game/LevelPrototyping/Meshes/SM_Cube" -FLOOR_MAT = "/Game/LevelPrototyping/Materials/MI_PrototypeGrid_Gray" -FLOOR_SCALE = unreal.Vector(25.0, 25.0, 0.3) -FLOOR_POS = unreal.Vector(0.0, 0.0, 15.0) - -PLAYER_START_POS = unreal.Vector(0.0, -400.0, 50.0) -SUN_ROT = unreal.Rotator(-42.0, 135.0, 0.0) -SUN_LUX = 40000.0 - -SKIP_DUPLICATES = True -FIX_LIGHTING = True -PREFERRED_SUN_LABEL = "Terrace_Sun" - - -def _log(message): - unreal.log(f"[TerraceSetup] {message}") - - -def _warn(message): - unreal.log_warning(f"[TerraceSetup] {message}") - - -def _editor_actors(): - subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem) - return list(subsystem.get_all_level_actors()) - - -def _actors_of_class(actor_class): - return [a for a in _editor_actors() if a.get_class() == actor_class] - - -def _any_of_class(actor_class): - return len(_actors_of_class(actor_class)) > 0 - - -def _any_with_label(fragment): - needle = fragment.lower() - return any(needle in actor.get_actor_label().lower() for actor in _editor_actors()) - - -def _destroy(actor): - if actor is None: - return - subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem) - subsystem.destroy_actor(actor) - - -def _pick_preferred(actors, preferred_label): - preferred_label = preferred_label.lower() - for actor in actors: - if actor.get_actor_label().lower() == preferred_label: - return actor - return actors[0] if actors else None - - -def _dedupe(actor_class, preferred_label): - actors = _actors_of_class(actor_class) - if len(actors) <= 1: - return _pick_preferred(actors, preferred_label) - - keep = _pick_preferred(actors, preferred_label) - removed = 0 - for actor in actors: - if actor != keep: - _destroy(actor) - removed += 1 - - class_name = actor_class.get_name() - _log(f"Removed {removed} extra {class_name} actor(s), kept {keep.get_actor_label()}") - return keep - - -def _configure_sun(actor): - if actor is None: - return - - component = actor.get_component_by_class(unreal.DirectionalLightComponent) - if component is None: - return - - component.set_mobility(unreal.ComponentMobility.STATIONARY) - component.set_intensity(SUN_LUX) - component.set_light_color(unreal.LinearColor(1.0, 0.92, 0.82, 1.0)) - component.set_atmosphere_sun_light(True) - component.set_cast_shadows(True) - - actor.set_actor_label(PREFERRED_SUN_LABEL) - _log("Configured primary DirectionalLight (Stationary)") - - -def _configure_sky_light(actor): - if actor is None: - return - component = actor.get_component_by_class(unreal.SkyLightComponent) - if component: - component.set_mobility(unreal.ComponentMobility.STATIONARY) - component.set_real_time_capture(True) - actor.set_actor_label("Terrace_SkyLight") - - -def _configure_fog(actor): - if actor is None: - return - component = actor.get_component_by_class(unreal.ExponentialHeightFogComponent) - if component: - component.set_fog_density(0.02) - component.set_fog_height_falloff(0.3) - component.set_volumetric_fog(False) - actor.set_actor_label("Terrace_Fog") - - -def _fix_post_process_volumes(): - volumes = _actors_of_class(unreal.PostProcessVolume) - if not volumes: - return - - for actor in volumes: - settings = actor.get_editor_property("settings") - - settings.set_editor_property("override_auto_exposure_method", True) - settings.set_editor_property( - "auto_exposure_method", unreal.AutoExposureMethod.AEM_MANUAL - ) - settings.set_editor_property("override_auto_exposure_bias", True) - settings.set_editor_property("auto_exposure_bias", 0.0) - settings.set_editor_property("override_auto_exposure_min_brightness", True) - settings.set_editor_property("auto_exposure_min_brightness", 0.5) - settings.set_editor_property("override_auto_exposure_max_brightness", True) - settings.set_editor_property("auto_exposure_max_brightness", 2.0) - - actor.set_editor_property("settings", settings) - - for prop in ("unbound", "b_unbound", "bUnbound"): - try: - actor.set_editor_property(prop, True) - break - except Exception: - pass - - if actor.get_actor_label().startswith("PostProcessVolume"): - actor.set_actor_label("Terrace_PostProcess") - - _log(f"Tuned exposure on {len(volumes)} PostProcessVolume(s)") - - -def _fix_lighting_conflicts(): - sun = _dedupe(unreal.DirectionalLight, PREFERRED_SUN_LABEL) - _configure_sun(sun) - - sky = _dedupe(unreal.SkyLight, "Terrace_SkyLight") - _configure_sky_light(sky) - - _dedupe(unreal.SkyAtmosphere, "Terrace_SkyAtmosphere") - fog = _dedupe(unreal.ExponentialHeightFog, "Terrace_Fog") - _configure_fog(fog) - - clouds = _actors_of_class(unreal.VolumetricCloud) - if len(clouds) > 1: - keep = _pick_preferred(clouds, "Terrace_Clouds") - for actor in clouds: - if actor != keep: - _destroy(actor) - _log("Removed duplicate VolumetricCloud actors") - - _fix_post_process_volumes() - - -def _spawn_class(actor_class, location, rotation=None, label=None): - rotation = rotation or unreal.Rotator(0.0, 0.0, 0.0) - subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem) - actor = subsystem.spawn_actor_from_class(actor_class, location, rotation) - if actor and label: - actor.set_actor_label(label) - return actor - - -def _spawn_mesh(mesh_path, location, scale, label): - mesh = unreal.load_asset(mesh_path) - if mesh is None: - _warn(f"Missing mesh: {mesh_path}") - return None - - subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem) - actor = subsystem.spawn_actor_from_object( - mesh, location, unreal.Rotator(0.0, 0.0, 0.0) - ) - if actor is None: - _warn(f"Could not place mesh: {mesh_path}") - return None - - actor.set_actor_scale3d(scale) - actor.set_actor_label(label) - - mesh_component = actor.get_component_by_class(unreal.StaticMeshComponent) - if mesh_component: - mesh_component.set_collision_enabled(unreal.CollisionEnabled.QUERY_AND_PHYSICS) - mesh_component.set_collision_profile_name("BlockAll") - material = unreal.load_asset(FLOOR_MAT) - if material: - mesh_component.set_material(0, material) - - return actor - - -def _open_terrace(): - if USE_OPEN_LEVEL: - world = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem).get_editor_world() - if world is None: - raise RuntimeError("No level is open.") - _log(f"Using open level: {world.get_name()}") - return - - if not unreal.EditorAssetLibrary.does_asset_exist(TERRACE_MAP): - raise RuntimeError(f"Map not found: {TERRACE_MAP}") - - unreal.EditorLoadingAndSavingUtils.load_map(TERRACE_MAP) - _log(f"Opened {TERRACE_MAP}") - - -def _save_terrace(): - world = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem).get_editor_world() - if world is None: - _warn("Nothing to save.") - return - - save_path = TERRACE_MAP - if USE_OPEN_LEVEL: - outer = world.get_outer() - if outer: - save_path = outer.get_path_name().split(".")[0] - - try: - unreal.EditorLoadingAndSavingUtils.save_map(world, save_path) - except Exception: - unreal.EditorLoadingAndSavingUtils.save_dirty_packages_with_confirmation(False) - - _log(f"Saved {save_path}") - - -def _try_step(name, step_fn): - try: - step_fn() - except Exception as error: - _warn(f"{name}: {error}") - - -def _add_sun(): - if SKIP_DUPLICATES and _any_of_class(unreal.DirectionalLight): - return - - actor = _spawn_class( - unreal.DirectionalLight, - unreal.Vector(0.0, 0.0, 500.0), - SUN_ROT, - PREFERRED_SUN_LABEL, - ) - _configure_sun(actor) - _log("Placed DirectionalLight") - - -def _add_sky_light(): - if SKIP_DUPLICATES and _any_of_class(unreal.SkyLight): - return - - actor = _spawn_class(unreal.SkyLight, unreal.Vector(0.0, 0.0, 600.0), label="Terrace_SkyLight") - _configure_sky_light(actor) - _log("Placed SkyLight") - - -def _add_sky_atmosphere(): - if SKIP_DUPLICATES and _any_of_class(unreal.SkyAtmosphere): - return - - _spawn_class(unreal.SkyAtmosphere, unreal.Vector(0.0, 0.0, 0.0), label="Terrace_SkyAtmosphere") - _log("Placed SkyAtmosphere") - - -def _add_fog(): - if SKIP_DUPLICATES and _any_of_class(unreal.ExponentialHeightFog): - return - - actor = _spawn_class(unreal.ExponentialHeightFog, unreal.Vector(0.0, 0.0, 0.0), label="Terrace_Fog") - _configure_fog(actor) - _log("Placed ExponentialHeightFog") - - -def _add_post_process(): - if SKIP_DUPLICATES and _any_of_class(unreal.PostProcessVolume): - return - - _spawn_class(unreal.PostProcessVolume, unreal.Vector(0.0, 0.0, 0.0), label="Terrace_PostProcess") - _log("Placed PostProcessVolume") - - -def _add_floor(): - if SKIP_DUPLICATES and _any_with_label("Terrace_Floor"): - return - - _spawn_mesh(FLOOR_MESH, FLOOR_POS, FLOOR_SCALE, "Terrace_Floor") - _log("Placed floor") - - -def _add_player_start(): - if SKIP_DUPLICATES and _any_of_class(unreal.PlayerStart): - return - - _spawn_class(unreal.PlayerStart, PLAYER_START_POS, label="Terrace_PlayerStart") - _log("Placed PlayerStart") - - -def run(): - _log("Starting") - _open_terrace() - - if FIX_LIGHTING: - _try_step("FixLighting", _fix_lighting_conflicts) - - for label, step in ( - ("SkyAtmosphere", _add_sky_atmosphere), - ("Sun", _add_sun), - ("SkyLight", _add_sky_light), - ("Fog", _add_fog), - ("PostProcess", _add_post_process), - ("Floor", _add_floor), - ("PlayerStart", _add_player_start), - ): - _try_step(label, step) - - if FIX_LIGHTING: - _try_step("FixLightingFinal", _fix_lighting_conflicts) - - _save_terrace() - _log("Finished") - - -if __name__ == "__main__": - run()