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 crosshairs = new Dictionary(); private readonly Dictionary verticleCrosshairs = new Dictionary(); 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("Textures/Crosshairs/Normal_SniperCrosshair")); crosshairs.Add(WeaponCrosshairType.Default_Reticle, OnDemandLoader.Load("Textures/Crosshairs/DefaultReticleSprite")); crosshairs.Add(WeaponCrosshairType.Shotun_Reticle, OnDemandLoader.Load("Textures/Crosshairs/ShotgunReticleSprite")); crosshairs.Add(WeaponCrosshairType.Automatic_Reticle, OnDemandLoader.Load("Textures/Crosshairs/AutomaticReticleSprite")); crosshairs.Add(WeaponCrosshairType.No_Reticle, null); //verticle reticle Sprite Loading. verticleCrosshairs.Add(WeaponCrosshairType.Sniper_Reticle, OnDemandLoader.Load("Textures/Crosshairs/Normal_SniperCrosshair")); verticleCrosshairs.Add(WeaponCrosshairType.Default_Reticle, OnDemandLoader.Load("Textures/Crosshairs/DefaultReticleVerticleSprite")); verticleCrosshairs.Add(WeaponCrosshairType.Shotun_Reticle, OnDemandLoader.Load("Textures/Crosshairs/ShotgunReticleVerticleSprite")); verticleCrosshairs.Add(WeaponCrosshairType.Automatic_Reticle, OnDemandLoader.Load("Textures/Crosshairs/AutomaticReticleVerticleSprite")); verticleCrosshairs.Add(WeaponCrosshairType.No_Reticle, null); } private void InitializeComponents() { sniperCrosshairImage = transform.GetChild(0).GetComponent(); reticlePanel = transform.GetChild(1).GetComponent(); topReticleLine = reticlePanel.GetChild(0).GetComponent(); bottomReticleLine = reticlePanel.GetChild(1).GetComponent(); leftReticleLine = reticlePanel.GetChild(2).GetComponent(); rightReticleLine = reticlePanel.GetChild(3).GetComponent(); centerDot = reticlePanel.GetChild(4).GetComponent(); hitMarker = transform.GetChild(transform.childCount - 1).GetComponent(); hitMarker.color = new Color(1, 1, 1, 0); canvasGroup = GetComponent(); ppVolume = GameObject.FindGameObjectWithTag("PostProcessing").GetComponent(); 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; } } }