Update
This commit is contained in:
@@ -1,123 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.UI
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.UltimateCharacterController.Traits;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// The AttributeMonitor will update the UI for the character's attributes.
|
||||
/// </summary>
|
||||
public class AttributeMonitor : CharacterMonitor
|
||||
{
|
||||
[Tooltip("The AttributeManager that contains the attribute. If null the character's Attribute Manager will be used.")]
|
||||
[SerializeField] protected AttributeManager m_AttributeManager;
|
||||
[Tooltip("The name of the attribute that the UI should monitor.")]
|
||||
[SerializeField] protected string m_AttributeName = "Health";
|
||||
[Tooltip("A reference used to the slider used to show the attribute value.")]
|
||||
[SerializeField] protected Slider m_Slider;
|
||||
|
||||
private Attribute m_Attribute;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
if (m_Slider == null) {
|
||||
m_Slider = GetComponent<Slider>();
|
||||
}
|
||||
|
||||
if (m_AttributeManager != null) {
|
||||
EventHandler.RegisterEvent<Attribute>(m_AttributeManager.gameObject, "OnAttributeUpdateValue", OnUpdateValue);
|
||||
}
|
||||
|
||||
// The monitor can't display if there is no slider.
|
||||
if (m_Slider != null) {
|
||||
base.Awake();
|
||||
} else {
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the monitor to the specified character.
|
||||
/// </summary>
|
||||
/// <param name="character">The character to attach the monitor to.</param>
|
||||
protected override void OnAttachCharacter(GameObject character)
|
||||
{
|
||||
if (m_Character != null) {
|
||||
if (m_AttributeManager != null && m_AttributeManager.gameObject == character) {
|
||||
EventHandler.UnregisterEvent<Attribute>(m_AttributeManager.gameObject, "OnAttributeUpdateValue", OnUpdateValue);
|
||||
m_AttributeManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
base.OnAttachCharacter(character);
|
||||
|
||||
if (m_Character == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_AttributeManager == null) {
|
||||
m_AttributeManager = m_Character.GetCachedComponent<AttributeManager>();
|
||||
EventHandler.RegisterEvent<Attribute>(m_AttributeManager.gameObject, "OnAttributeUpdateValue", OnUpdateValue);
|
||||
}
|
||||
if (m_AttributeManager == null) {
|
||||
enabled = false;
|
||||
gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_Attribute = m_AttributeManager.GetAttribute(m_AttributeName);
|
||||
if (m_Attribute == null) {
|
||||
enabled = false;
|
||||
gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
enabled = true;
|
||||
m_Slider.value = (m_Attribute.Value - m_Attribute.MinValue) / (m_Attribute.MaxValue - m_Attribute.MinValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The attribute's value has been updated.
|
||||
/// </summary>
|
||||
/// <param name="attribute">The attribute that was updated.</param>
|
||||
private void OnUpdateValue(Attribute attribute)
|
||||
{
|
||||
if (attribute != m_Attribute) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Slider.value = (m_Attribute.Value - m_Attribute.MinValue) / (m_Attribute.MaxValue - m_Attribute.MinValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object has been destroyed.
|
||||
/// </summary>
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
|
||||
if (m_AttributeManager != null) {
|
||||
EventHandler.UnregisterEvent<Attribute>(m_AttributeManager.gameObject, "OnAttributeUpdateValue", OnUpdateValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the UI be shown?
|
||||
/// </summary>
|
||||
/// <returns>True if the UI can be shown.</returns>
|
||||
protected override bool CanShowUI()
|
||||
{
|
||||
return base.CanShowUI() && m_Attribute != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6cbebeb99f037f43a661f3d59fd5b70
|
||||
timeCreated: 1518280555
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 400
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,123 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.UI
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.UltimateCharacterController.StateSystem;
|
||||
using Opsive.UltimateCharacterController.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// The CameraMonitor component allows for UI elements to mapped to a specific character (allowing for split screen and coop).
|
||||
/// </summary>
|
||||
public abstract class CharacterMonitor : StateBehavior
|
||||
{
|
||||
[Tooltip("The character that uses the UI represents. Can be null.")]
|
||||
[SerializeField] protected GameObject m_Character;
|
||||
[Tooltip("Is the UI visible?")]
|
||||
[SerializeField] protected bool m_Visible = true;
|
||||
|
||||
public GameObject Character { get { return m_Character; } set { OnAttachCharacter(value); } }
|
||||
public bool Visible { get { return m_Visible; } set { m_Visible = value; ShowUI(m_ShowUI); } }
|
||||
|
||||
protected bool m_ShowUI = true;
|
||||
protected GameObject m_CameraGameObject;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
var camera = UnityEngineUtility.FindCamera(m_Character);
|
||||
if (camera != null) {
|
||||
m_CameraGameObject = camera.gameObject;
|
||||
if (m_Character == null) {
|
||||
m_Character = m_CameraGameObject.GetCachedComponent<UltimateCharacterController.Camera.CameraController>().Character;
|
||||
}
|
||||
EventHandler.RegisterEvent<GameObject>(m_CameraGameObject, "OnCameraAttachCharacter", OnAttachCharacter);
|
||||
}
|
||||
|
||||
// Start disabled - attaching the character will enabe the component.
|
||||
enabled = false;
|
||||
|
||||
if (m_Character != null) {
|
||||
var character = m_Character;
|
||||
m_Character = null;
|
||||
OnAttachCharacter(character);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the monitor to the specified character.
|
||||
/// </summary>
|
||||
/// <param name="character">The character to attach the monitor to.</param>
|
||||
protected virtual void OnAttachCharacter(GameObject character)
|
||||
{
|
||||
if (m_Character == character) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Character != null) {
|
||||
StateManager.LinkGameObjects(m_Character, gameObject, false);
|
||||
EventHandler.UnregisterEvent<bool>(m_Character, "OnShowUI", ShowUI);
|
||||
}
|
||||
|
||||
m_Character = character;
|
||||
|
||||
if (m_Character != null) {
|
||||
StateManager.LinkGameObjects(m_Character, gameObject, true);
|
||||
EventHandler.RegisterEvent<bool>(m_Character, "OnShowUI", ShowUI);
|
||||
}
|
||||
|
||||
// The monitor may be in the process of being destroyed.
|
||||
enabled = m_Character != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides the UI if it's not visible.
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
if (!CanShowUI()) {
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows or hides the UI.
|
||||
/// </summary>
|
||||
/// <param name="show">Should the UI be shown?</param>
|
||||
private void ShowUI(bool show)
|
||||
{
|
||||
m_ShowUI = show;
|
||||
gameObject.SetActive(CanShowUI());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the UI be shown?
|
||||
/// </summary>
|
||||
/// <returns>True if the UI can be shown.</returns>
|
||||
protected virtual bool CanShowUI()
|
||||
{
|
||||
return m_ShowUI && m_Visible;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object has been destroyed.
|
||||
/// </summary>
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
if (m_CameraGameObject != null) {
|
||||
EventHandler.UnregisterEvent<GameObject>(m_CameraGameObject, "OnCameraAttachCharacter", OnAttachCharacter);
|
||||
}
|
||||
OnAttachCharacter(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61159c49be98c6e4787663a97dc9d1b7
|
||||
timeCreated: 1518280555
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 500
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,460 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.UI
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.UltimateCharacterController.Camera;
|
||||
using Opsive.UltimateCharacterController.Character;
|
||||
using Opsive.UltimateCharacterController.Items;
|
||||
using Opsive.UltimateCharacterController.Utility;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// The CrosshairsMonitor will update the UI for the crosshair.
|
||||
/// </summary>
|
||||
public class CrosshairsMonitor : CharacterMonitor
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[Tooltip("Draw a debug line to see the direction that the crosshairs is looking (editor only).")]
|
||||
[SerializeField] protected bool m_DebugDrawLookRay;
|
||||
#endif
|
||||
[Tooltip("The radius of the crosshair's collision sphere to detect if it is targetting an enemy.")]
|
||||
[SerializeField] protected float m_CollisionRadius = 0.05f;
|
||||
[Tooltip("The maximum number of colliders that the crosshairs can detect.")]
|
||||
[SerializeField] protected int m_MaxCollisionCount = 40;
|
||||
[Tooltip("Specifies if the crosshairscan detect triggers.")]
|
||||
[SerializeField] protected QueryTriggerInteraction m_TriggerInteraction = QueryTriggerInteraction.Ignore;
|
||||
[Tooltip("The crosshairs used when the item doesn't specify a crosshairs.")]
|
||||
[SerializeField] protected Sprite m_DefaultSprite;
|
||||
[Tooltip("The default color of the crosshairs.")]
|
||||
[SerializeField] protected Color m_DefaultColor = Color.white;
|
||||
[Tooltip("The color of the crosshairs when a target is in sight.")]
|
||||
[SerializeField] protected Color m_TargetColor = Color.red;
|
||||
[Tooltip("A reference to the image used for the center crosshairs.")]
|
||||
[SerializeField] protected Image m_CenterCrosshairsImage;
|
||||
[Tooltip("A reference to the image used for the left crosshairs.")]
|
||||
[SerializeField] protected Image m_LeftCrosshairsImage;
|
||||
[Tooltip("A reference to the image used for the top crosshairs.")]
|
||||
[SerializeField] protected Image m_TopCrosshairsImage;
|
||||
[Tooltip("A reference to the image used for the right crosshairs.")]
|
||||
[SerializeField] protected Image m_RightCrosshairsImage;
|
||||
[Tooltip("A reference to the image used for the bottom crosshairs.")]
|
||||
[SerializeField] protected Image m_BottomCrosshairsImage;
|
||||
[Tooltip("Should the crosshairs be disabled when the character dies?")]
|
||||
[SerializeField] protected bool m_DisableOnDeath = true;
|
||||
|
||||
public float CollisionRadius { get { return m_CollisionRadius; } set { m_CollisionRadius = value; } }
|
||||
public QueryTriggerInteraction TriggerInteraction { get { return m_TriggerInteraction; } set { m_TriggerInteraction = value; } }
|
||||
public Color DefaultColor { get { return m_DefaultColor; } set { m_DefaultColor = value; } }
|
||||
public Color TargetColor { get { return m_TargetColor; } set { m_TargetColor = value; } }
|
||||
public bool DisableOnDeath { get { return m_DisableOnDeath; } set { m_DisableOnDeath = value; } }
|
||||
|
||||
private GameObject m_GameObject;
|
||||
private UnityEngine.Camera m_Camera;
|
||||
private CameraController m_CameraController;
|
||||
private AimAssist m_AimAssist;
|
||||
private Transform m_CharacterTransform;
|
||||
private CharacterLayerManager m_CharacterLayerManager;
|
||||
private UltimateCharacterLocomotion m_CharacterLocomotion;
|
||||
|
||||
private RectTransform m_CenterRectTransform;
|
||||
private RectTransform m_LeftRectTransform;
|
||||
private RectTransform m_TopRectTransform;
|
||||
private RectTransform m_RightRectTransform;
|
||||
private RectTransform m_BottomRectTransform;
|
||||
|
||||
private RaycastHit[] m_RaycastHits;
|
||||
private UnityEngineUtility.RaycastHitComparer m_RaycastHitComparer = new UnityEngineUtility.RaycastHitComparer();
|
||||
private Item m_EquippedItem;
|
||||
private float m_CurrentCrosshairsSpread;
|
||||
private float m_TargetCrosshairsSpread;
|
||||
private float m_CrosshairsSpreadVelocity;
|
||||
private bool m_Aiming;
|
||||
private bool m_EnableImage;
|
||||
private int m_EquippedItemCount;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_GameObject = gameObject;
|
||||
if (m_CenterCrosshairsImage == null) {
|
||||
m_CenterCrosshairsImage = GetComponent<Image>();
|
||||
}
|
||||
m_CenterCrosshairsImage.sprite = m_DefaultSprite;
|
||||
m_CenterRectTransform = m_CenterCrosshairsImage.GetComponent<RectTransform>();
|
||||
if ((m_CenterCrosshairsImage.enabled = (m_DefaultSprite != null))) {
|
||||
UnityEngineUtility.SizeSprite(m_CenterCrosshairsImage.sprite, m_CenterRectTransform);
|
||||
}
|
||||
|
||||
if (m_LeftCrosshairsImage != null) m_LeftRectTransform = m_LeftCrosshairsImage.GetComponent<RectTransform>();
|
||||
if (m_TopCrosshairsImage != null) m_TopRectTransform = m_TopCrosshairsImage.GetComponent<RectTransform>();
|
||||
if (m_RightCrosshairsImage != null) m_RightRectTransform = m_RightCrosshairsImage.GetComponent<RectTransform>();
|
||||
if (m_BottomCrosshairsImage != null) m_BottomRectTransform = m_BottomCrosshairsImage.GetComponent<RectTransform>();
|
||||
|
||||
m_RaycastHits = new RaycastHit[m_MaxCollisionCount];
|
||||
|
||||
// Setup the crosshairs defaults.
|
||||
ResetMonitor();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the monitor to the specified character.
|
||||
/// </summary>
|
||||
/// <param name="character">The character to attach the monitor to.</param>
|
||||
protected override void OnAttachCharacter(GameObject character)
|
||||
{
|
||||
if (m_Character != null) {
|
||||
EventHandler.UnregisterEvent<Item, int>(m_Character, "OnAbilityWillEquipItem", OnEquipItem);
|
||||
EventHandler.UnregisterEvent<Item, bool>(m_Character, "OnItemUpdateDominantItem", OnUpdateDominantItem);
|
||||
EventHandler.UnregisterEvent<Item, int>(m_Character, "OnAbilityUnequipItemComplete", OnUnequipItem);
|
||||
EventHandler.UnregisterEvent<Item, int>(m_Character, "OnInventoryRemoveItem", OnUnequipItem);
|
||||
EventHandler.UnregisterEvent<bool, bool>(m_Character, "OnAddCrosshairsSpread", OnAddCrosshairsSpread);
|
||||
EventHandler.UnregisterEvent<bool, bool>(m_Character, "OnAimAbilityStart", OnAim);
|
||||
EventHandler.UnregisterEvent<Vector3, Vector3, GameObject>(m_Character, "OnDeath", OnDeath);
|
||||
EventHandler.UnregisterEvent(m_Character, "OnRespawn", OnRespawn);
|
||||
ResetMonitor();
|
||||
}
|
||||
|
||||
base.OnAttachCharacter(character);
|
||||
|
||||
if (m_Character == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Camera = UnityEngineUtility.FindCamera(m_Character);
|
||||
m_CameraController = m_Camera.gameObject.GetCachedComponent<CameraController>();
|
||||
m_CameraController.SetCrosshairs(transform);
|
||||
|
||||
m_AimAssist = m_Camera.GetComponent<AimAssist>();
|
||||
m_CharacterTransform = m_Character.transform;
|
||||
m_CharacterLayerManager = m_Character.GetCachedComponent<CharacterLayerManager>();
|
||||
m_CharacterLocomotion = m_Character.GetCachedComponent<UltimateCharacterLocomotion>();
|
||||
m_EnableImage = false;
|
||||
|
||||
EventHandler.RegisterEvent<Item, int>(m_Character, "OnAbilityWillEquipItem", OnEquipItem);
|
||||
EventHandler.RegisterEvent<Item, bool>(m_Character, "OnItemUpdateDominantItem", OnUpdateDominantItem);
|
||||
EventHandler.RegisterEvent<Item, int>(m_Character, "OnAbilityUnequipItemComplete", OnUnequipItem);
|
||||
EventHandler.RegisterEvent<Item, int>(m_Character, "OnInventoryRemoveItem", OnUnequipItem);
|
||||
EventHandler.RegisterEvent<bool, bool>(m_Character, "OnAddCrosshairsSpread", OnAddCrosshairsSpread);
|
||||
EventHandler.RegisterEvent<bool, bool>(m_Character, "OnAimAbilityStart", OnAim);
|
||||
EventHandler.RegisterEvent<Vector3, Vector3, GameObject>(m_Character, "OnDeath", OnDeath);
|
||||
EventHandler.RegisterEvent(m_Character, "OnRespawn", OnRespawn);
|
||||
|
||||
// An item may already be equipped.
|
||||
var inventory = m_Character.GetCachedComponent<Inventory.InventoryBase>();
|
||||
if (inventory != null) {
|
||||
for (int i = 0; i < inventory.SlotCount; ++i) {
|
||||
var item = inventory.GetActiveItem(i);
|
||||
if (item != null) {
|
||||
OnEquipItem(item, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine any targets that are within the crosshairs raycast.
|
||||
/// </summary>
|
||||
private void Update()
|
||||
{
|
||||
var crosshairsColor = m_DefaultColor;
|
||||
var crosshairsRay = m_Camera.ScreenPointToRay(m_CenterRectTransform.position);
|
||||
Transform target = null;
|
||||
// Prevent the ray between the character and the camera from causing a false collision.
|
||||
if (!m_CharacterLocomotion.FirstPersonPerspective) {
|
||||
var direction = m_CharacterTransform.InverseTransformPoint(crosshairsRay.origin);
|
||||
direction.y = 0;
|
||||
crosshairsRay.origin = crosshairsRay.GetPoint(direction.magnitude);
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
// Visualize the direction of the look direction.
|
||||
if (m_DebugDrawLookRay) {
|
||||
Debug.DrawRay(crosshairsRay.origin, crosshairsRay.direction * m_CameraController.LookDirectionDistance, Color.white);
|
||||
}
|
||||
#endif
|
||||
var hitCount = Physics.SphereCastNonAlloc(crosshairsRay, m_CollisionRadius, m_RaycastHits, m_CameraController.LookDirectionDistance, m_CharacterLayerManager.IgnoreInvisibleLayers, m_TriggerInteraction);
|
||||
#if UNITY_EDITOR
|
||||
if (hitCount == m_MaxCollisionCount) {
|
||||
Debug.LogWarning("Warning: The crosshairs detected the maximum number of objects. Consider increasing the Max Collision Count on the Crosshairs Monitor.");
|
||||
}
|
||||
#endif
|
||||
if (hitCount > 0) {
|
||||
for (int i = 0; i < hitCount; ++i) {
|
||||
var closestRaycastHit = QuickSelect.SmallestK(m_RaycastHits, hitCount, i, m_RaycastHitComparer);
|
||||
var closestRaycastHitTransform = closestRaycastHit.transform;
|
||||
// The crosshairs cannot hit the character that is attached to the camera.
|
||||
if (closestRaycastHitTransform.IsChildOf(m_CharacterTransform)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (MathUtility.InLayerMask(closestRaycastHitTransform.gameObject.layer, m_CharacterLayerManager.EnemyLayers)) {
|
||||
target = closestRaycastHitTransform;
|
||||
crosshairsColor = m_TargetColor;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_AimAssist != null) {
|
||||
m_AimAssist.SetTarget(target);
|
||||
}
|
||||
|
||||
if (m_EquippedItem != null) {
|
||||
m_CurrentCrosshairsSpread = Mathf.SmoothDamp(m_CurrentCrosshairsSpread, m_TargetCrosshairsSpread, ref m_CrosshairsSpreadVelocity,
|
||||
m_EquippedItem.QuadrantSpreadDamping);
|
||||
}
|
||||
m_CenterCrosshairsImage.color = crosshairsColor;
|
||||
if (m_LeftCrosshairsImage != null && m_LeftCrosshairsImage.enabled) {
|
||||
m_LeftCrosshairsImage.color = crosshairsColor;
|
||||
PositionSprite(m_LeftRectTransform, -m_EquippedItem.QuadrantOffset - m_CurrentCrosshairsSpread, 0);
|
||||
}
|
||||
if (m_TopCrosshairsImage != null && m_TopCrosshairsImage.enabled) {
|
||||
m_TopCrosshairsImage.color = crosshairsColor;
|
||||
PositionSprite(m_TopRectTransform, 0, m_EquippedItem.QuadrantOffset + m_CurrentCrosshairsSpread);
|
||||
}
|
||||
if (m_RightCrosshairsImage != null && m_RightCrosshairsImage.enabled) {
|
||||
m_RightCrosshairsImage.color = crosshairsColor;
|
||||
PositionSprite(m_RightRectTransform, m_EquippedItem.QuadrantOffset + m_CurrentCrosshairsSpread, 0);
|
||||
}
|
||||
if (m_BottomCrosshairsImage != null && m_BottomCrosshairsImage.enabled) {
|
||||
m_BottomCrosshairsImage.color = crosshairsColor;
|
||||
PositionSprite(m_BottomRectTransform, 0, -m_EquippedItem.QuadrantOffset - m_CurrentCrosshairsSpread);
|
||||
}
|
||||
|
||||
var enableImage = !m_Aiming || (m_EquippedItem != null && m_EquippedItem.ShowCrosshairsOnAim);
|
||||
if (enableImage != m_EnableImage) {
|
||||
m_EnableImage = enableImage;
|
||||
EnableCrosshairsImage(enableImage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An item has been equipped.
|
||||
/// </summary>
|
||||
/// <param name="item">The equipped item.</param>
|
||||
/// <param name="slotID">The slot that the item now occupies.</param>
|
||||
private void OnEquipItem(Item item, int slotID)
|
||||
{
|
||||
if (!item.DominantItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_CurrentCrosshairsSpread = m_TargetCrosshairsSpread = 0;
|
||||
m_EquippedItem = item;
|
||||
m_CenterCrosshairsImage.sprite = m_EquippedItem.CenterCrosshairs != null ? m_EquippedItem.CenterCrosshairs : m_DefaultSprite;
|
||||
if (m_CenterCrosshairsImage.sprite != null) {
|
||||
m_CenterCrosshairsImage.enabled = !m_Aiming || m_EquippedItem.ShowCrosshairsOnAim;
|
||||
UnityEngineUtility.SizeSprite(m_CenterCrosshairsImage.sprite, m_CenterRectTransform);
|
||||
} else {
|
||||
m_CenterCrosshairsImage.enabled = false;
|
||||
}
|
||||
if (m_LeftCrosshairsImage != null) {
|
||||
m_LeftCrosshairsImage.sprite = m_EquippedItem.LeftCrosshairs;
|
||||
if (m_LeftCrosshairsImage.sprite != null) {
|
||||
m_LeftCrosshairsImage.enabled = !m_Aiming || m_EquippedItem.ShowCrosshairsOnAim;
|
||||
PositionSprite(m_LeftRectTransform, -m_EquippedItem.QuadrantOffset, 0);
|
||||
UnityEngineUtility.SizeSprite(m_LeftCrosshairsImage.sprite, m_LeftRectTransform);
|
||||
} else {
|
||||
m_LeftCrosshairsImage.enabled = false;
|
||||
}
|
||||
}
|
||||
if (m_TopCrosshairsImage != null) {
|
||||
m_TopCrosshairsImage.sprite = m_EquippedItem.TopCrosshairs;
|
||||
if (m_TopCrosshairsImage.sprite != null) {
|
||||
m_TopCrosshairsImage.enabled = !m_Aiming || m_EquippedItem.ShowCrosshairsOnAim;
|
||||
PositionSprite(m_TopRectTransform, 0, m_EquippedItem.QuadrantOffset);
|
||||
UnityEngineUtility.SizeSprite(m_TopCrosshairsImage.sprite, m_TopRectTransform);
|
||||
} else {
|
||||
m_TopCrosshairsImage.enabled = false;
|
||||
}
|
||||
}
|
||||
if (m_RightCrosshairsImage != null) {
|
||||
m_RightCrosshairsImage.sprite = m_EquippedItem.RightCrosshairs;
|
||||
if (m_RightCrosshairsImage.sprite != null) {
|
||||
m_RightCrosshairsImage.enabled = !m_Aiming || m_EquippedItem.ShowCrosshairsOnAim;
|
||||
PositionSprite(m_RightRectTransform, m_EquippedItem.QuadrantOffset, 0);
|
||||
UnityEngineUtility.SizeSprite(m_RightCrosshairsImage.sprite, m_RightRectTransform);
|
||||
} else {
|
||||
m_RightCrosshairsImage.enabled = false;
|
||||
}
|
||||
}
|
||||
if (m_BottomCrosshairsImage != null) {
|
||||
m_BottomCrosshairsImage.sprite = m_EquippedItem.BottomCrosshairs;
|
||||
if (m_BottomCrosshairsImage.sprite != null) {
|
||||
m_BottomCrosshairsImage.enabled = !m_Aiming || m_EquippedItem.ShowCrosshairsOnAim;
|
||||
PositionSprite(m_BottomRectTransform, 0, -m_EquippedItem.QuadrantOffset);
|
||||
UnityEngineUtility.SizeSprite(m_BottomCrosshairsImage.sprite, m_BottomRectTransform);
|
||||
} else {
|
||||
m_BottomCrosshairsImage.enabled = false;
|
||||
}
|
||||
}
|
||||
m_EquippedItemCount++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The DominantItem field has been updated for the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The Item whose DominantItem field was updated.</param>
|
||||
/// <param name="dominantItem">True if the item is now a dominant item.</param>
|
||||
private void OnUpdateDominantItem(Item item, bool dominantItem)
|
||||
{
|
||||
if (item.DominantItem && item.IsActive()) {
|
||||
OnEquipItem(item, -1);
|
||||
} else if (m_EquippedItem == item) {
|
||||
m_EquippedItemCount--;
|
||||
if (m_EquippedItemCount == 0) {
|
||||
ResetMonitor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An item has been unequipped.
|
||||
/// </summary>
|
||||
/// <param name="item">The unequipped item.</param>
|
||||
/// <param name="slotID">The slot that the item previously occupied.</param>
|
||||
private void OnUnequipItem(Item item, int slotID)
|
||||
{
|
||||
if (item != m_EquippedItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_EquippedItemCount--;
|
||||
if (m_EquippedItemCount == 0) {
|
||||
ResetMonitor();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the monitor back to the default state.
|
||||
/// </summary>
|
||||
private void ResetMonitor()
|
||||
{
|
||||
m_EquippedItem = null;
|
||||
m_EquippedItemCount = 0;
|
||||
m_CenterCrosshairsImage.sprite = m_DefaultSprite;
|
||||
m_CenterCrosshairsImage.enabled = m_DefaultSprite != null;
|
||||
if (m_LeftCrosshairsImage != null) {
|
||||
m_LeftCrosshairsImage.sprite = null;
|
||||
m_LeftCrosshairsImage.enabled = false;
|
||||
}
|
||||
if (m_TopCrosshairsImage != null) {
|
||||
m_TopCrosshairsImage.sprite = null;
|
||||
m_TopCrosshairsImage.enabled = false;
|
||||
}
|
||||
if (m_RightCrosshairsImage != null) {
|
||||
m_RightCrosshairsImage.sprite = null;
|
||||
m_RightCrosshairsImage.enabled = false;
|
||||
}
|
||||
if (m_BottomCrosshairsImage != null) {
|
||||
m_BottomCrosshairsImage.sprite = null;
|
||||
m_BottomCrosshairsImage.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Positions the sprite according to the specified x and y position.
|
||||
/// </summary>
|
||||
/// <param name="spriteRectTransform">The transform to position.</param>
|
||||
/// <param name="xPosition">The x position of the sprite.</param>
|
||||
/// <param name="yPosition">The y position of the sprite.</param>
|
||||
private void PositionSprite(RectTransform spriteRectTransform, float xPosition, float yPosition)
|
||||
{
|
||||
var position = spriteRectTransform.localPosition;
|
||||
position.x = xPosition;
|
||||
position.y = yPosition;
|
||||
spriteRectTransform.localPosition = position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a force to the quadrant recoil spring.
|
||||
/// </summary>
|
||||
/// <param name="start">Is the spread just starting?</param>
|
||||
/// <param name="fromRecoil">Is the spread being added from a recoil?</param>
|
||||
private void OnAddCrosshairsSpread(bool start, bool fromRecoil)
|
||||
{
|
||||
if (m_EquippedItem == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (start) {
|
||||
m_CurrentCrosshairsSpread = fromRecoil ? m_EquippedItem.MaxQuadrantSpread : 0;
|
||||
m_TargetCrosshairsSpread = fromRecoil ? 0 : m_EquippedItem.MaxQuadrantSpread;
|
||||
} else {
|
||||
m_TargetCrosshairsSpread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Aim ability has started or stopped.
|
||||
/// </summary>
|
||||
/// <param name="start">Has the Aim ability started?</param>
|
||||
/// <param name="inputStart">Was the ability started from input?</param>
|
||||
private void OnAim(bool aim, bool inputStart)
|
||||
{
|
||||
if (!inputStart) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Aiming = aim;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the crosshairs image.
|
||||
/// </summary>
|
||||
/// <param name="enable">Should the crosshairs be enabled?</param>
|
||||
private void EnableCrosshairsImage(bool enable)
|
||||
{
|
||||
m_CenterCrosshairsImage.enabled = enable && m_CenterCrosshairsImage.sprite != null;
|
||||
if (m_LeftCrosshairsImage != null) m_LeftCrosshairsImage.enabled = enable && m_LeftCrosshairsImage.sprite != null;
|
||||
if (m_TopCrosshairsImage != null) m_TopCrosshairsImage.enabled = enable && m_TopCrosshairsImage.sprite != null;
|
||||
if (m_RightCrosshairsImage != null) m_RightCrosshairsImage.enabled = enable && m_RightCrosshairsImage.sprite != null;
|
||||
if (m_BottomCrosshairsImage != null) m_BottomCrosshairsImage.enabled = enable && m_BottomCrosshairsImage.sprite != null;
|
||||
if (!enable) { m_TargetCrosshairsSpread = m_CurrentCrosshairsSpread = 0; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The character has died.
|
||||
/// </summary>
|
||||
/// <param name="position">The position of the force.</param>
|
||||
/// <param name="force">The amount of force which killed the character.</param>
|
||||
/// <param name="attacker">The GameObject that killed the character.</param>
|
||||
private void OnDeath(Vector3 position, Vector3 force, GameObject attacker)
|
||||
{
|
||||
if (m_DisableOnDeath) {
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The character has respawned.
|
||||
/// </summary>
|
||||
private void OnRespawn()
|
||||
{
|
||||
if (m_DisableOnDeath && base.CanShowUI()) {
|
||||
m_GameObject.SetActive(true);
|
||||
}
|
||||
|
||||
// Force the crosshairs to update so the color will be correct.
|
||||
Update();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the UI be shown?
|
||||
/// </summary>
|
||||
/// <returns>True if the UI can be shown.</returns>
|
||||
protected override bool CanShowUI()
|
||||
{
|
||||
return base.CanShowUI() && (!m_DisableOnDeath || m_CharacterLocomotion.Alive);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9f656d2669e5794eac60f129fc8fcbb
|
||||
timeCreated: 1518280555
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 600
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,271 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.UI
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.Shared.Utility;
|
||||
using Opsive.UltimateCharacterController.Character;
|
||||
using Opsive.UltimateCharacterController.Utility;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// The DamageIndicatorMonitor will show a directional arrow of the direction that the character was damaged from.
|
||||
/// </summary>
|
||||
public class DamageIndicatorMonitor : CharacterMonitor
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates the direction that the character took damage.
|
||||
/// </summary>
|
||||
private struct DamageIndicator
|
||||
{
|
||||
[Tooltip("The GameObject that did the damage.")]
|
||||
private Transform m_Attacker;
|
||||
[Tooltip("The position that the character was hit.")]
|
||||
private Vector3 m_Position;
|
||||
[Tooltip("The angle of the indicator.")]
|
||||
private float m_Angle;
|
||||
[Tooltip("The time that the indicator was shown.")]
|
||||
private float m_DisplayTime;
|
||||
[Tooltip("A reference to the indicator's GameObject.")]
|
||||
private GameObject m_GameObject;
|
||||
[Tooltip("A reference to the indicator's rect transform.")]
|
||||
private RectTransform m_RectTransform;
|
||||
[Tooltip("A reference to the indicator's image.")]
|
||||
private Image m_Image;
|
||||
|
||||
public Transform Attacker { get { return m_Attacker; } }
|
||||
public Vector3 Position { get { return m_Position; } }
|
||||
public float Angle { get { return m_Angle; } set { m_Angle = value; } }
|
||||
public float DisplayTime { get { return m_DisplayTime; } set { m_DisplayTime = value; } }
|
||||
public GameObject GameObject { get { return m_GameObject; } }
|
||||
public RectTransform RectTransform { get { return m_RectTransform; } }
|
||||
public Image Image { get { return m_Image; } }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the pooled HitIndicator values.
|
||||
/// </summary>
|
||||
/// <param name="attacker">The GameObject that did the damage.</param>
|
||||
/// <param name="angle">The angle of the indicator.</param>
|
||||
/// <param name="image">A reference to the GameObject of the indicator.</param>
|
||||
public void Initialize(Transform attacker, Vector3 position, float angle, GameObject gameObject)
|
||||
{
|
||||
m_Attacker = attacker;
|
||||
m_Position = position;
|
||||
m_GameObject = gameObject;
|
||||
m_RectTransform = gameObject.GetComponent<RectTransform>();
|
||||
m_Image = gameObject.GetComponent<Image>();
|
||||
m_DisplayTime = Time.time;
|
||||
m_GameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
[Tooltip("Should the indicator be shown even if there isn't a force associated with the damage event?")]
|
||||
[SerializeField] protected bool m_AlwaysShowIndicator;
|
||||
[Tooltip("Should the indicator follow the position changes of the attacker?")]
|
||||
[SerializeField] protected bool m_FollowAttacker = true;
|
||||
[Tooltip("Prevents a new hit indicator from appearing if the angle is less than this threshold compared to an already displayed indicator.")]
|
||||
[SerializeField] protected float m_IndicatorAngleThreshold = 20;
|
||||
[Tooltip("The offset of the indicator from the center of the screen.")]
|
||||
[SerializeField] protected float m_IndicatorOffset = 50;
|
||||
[Tooltip("The amount of time that the indicator should be fully visible for.")]
|
||||
[SerializeField] protected float m_IndicatorVisiblityTime = 2;
|
||||
[Tooltip("The amount of time it takes for the indicator to fade.")]
|
||||
[SerializeField] protected float m_IndicatorFadeTime = 1;
|
||||
|
||||
public bool AlwaysShowIndicator { get { return m_AlwaysShowIndicator; } set { m_AlwaysShowIndicator = value; } }
|
||||
public bool FollowAttacker { get { return m_FollowAttacker; } set { m_FollowAttacker = value; } }
|
||||
public float IndicatorAngleTreshold { get { return m_IndicatorAngleThreshold; } set { m_IndicatorAngleThreshold = value; } }
|
||||
public float IndicatorOffset { get { return m_IndicatorOffset; } set { m_IndicatorOffset = value; } }
|
||||
public float IndicatorVisiblityTime { get { return m_IndicatorVisiblityTime; } set { m_IndicatorVisiblityTime = value; } }
|
||||
public float IndicatorFadeTime { get { return m_IndicatorFadeTime; } set { m_IndicatorFadeTime = value; } }
|
||||
|
||||
private GameObject m_GameObject;
|
||||
private Transform m_CameraTransform;
|
||||
private Transform m_CharacterTransform;
|
||||
private UltimateCharacterLocomotion m_CharacterLocomotion;
|
||||
|
||||
private int m_ActiveDamageIndicatorCount;
|
||||
private DamageIndicator[] m_ActiveDamageIndicators;
|
||||
private GameObject[] m_StoredIndicators;
|
||||
private int m_DamageIndicatorIndex;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_GameObject = gameObject;
|
||||
|
||||
var images = GetComponentsInChildren<Image>(true);
|
||||
m_StoredIndicators = new GameObject[images.Length];
|
||||
m_ActiveDamageIndicators = new DamageIndicator[m_StoredIndicators.Length];
|
||||
for (int i = 0; i < m_StoredIndicators.Length; ++i) {
|
||||
m_StoredIndicators[i] = images[i].gameObject;
|
||||
m_StoredIndicators[i].SetActive(false);
|
||||
}
|
||||
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the monitor to the specified character.
|
||||
/// </summary>
|
||||
/// <param name="character">The character to attach the monitor to.</param>
|
||||
protected override void OnAttachCharacter(GameObject character)
|
||||
{
|
||||
if (m_Character != null) {
|
||||
EventHandler.UnregisterEvent<float, Vector3, Vector3, GameObject, Collider>(m_Character, "OnHealthDamage", OnDamage);
|
||||
EventHandler.UnregisterEvent(m_Character, "OnRespawn", OnRespawn);
|
||||
m_CameraTransform = null;
|
||||
}
|
||||
|
||||
base.OnAttachCharacter(character);
|
||||
|
||||
if (m_Character == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// A camera must exist.
|
||||
var camera = UnityEngineUtility.FindCamera(m_Character);
|
||||
if (camera != null) {
|
||||
m_CameraTransform = camera.transform;
|
||||
}
|
||||
if (m_CameraTransform == null) {
|
||||
Debug.LogError("Error: The Damage Indicator Monitor must have a camera attached to the character.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_CharacterTransform = m_Character.transform;
|
||||
m_CharacterLocomotion = m_Character.GetCachedComponent<UltimateCharacterLocomotion>();
|
||||
EventHandler.RegisterEvent<float, Vector3, Vector3, GameObject, Collider>(m_Character, "OnHealthDamage", OnDamage);
|
||||
EventHandler.RegisterEvent(m_Character, "OnRespawn", OnRespawn);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object has taken damage.
|
||||
/// </summary>
|
||||
/// <param name="amount">The amount of damage taken.</param>
|
||||
/// <param name="position">The position of the damage.</param>
|
||||
/// <param name="force">The amount of force applied to the object while taking the damage.</param>
|
||||
/// <param name="attacker">The GameObject that did the damage.</param>
|
||||
/// <param name="hitCollider">The Collider that was hit.</param>
|
||||
private void OnDamage(float amount, Vector3 position, Vector3 force, GameObject attacker, Collider hitCollider)
|
||||
{
|
||||
// Don't show a hit indicator if the force is 0 or there is no attacker. This prevents damage such as fall damage from showing the damage indicator.
|
||||
if ((!m_AlwaysShowIndicator && force.sqrMagnitude == 0) || attacker == null || m_ActiveDamageIndicatorCount == m_ActiveDamageIndicators.Length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var direction = Vector3.ProjectOnPlane(m_CharacterTransform.position - ((m_FollowAttacker && m_Character != attacker) ? attacker.transform.position : position),
|
||||
m_CharacterLocomotion.Up);
|
||||
// The hit indicator is shown on a 2D canvas so the y direction should be ignored.
|
||||
direction.y = 0;
|
||||
direction.Normalize();
|
||||
|
||||
// Determine the angle of the damage position to determine if a new damage indicator should be shown.
|
||||
var angle = Vector3.Angle(direction, m_CameraTransform.forward) * Mathf.Sign(Vector3.Dot(direction, m_CameraTransform.right));
|
||||
|
||||
// Do not show a new damage indicator if the angle is less than a threshold compared to the already displayed indicators.
|
||||
DamageIndicator damageIndicator;
|
||||
for (int i = 0; i < m_ActiveDamageIndicatorCount; ++i) {
|
||||
damageIndicator = m_ActiveDamageIndicators[i];
|
||||
if (Mathf.Abs(angle - damageIndicator.Angle) < m_IndicatorAngleThreshold) {
|
||||
damageIndicator.DisplayTime = Time.time;
|
||||
m_ActiveDamageIndicators[i] = damageIndicator;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the indicator to the active hit indicators list and enable the component.
|
||||
damageIndicator = GenericObjectPool.Get<DamageIndicator>();
|
||||
damageIndicator.Initialize(attacker.transform, position, angle, m_StoredIndicators[m_DamageIndicatorIndex]);
|
||||
m_ActiveDamageIndicators[m_ActiveDamageIndicatorCount] = damageIndicator;
|
||||
m_ActiveDamageIndicatorCount++;
|
||||
m_DamageIndicatorIndex = (m_DamageIndicatorIndex + 1) % m_StoredIndicators.Length;
|
||||
|
||||
// Allow the indicators to move/fade.
|
||||
m_GameObject.SetActive(true);
|
||||
}
|
||||
/// <summary>
|
||||
/// One or more hit indicators are shown.
|
||||
/// </summary>
|
||||
private void Update()
|
||||
{
|
||||
for (int i = m_ActiveDamageIndicatorCount - 1; i > -1; --i) {
|
||||
// The alpha value is determined by the amount of time the damage indicator has been visible. The indicator should be visible for a time of m_IndicatorVisiblityTime
|
||||
// with no fading. After m_IndicatorVisiblityTime the indicator should fade for visibilityTime.
|
||||
var alpha = (m_IndicatorFadeTime - (Time.time - (m_ActiveDamageIndicators[i].DisplayTime + m_IndicatorVisiblityTime))) / m_IndicatorFadeTime;
|
||||
if (alpha <= 0) {
|
||||
m_ActiveDamageIndicators[i].GameObject.SetActive(false);
|
||||
GenericObjectPool.Return(m_ActiveDamageIndicators[i]);
|
||||
m_ActiveDamageIndicatorCount--;
|
||||
// Sort the array so the complete indicators are at the end.
|
||||
for (int j = i; j < m_ActiveDamageIndicatorCount; ++j) {
|
||||
m_ActiveDamageIndicators[j] = m_ActiveDamageIndicators[j + 1];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
var color = m_ActiveDamageIndicators[i].Image.color;
|
||||
color.a = alpha;
|
||||
m_ActiveDamageIndicators[i].Image.color = color;
|
||||
|
||||
var direction = Vector3.ProjectOnPlane(m_CharacterTransform.position - ((m_FollowAttacker && m_CharacterTransform != m_ActiveDamageIndicators[i].Attacker) ?
|
||||
m_ActiveDamageIndicators[i].Attacker.position : m_ActiveDamageIndicators[i].Position),
|
||||
m_CharacterLocomotion.Up);
|
||||
// The hit indicator is shown on a 2D canvas so the y direction should be ignored.
|
||||
direction.y = 0;
|
||||
direction.Normalize();
|
||||
|
||||
var angle = Vector3.Angle(direction, m_CameraTransform.forward) * Mathf.Sign(Vector3.Dot(direction, m_CameraTransform.right));
|
||||
m_ActiveDamageIndicators[i].Angle = angle;
|
||||
|
||||
// Face the image in the direction of the angle.
|
||||
var rotation = m_ActiveDamageIndicators[i].RectTransform.localEulerAngles;
|
||||
rotation.z = -m_ActiveDamageIndicators[i].Angle;
|
||||
m_ActiveDamageIndicators[i].RectTransform.localEulerAngles = rotation;
|
||||
|
||||
// Position the indicator relative to the direction.
|
||||
var position = m_ActiveDamageIndicators[i].RectTransform.localPosition;
|
||||
position.x = -Mathf.Sin(m_ActiveDamageIndicators[i].Angle * Mathf.Deg2Rad) * m_IndicatorOffset;
|
||||
position.y = -Mathf.Cos(m_ActiveDamageIndicators[i].Angle * Mathf.Deg2Rad) * m_IndicatorOffset;
|
||||
m_ActiveDamageIndicators[i].RectTransform.localPosition = position;
|
||||
}
|
||||
|
||||
// The component can be disabled when the damage indicators have disappeared.
|
||||
if (m_ActiveDamageIndicatorCount == 0) {
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The character has respawned.
|
||||
/// </summary>
|
||||
private void OnRespawn()
|
||||
{
|
||||
// No indicators should be shown when the character respawns.
|
||||
for (int i = m_ActiveDamageIndicatorCount - 1; i > -1; --i) {
|
||||
m_ActiveDamageIndicators[i].GameObject.SetActive(false);
|
||||
GenericObjectPool.Return(m_ActiveDamageIndicators[i]);
|
||||
}
|
||||
m_ActiveDamageIndicatorCount = 0;
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the UI be shown?
|
||||
/// </summary>
|
||||
/// <returns>True if the UI can be shown.</returns>
|
||||
protected override bool CanShowUI()
|
||||
{
|
||||
return base.CanShowUI() && m_ActiveDamageIndicatorCount > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9bebab3f9cb721428dfc4e9edb0d3b9
|
||||
timeCreated: 1529078902
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,88 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.UI
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.UltimateCharacterController.Character;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// The FullScreenItemUIMonitor will show the full screen item UI when the OnItemShowFullScreenUI event is triggered.
|
||||
/// </summary>
|
||||
public class FullScreenItemUIMonitor : CharacterMonitor
|
||||
{
|
||||
[Tooltip("Should the crosshairs be shown?")]
|
||||
[SerializeField] protected int m_ID;
|
||||
|
||||
public int ID { get { return m_ID; } set { m_ID = value; } }
|
||||
|
||||
private UltimateCharacterLocomotion m_CharacterController;
|
||||
private GameObject m_GameObject;
|
||||
private bool m_FullScreenUIShown;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_GameObject = gameObject;
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the monitor to the specified character.
|
||||
/// </summary>
|
||||
/// <param name="character">The character to attach the monitor to.</param>
|
||||
protected override void OnAttachCharacter(GameObject character)
|
||||
{
|
||||
if (m_Character != null) {
|
||||
EventHandler.UnregisterEvent<int, bool>(m_Character, "OnItemShowFullScreenUI", OnShowItemUI);
|
||||
}
|
||||
|
||||
base.OnAttachCharacter(character);
|
||||
|
||||
if (m_Character == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventHandler.RegisterEvent<int, bool>(m_Character, "OnItemShowFullScreenUI", OnShowItemUI);
|
||||
m_CharacterController = m_Character.GetCachedComponent<UltimateCharacterLocomotion>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows or hides the full screen item UI.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the UI that should be shown or hidden.</param>
|
||||
/// <param name="show">Should the UI be shown?</param>
|
||||
private void OnShowItemUI(int id, bool show)
|
||||
{
|
||||
if (id == -1 || id != m_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_FullScreenUIShown = show;
|
||||
|
||||
// Independent look movement types don't look in the direction of the camera so they shouldn't show the full screen UI.
|
||||
if (m_CharacterController.ActiveMovementType.UseIndependentLook(false)) {
|
||||
show = false;
|
||||
}
|
||||
m_GameObject.SetActive(m_ShowUI && show);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the UI be shown?
|
||||
/// </summary>
|
||||
/// <returns>True if the UI can be shown.</returns>
|
||||
protected override bool CanShowUI()
|
||||
{
|
||||
return base.CanShowUI() && m_FullScreenUIShown;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 502f28110d763fc4da5fadfbb4ea3825
|
||||
timeCreated: 1518280555
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 600
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,180 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.UI
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// The HealthFlashMonitor will show a full screen flash when the character takes damage or is healed.
|
||||
/// </summary>
|
||||
public class HealthFlashMonitor : CharacterMonitor
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores the flash settings.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public struct Flash
|
||||
{
|
||||
[Tooltip("Can the flash be activated?")]
|
||||
[SerializeField] private bool m_CanActivate;
|
||||
[Tooltip("The amount of time the flash should be fully visible for.")]
|
||||
[SerializeField] private float m_VisiblityDuration;
|
||||
[Tooltip("The amount of time it takes the flash UI to fade.")]
|
||||
[SerializeField] private float m_FadeDuration;
|
||||
[Tooltip("The color of the image flash.")]
|
||||
[SerializeField] private Color m_Color;
|
||||
[Tooltip("The image of the flash.")]
|
||||
[SerializeField] private Sprite m_Sprite;
|
||||
|
||||
public bool CanActivate { get { return m_CanActivate; } }
|
||||
public float VisiblityDuration { get { return m_VisiblityDuration; } }
|
||||
public float FadeDuration { get { return m_FadeDuration; } }
|
||||
public Color Color { get { return m_Color; } }
|
||||
public Sprite Sprite { get { return m_Sprite; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for the flash struct.
|
||||
/// </summary>
|
||||
/// <param name="canActivate">Can the flash be activated?</param>
|
||||
/// <param name="color">The amount of time the flash should be fully visible for.</param>
|
||||
/// <param name="visibilityDuration">The amount of time it takes the flash UI to fade.</param>
|
||||
/// <param name="fadeDuration">The amount of time it takes the flash UI to fade.</param>
|
||||
public Flash(bool canActivate, Color color, float visibilityDuration, float fadeDuration)
|
||||
{
|
||||
m_CanActivate = canActivate;
|
||||
m_Color = color;
|
||||
m_VisiblityDuration = visibilityDuration;
|
||||
m_FadeDuration = fadeDuration;
|
||||
m_Sprite = null;
|
||||
}
|
||||
}
|
||||
|
||||
[Tooltip("The flash when the character is damaged.")]
|
||||
[SerializeField] protected Flash m_DamageFlash = new Flash(true, new Color(1, 0, 0, 0.7f), 1.5f, 1f);
|
||||
[Tooltip("The flash when the character is healed.")]
|
||||
[SerializeField] protected Flash m_HealFlash = new Flash(true, new Color(1, 1, 1, 0.2f), 0.05f, 0.2f);
|
||||
|
||||
public Flash DamageFlash { get { return m_DamageFlash; } set { m_DamageFlash = value; } }
|
||||
public Flash HealFlash { get { return m_HealFlash; } set { m_HealFlash = value; } }
|
||||
|
||||
private GameObject m_GameObject;
|
||||
private Image m_FlashImage;
|
||||
private float m_FlashDisplayTime;
|
||||
private Flash m_ActiveFlash;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_FlashImage = GetComponentInChildren<Image>();
|
||||
if (m_FlashImage == null) {
|
||||
Debug.LogError("Error: Unable to find an Image component for the damage flash. Disabling.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_FlashImage.color = Color.clear;
|
||||
m_GameObject = gameObject;
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the monitor to the specified character.
|
||||
/// </summary>
|
||||
/// <param name="character">The character to attach the monitor to.</param>
|
||||
protected override void OnAttachCharacter(GameObject character)
|
||||
{
|
||||
if (m_Character != null) {
|
||||
EventHandler.UnregisterEvent<float, Vector3, Vector3, GameObject, Collider>(m_Character, "OnHealthDamage", OnDamage);
|
||||
EventHandler.UnregisterEvent<float>(m_Character, "OnHealthHeal", OnHeal);
|
||||
}
|
||||
|
||||
base.OnAttachCharacter(character);
|
||||
|
||||
if (m_Character == null || m_GameObject == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventHandler.RegisterEvent<float, Vector3, Vector3, GameObject, Collider>(m_Character, "OnHealthDamage", OnDamage);
|
||||
EventHandler.RegisterEvent<float>(m_Character, "OnHealthHeal", OnHeal);
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object has taken damage.
|
||||
/// </summary>
|
||||
/// <param name="amount">The amount of damage taken.</param>
|
||||
/// <param name="position">The position of the damage.</param>
|
||||
/// <param name="force">The amount of force applied to the object while taking the damage.</param>
|
||||
/// <param name="attacker">The GameObject that did the damage.</param>
|
||||
/// <param name="hitCollider">The Collider that was hit.</param>
|
||||
private void OnDamage(float amount, Vector3 position, Vector3 force, GameObject attacker, Collider hitCollider)
|
||||
{
|
||||
if (!m_DamageFlash.CanActivate) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show the flash image.
|
||||
m_ActiveFlash = m_DamageFlash;
|
||||
m_FlashImage.color = m_DamageFlash.Color;
|
||||
m_FlashImage.sprite = m_DamageFlash.Sprite;
|
||||
m_FlashDisplayTime = Time.time;
|
||||
|
||||
// Allow the flash to fade.
|
||||
m_GameObject.SetActive(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object has healed.
|
||||
/// </summary>
|
||||
/// <param name="amount">The amount that the object was healed by.</param>
|
||||
private void OnHeal(float amount)
|
||||
{
|
||||
if (!m_HealFlash.CanActivate) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show the flash image.
|
||||
m_ActiveFlash = m_HealFlash;
|
||||
m_FlashImage.color = m_HealFlash.Color;
|
||||
m_FlashImage.sprite = m_HealFlash.Sprite;
|
||||
m_FlashDisplayTime = Time.time;
|
||||
|
||||
// Allow the flash to fade.
|
||||
m_GameObject.SetActive(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fade the flash.
|
||||
/// </summary>
|
||||
private void Update()
|
||||
{
|
||||
// Update the flash alpha.
|
||||
var alpha = Mathf.Min((m_ActiveFlash.FadeDuration - (Time.time - (m_FlashDisplayTime + m_ActiveFlash.VisiblityDuration))) / m_ActiveFlash.FadeDuration, 1) * m_ActiveFlash.Color.a;
|
||||
var color = m_FlashImage.color;
|
||||
color.a = alpha;
|
||||
m_FlashImage.color = color;
|
||||
|
||||
if (alpha <= 0) {
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the UI be shown?
|
||||
/// </summary>
|
||||
/// <returns>True if the UI can be shown.</returns>
|
||||
protected override bool CanShowUI()
|
||||
{
|
||||
return m_FlashImage.color.a > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2df1debe593a5a447bac893a323e2e86
|
||||
timeCreated: 1529078902
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,89 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.UI
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.Shared.Inventory;
|
||||
using Opsive.UltimateCharacterController.Items;
|
||||
using Opsive.UltimateCharacterController.Inventory;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// The ItemMonitor will update the UI for the character's items.
|
||||
/// </summary>
|
||||
public abstract class ItemMonitor : CharacterMonitor
|
||||
{
|
||||
[Tooltip("A reference to the text used for primary ItemType count.")]
|
||||
[SerializeField] protected Text m_PrimaryCount;
|
||||
|
||||
protected InventoryBase m_CharacterInventory;
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the monitor to the specified character.
|
||||
/// </summary>
|
||||
/// <param name="character">The character to attach the monitor to.</param>
|
||||
protected override void OnAttachCharacter(GameObject character)
|
||||
{
|
||||
if (m_Character != null) {
|
||||
EventHandler.UnregisterEvent<IItemIdentifier, int, bool, bool>(m_Character, "OnInventoryPickupItemIdentifier", OnPickupItemIdentifier);
|
||||
EventHandler.UnregisterEvent<Item, bool>(m_Character, "OnItemUpdateDominantItem", OnUpdateDominantItem);
|
||||
EventHandler.UnregisterEvent<Item, IItemIdentifier, int>(m_Character, "OnItemUseConsumableItemIdentifier", OnUseConsumableItemIdentifier);
|
||||
EventHandler.UnregisterEvent<IItemIdentifier, int>(m_Character, "OnInventoryAdjustItemIdentifierAmount", OnAdjustItemIdentifierAmount);
|
||||
}
|
||||
|
||||
base.OnAttachCharacter(character);
|
||||
|
||||
if (m_Character == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The character must have an inventory.
|
||||
m_CharacterInventory = m_Character.GetCachedComponent<InventoryBase>();
|
||||
if (m_CharacterInventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventHandler.RegisterEvent<IItemIdentifier, int, bool, bool>(m_Character, "OnInventoryPickupItemIdentifier", OnPickupItemIdentifier);
|
||||
EventHandler.RegisterEvent<Item, bool>(m_Character, "OnItemUpdateDominantItem", OnUpdateDominantItem);
|
||||
EventHandler.RegisterEvent<Item, IItemIdentifier, int>(m_Character, "OnItemUseConsumableItemIdentifier", OnUseConsumableItemIdentifier);
|
||||
EventHandler.RegisterEvent<IItemIdentifier, int>(m_Character, "OnInventoryAdjustItemIdentifierAmount", OnAdjustItemIdentifierAmount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An ItemIdentifier has been picked up within the inventory.
|
||||
/// </summary>
|
||||
/// <param name="itemIdentifier">The ItemIdentifier that has been picked up.</param>
|
||||
/// <param name="amount">The amount of item picked up.</param>
|
||||
/// <param name="immediatePickup">Was the item be picked up immediately?</param>
|
||||
/// <param name="forceEquip">Should the item be force equipped?</param>
|
||||
protected virtual void OnPickupItemIdentifier(IItemIdentifier itemIdentifier, int amount, bool immediatePickup, bool forceEquip) { }
|
||||
|
||||
/// <summary>
|
||||
/// The DominantItem field has been updated for the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The Item whose DominantItem field was updated.</param>
|
||||
/// <param name="dominantItem">True if the item is now a dominant item.</param>
|
||||
protected virtual void OnUpdateDominantItem(Item item, bool dominantItem) { }
|
||||
|
||||
/// <summary>
|
||||
/// The specified consumable ItemIdentifier has been used.
|
||||
/// </summary>
|
||||
/// <param name="item">The Item that has been used.</param>
|
||||
/// <param name="itemIdentifier">The ItemIdentifier that has been used.</param>
|
||||
/// <param name="amount">The remaining amount of the specified IItemIdentifier.</param>
|
||||
protected virtual void OnUseConsumableItemIdentifier(Item item, IItemIdentifier itemIdentifier, int amount) { }
|
||||
|
||||
/// <summary>
|
||||
/// The specified ItemIdentifier amount has been adjusted.
|
||||
/// </summary>
|
||||
/// <param name="itemIdentifier">The ItemIdentifier to adjust.</param>
|
||||
/// <param name="amount">The amount of ItemIdentifier to adjust.</param>
|
||||
protected virtual void OnAdjustItemIdentifierAmount(IItemIdentifier itemIdentifier, int amount) { }
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10088630a24c1514f99bc290e02c7b32
|
||||
timeCreated: 1518280555
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 700
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,194 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.UI
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.UltimateCharacterController.Character.Abilities;
|
||||
using Opsive.UltimateCharacterController.Objects.CharacterAssist;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// The MessageMonitor will update the UI for any external object messages such as an ability being able to start or the character picking up an item.
|
||||
/// </summary>
|
||||
public class MessageMonitor : CharacterMonitor
|
||||
{
|
||||
[Tooltip("A reference to the object that will show the message icon.")]
|
||||
[SerializeField] protected Image m_Icon;
|
||||
[Tooltip("A reference to the object that will show the message text.")]
|
||||
[SerializeField] protected Text m_Text;
|
||||
[Tooltip("The length of time that the message should be visible for after picking up an object.")]
|
||||
[SerializeField] protected float m_ObjectVisiblityDuration = 1.5f;
|
||||
[Tooltip("The amount to fade the message after it should no longer be displayed.")]
|
||||
[SerializeField] protected float m_ObjectFadeSpeed = 0.05f;
|
||||
|
||||
private GameObject m_GameObject;
|
||||
private Ability m_Ability;
|
||||
private ObjectPickup m_ObjectPickup;
|
||||
private bool m_ShouldFade;
|
||||
private float m_ObjectAlphaColor;
|
||||
private ScheduledEventBase m_ScheduledFade;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_GameObject = gameObject;
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the monitor to the specified character.
|
||||
/// </summary>
|
||||
/// <param name="character">The character to attach the monitor to.</param>
|
||||
protected override void OnAttachCharacter(GameObject character)
|
||||
{
|
||||
if (m_Character != null) {
|
||||
EventHandler.UnregisterEvent<Ability, bool>(m_Character, "OnAbilityMessageCanStart", OnAbilityCanStart);
|
||||
EventHandler.UnregisterEvent<ObjectPickup>(m_Character, "OnObjectPickedUp", OnObjectPickedUp);
|
||||
}
|
||||
|
||||
base.OnAttachCharacter(character);
|
||||
|
||||
if (m_Character == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventHandler.RegisterEvent<Ability, bool>(m_Character, "OnAbilityMessageCanStart", OnAbilityCanStart);
|
||||
EventHandler.RegisterEvent<ObjectPickup>(m_Character, "OnObjectPickedUp", OnObjectPickedUp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The specified ability can start or no longer stop.
|
||||
/// </summary>
|
||||
/// <param name="ability">The ability that has changed start status.</param>
|
||||
/// <param name="canStart">Can the ability start?</param>
|
||||
private void OnAbilityCanStart(Ability ability, bool canStart)
|
||||
{
|
||||
// Only one ability message can be shown at a time.
|
||||
if (m_Ability != null && m_Ability != ability) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (canStart && (!string.IsNullOrEmpty(ability.AbilityMessageText) || ability.AbilityMessageIcon != null)) {
|
||||
m_Ability = ability;
|
||||
m_ShouldFade = false;
|
||||
if (m_ScheduledFade != null) {
|
||||
Scheduler.Cancel(m_ScheduledFade);
|
||||
m_ScheduledFade = null;
|
||||
}
|
||||
} else {
|
||||
m_Ability = null;
|
||||
}
|
||||
UpdateMessage();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An object has been picked up by the character.
|
||||
/// </summary>
|
||||
/// <param name="objectPickup">The object that was picked up.</param>
|
||||
private void OnObjectPickedUp(ObjectPickup objectPickup)
|
||||
{
|
||||
if ((!string.IsNullOrEmpty(objectPickup.PickupMessageText) || objectPickup.PickupMessageIcon != null)) {
|
||||
m_ObjectPickup = objectPickup;
|
||||
m_ShouldFade = true;
|
||||
m_ObjectAlphaColor = 1;
|
||||
if (m_ShouldFade) {
|
||||
Scheduler.Cancel(m_ScheduledFade);
|
||||
}
|
||||
} else {
|
||||
// Keep showing the previous object message if the new message doesn't have text or icons.
|
||||
if (m_ObjectPickup != null && m_ObjectPickup != objectPickup) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_ObjectPickup = null;
|
||||
}
|
||||
UpdateMessage();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the text and icon UI.
|
||||
/// </summary>
|
||||
private void UpdateMessage()
|
||||
{
|
||||
// Abilities have priority.
|
||||
if (m_Text != null) {
|
||||
m_Text.text = m_Ability != null ? m_Ability.AbilityMessageText : (m_ObjectPickup != null ? m_ObjectPickup.PickupMessageText : string.Empty);
|
||||
m_Text.enabled = !string.IsNullOrEmpty(m_Text.text);
|
||||
}
|
||||
if (m_Icon != null) {
|
||||
m_Icon.sprite = m_Ability != null ? m_Ability.AbilityMessageIcon : (m_ObjectPickup != null ? m_ObjectPickup.PickupMessageIcon : null);
|
||||
m_Icon.enabled = m_Icon.sprite != null;
|
||||
}
|
||||
|
||||
// The message will fade if an object is picked up.
|
||||
var messageVisible = m_Ability != null || m_ObjectPickup != null;
|
||||
if (messageVisible) {
|
||||
if (m_Text != null) {
|
||||
var color = m_Text.color;
|
||||
color.a = 1;
|
||||
m_Text.color = color;
|
||||
}
|
||||
if (m_Icon != null) {
|
||||
var color = m_Icon.color;
|
||||
color.a = 1;
|
||||
m_Icon.color = color;
|
||||
}
|
||||
|
||||
if (m_ShouldFade) {
|
||||
m_ScheduledFade = Scheduler.Schedule(m_ObjectVisiblityDuration, FadeMessage);
|
||||
}
|
||||
}
|
||||
|
||||
m_GameObject.SetActive(m_ShowUI && (messageVisible || m_ShouldFade));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fades the message according to the fade speed.
|
||||
/// </summary>
|
||||
private void FadeMessage()
|
||||
{
|
||||
m_ObjectAlphaColor = Mathf.Max(m_ObjectAlphaColor - m_ObjectFadeSpeed, 0);
|
||||
if (m_ObjectAlphaColor == 0) {
|
||||
m_GameObject.SetActive(false);
|
||||
m_ShouldFade = false;
|
||||
m_ScheduledFade = null;
|
||||
m_ObjectPickup = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Fade the text and icon.
|
||||
if (m_Text != null) {
|
||||
var color = m_Text.color;
|
||||
color.a = m_ObjectAlphaColor;
|
||||
m_Text.color = color;
|
||||
}
|
||||
if (m_Icon) {
|
||||
var color = m_Icon.color;
|
||||
color.a = m_ObjectAlphaColor;
|
||||
m_Icon.color = color;
|
||||
}
|
||||
|
||||
// Keep fading until there is nothing left to fade.
|
||||
m_ScheduledFade = Scheduler.Schedule(0.01f, FadeMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the UI be shown?
|
||||
/// </summary>
|
||||
/// <returns>True if the UI can be shown.</returns>
|
||||
protected override bool CanShowUI()
|
||||
{
|
||||
return base.CanShowUI() && (m_Ability != null || m_ObjectPickup != null || m_ShouldFade);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3c878983a99df54ebaf805160ac9330
|
||||
timeCreated: 1529078902
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,242 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.UI
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Inventory;
|
||||
using Opsive.UltimateCharacterController.Items;
|
||||
using Opsive.UltimateCharacterController.Items.Actions;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// The PersistentItemMonitor will update the UI for the specified ItemType.
|
||||
/// </summary>
|
||||
public class PersistentItemMonitor : ItemMonitor
|
||||
{
|
||||
[Tooltip("The ItemDefinition that the UI should monitor.")]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("m_ItemType")]
|
||||
[SerializeField] protected ItemDefinitionBase m_ItemDefinition;
|
||||
[Tooltip("Should the UI only be shown when the item is unequipped?")]
|
||||
[SerializeField] protected bool m_AlwaysVisible = true;
|
||||
[Tooltip("Should the UI still be shown when the character dies?")]
|
||||
[SerializeField] protected bool m_VisibleOnDeath = true;
|
||||
|
||||
public ItemDefinitionBase ItemDefinition { get { return m_ItemDefinition; } set { m_ItemDefinition = value; } }
|
||||
public bool AlwaysVisible { get { return m_AlwaysVisible; } set { m_AlwaysVisible = value; UpdateActiveState(false); } }
|
||||
public bool VisibleOnDeath { get { return m_VisibleOnDeath; } set { m_VisibleOnDeath = value; } }
|
||||
|
||||
private GameObject m_GameObject;
|
||||
private IItemIdentifier m_ItemIdentifier;
|
||||
private bool m_Alive = true;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_GameObject = gameObject;
|
||||
m_PrimaryCount.text = "0";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the monitor to the specified character.
|
||||
/// </summary>
|
||||
/// <param name="character">The character to attach the monitor to.</param>
|
||||
protected override void OnAttachCharacter(GameObject character)
|
||||
{
|
||||
if (m_Character != null) {
|
||||
EventHandler.UnregisterEvent<Item, int>(m_Character, "OnInventoryEquipItem", OnEquipItem);
|
||||
EventHandler.UnregisterEvent<Vector3, Vector3, GameObject>(m_Character, "OnDeath", OnDeath);
|
||||
EventHandler.UnregisterEvent(m_Character, "OnRespawn", OnRespawn);
|
||||
}
|
||||
|
||||
base.OnAttachCharacter(character);
|
||||
|
||||
if (m_Character == null || m_CharacterInventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventHandler.RegisterEvent<Item, int>(m_Character, "OnInventoryEquipItem", OnEquipItem);
|
||||
EventHandler.RegisterEvent<Vector3, Vector3, GameObject>(m_Character, "OnDeath", OnDeath);
|
||||
EventHandler.RegisterEvent(m_Character, "OnRespawn", OnRespawn);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An ItemIdentifier has been picked up within the inventory.
|
||||
/// </summary>
|
||||
/// <param name="itemIdentifier">The ItemIdentifier that has been picked up.</param>
|
||||
/// <param name="amount">The amount of item picked up.</param>
|
||||
/// <param name="immediatePickup">Was the item be picked up immediately?</param>
|
||||
/// <param name="forceEquip">Should the item be force equipped?</param>
|
||||
protected override void OnPickupItemIdentifier(IItemIdentifier itemIdentifier, int amount, bool immediatePickup, bool forceEquip)
|
||||
{
|
||||
if (itemIdentifier.GetItemDefinition() != m_ItemDefinition) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_ItemIdentifier = itemIdentifier;
|
||||
|
||||
if (!m_AlwaysVisible && !ShowCount()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_PrimaryCount.text = m_CharacterInventory.GetItemIdentifierAmount(itemIdentifier).ToString();
|
||||
m_GameObject.SetActive(m_ShowUI);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the ItemMonitor count should be shown.
|
||||
/// </summary>
|
||||
/// <returns>True if the ItemMonitor count should be shown.</returns>
|
||||
private bool ShowCount()
|
||||
{
|
||||
var slotsOccupied = true;
|
||||
var itemIdentifierMatch = false;
|
||||
for (int i = 0; i < m_CharacterInventory.SlotCount; ++i) {
|
||||
var item = m_CharacterInventory.GetActiveItem(i);
|
||||
if (item == null) {
|
||||
slotsOccupied = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ItemIdentifierMatch(item)) {
|
||||
itemIdentifierMatch = !item.DominantItem;
|
||||
if (!itemIdentifierMatch) {
|
||||
slotsOccupied = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !slotsOccupied || itemIdentifierMatch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An item has been equipped.
|
||||
/// </summary>
|
||||
/// <param name="item">The equipped item.</param>
|
||||
/// <param name="slotID">The slot that the item now occupies.</param>
|
||||
private void OnEquipItem(Item item, int slotID)
|
||||
{
|
||||
UpdateActiveState(!item.DominantItem && ItemIdentifierMatch(item));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The DominantItem field has been updated for the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The Item whose DominantItem field was updated.</param>
|
||||
/// <param name="dominantItem">True if the item is now a dominant item.</param>
|
||||
protected override void OnUpdateDominantItem(Item item, bool dominantItem)
|
||||
{
|
||||
if (m_CharacterInventory.GetItemIdentifierAmount(item.ItemIdentifier) == 0) {
|
||||
return;
|
||||
}
|
||||
UpdateActiveState(!item.DominantItem && ItemIdentifierMatch(item));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the GameObject's activated/deactivated state.
|
||||
/// </summary>
|
||||
/// <param name="forceActive">Should the monitor be shown even if the item isn't equipped?</param>
|
||||
private void UpdateActiveState(bool forceActive)
|
||||
{
|
||||
var active = m_ShowUI && (m_VisibleOnDeath || m_Alive) && (m_AlwaysVisible || forceActive || ShowCount());
|
||||
m_GameObject.SetActive(active);
|
||||
if (active) {
|
||||
m_PrimaryCount.text = m_CharacterInventory.GetItemIdentifierAmount(m_ItemIdentifier).ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the item match the ItemIdentifier used by the monitor?
|
||||
/// </summary>
|
||||
/// <param name="item">The item that may use the ItemIdentifier.</param>
|
||||
/// <returns>True if the item matches the ItemIdentifier used by the monitor.</returns>
|
||||
private bool ItemIdentifierMatch(Item item)
|
||||
{
|
||||
if (item.ItemIdentifier.GetItemDefinition() == m_ItemDefinition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The consumable ItemIdentifier may be specified.
|
||||
var itemActions = item.ItemActions;
|
||||
for (int i = 0; i < itemActions.Length; ++i) {
|
||||
var usableItem = itemActions[i] as IUsableItem;
|
||||
if (usableItem == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var consumableItemIdentifier = usableItem.GetConsumableItemIdentifier();
|
||||
if (consumableItemIdentifier != null && consumableItemIdentifier.GetItemDefinition() == m_ItemDefinition) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The specified consumable ItemIdentifier has been used.
|
||||
/// </summary>
|
||||
/// <param name="item">The Item that has been used.</param>
|
||||
/// <param name="itemIdentifier">The ItemIdentifier that has been used.</param>
|
||||
/// <param name="amount">The remaining amount of the specified ItemIdentifier.</param>
|
||||
protected override void OnUseConsumableItemIdentifier(Item item, IItemIdentifier itemIdentifier, int amount)
|
||||
{
|
||||
if (itemIdentifier.GetItemDefinition() != m_ItemDefinition) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_PrimaryCount.text = amount.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The specified ItemIdentifier amount has been adjusted.
|
||||
/// </summary>
|
||||
/// <param name="itemIdentifier">The ItemIdentifier to adjust.</param>
|
||||
/// <param name="amount">The amount of ItemIdentifier to adjust.</param>
|
||||
protected override void OnAdjustItemIdentifierAmount(IItemIdentifier itemIdentifier, int amount)
|
||||
{
|
||||
if (itemIdentifier.GetItemDefinition() != m_ItemDefinition) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_PrimaryCount.text = amount.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The character has died.
|
||||
/// </summary>
|
||||
/// <param name="position">The position of the force.</param>
|
||||
/// <param name="force">The amount of force which killed the character.</param>
|
||||
/// <param name="attacker">The GameObject that killed the character.</param>
|
||||
private void OnDeath(Vector3 position, Vector3 force, GameObject attacker)
|
||||
{
|
||||
m_Alive = false;
|
||||
UpdateActiveState(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The character has respawned.
|
||||
/// </summary>
|
||||
private void OnRespawn()
|
||||
{
|
||||
m_Alive = true;
|
||||
UpdateActiveState(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the UI be shown?
|
||||
/// </summary>
|
||||
/// <returns>True if the UI can be shown.</returns>
|
||||
protected override bool CanShowUI()
|
||||
{
|
||||
return base.CanShowUI() && (m_VisibleOnDeath || m_Alive) && (m_AlwaysVisible || ShowCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c91328812a38fa4e8d06b81b3e96154
|
||||
timeCreated: 1518280555
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 700
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,265 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.UI
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Inventory;
|
||||
using Opsive.UltimateCharacterController.Items;
|
||||
using Opsive.UltimateCharacterController.Items.Actions;
|
||||
using Opsive.UltimateCharacterController.Utility;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// The ItemMonitor will update the UI for the character's items.
|
||||
/// </summary>
|
||||
public class SlotItemMonitor : ItemMonitor
|
||||
{
|
||||
[SerializeField] protected GameObject m_CountParent;
|
||||
[Tooltip("A reference to the text used for the usable item loaded count.")]
|
||||
[SerializeField] protected Text m_LoadedCount;
|
||||
[Tooltip("A reference to the text used for the usable item unloaded count.")]
|
||||
[SerializeField] protected Text m_UnloadedCount;
|
||||
[Tooltip("The ID that UI represents.")]
|
||||
[SerializeField] protected int m_ID;
|
||||
[Tooltip("A reference to the image used for the item's icon.")]
|
||||
[SerializeField] protected Image m_ItemIcon;
|
||||
[Tooltip("The action ID that the UI represents.")]
|
||||
[SerializeField] protected int m_ItemActionID;
|
||||
|
||||
public Image ItemIcon { get { return m_ItemIcon; } }
|
||||
|
||||
private GameObject m_GameObject;
|
||||
|
||||
private RectTransform m_ItemRectTransform;
|
||||
private Item m_EquippedItem;
|
||||
private IItemIdentifier m_ConsumableItemIdentifier;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_GameObject = gameObject;
|
||||
if (m_ItemIcon == null) {
|
||||
m_ItemIcon = GetComponent<Image>();
|
||||
}
|
||||
m_ItemRectTransform = m_ItemIcon.GetComponent<RectTransform>();
|
||||
m_ItemIcon.sprite = null;
|
||||
|
||||
// Wait until an item has been equipped to activate.
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attaches the monitor to the specified character.
|
||||
/// </summary>
|
||||
/// <param name="character">The character to attach the monitor to.</param>
|
||||
protected override void OnAttachCharacter(GameObject character)
|
||||
{
|
||||
if (m_Character != null) {
|
||||
EventHandler.UnregisterEvent<Item, int>(m_Character, "OnAbilityWillEquipItem", OnEquipItem);
|
||||
EventHandler.UnregisterEvent<Item, int>(m_Character, "OnAbilityUnequipItemComplete", OnUnequipItem);
|
||||
EventHandler.UnregisterEvent<Item, int>(m_Character, "OnInventoryRemoveItem", OnUnequipItem);
|
||||
ResetMonitor();
|
||||
}
|
||||
|
||||
base.OnAttachCharacter(character);
|
||||
|
||||
if (m_Character == null || m_CharacterInventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventHandler.RegisterEvent<Item, int>(m_Character, "OnAbilityWillEquipItem", OnEquipItem);
|
||||
EventHandler.RegisterEvent<Item, int>(m_Character, "OnAbilityUnequipItemComplete", OnUnequipItem);
|
||||
EventHandler.RegisterEvent<Item, int>(m_Character, "OnInventoryRemoveItem", OnUnequipItem);
|
||||
// An item may already be equipped.
|
||||
for (int i = 0; i < m_CharacterInventory.SlotCount; ++i) {
|
||||
var item = m_CharacterInventory.GetActiveItem(i);
|
||||
if (item != null) {
|
||||
OnEquipItem(item, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An ItemIdentifier has been picked up within the inventory.
|
||||
/// </summary>
|
||||
/// <param name="itemIdentifier">The ItemIdentifier that has been picked up.</param>
|
||||
/// <param name="amount">The amount of item picked up.</param>
|
||||
/// <param name="immediatePickup">Was the item be picked up immediately?</param>
|
||||
/// <param name="forceEquip">Should the item be force equipped?</param>
|
||||
protected override void OnPickupItemIdentifier(IItemIdentifier itemIdentifier, int amount, bool immediatePickup, bool forceEquip)
|
||||
{
|
||||
if (itemIdentifier != m_ConsumableItemIdentifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
var countString = m_CharacterInventory.GetItemIdentifierAmount(m_ConsumableItemIdentifier).ToString();
|
||||
if (m_PrimaryCount.enabled) {
|
||||
m_PrimaryCount.text = countString;
|
||||
} else {
|
||||
m_UnloadedCount.text = countString;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An item has been equipped.
|
||||
/// </summary>
|
||||
/// <param name="item">The equipped item.</param>
|
||||
/// <param name="slotID">The slot that the item now occupies.</param>
|
||||
private void OnEquipItem(Item item, int slotID)
|
||||
{
|
||||
if (!item.DominantItem || item.UIMonitorID != m_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_EquippedItem = item;
|
||||
m_ItemIcon.sprite = item.Icon;
|
||||
UnityEngineUtility.SizeSprite(m_ItemIcon.sprite, m_ItemRectTransform);
|
||||
m_GameObject.SetActive(CanShowUI());
|
||||
|
||||
// Multiple item actions can be attached to the same item.
|
||||
ItemAction itemAction = null;
|
||||
if (m_ItemActionID < item.ItemActions.Length) {
|
||||
itemAction = item.ItemActions[m_ItemActionID];
|
||||
}
|
||||
|
||||
if (itemAction is IUsableItem) {
|
||||
var usableItem = itemAction as IUsableItem;
|
||||
if ((m_ConsumableItemIdentifier = usableItem.GetConsumableItemIdentifier()) != null) {
|
||||
var consumableItemIdentifierAmount = usableItem.GetConsumableItemIdentifierAmount();
|
||||
// If the count is -1 then only the loaded should be shown.
|
||||
if (consumableItemIdentifierAmount != -1) {
|
||||
m_LoadedCount.text = usableItem.GetConsumableItemIdentifierAmount().ToString();
|
||||
m_UnloadedCount.text = m_CharacterInventory.GetItemIdentifierAmount(usableItem.GetConsumableItemIdentifier()).ToString();
|
||||
m_LoadedCount.enabled = m_UnloadedCount.enabled = true;
|
||||
m_PrimaryCount.enabled = false;
|
||||
} else {
|
||||
m_PrimaryCount.text = m_CharacterInventory.GetItemIdentifierAmount(usableItem.GetConsumableItemIdentifier()).ToString();
|
||||
m_PrimaryCount.enabled = true;
|
||||
m_LoadedCount.enabled = m_UnloadedCount.enabled = false;
|
||||
}
|
||||
if (m_CountParent != null) {
|
||||
m_CountParent.SetActive(true);
|
||||
}
|
||||
} else {
|
||||
DisableCountText();
|
||||
}
|
||||
} else {
|
||||
DisableCountText();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the text objects.
|
||||
/// </summary>
|
||||
private void DisableCountText()
|
||||
{
|
||||
if (m_CountParent != null) {
|
||||
m_CountParent.SetActive(false);
|
||||
}
|
||||
if (m_PrimaryCount != null) {
|
||||
m_PrimaryCount.enabled = false;
|
||||
}
|
||||
if (m_LoadedCount != null) {
|
||||
m_LoadedCount.enabled = false;
|
||||
}
|
||||
if (m_UnloadedCount != null) {
|
||||
m_UnloadedCount.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The DominantItem field has been updated for the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The Item whose DominantItem field was updated.</param>
|
||||
/// <param name="dominantItem">True if the item is now a dominant item.</param>
|
||||
protected override void OnUpdateDominantItem(Item item, bool dominantItem)
|
||||
{
|
||||
if ((m_EquippedItem != null && item != m_EquippedItem) || m_CharacterInventory.GetItemIdentifierAmount(item.ItemIdentifier) == 0 || m_CharacterInventory.GetActiveItem(item.SlotID) != item) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.DominantItem) {
|
||||
OnEquipItem(item, item.SlotID);
|
||||
} else {
|
||||
ResetMonitor();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The specified consumable ItemIdentifier has been used.
|
||||
/// </summary>
|
||||
/// <param name="item">The Item that has been used.</param>
|
||||
/// <param name="itemIdentifier">The ItemIdentifier that has been used.</param>
|
||||
/// <param name="amount">The remaining amount of the specified ItemIdentifier.</param>
|
||||
protected override void OnUseConsumableItemIdentifier(Item item, IItemIdentifier itemIdentifier, int amount)
|
||||
{
|
||||
if (item.UIMonitorID != m_ID || itemIdentifier != m_ConsumableItemIdentifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_LoadedCount.text = amount.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The specified ItemIdentifier amount has been adjusted.
|
||||
/// </summary>
|
||||
/// <param name="itemIdentifier">The ItemIdentifier to adjust.</param>
|
||||
/// <param name="amount">The amount of ItemIdentifier to adjust.</param>
|
||||
protected override void OnAdjustItemIdentifierAmount(IItemIdentifier itemIdentifier, int amount)
|
||||
{
|
||||
if (itemIdentifier != m_ConsumableItemIdentifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The primary count will be disabled if the item has both a loaded and unloaded count.
|
||||
if (m_PrimaryCount.enabled) {
|
||||
m_PrimaryCount.text = amount.ToString();
|
||||
} else {
|
||||
m_UnloadedCount.text = amount.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An item has been unequipped.
|
||||
/// </summary>
|
||||
/// <param name="item">The unequipped item.</param>
|
||||
/// <param name="slotID">The slot that the item previously occupied.</param>
|
||||
private void OnUnequipItem(Item item, int slotID)
|
||||
{
|
||||
Item equippedItem = null;
|
||||
if (!item.DominantItem || item.UIMonitorID != m_ID || ((equippedItem = m_CharacterInventory.GetActiveItem(slotID)) != null && equippedItem.DominantItem && equippedItem != item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResetMonitor();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the UI be shown?
|
||||
/// </summary>
|
||||
/// <returns>True if the UI can be shown.</returns>
|
||||
protected override bool CanShowUI()
|
||||
{
|
||||
return base.CanShowUI() && m_EquippedItem != null && m_ItemIcon.sprite != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the monitor back to the default state.
|
||||
/// </summary>
|
||||
private void ResetMonitor()
|
||||
{
|
||||
m_EquippedItem = null;
|
||||
m_ConsumableItemIdentifier = null;
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cba7b223704d6c42a0a479a591fa84e
|
||||
timeCreated: 1518280555
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 700
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user