init
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using QuickOutline;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Abstract;
|
||||
using VOID.Generic.Objects.Item;
|
||||
using VOID.Generic.Objects.Unit;
|
||||
using VOID.Generic.Player.Input;
|
||||
using VOID.Generic.Player.Util;
|
||||
using VOID.Generic.Triggers;
|
||||
using VOID.UserInterface.Game.Party;
|
||||
using VOID.Generic.Util;
|
||||
using VOID.Generic.World;
|
||||
|
||||
namespace VOID.Generic.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages Highlights and Outlines of <see cref="UnitObject"/>s and <see cref="ItemObject"/>s in 2 modes:<br/>
|
||||
/// - When cursor is over specific object - highlight that object<br/>
|
||||
/// - When button is pressed - highlight all objects in range<br/>
|
||||
/// <br/>
|
||||
/// <see cref="UnitObject"/> can be selected from SCENE or <see cref="UnitPortraitUI"/>
|
||||
/// </summary>
|
||||
[DefaultExecutionOrder(-1)]
|
||||
public class HighlightManager : MonoBehaviour, IDynamicTrigger
|
||||
{
|
||||
public static HighlightManager current { get; private set; }
|
||||
|
||||
[Title("Shaders used")]
|
||||
[SerializeField] public Shader[] shaders;
|
||||
|
||||
[Title("Colors")]
|
||||
[SerializeField] private Color _enemyColor;
|
||||
[SerializeField] private Color _cautiousColor;
|
||||
[SerializeField] private Color _neutralColor;
|
||||
[SerializeField] private Color _friendlyColor;
|
||||
[SerializeField] private Color _companionColor;
|
||||
[SerializeField] private Color _selfColor;
|
||||
[SerializeField] private Color _itemColor;
|
||||
|
||||
[Title("Outline")]
|
||||
[SerializeField] private float _outlineWidth;
|
||||
[SerializeField] private Outline.Mode _outlineMode;
|
||||
|
||||
[Title("Group Outline")]
|
||||
[SerializeField] private float _range = Area.Size;
|
||||
|
||||
// Runtime
|
||||
private GameObject _highlightGameObject;
|
||||
private SphereCollider _collider;
|
||||
private Transform _stickTo;
|
||||
private readonly List<UnitObject> _unitsInRange = new();
|
||||
// private readonly List<AbstractObject> _objectsInRange = new();
|
||||
private AbstractObject _objectUnderCursor;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
current = this;
|
||||
|
||||
_highlightGameObject = new GameObject("Highlight Range");
|
||||
_highlightGameObject.transform.parent = gameObject.transform;
|
||||
_highlightGameObject.layer = LayerManager.TriggerIndex;
|
||||
_collider = _highlightGameObject.AddComponent<SphereCollider>();
|
||||
_collider.radius = _range;
|
||||
_collider.isTrigger = true;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
PlayerController.current.OnActiveUnitChange += OnActiveUnitChange;
|
||||
PlayerInputManager.current.OnHighlightStart += ShowHighlightForAllInRange;
|
||||
PlayerInputManager.current.OnHighlightEnd += HideHighlightForAllInRange;
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
StickTo();
|
||||
HighlightUnderCursor();
|
||||
}
|
||||
|
||||
private void StickTo()
|
||||
{
|
||||
if (_stickTo) _highlightGameObject.transform.position = _stickTo.position;
|
||||
}
|
||||
|
||||
private void HighlightUnderCursor()
|
||||
{
|
||||
// Find whats under cursor, we allow only ItemObject (from scene) and UnitObject (from scene and portraits)
|
||||
var select = SelectUtil.Select();
|
||||
|
||||
// There is nothing under cursor, but something was previous frame!
|
||||
if (!select.selectObject && _objectUnderCursor)
|
||||
{
|
||||
HideHighlight(_objectUnderCursor);
|
||||
_objectUnderCursor = null;
|
||||
}
|
||||
|
||||
// Nothing to highlight
|
||||
if (!select.selectObject) return;
|
||||
|
||||
// This one was already under cursor and is highlighted previously
|
||||
if (select.selectObject == _objectUnderCursor) return;
|
||||
|
||||
// There is something new under cursor - hide previous object highlight and continue
|
||||
if (_objectUnderCursor) HideHighlight(_objectUnderCursor);
|
||||
|
||||
_objectUnderCursor = select.selectObject;
|
||||
ShowHighlight(_objectUnderCursor);
|
||||
}
|
||||
|
||||
private void OnActiveUnitChange(UnitObject unitObject)
|
||||
{
|
||||
_stickTo = unitObject.transform;
|
||||
}
|
||||
|
||||
public void OnObjectEnter(AbstractObject obj)
|
||||
{
|
||||
if (obj is not UnitObject unit) return;
|
||||
_unitsInRange.Add(unit);
|
||||
if (PlayerInputManager.current.isHighlight) ShowHighlight(unit);
|
||||
}
|
||||
|
||||
public void OnObjectExit(AbstractObject obj)
|
||||
{
|
||||
if (obj is not UnitObject unit) return;
|
||||
_unitsInRange.Remove(unit);
|
||||
if (PlayerInputManager.current.isHighlight) HideHighlight(unit);
|
||||
}
|
||||
|
||||
private void ShowHighlight(AbstractObject obj)
|
||||
{
|
||||
// Highlighting only when object allow that on itself
|
||||
if (!obj.basicData.canBeSelected) return;
|
||||
|
||||
var outline = obj.gameObject.GetComponent<Outline>();
|
||||
if (!outline) outline = obj.gameObject.AddComponent<Outline>();
|
||||
|
||||
if (obj is UnitObject unit) outline.OutlineColor = GetColorForUnit(unit);
|
||||
else outline.OutlineColor = _itemColor;
|
||||
outline.OutlineMode = _outlineMode;
|
||||
outline.OutlineWidth = _outlineWidth;
|
||||
outline.enabled = true;
|
||||
}
|
||||
|
||||
private void HideHighlight(AbstractObject obj)
|
||||
{
|
||||
if (PlayerInputManager.current.isHighlight && obj is UnitObject unit && _unitsInRange.Contains(unit)) return;
|
||||
if (obj.TryGetComponent<Outline>(out var outline)) outline.enabled = false;
|
||||
}
|
||||
|
||||
private void ShowHighlightForAllInRange()
|
||||
{
|
||||
_unitsInRange.ForEach(ShowHighlight);
|
||||
}
|
||||
|
||||
private void HideHighlightForAllInRange()
|
||||
{
|
||||
_unitsInRange.ForEach(HideHighlight);
|
||||
}
|
||||
|
||||
private Color GetColorForUnit(UnitObject unit)
|
||||
{
|
||||
if (!PlayerController.current.activeUnit) return _neutralColor;
|
||||
if (unit == PlayerController.current.activeUnit) return _selfColor;
|
||||
var attitudeType = PlayerController.current.activeUnit.unitAttitude.GetAttitudeWith(unit);
|
||||
return attitudeType switch
|
||||
{
|
||||
AttitudeType.Hostile => _enemyColor,
|
||||
AttitudeType.Cautious => _cautiousColor,
|
||||
AttitudeType.Neutral => _neutralColor,
|
||||
AttitudeType.Friendly => _friendlyColor,
|
||||
AttitudeType.Companion => _companionColor,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(attitudeType), attitudeType, null)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user