Practice_Unity/Assets/Scripts/Managers/AnimatorManager.cs
Seonkyu.kim 04c6301b7c 작업
1. 애니메이터 매니저 완성
2. 플레이어 컨트롤러 마우스 이동 부분 만들어 야 함
  - 이전꺼 넣어서 해보려는데도 도저히 되지가 않는다...
2025-09-18 17:58:51 +09:00

135 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
namespace Animation
{
// 제네릭인 P 는 값 형식이면서 Enum을 상속한 타입이어야 한다.
public class AnimatorManager<P> where P : struct, Enum
{
private readonly Animator animator;
// 마지막 세팅 값을 저장해 불필요한 동작 방지용
private readonly Dictionary<P, object> cache = new();
// 키별 실제 타입을 매핑해두는 용도
private readonly Dictionary<P, AnimatorControllerParameterType> types = new();
// 없는 키를 경고하기 위한 용도 (Enum에는 있는데 Animator에는 없는 경우)
private readonly HashSet<P> missing = new();
// 없는 키를 경고하기 위한 용도 (Animator에는 있는데 Enum에는 없는 경우)
private readonly HashSet<string> extras = new();
public AnimatorManager(Animator animator)
{
this.animator = animator;
if (this.animator == null) return;
cache.Clear();
types.Clear();
missing.Clear();
extras.Clear();
var parameters = animator.parameters;
foreach (var param in parameters)
{
if (Enum.TryParse<P>(param.name, out var key))
{
types[key] = param.type;
switch (param.type)
{
case AnimatorControllerParameterType.Bool:
cache[key] = animator.GetBool(param.name);
break;
case AnimatorControllerParameterType.Float:
cache[key] = animator.GetFloat(param.name);
break;
case AnimatorControllerParameterType.Int:
cache[key] = animator.GetInteger(param.name);
break;
}
}
else
{
extras.Add(param.name);
}
}
foreach (P enumKey in (P[])Enum.GetValues(typeof(P)))
{
if (!types.ContainsKey(enumKey))
missing.Add(enumKey);
}
}
public void SetValue(P key, object value)
{
if (animator == null) throw new InvalidOperationException("Animator is null");
// missing은 가능하나 extras는 불가능(변수가 P 로 들어오기에 Animator에는 있는데 Enum에 없는 경우는 불가능)
if (missing.Contains(key)) throw new KeyNotFoundException("key is missing in animator: " + key);
string name = key.ToString();
switch (types[key])
{
case AnimatorControllerParameterType.Bool:
{
var newVal = Convert.ToBoolean(value);
if (!cache.TryGetValue(key, out var oldVal) || !Equals(newVal, (bool)oldVal))
{
animator.SetBool(name, newVal);
cache[key] = newVal;
}
break;
}
case AnimatorControllerParameterType.Float:
{
var newVal = Convert.ToSingle(value);
if (!cache.TryGetValue(key, out var oldVal) || !Mathf.Approximately(newVal, (float)oldVal))
{
animator.SetFloat(name, newVal);
cache[key] = newVal;
}
break;
}
case AnimatorControllerParameterType.Int:
{
var newVal = Convert.ToInt32(value);
if (!cache.TryGetValue(key, out var oldVal) || !Equals(newVal, (int)oldVal))
{
animator.SetInteger(name, newVal);
cache[key] = newVal;
}
break;
}
case AnimatorControllerParameterType.Trigger:
{
var newVal = Convert.ToBoolean(value);
if (newVal) animator.SetTrigger(name);
else animator.ResetTrigger(name);
break;
}
}
}
public object GetValue(P key)
{
if (types[key] != AnimatorControllerParameterType.Trigger)
{
return cache[key];
}
else
{
throw new InvalidOperationException("Trigger type cannot be get");
}
}
}
}