namespace Sandbox; [Expose] [Hide] [Title( "3D Skybox - Map" )] [Category( "Rendering" )] [Icon( "visibility" )] public class MapSkybox3D : Component, Component.ExecuteInEditor { private string TargetMapName { get; set; } private Vector3 CameraOffset { get; set; } SceneSkybox3D sceneSkybox3D; protected override void OnEnabled() { if ( TargetMapName is null ) return; Assert.True( sceneSkybox3D == null ); Assert.NotNull( Scene ); sceneSkybox3D = new SceneSkybox3D( Scene.SceneWorld, new SceneWorld() ); // Load with custom map loader for sky_camera to adjust the SceneSkybox3D new SceneMap( sceneSkybox3D.SkyboxWorld, TargetMapName, new SkyboxMapLoader( sceneSkybox3D, CameraOffset ) ); Transform.OnTransformChanged += OnTransformChanged; } protected override void OnDisabled() { Transform.OnTransformChanged -= OnTransformChanged; sceneSkybox3D?.Delete(); sceneSkybox3D = null; } private void OnTransformChanged() { CameraOffset = WorldPosition; sceneSkybox3D.Origin = sceneSkybox3D.CameraOrigin - CameraOffset / sceneSkybox3D.Scale; sceneSkybox3D.Update(); } internal static void InitializeFromLegacy( GameObject go, MapLoader.ObjectEntry kv ) { var mapName = kv.GetString( "targetMapName" ); if ( string.IsNullOrEmpty( mapName ) ) return; var component = go.Components.Create(); component.TargetMapName = mapName; component.CameraOffset = kv.Position; } } /// /// Loader for a 3D skybox which updates the values on the parent sceneworld /// file class SkyboxMapLoader : SceneMapLoader { readonly SceneSkybox3D Skybox3D; readonly Vector3 CameraOffset; public SkyboxMapLoader( SceneSkybox3D skybox3D, Vector3 cameraOffset ) : base( skybox3D.SkyboxWorld, null ) { Skybox3D = skybox3D; CameraOffset = cameraOffset; } protected override void CreateObject( ObjectEntry kv ) { if ( kv.TypeName == "sky_camera" ) { Skybox3D.CameraOrigin = kv.Position; Skybox3D.Origin = Skybox3D.CameraOrigin - CameraOffset / kv.GetValue( "scale", 16 ); Skybox3D.Angles = kv.Angles; Skybox3D.Scale = kv.GetValue( "scale", 16 ); Skybox3D.Update(); return; } if ( kv.TypeName == "env_sky" ) { var skyMaterial = kv.GetResource( "skyname" ); var tintColor = kv.GetValue( "tint_color" ); var transform = kv.Transform; new SceneSkyBox( Skybox3D.SkyboxWorld, skyMaterial ) { SkyTint = tintColor, Transform = transform }; } base.CreateObject( kv ); } }