This commit is contained in:
Alex38Lyon
2025-06-03 12:00:47 +02:00
parent ed8041abcd
commit 878ea46cac
1300 changed files with 527178 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
using TMPro;
using Unity.FPS.Game;
using Unity.FPS.Gameplay;
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
[RequireComponent(typeof(FillBarColorChange))]
public class AmmoCounter : MonoBehaviour
{
[Tooltip("CanvasGroup to fade the ammo UI")]
public CanvasGroup CanvasGroup;
[Tooltip("Image for the weapon icon")] public Image WeaponImage;
[Tooltip("Image component for the background")]
public Image AmmoBackgroundImage;
[Tooltip("Image component to display fill ratio")]
public Image AmmoFillImage;
[Tooltip("Text for Weapon index")]
public TextMeshProUGUI WeaponIndexText;
[Tooltip("Text for Bullet Counter")]
public TextMeshProUGUI BulletCounter;
[Tooltip("Reload Text for Weapons with physical bullets")]
public RectTransform Reload;
[Header("Selection")] [Range(0, 1)] [Tooltip("Opacity when weapon not selected")]
public float UnselectedOpacity = 0.5f;
[Tooltip("Scale when weapon not selected")]
public Vector3 UnselectedScale = Vector3.one * 0.8f;
[Tooltip("Root for the control keys")] public GameObject ControlKeysRoot;
[Header("Feedback")] [Tooltip("Component to animate the color when empty or full")]
public FillBarColorChange FillBarColorChange;
[Tooltip("Sharpness for the fill ratio movements")]
public float AmmoFillMovementSharpness = 20f;
public int WeaponCounterIndex { get; set; }
PlayerWeaponsManager m_PlayerWeaponsManager;
WeaponController m_Weapon;
void Awake()
{
EventManager.AddListener<AmmoPickupEvent>(OnAmmoPickup);
}
void OnAmmoPickup(AmmoPickupEvent evt)
{
if (evt.Weapon == m_Weapon)
{
BulletCounter.text = m_Weapon.GetCarriedPhysicalBullets().ToString();
}
}
public void Initialize(WeaponController weapon, int weaponIndex)
{
m_Weapon = weapon;
WeaponCounterIndex = weaponIndex;
WeaponImage.sprite = weapon.WeaponIcon;
if (!weapon.HasPhysicalBullets)
BulletCounter.transform.parent.gameObject.SetActive(false);
else
BulletCounter.text = weapon.GetCarriedPhysicalBullets().ToString();
Reload.gameObject.SetActive(false);
m_PlayerWeaponsManager = FindFirstObjectByType<PlayerWeaponsManager>();
DebugUtility.HandleErrorIfNullFindObject<PlayerWeaponsManager, AmmoCounter>(m_PlayerWeaponsManager, this);
WeaponIndexText.text = (WeaponCounterIndex + 1).ToString();
FillBarColorChange.Initialize(1f, m_Weapon.GetAmmoNeededToShoot());
}
void Update()
{
float currenFillRatio = m_Weapon.CurrentAmmoRatio;
AmmoFillImage.fillAmount = Mathf.Lerp(AmmoFillImage.fillAmount, currenFillRatio,
Time.deltaTime * AmmoFillMovementSharpness);
BulletCounter.text = m_Weapon.GetCarriedPhysicalBullets().ToString();
bool isActiveWeapon = m_Weapon == m_PlayerWeaponsManager.GetActiveWeapon();
CanvasGroup.alpha = Mathf.Lerp(CanvasGroup.alpha, isActiveWeapon ? 1f : UnselectedOpacity,
Time.deltaTime * 10);
transform.localScale = Vector3.Lerp(transform.localScale, isActiveWeapon ? Vector3.one : UnselectedScale,
Time.deltaTime * 10);
ControlKeysRoot.SetActive(!isActiveWeapon);
FillBarColorChange.UpdateVisual(currenFillRatio);
Reload.gameObject.SetActive(m_Weapon.GetCarriedPhysicalBullets() > 0 && m_Weapon.GetCurrentAmmo() == 0 && m_Weapon.IsWeaponActive);
}
void Destroy()
{
EventManager.RemoveListener<AmmoPickupEvent>(OnAmmoPickup);
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2f55bbfc17a3a894281c47b1182205a4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+96
View File
@@ -0,0 +1,96 @@
using System.Collections.Generic;
using Unity.FPS.Game;
using Unity.FPS.Gameplay;
using UnityEngine;
namespace Unity.FPS.UI
{
public class Compass : MonoBehaviour
{
public RectTransform CompasRect;
public float VisibilityAngle = 180f;
public float HeightDifferenceMultiplier = 2f;
public float MinScale = 0.5f;
public float DistanceMinScale = 50f;
public float CompasMarginRatio = 0.8f;
public GameObject MarkerDirectionPrefab;
Transform m_PlayerTransform;
Dictionary<Transform, CompassMarker> m_ElementsDictionnary = new Dictionary<Transform, CompassMarker>();
float m_WidthMultiplier;
float m_HeightOffset;
void Awake()
{
PlayerCharacterController playerCharacterController = FindFirstObjectByType<PlayerCharacterController>();
DebugUtility.HandleErrorIfNullFindObject<PlayerCharacterController, Compass>(playerCharacterController,
this);
m_PlayerTransform = playerCharacterController.transform;
m_WidthMultiplier = CompasRect.rect.width / VisibilityAngle;
m_HeightOffset = -CompasRect.rect.height / 2;
}
void Update()
{
// this is all very WIP, and needs to be reworked
foreach (var element in m_ElementsDictionnary)
{
float distanceRatio = 1;
float heightDifference = 0;
float angle;
if (element.Value.IsDirection)
{
angle = Vector3.SignedAngle(m_PlayerTransform.forward,
element.Key.transform.localPosition.normalized, Vector3.up);
}
else
{
Vector3 targetDir = (element.Key.transform.position - m_PlayerTransform.position).normalized;
targetDir = Vector3.ProjectOnPlane(targetDir, Vector3.up);
Vector3 playerForward = Vector3.ProjectOnPlane(m_PlayerTransform.forward, Vector3.up);
angle = Vector3.SignedAngle(playerForward, targetDir, Vector3.up);
Vector3 directionVector = element.Key.transform.position - m_PlayerTransform.position;
heightDifference = (directionVector.y) * HeightDifferenceMultiplier;
heightDifference = Mathf.Clamp(heightDifference, -CompasRect.rect.height / 2 * CompasMarginRatio,
CompasRect.rect.height / 2 * CompasMarginRatio);
distanceRatio = directionVector.magnitude / DistanceMinScale;
distanceRatio = Mathf.Clamp01(distanceRatio);
}
if (angle > -VisibilityAngle / 2 && angle < VisibilityAngle / 2)
{
element.Value.CanvasGroup.alpha = 1;
element.Value.CanvasGroup.transform.localPosition = new Vector2(m_WidthMultiplier * angle,
heightDifference + m_HeightOffset);
element.Value.CanvasGroup.transform.localScale =
Vector3.one * Mathf.Lerp(1, MinScale, distanceRatio);
}
else
{
element.Value.CanvasGroup.alpha = 0;
}
}
}
public void RegisterCompassElement(Transform element, CompassMarker marker)
{
marker.transform.SetParent(CompasRect);
m_ElementsDictionnary.Add(element, marker);
}
public void UnregisterCompassElement(Transform element)
{
if (m_ElementsDictionnary.TryGetValue(element, out CompassMarker marker) && marker.CanvasGroup != null)
Destroy(marker.CanvasGroup.gameObject);
m_ElementsDictionnary.Remove(element);
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fa1d13df263b6a0429b733192dcff01f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+32
View File
@@ -0,0 +1,32 @@
using Unity.FPS.Game;
using UnityEngine;
namespace Unity.FPS.UI
{
public class CompassElement : MonoBehaviour
{
[Tooltip("The marker on the compass for this element")]
public CompassMarker CompassMarkerPrefab;
[Tooltip("Text override for the marker, if it's a direction")]
public string TextDirection;
Compass m_Compass;
void Awake()
{
m_Compass = FindFirstObjectByType<Compass>();
DebugUtility.HandleErrorIfNullFindObject<Compass, CompassElement>(m_Compass, this);
var markerInstance = Instantiate(CompassMarkerPrefab);
markerInstance.Initialize(this, TextDirection);
m_Compass.RegisterCompassElement(transform, markerInstance);
}
void OnDestroy()
{
m_Compass.UnregisterCompassElement(transform);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 14b7698ec50c85c44a849a968dc1d57d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+58
View File
@@ -0,0 +1,58 @@
using Unity.FPS.AI;
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class CompassMarker : MonoBehaviour
{
[Tooltip("Main marker image")] public Image MainImage;
[Tooltip("Canvas group for the marker")]
public CanvasGroup CanvasGroup;
[Header("Enemy element")] [Tooltip("Default color for the marker")]
public Color DefaultColor;
[Tooltip("Alternative color for the marker")]
public Color AltColor;
[Header("Direction element")] [Tooltip("Use this marker as a magnetic direction")]
public bool IsDirection;
[Tooltip("Text content for the direction")]
public TMPro.TextMeshProUGUI TextContent;
EnemyController m_EnemyController;
public void Initialize(CompassElement compassElement, string textDirection)
{
if (IsDirection && TextContent)
{
TextContent.text = textDirection;
}
else
{
m_EnemyController = compassElement.transform.GetComponent<EnemyController>();
if (m_EnemyController)
{
m_EnemyController.onDetectedTarget += DetectTarget;
m_EnemyController.onLostTarget += LostTarget;
LostTarget();
}
}
}
public void DetectTarget()
{
MainImage.color = AltColor;
}
public void LostTarget()
{
MainImage.color = DefaultColor;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 591d30c26600b7c478aa30a3e005633b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+89
View File
@@ -0,0 +1,89 @@
using Unity.FPS.Game;
using Unity.FPS.Gameplay;
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class CrosshairManager : MonoBehaviour
{
public Image CrosshairImage;
public Sprite NullCrosshairSprite;
public float CrosshairUpdateshrpness = 5f;
PlayerWeaponsManager m_WeaponsManager;
bool m_WasPointingAtEnemy;
RectTransform m_CrosshairRectTransform;
CrosshairData m_CrosshairDataDefault;
CrosshairData m_CrosshairDataTarget;
CrosshairData m_CurrentCrosshair;
void Start()
{
m_WeaponsManager = FindFirstObjectByType<PlayerWeaponsManager>();
DebugUtility.HandleErrorIfNullFindObject<PlayerWeaponsManager, CrosshairManager>(m_WeaponsManager, this);
OnWeaponChanged(m_WeaponsManager.GetActiveWeapon());
m_WeaponsManager.OnSwitchedToWeapon += OnWeaponChanged;
}
void Update()
{
UpdateCrosshairPointingAtEnemy(false);
m_WasPointingAtEnemy = m_WeaponsManager.IsPointingAtEnemy;
}
void UpdateCrosshairPointingAtEnemy(bool force)
{
if (m_CrosshairDataDefault.CrosshairSprite == null)
return;
if ((force || !m_WasPointingAtEnemy) && m_WeaponsManager.IsPointingAtEnemy)
{
m_CurrentCrosshair = m_CrosshairDataTarget;
CrosshairImage.sprite = m_CurrentCrosshair.CrosshairSprite;
m_CrosshairRectTransform.sizeDelta = m_CurrentCrosshair.CrosshairSize * Vector2.one;
}
else if ((force || m_WasPointingAtEnemy) && !m_WeaponsManager.IsPointingAtEnemy)
{
m_CurrentCrosshair = m_CrosshairDataDefault;
CrosshairImage.sprite = m_CurrentCrosshair.CrosshairSprite;
m_CrosshairRectTransform.sizeDelta = m_CurrentCrosshair.CrosshairSize * Vector2.one;
}
CrosshairImage.color = Color.Lerp(CrosshairImage.color, m_CurrentCrosshair.CrosshairColor,
Time.deltaTime * CrosshairUpdateshrpness);
m_CrosshairRectTransform.sizeDelta = Mathf.Lerp(m_CrosshairRectTransform.sizeDelta.x,
m_CurrentCrosshair.CrosshairSize,
Time.deltaTime * CrosshairUpdateshrpness) * Vector2.one;
}
void OnWeaponChanged(WeaponController newWeapon)
{
if (newWeapon)
{
CrosshairImage.enabled = true;
m_CrosshairDataDefault = newWeapon.CrosshairDataDefault;
m_CrosshairDataTarget = newWeapon.CrosshairDataTargetInSight;
m_CrosshairRectTransform = CrosshairImage.GetComponent<RectTransform>();
DebugUtility.HandleErrorIfNullGetComponent<RectTransform, CrosshairManager>(m_CrosshairRectTransform,
this, CrosshairImage.gameObject);
}
else
{
if (NullCrosshairSprite)
{
CrosshairImage.sprite = NullCrosshairSprite;
}
else
{
CrosshairImage.enabled = false;
}
}
UpdateCrosshairPointingAtEnemy(true);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d45ca35e6c74bd74fb22336cb0d508db
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+46
View File
@@ -0,0 +1,46 @@
using UnityEngine;
namespace Unity.FPS.UI
{
public class DisplayMessage : MonoBehaviour
{
//[Tooltip("The text that will be displayed")] [TextArea]
//public string message;
//
//[Tooltip("Prefab for the message")] public GameObject messagePrefab;
//
//[Tooltip("Delay before displaying the message")]
//public float delayBeforeShowing;
//
//float m_InitTime = float.NegativeInfinity;
//bool m_WasDisplayed;
//DisplayMessageManager m_DisplayMessageManager;
//
//void Start()
//{
// m_InitTime = Time.time;
// m_DisplayMessageManager = FindObjectOfType<DisplayMessageManager>();
// DebugUtility.HandleErrorIfNullFindObject<DisplayMessageManager, DisplayMessage>(m_DisplayMessageManager,
// this);
//}
//
// Update is called once per frame
//void Update()
//{
// if (m_WasDisplayed)
// return;
//
// if (Time.time - m_InitTime > delayBeforeShowing)
// {
// var messageInstance = Instantiate(messagePrefab, m_DisplayMessageManager.DisplayMessageRect);
// var notification = messageInstance.GetComponent<NotificationToast>();
// if (notification)
// {
// notification.Initialize(message);
// }
//
// m_WasDisplayed = true;
// }
//}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ea4170175d245c6409bb0cb4cc7b2c5f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,52 @@
using System.Collections.Generic;
using Unity.FPS.Game;
using UnityEngine;
namespace Unity.FPS.UI
{
public class DisplayMessageManager : MonoBehaviour
{
public UITable DisplayMessageRect;
public NotificationToast MessagePrefab;
List<(float timestamp, float delay, string message, NotificationToast notification)> m_PendingMessages;
void Awake()
{
EventManager.AddListener<DisplayMessageEvent>(OnDisplayMessageEvent);
m_PendingMessages = new List<(float, float, string, NotificationToast)>();
}
void OnDisplayMessageEvent(DisplayMessageEvent evt)
{
NotificationToast notification = Instantiate(MessagePrefab, DisplayMessageRect.transform).GetComponent<NotificationToast>();
m_PendingMessages.Add((Time.time, evt.DelayBeforeDisplay, evt.Message, notification));
}
void Update()
{
foreach (var message in m_PendingMessages)
{
if (Time.time - message.timestamp > message.delay)
{
message.Item4.Initialize(message.message);
DisplayMessage(message.notification);
}
}
// Clear deprecated messages
m_PendingMessages.RemoveAll(x => x.notification.Initialized);
}
void DisplayMessage(NotificationToast notification)
{
DisplayMessageRect.UpdateTable(notification.gameObject);
//StartCoroutine(MessagePrefab.ReturnWithDelay(notification.gameObject, notification.TotalRunTime));
}
void OnDestroy()
{
EventManager.RemoveListener<DisplayMessageEvent>(OnDisplayMessageEvent);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f05022e63392c3c499c70ac5ae3b5d4d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+26
View File
@@ -0,0 +1,26 @@
using Unity.FPS.AI;
using Unity.FPS.Game;
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class EnemyCounter : MonoBehaviour
{
[Header("Enemies")] [Tooltip("Text component for displaying enemy objective progress")]
public Text EnemiesText;
EnemyManager m_EnemyManager;
void Awake()
{
m_EnemyManager = FindFirstObjectByType<EnemyManager>();
DebugUtility.HandleErrorIfNullFindObject<EnemyManager, EnemyCounter>(m_EnemyManager, this);
}
void Update()
{
EnemiesText.text = m_EnemyManager.NumberOfEnemiesRemaining + "/" + m_EnemyManager.NumberOfEnemiesTotal;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 08c7efe3ccf2ba046911cbd83f3c8b72
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+124
View File
@@ -0,0 +1,124 @@
using Unity.FPS.Game;
using Unity.FPS.Gameplay;
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class FeedbackFlashHUD : MonoBehaviour
{
[Header("References")] [Tooltip("Image component of the flash")]
public Image FlashImage;
[Tooltip("CanvasGroup to fade the damage flash, used when recieving damage end healing")]
public CanvasGroup FlashCanvasGroup;
[Tooltip("CanvasGroup to fade the critical health vignette")]
public CanvasGroup VignetteCanvasGroup;
[Header("Damage")] [Tooltip("Color of the damage flash")]
public Color DamageFlashColor;
[Tooltip("Duration of the damage flash")]
public float DamageFlashDuration;
[Tooltip("Max alpha of the damage flash")]
public float DamageFlashMaxAlpha = 1f;
[Header("Critical health")] [Tooltip("Max alpha of the critical vignette")]
public float CriticaHealthVignetteMaxAlpha = .8f;
[Tooltip("Frequency at which the vignette will pulse when at critical health")]
public float PulsatingVignetteFrequency = 4f;
[Header("Heal")] [Tooltip("Color of the heal flash")]
public Color HealFlashColor;
[Tooltip("Duration of the heal flash")]
public float HealFlashDuration;
[Tooltip("Max alpha of the heal flash")]
public float HealFlashMaxAlpha = 1f;
bool m_FlashActive;
float m_LastTimeFlashStarted = Mathf.NegativeInfinity;
Health m_PlayerHealth;
GameFlowManager m_GameFlowManager;
void Start()
{
// Subscribe to player damage events
PlayerCharacterController playerCharacterController = FindFirstObjectByType<PlayerCharacterController>();
DebugUtility.HandleErrorIfNullFindObject<PlayerCharacterController, FeedbackFlashHUD>(
playerCharacterController, this);
m_PlayerHealth = playerCharacterController.GetComponent<Health>();
DebugUtility.HandleErrorIfNullGetComponent<Health, FeedbackFlashHUD>(m_PlayerHealth, this,
playerCharacterController.gameObject);
m_GameFlowManager = FindFirstObjectByType<GameFlowManager>();
DebugUtility.HandleErrorIfNullFindObject<GameFlowManager, FeedbackFlashHUD>(m_GameFlowManager, this);
m_PlayerHealth.OnDamaged += OnTakeDamage;
m_PlayerHealth.OnHealed += OnHealed;
}
void Update()
{
if (m_PlayerHealth.IsCritical())
{
VignetteCanvasGroup.gameObject.SetActive(true);
float vignetteAlpha =
(1 - (m_PlayerHealth.CurrentHealth / m_PlayerHealth.MaxHealth /
m_PlayerHealth.CriticalHealthRatio)) * CriticaHealthVignetteMaxAlpha;
if (m_GameFlowManager.GameIsEnding)
VignetteCanvasGroup.alpha = vignetteAlpha;
else
VignetteCanvasGroup.alpha =
((Mathf.Sin(Time.time * PulsatingVignetteFrequency) / 2) + 0.5f) * vignetteAlpha;
}
else
{
VignetteCanvasGroup.gameObject.SetActive(false);
}
if (m_FlashActive)
{
float normalizedTimeSinceDamage = (Time.time - m_LastTimeFlashStarted) / DamageFlashDuration;
if (normalizedTimeSinceDamage < 1f)
{
float flashAmount = DamageFlashMaxAlpha * (1f - normalizedTimeSinceDamage);
FlashCanvasGroup.alpha = flashAmount;
}
else
{
FlashCanvasGroup.gameObject.SetActive(false);
m_FlashActive = false;
}
}
}
void ResetFlash()
{
m_LastTimeFlashStarted = Time.time;
m_FlashActive = true;
FlashCanvasGroup.alpha = 0f;
FlashCanvasGroup.gameObject.SetActive(true);
}
void OnTakeDamage(float dmg, GameObject damageSource)
{
ResetFlash();
FlashImage.color = DamageFlashColor;
}
void OnHealed(float amount)
{
ResetFlash();
FlashImage.color = HealFlashColor;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fed84cad6ab9472468348126dddd368a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,64 @@
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class FillBarColorChange : MonoBehaviour
{
[Header("Foreground")] [Tooltip("Image for the foreground")]
public Image ForegroundImage;
[Tooltip("Default foreground color")] public Color DefaultForegroundColor;
[Tooltip("Flash foreground color when full")]
public Color FlashForegroundColorFull;
[Header("Background")] [Tooltip("Image for the background")]
public Image BackgroundImage;
[Tooltip("Flash background color when empty")]
public Color DefaultBackgroundColor;
[Tooltip("Sharpness for the color change")]
public Color FlashBackgroundColorEmpty;
[Header("Values")] [Tooltip("Value to consider full")]
public float FullValue = 1f;
[Tooltip("Value to consider empty")] public float EmptyValue = 0f;
[Tooltip("Sharpness for the color change")]
public float ColorChangeSharpness = 5f;
float m_PreviousValue;
public void Initialize(float fullValueRatio, float emptyValueRatio)
{
FullValue = fullValueRatio;
EmptyValue = emptyValueRatio;
m_PreviousValue = fullValueRatio;
}
public void UpdateVisual(float currentRatio)
{
if (currentRatio == FullValue && currentRatio != m_PreviousValue)
{
ForegroundImage.color = FlashForegroundColorFull;
}
else if (currentRatio < EmptyValue)
{
BackgroundImage.color = FlashBackgroundColorEmpty;
}
else
{
ForegroundImage.color = Color.Lerp(ForegroundImage.color, DefaultForegroundColor,
Time.deltaTime * ColorChangeSharpness);
BackgroundImage.color = Color.Lerp(BackgroundImage.color, DefaultBackgroundColor,
Time.deltaTime * ColorChangeSharpness);
}
m_PreviousValue = currentRatio;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0198f43c5a6fcac45a5ddbcb630835a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+32
View File
@@ -0,0 +1,32 @@
using UnityEngine;
using TMPro;
namespace Unity.FPS.UI
{
public class FramerateCounter : MonoBehaviour
{
[Tooltip("Delay between updates of the displayed framerate value")]
public float PollingTime = 0.5f;
[Tooltip("The text field displaying the framerate")]
public TextMeshProUGUI UIText;
float m_AccumulatedDeltaTime = 0f;
int m_AccumulatedFrameCount = 0;
void Update()
{
m_AccumulatedDeltaTime += Time.deltaTime;
m_AccumulatedFrameCount++;
if (m_AccumulatedDeltaTime >= PollingTime)
{
int framerate = Mathf.RoundToInt((float) m_AccumulatedFrameCount / m_AccumulatedDeltaTime);
UIText.text = framerate.ToString();
m_AccumulatedDeltaTime = 0f;
m_AccumulatedFrameCount = 0;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9bb4b9b492a196d46b75760761528eeb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+154
View File
@@ -0,0 +1,154 @@
using Unity.FPS.Game;
using Unity.FPS.Gameplay;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class InGameMenuManager : MonoBehaviour
{
[Tooltip("Root GameObject of the menu used to toggle its activation")]
public GameObject MenuRoot;
[Tooltip("Master volume when menu is open")] [Range(0.001f, 1f)]
public float VolumeWhenMenuOpen = 0.5f;
[Tooltip("Slider component for look sensitivity")]
public Slider LookSensitivitySlider;
[Tooltip("Toggle component for shadows")]
public Toggle ShadowsToggle;
[Tooltip("Toggle component for invincibility")]
public Toggle InvincibilityToggle;
[Tooltip("Toggle component for framerate display")]
public Toggle FramerateToggle;
[Tooltip("GameObject for the controls")]
public GameObject ControlImage;
PlayerInputHandler m_PlayerInputsHandler;
Health m_PlayerHealth;
FramerateCounter m_FramerateCounter;
void Start()
{
m_PlayerInputsHandler = FindFirstObjectByType<PlayerInputHandler>();
DebugUtility.HandleErrorIfNullFindObject<PlayerInputHandler, InGameMenuManager>(m_PlayerInputsHandler,
this);
m_PlayerHealth = m_PlayerInputsHandler.GetComponent<Health>();
DebugUtility.HandleErrorIfNullGetComponent<Health, InGameMenuManager>(m_PlayerHealth, this, gameObject);
m_FramerateCounter = FindFirstObjectByType<FramerateCounter>();
DebugUtility.HandleErrorIfNullFindObject<FramerateCounter, InGameMenuManager>(m_FramerateCounter, this);
MenuRoot.SetActive(false);
LookSensitivitySlider.value = m_PlayerInputsHandler.LookSensitivity;
LookSensitivitySlider.onValueChanged.AddListener(OnMouseSensitivityChanged);
ShadowsToggle.isOn = QualitySettings.shadows != ShadowQuality.Disable;
ShadowsToggle.onValueChanged.AddListener(OnShadowsChanged);
InvincibilityToggle.isOn = m_PlayerHealth.Invincible;
InvincibilityToggle.onValueChanged.AddListener(OnInvincibilityChanged);
FramerateToggle.isOn = m_FramerateCounter.UIText.gameObject.activeSelf;
FramerateToggle.onValueChanged.AddListener(OnFramerateCounterChanged);
}
void Update()
{
// Lock cursor when clicking outside of menu
if (!MenuRoot.activeSelf && Input.GetMouseButtonDown(0))
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
if (Input.GetKeyDown(KeyCode.Escape))
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
if (Input.GetButtonDown(GameConstants.k_ButtonNamePauseMenu)
|| (MenuRoot.activeSelf && Input.GetButtonDown(GameConstants.k_ButtonNameCancel)))
{
if (ControlImage.activeSelf)
{
ControlImage.SetActive(false);
return;
}
SetPauseMenuActivation(!MenuRoot.activeSelf);
}
if (Input.GetAxisRaw(GameConstants.k_AxisNameVertical) != 0)
{
if (EventSystem.current.currentSelectedGameObject == null)
{
EventSystem.current.SetSelectedGameObject(null);
LookSensitivitySlider.Select();
}
}
}
public void ClosePauseMenu()
{
SetPauseMenuActivation(false);
}
void SetPauseMenuActivation(bool active)
{
MenuRoot.SetActive(active);
if (MenuRoot.activeSelf)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
Time.timeScale = 0f;
AudioUtility.SetMasterVolume(VolumeWhenMenuOpen);
EventSystem.current.SetSelectedGameObject(null);
}
else
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
Time.timeScale = 1f;
AudioUtility.SetMasterVolume(1);
}
}
void OnMouseSensitivityChanged(float newValue)
{
m_PlayerInputsHandler.LookSensitivity = newValue;
}
void OnShadowsChanged(bool newValue)
{
QualitySettings.shadows = newValue ? ShadowQuality.All : ShadowQuality.Disable;
}
void OnInvincibilityChanged(bool newValue)
{
m_PlayerHealth.Invincible = newValue;
}
void OnFramerateCounterChanged(bool newValue)
{
m_FramerateCounter.UIText.gameObject.SetActive(newValue);
}
public void OnShowControlButtonClicked(bool show)
{
ControlImage.SetActive(show);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 18998fe37a74de64d861e190ab499e45
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+40
View File
@@ -0,0 +1,40 @@
using Unity.FPS.Game;
using Unity.FPS.Gameplay;
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class JetpackCounter : MonoBehaviour
{
[Tooltip("Image component representing jetpack fuel")]
public Image JetpackFillImage;
[Tooltip("Canvas group that contains the whole UI for the jetack")]
public CanvasGroup MainCanvasGroup;
[Tooltip("Component to animate the color when empty or full")]
public FillBarColorChange FillBarColorChange;
Jetpack m_Jetpack;
void Awake()
{
m_Jetpack = FindFirstObjectByType<Jetpack>();
DebugUtility.HandleErrorIfNullFindObject<Jetpack, JetpackCounter>(m_Jetpack, this);
FillBarColorChange.Initialize(1f, 0f);
}
void Update()
{
MainCanvasGroup.gameObject.SetActive(m_Jetpack.IsJetpackUnlocked);
if (m_Jetpack.IsJetpackUnlocked)
{
JetpackFillImage.fillAmount = m_Jetpack.CurrentFillRatio;
FillBarColorChange.UpdateVisual(m_Jetpack.CurrentFillRatio);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c971cff0496fb3d48a9ce082496d6ef8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+26
View File
@@ -0,0 +1,26 @@
using Unity.FPS.Game;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
namespace Unity.FPS.UI
{
public class LoadSceneButton : MonoBehaviour
{
public string SceneName = "";
void Update()
{
if (EventSystem.current.currentSelectedGameObject == gameObject
&& Input.GetButtonDown(GameConstants.k_ButtonNameSubmit))
{
LoadTargetScene();
}
}
public void LoadTargetScene()
{
SceneManager.LoadScene(SceneName);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b9d73053268a2ae48bb9e7d4bf6419fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+32
View File
@@ -0,0 +1,32 @@
using Unity.FPS.Game;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class MenuNavigation : MonoBehaviour
{
public Selectable DefaultSelection;
void Start()
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
EventSystem.current.SetSelectedGameObject(null);
}
void LateUpdate()
{
if (EventSystem.current.currentSelectedGameObject == null)
{
if (Input.GetButtonDown(GameConstants.k_ButtonNameSubmit)
|| Input.GetAxisRaw(GameConstants.k_AxisNameHorizontal) != 0
|| Input.GetAxisRaw(GameConstants.k_AxisNameVertical) != 0)
{
EventSystem.current.SetSelectedGameObject(DefaultSelection.gameObject);
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 705b060d91dd25446a76cfc9640acee4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,63 @@
using Unity.FPS.Game;
using Unity.FPS.Gameplay;
using UnityEngine;
namespace Unity.FPS.UI
{
public class NotificationHUDManager : MonoBehaviour
{
[Tooltip("UI panel containing the layoutGroup for displaying notifications")]
public RectTransform NotificationPanel;
[Tooltip("Prefab for the notifications")]
public GameObject NotificationPrefab;
void Awake()
{
PlayerWeaponsManager playerWeaponsManager = FindFirstObjectByType<PlayerWeaponsManager>();
DebugUtility.HandleErrorIfNullFindObject<PlayerWeaponsManager, NotificationHUDManager>(playerWeaponsManager,
this);
playerWeaponsManager.OnAddedWeapon += OnPickupWeapon;
Jetpack jetpack = FindFirstObjectByType<Jetpack>();
DebugUtility.HandleErrorIfNullFindObject<Jetpack, NotificationHUDManager>(jetpack, this);
jetpack.OnUnlockJetpack += OnUnlockJetpack;
EventManager.AddListener<ObjectiveUpdateEvent>(OnObjectiveUpdateEvent);
}
void OnObjectiveUpdateEvent(ObjectiveUpdateEvent evt)
{
if (!string.IsNullOrEmpty(evt.NotificationText))
CreateNotification(evt.NotificationText);
}
void OnPickupWeapon(WeaponController weaponController, int index)
{
if (index != 0)
CreateNotification("Picked up weapon : " + weaponController.WeaponName);
}
void OnUnlockJetpack(bool unlock)
{
CreateNotification("Jetpack unlocked");
}
public void CreateNotification(string text)
{
GameObject notificationInstance = Instantiate(NotificationPrefab, NotificationPanel);
notificationInstance.transform.SetSiblingIndex(0);
NotificationToast toast = notificationInstance.GetComponent<NotificationToast>();
if (toast)
{
toast.Initialize(text);
}
}
void OnDestroy()
{
EventManager.RemoveListener<ObjectiveUpdateEvent>(OnObjectiveUpdateEvent);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7cc74ffbc49331241b49395553802a02
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,62 @@
using UnityEngine;
namespace Unity.FPS.UI
{
public class NotificationToast : MonoBehaviour
{
[Tooltip("Text content that will display the notification text")]
public TMPro.TextMeshProUGUI TextContent;
[Tooltip("Canvas used to fade in and out the content")]
public CanvasGroup CanvasGroup;
[Tooltip("How long it will stay visible")]
public float VisibleDuration;
[Tooltip("Duration of the fade in")]
public float FadeInDuration = 0.5f;
[Tooltip("Duration of the fade out")]
public float FadeOutDuration = 2f;
public bool Initialized { get; private set; }
float m_InitTime;
public float TotalRunTime => VisibleDuration + FadeInDuration + FadeOutDuration;
public void Initialize(string text)
{
TextContent.text = text;
m_InitTime = Time.time;
// start the fade out
Initialized = true;
}
void Update()
{
if (Initialized)
{
float timeSinceInit = Time.time - m_InitTime;
if (timeSinceInit < FadeInDuration)
{
// fade in
CanvasGroup.alpha = timeSinceInit / FadeInDuration;
}
else if (timeSinceInit < FadeInDuration + VisibleDuration)
{
// stay visible
CanvasGroup.alpha = 1f;
}
else if (timeSinceInit < FadeInDuration + VisibleDuration + FadeOutDuration)
{
// fade out
CanvasGroup.alpha = 1 - (timeSinceInit - FadeInDuration - VisibleDuration) / FadeOutDuration;
}
else
{
CanvasGroup.alpha = 0f;
// fade out over, destroy the object
Destroy(gameObject);
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7105c0d95b5d43042b5ab0674df1e09a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,89 @@
using System.Collections.Generic;
using Unity.FPS.Game;
using UnityEngine;
namespace Unity.FPS.UI
{
public class ObjectiveHUDManager : MonoBehaviour
{
[Tooltip("UI panel containing the layoutGroup for displaying objectives")]
public RectTransform ObjectivePanel;
[Tooltip("Prefab for the primary objectives")]
public GameObject PrimaryObjectivePrefab;
[Tooltip("Prefab for the primary objectives")]
public GameObject SecondaryObjectivePrefab;
Dictionary<Objective, ObjectiveToast> m_ObjectivesDictionnary;
void Awake()
{
m_ObjectivesDictionnary = new Dictionary<Objective, ObjectiveToast>();
EventManager.AddListener<ObjectiveUpdateEvent>(OnUpdateObjective);
Objective.OnObjectiveCreated += RegisterObjective;
Objective.OnObjectiveCompleted += UnregisterObjective;
}
public void RegisterObjective(Objective objective)
{
// instanciate the Ui element for the new objective
GameObject objectiveUIInstance =
Instantiate(objective.IsOptional ? SecondaryObjectivePrefab : PrimaryObjectivePrefab, ObjectivePanel);
if (!objective.IsOptional)
objectiveUIInstance.transform.SetSiblingIndex(0);
ObjectiveToast toast = objectiveUIInstance.GetComponent<ObjectiveToast>();
DebugUtility.HandleErrorIfNullGetComponent<ObjectiveToast, ObjectiveHUDManager>(toast, this,
objectiveUIInstance.gameObject);
// initialize the element and give it the objective description
toast.Initialize(objective.Title, objective.Description, "", objective.IsOptional, objective.DelayVisible);
m_ObjectivesDictionnary.Add(objective, toast);
UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(ObjectivePanel);
}
public void UnregisterObjective(Objective objective)
{
// if the objective if in the list, make it fade out, and remove it from the list
if (m_ObjectivesDictionnary.TryGetValue(objective, out ObjectiveToast toast) && toast != null)
{
toast.Complete();
}
m_ObjectivesDictionnary.Remove(objective);
}
void OnUpdateObjective(ObjectiveUpdateEvent evt)
{
if (m_ObjectivesDictionnary.TryGetValue(evt.Objective, out ObjectiveToast toast) && toast != null)
{
// set the new updated description for the objective, and forces the content size fitter to be recalculated
Canvas.ForceUpdateCanvases();
if (!string.IsNullOrEmpty(evt.DescriptionText))
toast.DescriptionTextContent.text = evt.DescriptionText;
if (!string.IsNullOrEmpty(evt.CounterText))
toast.CounterTextContent.text = evt.CounterText;
if (toast.GetComponent<RectTransform>())
{
UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(toast.GetComponent<RectTransform>());
}
}
}
void OnDestroy()
{
EventManager.AddListener<ObjectiveUpdateEvent>(OnUpdateObjective);
Objective.OnObjectiveCreated -= RegisterObjective;
Objective.OnObjectiveCompleted -= UnregisterObjective;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6df5ceb43b5e7254f90afdf178b9cc04
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+195
View File
@@ -0,0 +1,195 @@
using Unity.FPS.Game;
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class ObjectiveToast : MonoBehaviour
{
[Header("References")] [Tooltip("Text content that will display the title")]
public TMPro.TextMeshProUGUI TitleTextContent;
[Tooltip("Text content that will display the description")]
public TMPro.TextMeshProUGUI DescriptionTextContent;
[Tooltip("Text content that will display the counter")]
public TMPro.TextMeshProUGUI CounterTextContent;
[Tooltip("Rect that will display the description")]
public RectTransform SubTitleRect;
[Tooltip("Canvas used to fade in and out the content")]
public CanvasGroup CanvasGroup;
[Tooltip("Layout group containing the objective")]
public HorizontalOrVerticalLayoutGroup LayoutGroup;
[Header("Transitions")] [Tooltip("Delay before moving complete")]
public float CompletionDelay;
[Tooltip("Duration of the fade in")] public float FadeInDuration = 0.5f;
[Tooltip("Duration of the fade out")] public float FadeOutDuration = 2f;
[Header("Sound")] [Tooltip("Sound that will be player on initialization")]
public AudioClip InitSound;
[Tooltip("Sound that will be player on completion")]
public AudioClip CompletedSound;
[Header("Movement")] [Tooltip("Time it takes to move in the screen")]
public float MoveInDuration = 0.5f;
[Tooltip("Animation curve for move in, position in x over time")]
public AnimationCurve MoveInCurve;
[Tooltip("Time it takes to move out of the screen")]
public float MoveOutDuration = 2f;
[Tooltip("Animation curve for move out, position in x over time")]
public AnimationCurve MoveOutCurve;
float m_StartFadeTime;
bool m_IsFadingIn;
bool m_IsFadingOut;
bool m_IsMovingIn;
bool m_IsMovingOut;
AudioSource m_AudioSource;
RectTransform m_RectTransform;
public void Initialize(string titleText, string descText, string counterText, bool isOptionnal, float delay)
{
// set the description for the objective, and forces the content size fitter to be recalculated
Canvas.ForceUpdateCanvases();
TitleTextContent.text = titleText;
DescriptionTextContent.text = descText;
CounterTextContent.text = counterText;
if (GetComponent<RectTransform>())
{
LayoutRebuilder.ForceRebuildLayoutImmediate(GetComponent<RectTransform>());
}
m_StartFadeTime = Time.time + delay;
// start the fade in
m_IsFadingIn = true;
m_IsMovingIn = true;
}
public void Complete()
{
m_StartFadeTime = Time.time + CompletionDelay;
m_IsFadingIn = false;
m_IsMovingIn = false;
// if a sound was set, play it
PlaySound(CompletedSound);
// start the fade out
m_IsFadingOut = true;
m_IsMovingOut = true;
}
void Update()
{
float timeSinceFadeStarted = Time.time - m_StartFadeTime;
SubTitleRect.gameObject.SetActive(!string.IsNullOrEmpty(DescriptionTextContent.text));
if (m_IsFadingIn && !m_IsFadingOut)
{
// fade in
if (timeSinceFadeStarted < FadeInDuration)
{
// calculate alpha ratio
CanvasGroup.alpha = timeSinceFadeStarted / FadeInDuration;
}
else
{
CanvasGroup.alpha = 1f;
// end the fade in
m_IsFadingIn = false;
PlaySound(InitSound);
}
}
if (m_IsMovingIn && !m_IsMovingOut)
{
// move in
if (timeSinceFadeStarted < MoveInDuration)
{
LayoutGroup.padding.left = (int) MoveInCurve.Evaluate(timeSinceFadeStarted / MoveInDuration);
if (GetComponent<RectTransform>())
{
LayoutRebuilder.ForceRebuildLayoutImmediate(GetComponent<RectTransform>());
}
}
else
{
// making sure the position is exact
LayoutGroup.padding.left = 0;
if (GetComponent<RectTransform>())
{
LayoutRebuilder.ForceRebuildLayoutImmediate(GetComponent<RectTransform>());
}
m_IsMovingIn = false;
}
}
if (m_IsFadingOut)
{
// fade out
if (timeSinceFadeStarted < FadeOutDuration)
{
// calculate alpha ratio
CanvasGroup.alpha = 1 - (timeSinceFadeStarted) / FadeOutDuration;
}
else
{
CanvasGroup.alpha = 0f;
// end the fade out, then destroy the object
m_IsFadingOut = false;
Destroy(gameObject);
}
}
if (m_IsMovingOut)
{
// move out
if (timeSinceFadeStarted < MoveOutDuration)
{
LayoutGroup.padding.left = (int) MoveOutCurve.Evaluate(timeSinceFadeStarted / MoveOutDuration);
if (GetComponent<RectTransform>())
{
LayoutRebuilder.ForceRebuildLayoutImmediate(GetComponent<RectTransform>());
}
}
else
{
m_IsMovingOut = false;
}
}
}
void PlaySound(AudioClip sound)
{
if (!sound)
return;
if (!m_AudioSource)
{
m_AudioSource = gameObject.AddComponent<AudioSource>();
m_AudioSource.outputAudioMixerGroup = AudioUtility.GetAudioGroup(AudioUtility.AudioGroups.HUDObjective);
}
m_AudioSource.PlayOneShot(sound);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0511a19aa4a23374180039b212baa206
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+33
View File
@@ -0,0 +1,33 @@
using Unity.FPS.Game;
using Unity.FPS.Gameplay;
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class PlayerHealthBar : MonoBehaviour
{
[Tooltip("Image component dispplaying current health")]
public Image HealthFillImage;
Health m_PlayerHealth;
void Start()
{
PlayerCharacterController playerCharacterController =
GameObject.FindFirstObjectByType<PlayerCharacterController>();
DebugUtility.HandleErrorIfNullFindObject<PlayerCharacterController, PlayerHealthBar>(
playerCharacterController, this);
m_PlayerHealth = playerCharacterController.GetComponent<Health>();
DebugUtility.HandleErrorIfNullGetComponent<Health, PlayerHealthBar>(m_PlayerHealth, this,
playerCharacterController.gameObject);
}
void Update()
{
// update health bar value
HealthFillImage.fillAmount = m_PlayerHealth.CurrentHealth / m_PlayerHealth.MaxHealth;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ef607aeb00cc1214ab7aa1f86a984abf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+33
View File
@@ -0,0 +1,33 @@
using Unity.FPS.Game;
using Unity.FPS.Gameplay;
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class StanceHUD : MonoBehaviour
{
[Tooltip("Image component for the stance sprites")]
public Image StanceImage;
[Tooltip("Sprite to display when standing")]
public Sprite StandingSprite;
[Tooltip("Sprite to display when crouching")]
public Sprite CrouchingSprite;
void Start()
{
PlayerCharacterController character = FindFirstObjectByType<PlayerCharacterController>();
DebugUtility.HandleErrorIfNullFindObject<PlayerCharacterController, StanceHUD>(character, this);
character.OnStanceChanged += OnStanceChanged;
OnStanceChanged(character.IsCrouching);
}
void OnStanceChanged(bool crouched)
{
StanceImage.sprite = crouched ? CrouchingSprite : StandingSprite;
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2758505f22acf1d4e8dbb9e9e9ac6e85
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+100
View File
@@ -0,0 +1,100 @@
using System.IO;
using Unity.FPS.Game;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class TakeScreenshot : MonoBehaviour
{
[Tooltip("Root of the screenshot panel in the menu")]
public GameObject ScreenshotPanel;
[Tooltip("Name for the screenshot file")]
public string FileName = "Screenshot";
[Tooltip("Image to display the screenshot in")]
public RawImage PreviewImage;
CanvasGroup m_MenuCanvas = null;
Texture2D m_Texture;
bool m_TakeScreenshot;
bool m_ScreenshotTaken;
bool m_IsFeatureDisable;
string GetPath() => k_ScreenshotPath + FileName + ".png";
const string k_ScreenshotPath = "Assets/";
void Awake()
{
#if !UNITY_EDITOR
// this feature is available only in the editor
ScreenshotPanel.SetActive(false);
m_IsFeatureDisable = true;
#else
m_IsFeatureDisable = false;
var gameMenuManager = GetComponent<InGameMenuManager>();
DebugUtility.HandleErrorIfNullGetComponent<InGameMenuManager, TakeScreenshot>(gameMenuManager, this,
gameObject);
m_MenuCanvas = gameMenuManager.MenuRoot.GetComponent<CanvasGroup>();
DebugUtility.HandleErrorIfNullGetComponent<CanvasGroup, TakeScreenshot>(m_MenuCanvas, this,
gameMenuManager.MenuRoot.gameObject);
LoadScreenshot();
#endif
}
void Update()
{
PreviewImage.enabled = PreviewImage.texture != null;
if (m_IsFeatureDisable)
return;
if (m_TakeScreenshot)
{
m_MenuCanvas.alpha = 0;
ScreenCapture.CaptureScreenshot(GetPath());
m_TakeScreenshot = false;
m_ScreenshotTaken = true;
return;
}
if (m_ScreenshotTaken)
{
LoadScreenshot();
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
m_MenuCanvas.alpha = 1;
m_ScreenshotTaken = false;
}
}
public void OnTakeScreenshotButtonPressed()
{
m_TakeScreenshot = true;
}
void LoadScreenshot()
{
if (File.Exists(GetPath()))
{
var bytes = File.ReadAllBytes(GetPath());
m_Texture = new Texture2D(2, 2);
m_Texture.LoadImage(bytes);
m_Texture.Apply();
PreviewImage.texture = m_Texture;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 91538b0281dc4aa4fbe5784a7e562751
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,28 @@
using Unity.FPS.Game;
using UnityEngine;
using UnityEngine.EventSystems;
namespace Unity.FPS.UI
{
public class ToggleGameObjectButton : MonoBehaviour
{
public GameObject ObjectToToggle;
public bool ResetSelectionAfterClick;
void Update()
{
if (ObjectToToggle.activeSelf && Input.GetButtonDown(GameConstants.k_ButtonNameCancel))
{
SetGameObjectActive(false);
}
}
public void SetGameObjectActive(bool active)
{
ObjectToToggle.SetActive(active);
if (ResetSelectionAfterClick)
EventSystem.current.SetSelectedGameObject(null);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8e892a77fbd0909468372b0f88c7c5d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+38
View File
@@ -0,0 +1,38 @@
using UnityEngine;
namespace Unity.FPS.UI
{
// The component that is used to display the Objectives, the Notification and the game messages like a list
// When a new one is created, the previous ones move down to make room for the new one
public class UITable : MonoBehaviour
{
[Tooltip("How much space should there be between items?")]
public float Offset;
[Tooltip("Add new the new items below existing items.")]
public bool Down;
public void UpdateTable(GameObject newItem)
{
if (newItem != null)
newItem.GetComponent<RectTransform>().localScale = Vector3.one;
float height = 0;
for (int i = 0; i < transform.childCount; i++)
{
RectTransform child = transform.GetChild(i).GetComponent<RectTransform>();
Vector2 size = child.sizeDelta;
height += Down ? -(1 - child.pivot.y) * size.y : (1 - child.pivot.y) * size.y;
if (i != 0)
height += Down ? -Offset : Offset;
Vector2 newPos = Vector2.zero;
newPos.y = height;
newPos.x = 0;//-child.pivot.x * size.x * hi.localScale.x;
child.anchoredPosition = newPos;
}
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4707fbaf17e28342b6a52817c6de926
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+72
View File
@@ -0,0 +1,72 @@
using System.Collections.Generic;
using Unity.FPS.Game;
using Unity.FPS.Gameplay;
using UnityEngine;
namespace Unity.FPS.UI
{
public class WeaponHUDManager : MonoBehaviour
{
[Tooltip("UI panel containing the layoutGroup for displaying weapon ammo")]
public RectTransform AmmoPanel;
[Tooltip("Prefab for displaying weapon ammo")]
public GameObject AmmoCounterPrefab;
PlayerWeaponsManager m_PlayerWeaponsManager;
List<AmmoCounter> m_AmmoCounters = new List<AmmoCounter>();
void Start()
{
m_PlayerWeaponsManager = FindFirstObjectByType<PlayerWeaponsManager>();
DebugUtility.HandleErrorIfNullFindObject<PlayerWeaponsManager, WeaponHUDManager>(m_PlayerWeaponsManager,
this);
WeaponController activeWeapon = m_PlayerWeaponsManager.GetActiveWeapon();
if (activeWeapon)
{
AddWeapon(activeWeapon, m_PlayerWeaponsManager.ActiveWeaponIndex);
ChangeWeapon(activeWeapon);
}
m_PlayerWeaponsManager.OnAddedWeapon += AddWeapon;
m_PlayerWeaponsManager.OnRemovedWeapon += RemoveWeapon;
m_PlayerWeaponsManager.OnSwitchedToWeapon += ChangeWeapon;
}
void AddWeapon(WeaponController newWeapon, int weaponIndex)
{
GameObject ammoCounterInstance = Instantiate(AmmoCounterPrefab, AmmoPanel);
AmmoCounter newAmmoCounter = ammoCounterInstance.GetComponent<AmmoCounter>();
DebugUtility.HandleErrorIfNullGetComponent<AmmoCounter, WeaponHUDManager>(newAmmoCounter, this,
ammoCounterInstance.gameObject);
newAmmoCounter.Initialize(newWeapon, weaponIndex);
m_AmmoCounters.Add(newAmmoCounter);
}
void RemoveWeapon(WeaponController newWeapon, int weaponIndex)
{
int foundCounterIndex = -1;
for (int i = 0; i < m_AmmoCounters.Count; i++)
{
if (m_AmmoCounters[i].WeaponCounterIndex == weaponIndex)
{
foundCounterIndex = i;
Destroy(m_AmmoCounters[i].gameObject);
}
}
if (foundCounterIndex >= 0)
{
m_AmmoCounters.RemoveAt(foundCounterIndex);
}
}
void ChangeWeapon(WeaponController weapon)
{
UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(AmmoPanel);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d92192f1b2e47e444a80f725b8cbca36
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
using Unity.FPS.Game;
using UnityEngine;
using UnityEngine.UI;
namespace Unity.FPS.UI
{
public class WorldspaceHealthBar : MonoBehaviour
{
[Tooltip("Health component to track")] public Health Health;
[Tooltip("Image component displaying health left")]
public Image HealthBarImage;
[Tooltip("The floating healthbar pivot transform")]
public Transform HealthBarPivot;
[Tooltip("Whether the health bar is visible when at full health or not")]
public bool HideFullHealthBar = true;
void Update()
{
// update health bar value
HealthBarImage.fillAmount = Health.CurrentHealth / Health.MaxHealth;
// rotate health bar to face the camera/player
HealthBarPivot.LookAt(Camera.main.transform.position);
// hide health bar if needed
if (HideFullHealthBar)
HealthBarPivot.gameObject.SetActive(HealthBarImage.fillAmount != 1);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 88567379ffc126c4e96b34011148ffa0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+18
View File
@@ -0,0 +1,18 @@
{
"name": "fps.UI",
"references": [
"GUID:9c5543eabb73a6249ac07b2c065ee8b4",
"GUID:27b7e9efd224f064990a97ed99e4456f",
"GUID:e9dc24b3d0971d64a9e95b6986d97af5",
"GUID:6055be8ebefd69e48b49212b09b47b2f"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 269903ea973e2a64ca0fb91ee07d3625
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: