diff --git a/Nautilus/Utility/MaterialUtils.cs b/Nautilus/Utility/MaterialUtils.cs index 44657aefc..7dbd9e8e6 100644 --- a/Nautilus/Utility/MaterialUtils.cs +++ b/Nautilus/Utility/MaterialUtils.cs @@ -19,9 +19,8 @@ internal static void Patch() private static IEnumerator LoadReferences() { -#if SUBNAUTICA yield return PatchInternal(); -#endif + IsReady = true; yield break; @@ -32,6 +31,26 @@ private static IEnumerator LoadReferences() /// public static bool IsReady { get; private set; } + /// + /// Gets the basic glass material + /// + public static Material GlassMaterial { get; private set; } + + /// + /// Gets the material for the outside of glass, such as for base windows + /// + public static Material ExteriorGlassMaterial { get; private set; } + + /// + /// Gets the material for the inside of glass, such as the inside of the Cyclops windshield + /// + public static Material InteriorGlassMaterial { get; private set; } + + /// + /// Gets a shiny glass material + /// + public static Material ShinyGlassMaterial { get; private set; } + /// /// Contains references to various Shaders. /// diff --git a/Nautilus/Utility/MaterialUtils_BelowZero.cs b/Nautilus/Utility/MaterialUtils_BelowZero.cs new file mode 100644 index 000000000..a126260a7 --- /dev/null +++ b/Nautilus/Utility/MaterialUtils_BelowZero.cs @@ -0,0 +1,47 @@ +using System.Collections; +using UnityEngine; + +#if BELOWZERO +namespace Nautilus.Utility; + +public static partial class MaterialUtils +{ + private static IEnumerator PatchInternal() + { + yield return LoadGlassMaterials(); + } + + private static IEnumerator LoadGlassMaterials() + { + var seamothTask = CraftData.GetPrefabForTechTypeAsync(TechType.SeaTruck); + + yield return seamothTask; + + var glassMaterial = seamothTask.GetResult() + .transform.Find("model/seatruck_anim/Seatruck_cabin_exterior_glass_geo") + .GetComponent().material; + + GlassMaterial = new Material(glassMaterial); + + ExteriorGlassMaterial = new Material(glassMaterial); + ExteriorGlassMaterial.SetFloat("_SpecInt", 100); + ExteriorGlassMaterial.SetFloat("_Shininess", 6.3f); + ExteriorGlassMaterial.SetFloat("_Fresnel", 0.85f); + ExteriorGlassMaterial.SetColor("_Color", new Color(0.33f, 0.58f, 0.71f, 0.1f)); + ExteriorGlassMaterial.SetColor("_SpecColor", new Color(0.5f, 0.76f, 1f, 1f)); + + ShinyGlassMaterial = new Material(glassMaterial); + ShinyGlassMaterial.SetColor("_Color", new Color(1, 1, 1, 0.2f)); + ShinyGlassMaterial.SetFloat("_SpecInt", 3); + ShinyGlassMaterial.SetFloat("_Shininess", 8); + ShinyGlassMaterial.SetFloat("_Fresnel", 0.78f); + + InteriorGlassMaterial = new Material(glassMaterial); + InteriorGlassMaterial.SetColor("_Color", new Color(0.67f, 0.71f, 0.76f, 0.56f)); + InteriorGlassMaterial.SetFloat("_SpecInt", 2); + InteriorGlassMaterial.SetFloat("_Shininess", 6f); + InteriorGlassMaterial.SetFloat("_Fresnel", 0.88f); + } +} + +#endif \ No newline at end of file diff --git a/Nautilus/Utility/MaterialUtils_Subnautica.cs b/Nautilus/Utility/MaterialUtils_Subnautica.cs index 88636f59f..a39bba9ef 100644 --- a/Nautilus/Utility/MaterialUtils_Subnautica.cs +++ b/Nautilus/Utility/MaterialUtils_Subnautica.cs @@ -15,6 +15,8 @@ private static IEnumerator PatchInternal() yield return LoadAirWaterBarrierMaterial(); yield return LoadForcefieldMaterial(); yield return LoadGhostMaterial(); + yield return LoadGlassMaterials(); + yield return LoadUIMaterial(); } /// @@ -47,6 +49,11 @@ private static IEnumerator PatchInternal() /// public static Material GhostMaterial { get; private set; } + /// + /// Gets the material used by the UI in the Cyclops + /// + public static Material HolographicUIMaterial { get; private set; } + private static IEnumerator LoadIonCubeMaterial() { if (IonCubeMaterial) @@ -128,5 +135,57 @@ private static IEnumerator LoadGhostMaterial() GhostMaterial = wallShelf.GetComponentInChildren().ghostMaterial; } } + + private static IEnumerator LoadGlassMaterials() + { + var seamothTask = CraftData.GetPrefabForTechTypeAsync(TechType.Seamoth); + + yield return seamothTask; + + var glassMaterial = seamothTask.GetResult() + .transform.Find("Model/Submersible_SeaMoth/Submersible_seaMoth_geo/Submersible_SeaMoth_glass_geo") + .GetComponent().material; + + GlassMaterial = new Material(glassMaterial); + + ExteriorGlassMaterial = new Material(glassMaterial); + ExteriorGlassMaterial.SetFloat("_SpecInt", 100); + ExteriorGlassMaterial.SetFloat("_Shininess", 6.3f); + ExteriorGlassMaterial.SetFloat("_Fresnel", 0.85f); + ExteriorGlassMaterial.SetColor("_Color", new Color(0.33f, 0.58f, 0.71f, 0.1f)); + ExteriorGlassMaterial.SetColor("_SpecColor", new Color(0.5f, 0.76f, 1f, 1f)); + + ShinyGlassMaterial = new Material(glassMaterial); + ShinyGlassMaterial.SetColor("_Color", new Color(1, 1, 1, 0.2f)); + ShinyGlassMaterial.SetFloat("_SpecInt", 3); + ShinyGlassMaterial.SetFloat("_Shininess", 8); + ShinyGlassMaterial.SetFloat("_Fresnel", 0.78f); + + InteriorGlassMaterial = new Material(glassMaterial); + InteriorGlassMaterial.SetColor("_Color", new Color(0.67f, 0.71f, 0.76f, 0.56f)); + InteriorGlassMaterial.SetFloat("_SpecInt", 2); + InteriorGlassMaterial.SetFloat("_Shininess", 6f); + InteriorGlassMaterial.SetFloat("_Fresnel", 0.88f); + } + + private static bool _cyclopsLoaded; + + private static IEnumerator LoadUIMaterial() + { + yield return new WaitUntil(() => LightmappedPrefabs.main); + + LightmappedPrefabs.main.RequestScenePrefab("Cyclops", new LightmappedPrefabs.OnPrefabLoaded(OnCyclopsLoaded)); + + yield return new WaitUntil(() => _cyclopsLoaded); + } + + private static void OnCyclopsLoaded(GameObject cyclops) + { + var holoMat = cyclops.transform.Find("HelmHUD/HelmHUDVisuals/Canvas_LeftHUD/EngineOnUI/EngineOff_Button") + .GetComponent().material; + + HolographicUIMaterial = new Material(holoMat); + _cyclopsLoaded = true; + } } #endif \ No newline at end of file diff --git a/Nautilus/Utility/ThunderkitUtilities/ApplySNFont.cs b/Nautilus/Utility/ThunderkitUtilities/ApplySNFont.cs new file mode 100644 index 000000000..881d48996 --- /dev/null +++ b/Nautilus/Utility/ThunderkitUtilities/ApplySNFont.cs @@ -0,0 +1,27 @@ +using UnityEngine; +using TMPro; + +namespace Nautilus.Utility.ThunderkitUtilities; + +internal class ApplySNFont : MonoBehaviour +{ + [Tooltip("How to apply the font")] + public GeneralSetMode fontSetMode; + + private void Start() + { + switch (fontSetMode) + { + case GeneralSetMode.SingleObject: + GetComponent().font = FontUtils.Aller_Rg; + break; + case GeneralSetMode.AllChildObjects: + GetComponentsInChildren().ForEach(t => t.font = FontUtils.Aller_Rg); + break; + case GeneralSetMode.AllChildObjectsIncludeInactive: + GetComponentsInChildren(true).ForEach(t => t.font = FontUtils.Aller_Rg); + break; + } + + } +} diff --git a/Nautilus/Utility/ThunderkitUtilities/ApplySNLayer.cs b/Nautilus/Utility/ThunderkitUtilities/ApplySNLayer.cs new file mode 100644 index 000000000..4f07755fd --- /dev/null +++ b/Nautilus/Utility/ThunderkitUtilities/ApplySNLayer.cs @@ -0,0 +1,79 @@ +using System.Reflection; +using UnityEngine; +using UnityEngine.UI; + +namespace Nautilus.Utility.ThunderkitUtilities; + +internal class ApplySNLayer : MonoBehaviour +{ + [Tooltip("The name of the layer you want to apply")] + public LayerName layerName; + + [Tooltip("How to apply the layer")] + public MaterialSetMode layerSetMode; + + private void Start() + { + int layer = layerName switch + { + LayerName.Default => LayerID.Default, + LayerName.Useable => LayerID.Useable, + LayerName.NotUseable => LayerID.NotUseable, + LayerName.Player => LayerID.Player, + LayerName.TerrainCollider => LayerID.TerrainCollider, + LayerName.UI => LayerID.UI, + LayerName.Trigger => LayerID.Trigger, + LayerName.BaseClipProxy => LayerID.BaseClipProxy, + LayerName.OnlyVehicle => LayerID.OnlyVehicle, + LayerName.Vehicle => LayerID.Vehicle, +#if SUBNAUTICA + LayerName.DefaultCollisionMask => LayerID.DefaultCollisionMask, + LayerName.SubRigidbodyExclude => LayerID.SubRigidbodyExclude, +#elif BELOWZERO + LayerName.Interior => LayerID.Interior, + LayerName.AllowPlayerAndVehicle => LayerID.AllowPlayerAndVehicle, +#endif + _ => 0 + }; + + switch(layerSetMode) + { + case MaterialSetMode.SingleObject: + gameObject.layer = layer; + break; + case MaterialSetMode.AllChildObjects: + GetComponentsInChildren().ForEach(g => g.layer = layer); + break; + case MaterialSetMode.AllChildObjectsIncludeInactive: + GetComponentsInChildren(true).ForEach(g => g.layer = layer); + break; + case MaterialSetMode.AllChildGraphics: + GetComponentsInChildren(true).ForEach(g => g.gameObject.layer = layer); + break; + } + } + + /// + /// These are taken from + /// + public enum LayerName + { + Default, + Useable, + NotUseable, + Player, + TerrainCollider, + UI, + Trigger, + BaseClipProxy, + OnlyVehicle, + Vehicle, +#if SUBNAUTICA + DefaultCollisionMask, + SubRigidbodyExclude, +#elif BELOWZERO + Interior, + AllowPlayerAndVehicle +#endif + } +} diff --git a/Nautilus/Utility/ThunderkitUtilities/ApplySNMaterial.cs b/Nautilus/Utility/ThunderkitUtilities/ApplySNMaterial.cs new file mode 100644 index 000000000..adba9e314 --- /dev/null +++ b/Nautilus/Utility/ThunderkitUtilities/ApplySNMaterial.cs @@ -0,0 +1,120 @@ +using System.Collections; +using UnityEngine; +using UnityEngine.UI; + +namespace Nautilus.Utility.ThunderkitUtilities; + +internal class ApplySNMaterial : MonoBehaviour +{ + [Tooltip("How to apply the material")] + public MaterialSetMode materialSetMode; + + [Tooltip("What material to apply")] + public MaterialType materialType; + + [Tooltip("Run at start, or be manually called?")] + public bool runAtStart = true; + + [Header("Single Object Settings:")] + public Renderer renderer; + public int[] materialIndices = new[] { 0 }; + + private void OnValidate() + { + if (!renderer) TryGetComponent(out renderer); + } + + private void Start() + { + if (!runAtStart) return; + + AssignMaterials(); + } + + /// + /// Applies the set material using the specified + /// + public void AssignMaterials() + { + switch(materialSetMode) + { + case MaterialSetMode.SingleObject: + ApplyMaterialsOnSingleRend(); + break; + case MaterialSetMode.AllChildObjects: + ApplyMaterialsOnChildren(false); + break; + case MaterialSetMode.AllChildObjectsIncludeInactive: + ApplyMaterialsOnChildren(true); + break; + case MaterialSetMode.AllChildGraphics: + foreach (var graphic in GetComponentsInChildren(true)) + { + graphic.material = GetMaterial(materialType); + } + break; + } + } + + private void ApplyMaterialsOnSingleRend() + { + if (renderer == null) throw new System.Exception($"The renderer is null on {gameObject} when SN materials were trying to be applied"); + + var mats = renderer.materials; + foreach (var index in materialIndices) + { + mats[index] = GetMaterial(materialType); + } + + renderer.materials = mats; + } + + private void ApplyMaterialsOnChildren(bool includeInactive) + { + var rends = GetComponentsInChildren(includeInactive); + foreach (var rend in rends) + { + var materials = rend.materials; + for (int i = 0; i < materials.Length; i++) + { + materials[i] = GetMaterial(materialType); + } + + rend.materials = materials; + } + } + + private Material GetMaterial(MaterialType type) + { + Material mat = type switch + { +#if SN_STABLE + MaterialType.WaterBarrier => MaterialUtils.AirWaterBarrierMaterial, + MaterialType.ForceField => MaterialUtils.ForceFieldMaterial, + MaterialType.StasisField => MaterialUtils.StasisFieldMaterial, + MaterialType.HolographicUI => MaterialUtils.HolographicUIMaterial, +#endif + MaterialType.Glass => MaterialUtils.GlassMaterial, + MaterialType.ExteriorGlass => MaterialUtils.ExteriorGlassMaterial, + MaterialType.ShinyGlass => MaterialUtils.ShinyGlassMaterial, + MaterialType.InteriorWindowGlass => MaterialUtils.InteriorGlassMaterial, + _ => null + }; + + return mat; + } + + internal enum MaterialType + { + Glass, + ExteriorGlass, + ShinyGlass, + InteriorWindowGlass, +#if SN_STABLE + WaterBarrier, + ForceField, + StasisField, + HolographicUI +#endif + } +} diff --git a/Nautilus/Utility/ThunderkitUtilities/ApplySNShaders.cs b/Nautilus/Utility/ThunderkitUtilities/ApplySNShaders.cs new file mode 100644 index 000000000..743aa428c --- /dev/null +++ b/Nautilus/Utility/ThunderkitUtilities/ApplySNShaders.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace Nautilus.Utility.ThunderkitUtilities; + +internal class ApplySNShaders : MonoBehaviour +{ + [Tooltip("Which GameObject to apply the shaders to (All children will also be affected)")] + public GameObject applyTo; + + private void OnValidate() + { + if (applyTo == null) applyTo = gameObject; + } + + private void Start() + { + MaterialUtils.ApplySNShaders(applyTo); + } +} diff --git a/Nautilus/Utility/ThunderkitUtilities/SetModes.cs b/Nautilus/Utility/ThunderkitUtilities/SetModes.cs new file mode 100644 index 000000000..d6f8d3846 --- /dev/null +++ b/Nautilus/Utility/ThunderkitUtilities/SetModes.cs @@ -0,0 +1,16 @@ +namespace Nautilus.Utility.ThunderkitUtilities; + +internal enum GeneralSetMode +{ + SingleObject, + AllChildObjects, + AllChildObjectsIncludeInactive, +} + +internal enum MaterialSetMode +{ + SingleObject, + AllChildObjects, + AllChildObjectsIncludeInactive, + AllChildGraphics +}