Files
butchers-games-test/Assets/Scripts/Game/Ambiance/AmbianceController.cs
T
Boris Nikolaev 5f1e94b653 add project files
2026-08-14 01:58:31 +03:00

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;
}
}
}
}