124 lines
3.4 KiB
C#
124 lines
3.4 KiB
C#
using DG.Tweening;
|
|
using UnityEngine;
|
|
using TMPro;
|
|
|
|
namespace TPSBR.UI
|
|
{
|
|
public class UICrosshair : UIWidget
|
|
{
|
|
// PRIVATE MEMBERS
|
|
|
|
[SerializeField]
|
|
private RectTransform _resizingGroup;
|
|
[SerializeField]
|
|
private CanvasGroup _crosshairRootGroup;
|
|
[SerializeField]
|
|
private CanvasGroup _unarmedGroup;
|
|
[SerializeField]
|
|
private CanvasGroup _armedGroup;
|
|
[SerializeField]
|
|
private GameObject _sniperScope;
|
|
[SerializeField]
|
|
private UIBehaviour _undesiredFirePosition;
|
|
[SerializeField]
|
|
private float _undesiredFireCrosshairAlpha = 0.6f;
|
|
|
|
[Header("Audio")]
|
|
[SerializeField]
|
|
private AudioSetup _hitPerformed;
|
|
[SerializeField]
|
|
private AudioSetup _criticalHitPerformed;
|
|
|
|
[Header("Hit Feedback")]
|
|
[SerializeField]
|
|
private CanvasGroup _hitGroup;
|
|
[SerializeField]
|
|
private CanvasGroup _criticalHitGroup;
|
|
[SerializeField]
|
|
private CanvasGroup _fatalHitGroup;
|
|
[SerializeField]
|
|
private float _hitGroupDelay = 0.15f;
|
|
[SerializeField]
|
|
private float _hitGroupFadeInDuration = 0.1f;
|
|
[SerializeField]
|
|
private float _hitGroupFadeOutDuration = 0.8f;
|
|
|
|
[Header("Dispersion")]
|
|
[SerializeField]
|
|
private float _sizeDispersion0 = 24f;
|
|
[SerializeField]
|
|
private float _sizeDispersion50 = 1000f;
|
|
[SerializeField]
|
|
private float _changeSpeed = 20f;
|
|
|
|
private float _defaultSize;
|
|
private int _lastSoundFrame;
|
|
|
|
private Vector2 _targetSize;
|
|
|
|
// PUBLIC METHODS
|
|
|
|
public void HitPerformed(HitData hitData)
|
|
{
|
|
PlayEffect(hitData.IsCritical == true ? _criticalHitPerformed : _hitPerformed);
|
|
|
|
var hitGroup = hitData.IsFatal == true ? _fatalHitGroup : (hitData.IsCritical == true ? _criticalHitGroup : _hitGroup);
|
|
DOTween.Kill(hitGroup);
|
|
|
|
hitGroup.DOFade(1f, _hitGroupFadeInDuration).SetDelay(_hitGroupDelay);
|
|
hitGroup.DOFade(0f, _hitGroupFadeOutDuration).SetDelay(_hitGroupDelay + _hitGroupFadeInDuration + 0.1f);
|
|
}
|
|
|
|
public void UpdateCrosshair(Agent agent)
|
|
{
|
|
var weapon = agent.Weapons.CurrentWeapon;
|
|
float size = _defaultSize;
|
|
|
|
bool weaponValid = weapon != null && weapon.Object.IsValid;
|
|
|
|
if (weaponValid == true && weapon is FirearmWeapon firearmWeapon)
|
|
{
|
|
size = Mathf.Lerp(_sizeDispersion0, _sizeDispersion50, firearmWeapon.TotalDispersion / 50f);
|
|
}
|
|
|
|
_targetSize = new Vector2(size, size);
|
|
_resizingGroup.sizeDelta = Vector2.Lerp(_resizingGroup.sizeDelta, _targetSize, Time.deltaTime * _changeSpeed);
|
|
|
|
bool showScope = weaponValid == true && weapon.HitType == EHitType.Sniper && agent.Character.CharacterController.Data.Aim == true;
|
|
|
|
_armedGroup.SetVisibility(showScope == false && weaponValid);
|
|
_unarmedGroup.SetVisibility(weaponValid == false);
|
|
|
|
_sniperScope.SetActive(showScope);
|
|
|
|
bool showUndesiredFirePosition = weaponValid == true && agent.Interactions.IsUndesiredTargetPoint;
|
|
_undesiredFirePosition.SetActive(showUndesiredFirePosition);
|
|
|
|
if (showUndesiredFirePosition == true)
|
|
{
|
|
_undesiredFirePosition.transform.position = Context.Camera.Camera.WorldToScreenPoint(agent.Interactions.TargetPoint);
|
|
}
|
|
|
|
_crosshairRootGroup.alpha = Mathf.Lerp(_crosshairRootGroup.alpha, showUndesiredFirePosition == true ? _undesiredFireCrosshairAlpha : 1f, Time.deltaTime * 8f);
|
|
}
|
|
|
|
// MONOBEHAVIOUR
|
|
|
|
private void Awake()
|
|
{
|
|
_defaultSize = _resizingGroup.sizeDelta.x;
|
|
}
|
|
|
|
// PRIVATE MEMBERS
|
|
|
|
private void PlayEffect(AudioSetup setup)
|
|
{
|
|
if (Time.frameCount == _lastSoundFrame)
|
|
return; // Play only one sound per frame
|
|
|
|
SceneUI.PlaySound(setup);
|
|
_lastSoundFrame = Time.frameCount;
|
|
}
|
|
}
|
|
}
|