Skip to content

Commit

Permalink
feat: Thunderkit Utilities (#558)
Browse files Browse the repository at this point in the history
* Added thunderkit utilites

* Added SN/BZ checking

* Added separate enums for the layers in SN & BZ

* Changed name of application modes

* Moved material getters to MaterialUtils

* Changed layer application to use switch expression

* Removed unnecessary comment

* Changed property names to respect their type name

* Added default index of 0 to material indices

* Added graphic setting and reverted default build config

* Added graphic option to layer applier & removed outdated comment
  • Loading branch information
Indigocoder1 authored Sep 18, 2024
1 parent 3215981 commit 288e473
Show file tree
Hide file tree
Showing 8 changed files with 388 additions and 2 deletions.
23 changes: 21 additions & 2 deletions Nautilus/Utility/MaterialUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ internal static void Patch()

private static IEnumerator LoadReferences()
{
#if SUBNAUTICA
yield return PatchInternal();
#endif

IsReady = true;

yield break;
Expand All @@ -32,6 +31,26 @@ private static IEnumerator LoadReferences()
/// </summary>
public static bool IsReady { get; private set; }

/// <summary>
/// Gets the basic glass material
/// </summary>
public static Material GlassMaterial { get; private set; }

/// <summary>
/// Gets the material for the outside of glass, such as for base windows
/// </summary>
public static Material ExteriorGlassMaterial { get; private set; }

/// <summary>
/// Gets the material for the inside of glass, such as the inside of the Cyclops windshield
/// </summary>
public static Material InteriorGlassMaterial { get; private set; }

/// <summary>
/// Gets a shiny glass material
/// </summary>
public static Material ShinyGlassMaterial { get; private set; }

/// <summary>
/// Contains references to various Shaders.
/// </summary>
Expand Down
47 changes: 47 additions & 0 deletions Nautilus/Utility/MaterialUtils_BelowZero.cs
Original file line number Diff line number Diff line change
@@ -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<Renderer>().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
59 changes: 59 additions & 0 deletions Nautilus/Utility/MaterialUtils_Subnautica.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ private static IEnumerator PatchInternal()
yield return LoadAirWaterBarrierMaterial();
yield return LoadForcefieldMaterial();
yield return LoadGhostMaterial();
yield return LoadGlassMaterials();
yield return LoadUIMaterial();
}

/// <summary>
Expand Down Expand Up @@ -47,6 +49,11 @@ private static IEnumerator PatchInternal()
/// </summary>
public static Material GhostMaterial { get; private set; }

/// <summary>
/// Gets the material used by the UI in the Cyclops
/// </summary>
public static Material HolographicUIMaterial { get; private set; }

private static IEnumerator LoadIonCubeMaterial()
{
if (IonCubeMaterial)
Expand Down Expand Up @@ -128,5 +135,57 @@ private static IEnumerator LoadGhostMaterial()
GhostMaterial = wallShelf.GetComponentInChildren<Constructable>().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<Renderer>().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<UnityEngine.UI.Image>().material;

HolographicUIMaterial = new Material(holoMat);
_cyclopsLoaded = true;
}
}
#endif
27 changes: 27 additions & 0 deletions Nautilus/Utility/ThunderkitUtilities/ApplySNFont.cs
Original file line number Diff line number Diff line change
@@ -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<TextMeshProUGUI>().font = FontUtils.Aller_Rg;
break;
case GeneralSetMode.AllChildObjects:
GetComponentsInChildren<TextMeshProUGUI>().ForEach(t => t.font = FontUtils.Aller_Rg);
break;
case GeneralSetMode.AllChildObjectsIncludeInactive:
GetComponentsInChildren<TextMeshProUGUI>(true).ForEach(t => t.font = FontUtils.Aller_Rg);
break;
}

}
}
79 changes: 79 additions & 0 deletions Nautilus/Utility/ThunderkitUtilities/ApplySNLayer.cs
Original file line number Diff line number Diff line change
@@ -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<GameObject>().ForEach(g => g.layer = layer);
break;
case MaterialSetMode.AllChildObjectsIncludeInactive:
GetComponentsInChildren<GameObject>(true).ForEach(g => g.layer = layer);
break;
case MaterialSetMode.AllChildGraphics:
GetComponentsInChildren<Graphic>(true).ForEach(g => g.gameObject.layer = layer);
break;
}
}

/// <summary>
/// These are taken from <see cref="LayerID"/>
/// </summary>
public enum LayerName
{
Default,
Useable,
NotUseable,
Player,
TerrainCollider,
UI,
Trigger,
BaseClipProxy,
OnlyVehicle,
Vehicle,
#if SUBNAUTICA
DefaultCollisionMask,
SubRigidbodyExclude,
#elif BELOWZERO
Interior,
AllowPlayerAndVehicle
#endif
}
}
120 changes: 120 additions & 0 deletions Nautilus/Utility/ThunderkitUtilities/ApplySNMaterial.cs
Original file line number Diff line number Diff line change
@@ -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();
}

/// <summary>
/// Applies the set material using the specified <see cref="MaterialSetMode"/>
/// </summary>
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<Graphic>(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<Renderer>(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
}
}
Loading

0 comments on commit 288e473

Please sign in to comment.