mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
commit
d7c1812741
@ -1,12 +1,17 @@
|
|||||||
using NewHorizons.External.Configs;
|
using NewHorizons.External.Configs;
|
||||||
using NewHorizons.Utility;
|
using NewHorizons.Utility;
|
||||||
using OWML.Common;
|
using OWML.Common;
|
||||||
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Logger = NewHorizons.Utility.Logger;
|
using Logger = NewHorizons.Utility.Logger;
|
||||||
namespace NewHorizons.Builder.StarSystem
|
namespace NewHorizons.Builder.StarSystem
|
||||||
{
|
{
|
||||||
public class SkyboxBuilder
|
public static class SkyboxBuilder
|
||||||
{
|
{
|
||||||
|
private static readonly int _skyboxLayer = LayerMask.NameToLayer("Skybox");
|
||||||
|
private static readonly Shader _unlitShader = Shader.Find("Unlit/Texture");
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
public static void Make(StarSystemConfig.SkyboxConfig info, IModBehaviour mod)
|
public static void Make(StarSystemConfig.SkyboxConfig info, IModBehaviour mod)
|
||||||
{
|
{
|
||||||
Logger.Log("Building Skybox");
|
Logger.Log("Building Skybox");
|
||||||
@ -17,5 +22,131 @@ namespace NewHorizons.Builder.StarSystem
|
|||||||
camera.clearFlags = CameraClearFlags.Skybox;
|
camera.clearFlags = CameraClearFlags.Skybox;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Make(StarSystemConfig.SkyboxModule module, IModBehaviour mod)
|
||||||
|
{
|
||||||
|
Logger.Log("Building Skybox");
|
||||||
|
BuildSkySphere(module, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameObject BuildSkySphere(StarSystemConfig.SkyboxModule module, IModBehaviour mod)
|
||||||
|
{
|
||||||
|
var skybox = SearchUtilities.Find("Skybox");
|
||||||
|
|
||||||
|
var rightTex = ImageUtilities.GetTexture(mod, module.rightPath);
|
||||||
|
var leftTex = ImageUtilities.GetTexture(mod, module.leftPath);
|
||||||
|
var topTex = ImageUtilities.GetTexture(mod, module.topPath);
|
||||||
|
var bottomTex = ImageUtilities.GetTexture(mod, module.bottomPath);
|
||||||
|
var frontTex = ImageUtilities.GetTexture(mod, module.frontPath);
|
||||||
|
var backTex = ImageUtilities.GetTexture(mod, module.backPath);
|
||||||
|
|
||||||
|
var mesh = BuildSkySphereFaceMesh(module.useCube ? 1 : 32);
|
||||||
|
|
||||||
|
var skySphere = new GameObject("Sky Sphere");
|
||||||
|
skySphere.transform.SetParent(skybox.transform, false);
|
||||||
|
skySphere.layer = _skyboxLayer;
|
||||||
|
skySphere.transform.localScale = Vector3.one * 5f;
|
||||||
|
|
||||||
|
BuildSkySphereFace(skySphere, "Right", Quaternion.Euler(0f, 90f, 0f), mesh, rightTex);
|
||||||
|
BuildSkySphereFace(skySphere, "Left", Quaternion.Euler(0f, 270f, 0f), mesh, leftTex);
|
||||||
|
BuildSkySphereFace(skySphere, "Top", Quaternion.Euler(270f, 0f, 0f), mesh, topTex);
|
||||||
|
BuildSkySphereFace(skySphere, "Bottom", Quaternion.Euler(90f, 0f, 0f), mesh, bottomTex);
|
||||||
|
BuildSkySphereFace(skySphere, "Front", Quaternion.Euler(0f, 0f, 0f), mesh, frontTex);
|
||||||
|
BuildSkySphereFace(skySphere, "Back", Quaternion.Euler(0f, 180f, 0f), mesh, backTex);
|
||||||
|
|
||||||
|
return skySphere;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameObject BuildSkySphereFace(GameObject skySphere, string name, Quaternion rotation, Mesh mesh, Texture2D tex)
|
||||||
|
{
|
||||||
|
if (!tex)
|
||||||
|
{
|
||||||
|
Logger.LogError($"Failed to load texture for skybox {name.ToLower()} face");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var go = new GameObject(name)
|
||||||
|
{
|
||||||
|
layer = _skyboxLayer
|
||||||
|
};
|
||||||
|
|
||||||
|
var mf = go.AddComponent<MeshFilter>();
|
||||||
|
mf.sharedMesh = mesh;
|
||||||
|
|
||||||
|
var mat = new Material(_unlitShader)
|
||||||
|
{
|
||||||
|
name = $"Sky Sphere {name}",
|
||||||
|
mainTexture = tex
|
||||||
|
};
|
||||||
|
|
||||||
|
var mr = go.AddComponent<MeshRenderer>();
|
||||||
|
mr.sharedMaterial = mat;
|
||||||
|
|
||||||
|
var sr = go.AddComponent<SkyboxRenderer>();
|
||||||
|
Delay.RunWhen(() => SkyboxRenderer.s_active.Contains(sr), () =>
|
||||||
|
{
|
||||||
|
SkyboxRenderer.s_active.Remove(sr);
|
||||||
|
SkyboxRenderer.s_active.Insert(0, sr);
|
||||||
|
});
|
||||||
|
|
||||||
|
go.transform.SetParent(skySphere.transform, false);
|
||||||
|
go.transform.localRotation = rotation;
|
||||||
|
go.transform.localScale = Vector3.one;
|
||||||
|
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mesh BuildSkySphereFaceMesh(int quadsPerAxis)
|
||||||
|
{
|
||||||
|
var mesh = new Mesh
|
||||||
|
{
|
||||||
|
name = $"Sky Sphere Face"
|
||||||
|
};
|
||||||
|
|
||||||
|
var vertices = new Vector3[(quadsPerAxis + 1) * (quadsPerAxis + 1)];
|
||||||
|
var normals = new Vector3[vertices.Length];
|
||||||
|
var uvs = new Vector2[vertices.Length];
|
||||||
|
var tris = new int[quadsPerAxis * quadsPerAxis * 2 * 3];
|
||||||
|
|
||||||
|
for (var x = 0; x <= quadsPerAxis; x++)
|
||||||
|
{
|
||||||
|
for (var y = 0; y <= quadsPerAxis; y++)
|
||||||
|
{
|
||||||
|
var i = y * (quadsPerAxis + 1) + x;
|
||||||
|
var fx = (float)x / quadsPerAxis;
|
||||||
|
var fy = (float)y / quadsPerAxis;
|
||||||
|
vertices[i] = new Vector3(-0.5f + fx, -0.5f + fy, 0.5f).normalized;
|
||||||
|
normals[i] = -vertices[i].normalized;
|
||||||
|
uvs[i] = new Vector2(fx, fy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int t = 0;
|
||||||
|
for (var x = 0; x < quadsPerAxis; x++)
|
||||||
|
{
|
||||||
|
for (var y = 0; y < quadsPerAxis; y++)
|
||||||
|
{
|
||||||
|
var i0 = (y + 1) * (quadsPerAxis + 1) + (x + 0);
|
||||||
|
var i1 = (y + 1) * (quadsPerAxis + 1) + (x + 1);
|
||||||
|
var i2 = (y + 0) * (quadsPerAxis + 1) + (x + 1);
|
||||||
|
var i3 = (y + 0) * (quadsPerAxis + 1) + (x + 0);
|
||||||
|
|
||||||
|
tris[t++] = i0;
|
||||||
|
tris[t++] = i1;
|
||||||
|
tris[t++] = i2;
|
||||||
|
|
||||||
|
tris[t++] = i2;
|
||||||
|
tris[t++] = i3;
|
||||||
|
tris[t++] = i0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.vertices = vertices;
|
||||||
|
mesh.normals = normals;
|
||||||
|
mesh.uv = uvs;
|
||||||
|
mesh.triangles = tris;
|
||||||
|
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
64
NewHorizons/External/Configs/StarSystemConfig.cs
vendored
64
NewHorizons/External/Configs/StarSystemConfig.cs
vendored
@ -43,8 +43,14 @@ namespace NewHorizons.External.Configs
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Customize the skybox for this system
|
/// Customize the skybox for this system
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete("skybox is deprecated, please use Skybox instead")]
|
||||||
public SkyboxConfig skybox;
|
public SkyboxConfig skybox;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Customize the skybox for this system
|
||||||
|
/// </summary>
|
||||||
|
public SkyboxModule Skybox;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to `true` if you want to spawn here after dying, not Timber Hearth. You can still warp back to the main star
|
/// Set to `true` if you want to spawn here after dying, not Timber Hearth. You can still warp back to the main star
|
||||||
/// system.
|
/// system.
|
||||||
@ -117,6 +123,7 @@ namespace NewHorizons.External.Configs
|
|||||||
public int[] z;
|
public int[] z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("SkyboxConfig is deprecated, please use SkyboxModule instead")]
|
||||||
[JsonObject]
|
[JsonObject]
|
||||||
public class SkyboxConfig
|
public class SkyboxConfig
|
||||||
{
|
{
|
||||||
@ -134,6 +141,52 @@ namespace NewHorizons.External.Configs
|
|||||||
/// Path to the material within the asset bundle specified by `assetBundle` to use for the skybox
|
/// Path to the material within the asset bundle specified by `assetBundle` to use for the skybox
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string path;
|
public string path;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonObject]
|
||||||
|
public class SkyboxModule
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to destroy the star field around the player
|
||||||
|
/// </summary>
|
||||||
|
public bool destroyStarField;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to use a cube for the skybox instead of a smooth sphere
|
||||||
|
/// </summary>
|
||||||
|
public bool useCube;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relative filepath to the texture to use for the skybox's positive X direction
|
||||||
|
/// </summary>
|
||||||
|
public string rightPath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relative filepath to the texture to use for the skybox's negative X direction
|
||||||
|
/// </summary>
|
||||||
|
public string leftPath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relative filepath to the texture to use for the skybox's positive Y direction
|
||||||
|
/// </summary>
|
||||||
|
public string topPath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relative filepath to the texture to use for the skybox's negative Y direction
|
||||||
|
/// </summary>
|
||||||
|
public string bottomPath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relative filepath to the texture to use for the skybox's positive Z direction
|
||||||
|
/// </summary>
|
||||||
|
public string frontPath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relative filepath to the texture to use for the skybox's negative Z direction
|
||||||
|
/// </summary>
|
||||||
|
public string backPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -162,7 +215,10 @@ namespace NewHorizons.External.Configs
|
|||||||
|
|
||||||
// If current one is null take the other
|
// If current one is null take the other
|
||||||
factRequiredForWarp = string.IsNullOrEmpty(factRequiredForWarp) ? otherConfig.factRequiredForWarp : factRequiredForWarp;
|
factRequiredForWarp = string.IsNullOrEmpty(factRequiredForWarp) ? otherConfig.factRequiredForWarp : factRequiredForWarp;
|
||||||
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
skybox = skybox == null ? otherConfig.skybox : skybox;
|
skybox = skybox == null ? otherConfig.skybox : skybox;
|
||||||
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
|
Skybox = Skybox == null ? otherConfig.Skybox : Skybox;
|
||||||
travelAudio = string.IsNullOrEmpty(travelAudio) ? otherConfig.travelAudio : travelAudio;
|
travelAudio = string.IsNullOrEmpty(travelAudio) ? otherConfig.travelAudio : travelAudio;
|
||||||
|
|
||||||
// False by default so if one is true go true
|
// False by default so if one is true go true
|
||||||
@ -187,6 +243,14 @@ namespace NewHorizons.External.Configs
|
|||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
if (!string.IsNullOrEmpty(travelAudioClip)) travelAudio = travelAudioClip;
|
if (!string.IsNullOrEmpty(travelAudioClip)) travelAudio = travelAudioClip;
|
||||||
if (!string.IsNullOrEmpty(travelAudioFilePath)) travelAudio = travelAudioFilePath;
|
if (!string.IsNullOrEmpty(travelAudioFilePath)) travelAudio = travelAudioFilePath;
|
||||||
|
if (skybox != null)
|
||||||
|
{
|
||||||
|
if (Skybox == null)
|
||||||
|
{
|
||||||
|
Skybox = new SkyboxModule();
|
||||||
|
Skybox.destroyStarField = skybox.destroyStarField;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12,15 +12,27 @@ namespace NewHorizons.Handlers
|
|||||||
{
|
{
|
||||||
var skybox = SearchUtilities.Find("Skybox/Starfield");
|
var skybox = SearchUtilities.Find("Skybox/Starfield");
|
||||||
|
|
||||||
if (system.Config.skybox?.destroyStarField ?? false)
|
if (system.Config.Skybox?.destroyStarField ?? false)
|
||||||
{
|
{
|
||||||
Object.Destroy(skybox);
|
Object.Destroy(skybox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (system.Config.Skybox?.rightPath != null ||
|
||||||
|
system.Config.Skybox?.leftPath != null ||
|
||||||
|
system.Config.Skybox?.topPath != null ||
|
||||||
|
system.Config.Skybox?.bottomPath != null ||
|
||||||
|
system.Config.Skybox?.frontPath != null ||
|
||||||
|
system.Config.Skybox?.bottomPath != null)
|
||||||
|
{
|
||||||
|
SkyboxBuilder.Make(system.Config.Skybox, system.Mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CS0618, CS0612 // Type or member is obsolete
|
||||||
if (system.Config.skybox?.assetBundle != null && system.Config.skybox?.path != null)
|
if (system.Config.skybox?.assetBundle != null && system.Config.skybox?.path != null)
|
||||||
{
|
{
|
||||||
SkyboxBuilder.Make(system.Config.skybox, system.Mod);
|
SkyboxBuilder.Make(system.Config.skybox, system.Mod);
|
||||||
}
|
}
|
||||||
|
#pragma warning restore CS0618, CS0612 // Type or member is obsolete
|
||||||
|
|
||||||
if (system.Config.enableTimeLoop)
|
if (system.Config.enableTimeLoop)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -28,9 +28,9 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Should the player not be able to view the map in this system?"
|
"description": "Should the player not be able to view the map in this system?"
|
||||||
},
|
},
|
||||||
"skybox": {
|
"Skybox": {
|
||||||
"description": "Customize the skybox for this system",
|
"description": "Customize the skybox for this system",
|
||||||
"$ref": "#/definitions/SkyboxConfig"
|
"$ref": "#/definitions/SkyboxModule"
|
||||||
},
|
},
|
||||||
"startHere": {
|
"startHere": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@ -87,21 +87,41 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"SkyboxConfig": {
|
"SkyboxModule": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"assetBundle": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Path to the Unity asset bundle to load the skybox material from"
|
|
||||||
},
|
|
||||||
"destroyStarField": {
|
"destroyStarField": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Whether to destroy the star field around the player"
|
"description": "Whether to destroy the star field around the player"
|
||||||
},
|
},
|
||||||
"path": {
|
"useCube": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether to use a cube for the skybox instead of a smooth sphere"
|
||||||
|
},
|
||||||
|
"rightPath": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Path to the material within the asset bundle specified by `assetBundle` to use for the skybox"
|
"description": "Relative filepath to the texture to use for the skybox's positive X direction"
|
||||||
|
},
|
||||||
|
"leftPath": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Relative filepath to the texture to use for the skybox's negative X direction"
|
||||||
|
},
|
||||||
|
"topPath": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Relative filepath to the texture to use for the skybox's positive Y direction"
|
||||||
|
},
|
||||||
|
"bottomPath": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Relative filepath to the texture to use for the skybox's negative Y direction"
|
||||||
|
},
|
||||||
|
"frontPath": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Relative filepath to the texture to use for the skybox's positive Z direction"
|
||||||
|
},
|
||||||
|
"backPath": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Relative filepath to the texture to use for the skybox's negative Z direction"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user