ClientServer/Client/Assets/Scripts/Weapons/CrosshairManager.cs

357 lines
12 KiB
C#
Raw Normal View History

2025-09-06 17:17:39 +04:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
//Thomas09
//The WeaponReticle array needs to be in the same order as this enum!!!
public enum WeaponCrosshairType
{
Default_Reticle,
Shotun_Reticle,
Automatic_Reticle,
Sniper_Reticle,
No_Reticle
}
public class CrosshairManager : MonoBehaviour
{
public static CrosshairManager Instance;
private readonly Dictionary<WeaponCrosshairType, Sprite> crosshairs = new Dictionary<WeaponCrosshairType, Sprite>();
private readonly Dictionary<WeaponCrosshairType, Sprite> verticleCrosshairs = new Dictionary<WeaponCrosshairType, Sprite>();
private Image sniperCrosshairImage;
private CanvasGroup canvasGroup;
private Coroutine hitMarkerCoroutine;
//Dynamic Crosshair
private RectTransform reticlePanel;
private Image hitMarker;
private Image topReticleLine;
private Image bottomReticleLine;
private Image leftReticleLine;
private Image rightReticleLine;
private Image centerDot;
private float currentSize;
private float defaultAimInTime = 10.0f;
//post processing
private Volume ppVolume;
private LensDistortion lensDistortion;
private DepthOfField depthOfField;
public class ReticleConfig
{
public Color topReticleLineColor;
public Color leftReticleLineColor;
public Color rightReticleLineColor;
public Color bottomReticleLineColor;
public Color centerDotColor;
}
public class WeaponReticles
{
public ReticleConfig Aiming;
public ReticleConfig NotAiming;
}
static readonly Color defaultColor = new Color(1, 1, 1, 0.5f); //50% opacity
static readonly Color zeroAlpha = new Color(1, 1, 1, 0); //0% opacity
WeaponReticles[] reticles =
{
new WeaponReticles //Default_Reticle
{
Aiming = new ReticleConfig
{
topReticleLineColor = zeroAlpha,
leftReticleLineColor = zeroAlpha,
rightReticleLineColor = zeroAlpha,
bottomReticleLineColor = zeroAlpha,
centerDotColor = zeroAlpha
},
NotAiming = new ReticleConfig
{
topReticleLineColor = zeroAlpha,
leftReticleLineColor = defaultColor,
rightReticleLineColor = defaultColor,
bottomReticleLineColor = defaultColor,
centerDotColor = defaultColor
},
},
new WeaponReticles //Shotgun_Reticle
{
Aiming = new ReticleConfig
{
topReticleLineColor = zeroAlpha,
leftReticleLineColor = zeroAlpha,
rightReticleLineColor = zeroAlpha,
bottomReticleLineColor = zeroAlpha,
centerDotColor = zeroAlpha
},
NotAiming = new ReticleConfig
{
topReticleLineColor = zeroAlpha,
leftReticleLineColor = defaultColor,
rightReticleLineColor = defaultColor,
bottomReticleLineColor = zeroAlpha,
centerDotColor = defaultColor
},
},
new WeaponReticles //Automatic_Reticle
{
Aiming = new ReticleConfig
{
topReticleLineColor = zeroAlpha,
leftReticleLineColor = zeroAlpha,
rightReticleLineColor = zeroAlpha,
bottomReticleLineColor = zeroAlpha,
centerDotColor = zeroAlpha
},
NotAiming = new ReticleConfig
{
topReticleLineColor = defaultColor,
leftReticleLineColor = defaultColor,
rightReticleLineColor = defaultColor,
bottomReticleLineColor = defaultColor,
centerDotColor = defaultColor
},
},
new WeaponReticles //Sniper_Reticle
{
Aiming = new ReticleConfig
{
topReticleLineColor = zeroAlpha,
leftReticleLineColor = zeroAlpha,
rightReticleLineColor = zeroAlpha,
bottomReticleLineColor = zeroAlpha,
centerDotColor = zeroAlpha
},
NotAiming = new ReticleConfig
{
topReticleLineColor = zeroAlpha,
leftReticleLineColor = zeroAlpha,
rightReticleLineColor = zeroAlpha,
bottomReticleLineColor = zeroAlpha,
centerDotColor = defaultColor
},
},
new WeaponReticles //Sniper_Reticle
{
Aiming = new ReticleConfig
{
topReticleLineColor = zeroAlpha,
leftReticleLineColor = zeroAlpha,
rightReticleLineColor = zeroAlpha,
bottomReticleLineColor = zeroAlpha,
centerDotColor = zeroAlpha
},
NotAiming = new ReticleConfig
{
topReticleLineColor = zeroAlpha,
leftReticleLineColor = zeroAlpha,
rightReticleLineColor = zeroAlpha,
bottomReticleLineColor = zeroAlpha,
centerDotColor = zeroAlpha
},
},
};
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else
{
Destroy(this);
}
InitializeComponents();
crosshairs.Add(WeaponCrosshairType.Sniper_Reticle, OnDemandLoader.Load<Sprite>("Textures/Crosshairs/Normal_SniperCrosshair"));
crosshairs.Add(WeaponCrosshairType.Default_Reticle, OnDemandLoader.Load<Sprite>("Textures/Crosshairs/DefaultReticleSprite"));
crosshairs.Add(WeaponCrosshairType.Shotun_Reticle, OnDemandLoader.Load<Sprite>("Textures/Crosshairs/ShotgunReticleSprite"));
crosshairs.Add(WeaponCrosshairType.Automatic_Reticle, OnDemandLoader.Load<Sprite>("Textures/Crosshairs/AutomaticReticleSprite"));
crosshairs.Add(WeaponCrosshairType.No_Reticle, null);
//verticle reticle Sprite Loading.
verticleCrosshairs.Add(WeaponCrosshairType.Sniper_Reticle, OnDemandLoader.Load<Sprite>("Textures/Crosshairs/Normal_SniperCrosshair"));
verticleCrosshairs.Add(WeaponCrosshairType.Default_Reticle, OnDemandLoader.Load<Sprite>("Textures/Crosshairs/DefaultReticleVerticleSprite"));
verticleCrosshairs.Add(WeaponCrosshairType.Shotun_Reticle, OnDemandLoader.Load<Sprite>("Textures/Crosshairs/ShotgunReticleVerticleSprite"));
verticleCrosshairs.Add(WeaponCrosshairType.Automatic_Reticle, OnDemandLoader.Load<Sprite>("Textures/Crosshairs/AutomaticReticleVerticleSprite"));
verticleCrosshairs.Add(WeaponCrosshairType.No_Reticle, null);
}
private void InitializeComponents()
{
sniperCrosshairImage = transform.GetChild(0).GetComponent<Image>();
reticlePanel = transform.GetChild(1).GetComponent<RectTransform>();
topReticleLine = reticlePanel.GetChild(0).GetComponent<Image>();
bottomReticleLine = reticlePanel.GetChild(1).GetComponent<Image>();
leftReticleLine = reticlePanel.GetChild(2).GetComponent<Image>();
rightReticleLine = reticlePanel.GetChild(3).GetComponent<Image>();
centerDot = reticlePanel.GetChild(4).GetComponent<Image>();
hitMarker = transform.GetChild(transform.childCount - 1).GetComponent<Image>();
hitMarker.color = new Color(1, 1, 1, 0);
canvasGroup = GetComponent<CanvasGroup>();
ppVolume = GameObject.FindGameObjectWithTag("PostProcessing").GetComponent<Volume>();
SetSniperCrosshairAlpha(0.0f);
}
public void SetDynamicCrossHair(float restingSize, float maxSize, float openSpeed, float closeSpeed, Player player, WeaponCrosshairType type, int weaponID = -1)
{
SetCrossHairSprite(type);
if (player.IsMoving)
{
currentSize = Mathf.Lerp(currentSize, maxSize, Time.deltaTime * openSpeed);
}
else if (player.hasFiredWeapon) //bool is true for one frame only, too short to lerp so set current to max size instantly!
{
currentSize = maxSize;
}
else
{
currentSize = Mathf.Lerp(currentSize, restingSize, Time.deltaTime * closeSpeed);
}
WeaponReticles weaponReticles = reticles[(int)type];
ReticleConfig reticleConfig = player.IsAiming ? weaponReticles.Aiming : weaponReticles.NotAiming;
LerpColor(topReticleLine, reticleConfig.topReticleLineColor);
LerpColor(leftReticleLine, reticleConfig.leftReticleLineColor);
LerpColor(rightReticleLine, reticleConfig.rightReticleLineColor);
LerpColor(bottomReticleLine, reticleConfig.bottomReticleLineColor);
LerpColor(centerDot, reticleConfig.centerDotColor);
reticlePanel.sizeDelta = new Vector2(currentSize, currentSize);
//potential switch candidate.
if (weaponID == 24 && Player.Instance.IsAiming)
{
SetDepthOfField(false);
}
else
{
SetDepthOfField(true);
}
}
public void EnableCrosshair(bool isEnabled)
{
canvasGroup.alpha = isEnabled ? 1 : 0;
}
private void LerpColor(Image image, Color targetColor)
{
image.color = Color.Lerp(image.color, targetColor, Time.deltaTime * defaultAimInTime);
}
public void SetSniperCrosshair(WeaponCrosshairType type)
{
sniperCrosshairImage.gameObject.SetActive(true);
sniperCrosshairImage.sprite = crosshairs[type];
}
private void SetCrossHairSprite(WeaponCrosshairType type)
{
topReticleLine.sprite = verticleCrosshairs[type];
leftReticleLine.sprite = crosshairs[type];
rightReticleLine.sprite = crosshairs[type];
bottomReticleLine.sprite = verticleCrosshairs[type];
}
public void CreateHitMarkerCoroutine(bool playHitAudio, RaycastHit hit, bool isRocketLauncher)
{
if(isRocketLauncher) { return; }
if (hitMarkerCoroutine != null) StopCoroutine(hitMarkerCoroutine);
hitMarkerCoroutine = StartCoroutine(HitMarker());
if (playHitAudio)
{
float randPitch = Random.Range(0.85f, 1.25f);
if (hit.collider.CompareTag("Shield"))
{
AudioManager.Instance.playSound("Bullet_Sheild_Hit", randPitch);
}
else
{
int randClip = Random.Range(0, 3);
if (randClip == 0) { AudioManager.Instance.playSound("Hit_Enemy", randPitch); }
else if (randClip == 1) { AudioManager.Instance.playSound("Hit_Enemy2", randPitch); }
else if (randClip == 2) { AudioManager.Instance.playSound("Hit_Enemy3", randPitch); }
}
}
}
private IEnumerator HitMarker()
{
float startTime = 0;
float endTime = 0.75f;
Color zero = new Color(1, 1, 1, 0);
Color normal = new Color(1, 1, 1, 0.5f);
Vector3 defaultScale = new Vector3(0.75f, 0.75f, 0);
hitMarker.transform.localScale = defaultScale;
hitMarker.color = zero;
while (startTime < 1)
{
hitMarker.color = Color.Lerp(hitMarker.color, normal, startTime);
hitMarker.transform.localScale = Vector3.Lerp(hitMarker.transform.localScale, Vector3.zero, startTime);
startTime += Time.deltaTime / endTime;
yield return null;
}
hitMarkerCoroutine = null;
}
public void SetSniperCrosshairAlpha(float alpha)
{
Color newAlpha = sniperCrosshairImage.color;
newAlpha.a = alpha;
sniperCrosshairImage.color = newAlpha;
if (alpha == 1.0f)
{
SetLensDistortion(0.7f);
SetDepthOfField(false);
}
else
{
SetLensDistortion(0.0f);
SetDepthOfField(true);
}
}
private void SetLensDistortion(float distortionIntensity)
{
if (ppVolume.profile.TryGet(out lensDistortion))
{
lensDistortion.intensity.value = distortionIntensity;
}
}
private void SetDepthOfField(bool isActive)
{
if (ppVolume.profile.TryGet(out depthOfField))
{
depthOfField.active = isActive;
}
}
}