241 lines
6.0 KiB
C#
241 lines
6.0 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using OHM.UnityToolkit;
|
|
using UnityEngine.Serialization;
|
|
|
|
namespace Ambiance
|
|
{
|
|
public class AmbianceController : UniqueInstance<AmbianceController>
|
|
{
|
|
[SerializeField]
|
|
public AmbiancesDef ambiancesDef;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("skyMatRef")]
|
|
private Material _skyMatRef;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("dirLight")]
|
|
private Light _dirLight;
|
|
|
|
private Camera camera;
|
|
|
|
public Dictionary<string, Color> debugColors = new Dictionary<string, Color>();
|
|
|
|
public int changeAmbianceSectionCount = 1;
|
|
|
|
private AmbianceDef _forcedAmbiance;
|
|
|
|
private bool currentlyOnFire;
|
|
|
|
public UnityEvent OnAmbianceChange;
|
|
|
|
public AmbianceDef CurrentAmbiance { get; private set; }
|
|
|
|
public AmbianceDef CurrentAmbianceToUse { get; private set; }
|
|
|
|
public int CurrentLevelIdx { get; private set; }
|
|
|
|
public int CurrentAmbianceIdx { get; private set; }
|
|
|
|
public int CurrentAmbianceRealIdx { get; private set; }
|
|
|
|
public Material SkyMat { get; private set; }
|
|
|
|
public Dictionary<string, Material> SpecialMats { get; private set; }
|
|
|
|
public bool Flip { get; set; }
|
|
|
|
public string _debugSkyColorKey { get; private set; } = "debug_sky_color";
|
|
|
|
public string GetFlippedId(string id)
|
|
{
|
|
return id + "_f";
|
|
}
|
|
|
|
protected override void AwakeInstance()
|
|
{
|
|
SpecialMats = new Dictionary<string, Material>();
|
|
foreach (SpecialMatDef def in ambiancesDef.specialsMatRef)
|
|
{
|
|
var mat = new Material(def.materialRef);
|
|
mat.name = mat.name + "_" + def.id;
|
|
SpecialMats[def.id] = mat;
|
|
if (!def.flippable)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var flipped = new Material(def.materialRef);
|
|
string flippedId = GetFlippedId(def.id);
|
|
flipped.name = flipped.name + "_" + flippedId;
|
|
flipped.mainTextureScale = new Vector2(flipped.mainTextureScale.x, 0f - flipped.mainTextureScale.y);
|
|
SpecialMats[flippedId] = flipped;
|
|
}
|
|
if (_skyMatRef != null)
|
|
{
|
|
SkyMat = new Material(_skyMatRef);
|
|
RenderSettings.skybox = SkyMat;
|
|
}
|
|
}
|
|
|
|
public void UpdateCameraAmbiance(Camera camera)
|
|
{
|
|
this.camera = camera;
|
|
SetAmbiance(CurrentAmbiance, currentlyOnFire);
|
|
}
|
|
|
|
public void ForceAmbiance(AmbianceDef amb)
|
|
{
|
|
_forcedAmbiance = amb;
|
|
SetLevelIdx(CurrentLevelIdx, currentlyOnFire, forceReload: true);
|
|
}
|
|
|
|
public void SetLevelIdx(int levelIdx, bool onFire, bool forceReload)
|
|
{
|
|
if (!forceReload && CurrentLevelIdx == levelIdx && currentlyOnFire == onFire)
|
|
{
|
|
return;
|
|
}
|
|
CurrentLevelIdx = levelIdx;
|
|
currentlyOnFire = onFire;
|
|
if (_forcedAmbiance != null)
|
|
{
|
|
SetAmbiance(_forcedAmbiance, onFire);
|
|
return;
|
|
}
|
|
CurrentAmbianceIdx = levelIdx / changeAmbianceSectionCount;
|
|
List<AmbianceDef> ambiances = ambiancesDef.GetAmbiancesList();
|
|
CurrentAmbianceRealIdx = CurrentAmbianceIdx % ambiances.Count;
|
|
SetAmbiance(ambiances[CurrentAmbianceRealIdx], onFire);
|
|
}
|
|
|
|
public void TryAmbiance(AmbianceDef ambianceDef, bool onFire)
|
|
{
|
|
SetAmbiance(ambianceDef, onFire);
|
|
}
|
|
|
|
public Material GetSpecialMat(string id, bool allowFlip = false)
|
|
{
|
|
if (SpecialMats == null)
|
|
{
|
|
return null;
|
|
}
|
|
if (Flip && allowFlip)
|
|
{
|
|
string flippedId = GetFlippedId(id);
|
|
if (SpecialMats.ContainsKey(flippedId))
|
|
{
|
|
return SpecialMats[flippedId];
|
|
}
|
|
}
|
|
if (SpecialMats.ContainsKey(id))
|
|
{
|
|
return SpecialMats[id];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void SetAmbiance(AmbianceDef def, bool fire)
|
|
{
|
|
CurrentAmbiance = def;
|
|
AmbianceDef toUse = (fire && def != null && def.fireAmbiance != null) ? def.fireAmbiance : def;
|
|
CurrentAmbianceToUse = toUse;
|
|
if (toUse == null)
|
|
{
|
|
return;
|
|
}
|
|
RenderSettings.fogColor = toUse.fogColor;
|
|
ApplySpecialColor(toUse);
|
|
if (SkyMat != null)
|
|
{
|
|
if (debugColors.ContainsKey(_debugSkyColorKey))
|
|
{
|
|
Color debugColor = debugColors[_debugSkyColorKey];
|
|
SkyMat.SetColor("_SkyColor1", debugColor);
|
|
SkyMat.SetColor("_SkyColor2", debugColor);
|
|
SkyMat.SetColor("_SkyColor3", debugColor);
|
|
}
|
|
else
|
|
{
|
|
SkyMat.SetTexture("_MainTex", def.skyPano);
|
|
}
|
|
}
|
|
FogDistance fog = (def.fogDistance != null) ? def.fogDistance : ambiancesDef.defaultFogDistance;
|
|
RenderSettings.fogStartDistance = fog.start;
|
|
RenderSettings.fogEndDistance = fog.end;
|
|
OnAmbianceChange.Invoke();
|
|
}
|
|
|
|
private void ApplySpecialColor(AmbianceDef def)
|
|
{
|
|
if (def == null || def.specialColors == null)
|
|
{
|
|
return;
|
|
}
|
|
foreach (SpecialColorDef sc in def.specialColors)
|
|
{
|
|
Material mat = GetSpecialMat(sc.id);
|
|
if (mat != null)
|
|
{
|
|
ApplySpecialColorToMat(mat, sc);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogErrorFormat(
|
|
"Ambiance {0} is trying to set undefined special material {1}. Please check ambiance or def",
|
|
def.name, sc.id);
|
|
}
|
|
Material flipped = GetSpecialMat(GetFlippedId(sc.id));
|
|
if (flipped != null)
|
|
{
|
|
ApplySpecialColorToMat(flipped, sc);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ApplySpecialColorToMat(Material specMat, SpecialColorDef sc)
|
|
{
|
|
if (debugColors.ContainsKey(sc.id))
|
|
{
|
|
Color debugColor = debugColors[sc.id];
|
|
specMat.SetColor("_TintColor", debugColor);
|
|
specMat.SetColor("_ColorAdd", debugColor);
|
|
specMat.SetColor("_EmissionColor", debugColor);
|
|
specMat.mainTexture = null;
|
|
return;
|
|
}
|
|
specMat.color = sc.color;
|
|
if (specMat.HasProperty("_TintColor"))
|
|
{
|
|
specMat.SetColor("_TintColor", sc.color);
|
|
}
|
|
if (specMat.HasProperty("_ColorAdd"))
|
|
{
|
|
specMat.SetColor("_ColorAdd", sc.colorAdd);
|
|
}
|
|
if (specMat.HasProperty("_EmissionColor"))
|
|
{
|
|
specMat.EnableKeyword("_EMISSION");
|
|
specMat.SetColor("_EmissionColor", sc.colorEmission);
|
|
}
|
|
if (specMat.HasProperty("_EmissionMap") && sc.textureEmission != null)
|
|
{
|
|
specMat.SetTexture("_EmissionMap", sc.textureEmission);
|
|
}
|
|
if (sc.texture != null)
|
|
{
|
|
specMat.mainTexture = sc.texture;
|
|
return;
|
|
}
|
|
|
|
SpecialMatDef matDef = ambiancesDef.specialsMatRef.Find((SpecialMatDef d) => d.id == sc.id);
|
|
if (matDef != null)
|
|
{
|
|
specMat.mainTexture = matDef.materialRef.mainTexture;
|
|
}
|
|
}
|
|
}
|
|
}
|