145 lines
4.0 KiB
C#
Raw Normal View History

2025-09-24 11:24:38 +05:00
namespace TPSBR.UI
{
using UnityEngine;
using UnityEngine.UI;
public class UIMinimap : UIWidget
{
// CONSTANTS
private static readonly int ID_CIRCLE_RADIUS = Shader.PropertyToID("_CircleRadius");
private static readonly int ID_CIRCLE_CENTER = Shader.PropertyToID("_CircleCenter");
private static readonly int ID_CUTOUT_RADIUS = Shader.PropertyToID("_CutoutRadius");
private static readonly int ID_CUTOUT_CENTER = Shader.PropertyToID("_CutoutCenter");
private static readonly Vector3 MAP_CENTER_SHIFT = new Vector3(0.5f, 0f, 0.5f);
// PRIVATE MEMBERS
[SerializeField]
private RawImage _mapImage;
[SerializeField]
private Image _currentShrinkArea;
[SerializeField]
private Image _nextShrinkArea;
[SerializeField]
private RectTransform _localPlayer;
[SerializeField]
private RectTransform _airplane;
private Material _currentAreaMaterial;
private Material _nextAreaMaterial;
// UIWidget INTERFACE
protected override void OnInitialize()
{
base.OnInitialize();
_currentAreaMaterial = Instantiate(_currentShrinkArea.material);
_currentShrinkArea.material = _currentAreaMaterial;
_nextAreaMaterial = Instantiate(_nextShrinkArea.material);
_nextShrinkArea.material = _nextAreaMaterial;
}
protected override void OnDeinitialize()
{
if (_currentAreaMaterial != null)
{
Destroy(_currentAreaMaterial);
}
if (_nextAreaMaterial != null)
{
Destroy(_nextAreaMaterial);
}
}
protected override void OnTick()
{
if (Context.Runner.Exists(Context.GameplayMode.Object) == false)
return;
var map = Context.Map;
var shrinkArea = Context.GameplayMode.ShrinkingArea;
if (map.MapTexture == null)
return;
_mapImage.texture = map.MapTexture;
var mapSize = Mathf.Max(map.WorldDimensions.x, map.WorldDimensions.y);
var mapCenter = map.transform.position;
if (shrinkArea != null)
{
_currentShrinkArea.SetActive(true);
var currentCenter = (shrinkArea.Center - mapCenter) / mapSize + MAP_CENTER_SHIFT;
if (shrinkArea.IsAnnounced == true)
{
_nextShrinkArea.SetActive(true);
var nextCenter = (shrinkArea.ShrinkCenter - mapCenter) / mapSize + MAP_CENTER_SHIFT;
_nextAreaMaterial.SetFloat(ID_CIRCLE_RADIUS, shrinkArea.ShrinkRadius / mapSize);
_nextAreaMaterial.SetVector(ID_CIRCLE_CENTER, new Vector4(nextCenter.x, nextCenter.z, 0f, 0f));
_nextAreaMaterial.SetFloat(ID_CUTOUT_RADIUS, shrinkArea.Radius / mapSize);
_nextAreaMaterial.SetVector(ID_CUTOUT_CENTER, new Vector4(currentCenter.x, currentCenter.z, 0f, 0f));
}
else
{
_nextShrinkArea.SetActive(false);
}
_currentAreaMaterial.SetFloat(ID_CIRCLE_RADIUS, shrinkArea.Radius / mapSize);
_currentAreaMaterial.SetVector(ID_CIRCLE_CENTER, new Vector4(currentCenter.x, currentCenter.z, 0f, 0f));
}
else
{
_currentShrinkArea.SetActive(false);
_nextShrinkArea.SetActive(false);
}
var playerTransform = Context.ObservedAgent != null ? Context.ObservedAgent.transform : Context.WaitingAgentTransform;
if (playerTransform != null)
{
_localPlayer.SetActive(true);
UpdateMinimapObject(_localPlayer, playerTransform);
}
else
{
_localPlayer.SetActive(false);
}
if (Context.GameplayMode is BattleRoyaleGameplayMode battleRoyale && battleRoyale.Airplane != null)
{
_airplane.SetActive(true);
UpdateMinimapObject(_airplane, battleRoyale.Airplane.transform);
}
else
{
_airplane.SetActive(false);
}
}
// PRIVATE METHODS
private void UpdateMinimapObject(RectTransform minimapObject, Transform objectTransform)
{
var map = Context.Map;
int mapSize = Mathf.Max(map.WorldDimensions.x, map.WorldDimensions.y);
var objectPosition = (objectTransform.position - map.transform.position) / mapSize;
minimapObject.localPosition = new Vector2(objectPosition.x * RectTransform.sizeDelta.x, objectPosition.z * RectTransform.sizeDelta.y);
minimapObject.rotation = Quaternion.Euler(0f, 0f, -objectTransform.rotation.eulerAngles.y);
}
}
}