This commit is contained in:
2026-06-09 09:18:17 +07:00
parent 3578a2750c
commit 71a096556a
5777 changed files with 6675 additions and 13 deletions

View File

@@ -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;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: f6cbebeb99f037f43a661f3d59fd5b70
timeCreated: 1518280555
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 400
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 61159c49be98c6e4787663a97dc9d1b7
timeCreated: 1518280555
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 500
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: d9f656d2669e5794eac60f129fc8fcbb
timeCreated: 1518280555
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 600
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: a9bebab3f9cb721428dfc4e9edb0d3b9
timeCreated: 1529078902
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 502f28110d763fc4da5fadfbb4ea3825
timeCreated: 1518280555
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 600
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 2df1debe593a5a447bac893a323e2e86
timeCreated: 1529078902
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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) { }
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 10088630a24c1514f99bc290e02c7b32
timeCreated: 1518280555
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 700
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: f3c878983a99df54ebaf805160ac9330
timeCreated: 1529078902
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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());
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 2c91328812a38fa4e8d06b81b3e96154
timeCreated: 1518280555
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 700
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 0cba7b223704d6c42a0a479a591fa84e
timeCreated: 1518280555
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 700
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: