Files
FallBots/Assets/Content/Scripts/PlayerVisual.cs
2026-03-19 06:31:08 +01:00

175 lines
4.7 KiB
C#

using System.Linq;
using UnityEngine;
public class PlayerVisual : MonoBehaviour
{
[System.Serializable]
private class Customization
{
public int HeadID;
public int BodyID;
[ColorUsage(false, true)] public Color[] Colors;
}
[System.Serializable]
private class References
{
public Player Player;
public Animator Anim;
public Renderer[] Renderers;
public Material[] Materials;
public GameObject[] HeadAccessories;
public GameObject[] BodyAccessories;
}
[System.Serializable]
private class PlayerAnimationStateMapper
{
public Player.PlayerState PlayerState;
public string AnimatorState;
public string BlockingState;
public string Trigger;
}
[SerializeField]
private Customization _customization;
[SerializeField]
private References _references;
[SerializeField]
private PlayerAnimationStateMapper[] _playerAnimationStateMapper;
private const string PP_CUSTOM = "CustomPlayer";
void Start()
{
LoadCustom();
}
void Update()
{
UpdateAnimation();
}
public void RandomizeCustom()
{
float hueShift = Random.Range(0f, 360f);
// Accessories
_customization.HeadID = Random.Range(0, _references.HeadAccessories.Length + 1);
_customization.BodyID = Random.Range(0, _references.BodyAccessories.Length + 1);
// Colors
_customization.Colors = new Color[_references.Materials.Length];
for (int i = 0; i < _customization.Colors.Length; i++)
{
Material mat = _references.Materials[i];
Color col = mat.color;
if (mat.IsKeywordEnabled("_EMISSION"))
col = mat.GetColor("_EmissionColor");
col = ShiftHue(col, hueShift);
_customization.Colors[i] = col;
}
SetCustom();
SaveCustom();
}
private void SetCustom()
{
// Accessories
for (int i = 0; i < _references.HeadAccessories.Length; i++)
_references.HeadAccessories[i].SetActive(i == _customization.HeadID);
for (int i = 0; i < _references.BodyAccessories.Length; i++)
_references.BodyAccessories[i].SetActive(i == _customization.BodyID);
// Colors
foreach (Renderer rend in _references.Renderers)
{
foreach (Material mat in rend.materials)
{
Material sourceMat = _references.Materials.FirstOrDefault(m => mat.name.StartsWith(m.name));
if (sourceMat)
{
Color col = _customization.Colors[System.Array.IndexOf(_references.Materials, sourceMat)];
if (!mat.IsKeywordEnabled("_EMISSION"))
mat.color = col;
else
mat.SetColor("_EmissionColor", col);
}
}
}
}
private void LoadCustom()
{
if (!PlayerPrefs.HasKey(PP_CUSTOM))
return;
string json = PlayerPrefs.GetString(PP_CUSTOM);
_customization = JsonUtility.FromJson<Customization>(json);
SetCustom();
}
private void SaveCustom()
{
string json = JsonUtility.ToJson(_customization);
PlayerPrefs.SetString(PP_CUSTOM, json);
}
private void UpdateAnimation()
{
if (!_references.Player)
return;
if (_references.Anim.IsInTransition(0))
return;
AnimatorStateInfo currentState = _references.Anim.GetCurrentAnimatorStateInfo(0);
AnimatorStateInfo nextState = _references.Anim.GetNextAnimatorStateInfo(0);
PlayerAnimationStateMapper currentStateMapper = _playerAnimationStateMapper.FirstOrDefault(m => m.PlayerState == _references.Player.State.CurrentState);
if (currentStateMapper != null &&
!currentState.IsName(currentStateMapper.AnimatorState) &&
!nextState.IsName(currentStateMapper.AnimatorState) &&
!currentState.IsName(currentStateMapper.BlockingState))
{
_references.Anim.SetTrigger(currentStateMapper.Trigger);
}
switch (_references.Player.State.CurrentState)
{
case Player.PlayerState.Idle:
case Player.PlayerState.Moving:
_references.Anim.SetFloat("move", _references.Player.State.HorizontalVelocity.magnitude);
break;
}
}
public static Color ShiftHue(Color color, float hueShift)
{
Color.RGBToHSV(color, out float h, out float s, out float v);
h += hueShift / 360f;
h = Mathf.Repeat(h, 1f);
Color result = Color.HSVToRGB(h, s, v);
result.a = color.a;
return result;
}
}