You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

74 lines
2.5 KiB

using UnityEngine;
public class DamageIndicatorHandler : MonoBehaviour, IOwnedComponent<Character>
{
struct DmgIndicatorProperty
{
public float fontSize;
public Color color;
}
static readonly DmgIndicatorProperty _normalDmgIndicatorProp = new DmgIndicatorProperty { fontSize = 24f, color = new Color(1f, 1f, 1f) };
static readonly DmgIndicatorProperty _criticalDmgIndicatorProp = new DmgIndicatorProperty { fontSize = 32f, color = new Color(1f, 56f / 255f, 0f) };
[SerializeField] Transform spawnPosition;
[SerializeField] DamageIndicatorText indicatorPrefab;
public Character Owner { get; private set; }
Camera mainCamera;
Camera uiCamera;
RectTransform indicatorRoot;
DynamicMonoObjectPool<DamageIndicatorText> indicatorPool;
public void Initialize(Character owner)
{
Owner = owner;
Owner.OnDamaged += OnDamaged;
mainCamera = Camera.main;
uiCamera = GameObject.FindGameObjectWithTag("UICamera").GetComponent<Camera>();
indicatorRoot = GameObject.FindGameObjectWithTag("DamageIndicatorRoot").GetComponent<RectTransform>();
indicatorPool = new();
indicatorPool.Initialize(InstantiateIndicator, DestroyIndicator, 5);
}
private DamageIndicatorText InstantiateIndicator()
{
var indicator = Instantiate(indicatorPrefab, indicatorRoot);
indicator.OnComplete += indicatorPool.Return;
return indicator;
}
private void DestroyIndicator(DamageIndicatorText indicator)
{
if (indicator == null || indicator.gameObject == null) return;
Destroy(indicator.gameObject);
}
private void OnDamaged(Character _, Damage damage)
{
var indicator = indicatorPool.Get();
if (damage.isCritical)
indicator.SetText(FormatString.BigIntString1(damage.value), _criticalDmgIndicatorProp.fontSize, _criticalDmgIndicatorProp.color);
else
indicator.SetText(FormatString.BigIntString1(damage.value), _normalDmgIndicatorProp.fontSize, _normalDmgIndicatorProp.color);
var screenPos = mainCamera.WorldToScreenPoint(spawnPosition.position);
RectTransformUtility.ScreenPointToLocalPointInRectangle(indicatorRoot, screenPos, uiCamera, out Vector2 localPos);
indicator.transform.localPosition = localPos;
indicator.Show();
}
private void OnDestroy()
{
if (Owner == null) return;
Owner.OnDamaged -= OnDamaged;
indicatorPool.Dispose();
}
}