update
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f55bbfc17a3a894281c47b1182205a4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa1d13df263b6a0429b733192dcff01f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2758505f22acf1d4e8dbb9e9e9ac6e85
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4707fbaf17e28342b6a52817c6de926
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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:
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 269903ea973e2a64ca0fb91ee07d3625
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user