using UnityEngine;
using UnityEngine.UIElements;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace EasyChart.UGUI
{
///
/// Render mode for UGUIChartBridge.
///
public enum ChartRenderMode
{
///
/// Screen Space Overlay mode. Best quality, no RenderTexture.
/// Visible in Game view only.
///
ScreenSpaceOverlay,
///
/// World Space mode using RenderTexture.
/// Visible in both Scene and Game views.
/// May have slight quality differences due to RenderTexture.
///
WorldSpace
}
///
/// Bridge component that positions a ChartElement (UI Toolkit) to overlay a UGUI RectTransform.
/// Supports both Screen Space Overlay mode (default, best quality) and World Space mode (visible in Scene view).
///
/// Screen Space Overlay: Renders directly without RenderTexture, best quality.
/// World Space: Uses RenderTexture, visible in Scene view but may have slight quality differences.
///
/// Requires Unity 2021.2+.
///
[AddComponentMenu("EasyChart/UGUI Chart Bridge")]
[ExecuteAlways]
public class UGUIChartBridge : MonoBehaviour
{
[Header("Chart Configuration")]
[Tooltip("The ChartProfile to display")]
[SerializeField] private ChartProfile _profile;
[Tooltip("PanelSettings asset for UI Toolkit rendering. REQUIRED for proper font rendering.")]
[SerializeField] private PanelSettings _panelSettingsAsset;
[Header("Render Settings")]
[Tooltip("Render mode for the chart.\nScreen Space Overlay: Best quality, visible in Game view only.\nWorld Space: Visible in Scene view, uses RenderTexture.")]
[SerializeField] private ChartRenderMode _renderMode = ChartRenderMode.ScreenSpaceOverlay;
[Tooltip("If enabled, render through a RawImage/RenderTexture so the chart participates in normal UGUI masking and draw order. This fixes charts always appearing above UGUI, at the cost of using the RenderTexture path.")]
[SerializeField] private bool _respectUGUILayering = true;
[Header("Layer Settings")]
[Tooltip("Sort order for the UIDocument panel. Higher values render on top. (Screen Space Overlay only)")]
[SerializeField] private int _sortOrder = 100;
[Header("Debug")]
[Tooltip("If enabled, logs size/resolution changes (only when changed).")]
[SerializeField] private bool _logResolutionChanges = false;
private UIDocument _uiDocument;
private ChartElement _chartElement;
private RectTransform _rectTransform;
private Canvas _parentCanvas;
private VisualElement _rootContainer;
private PanelSettings _runtimePanelSettings;
private bool _createdPanelSettings;
private bool _isInitialized;
private bool _loggedOnce;
private Rect _lastScreenRect;
// World Space mode fields
private RenderTexture _renderTexture;
private UnityEngine.UI.RawImage _rawImage;
private ChartRenderMode _lastRenderMode;
private const string DefaultPanelSettingsAssetPath = "Assets/EasyChart/UGUI/Prefabs/EasyChartPanelSettings.asset";
///
/// The ChartProfile being displayed.
///
public ChartProfile Profile
{
get => _profile;
set
{
if (_profile != value)
{
_profile = value;
UpdateChartProfile();
}
}
}
///
/// The underlying ChartElement instance.
///
public ChartElement ChartElement => _chartElement;
///
/// Sort order for the UIDocument panel.
///
public int SortOrder
{
get => _sortOrder;
set
{
if (_sortOrder != value)
{
_sortOrder = value;
if (_uiDocument != null)
{
_uiDocument.sortingOrder = _sortOrder;
}
}
}
}
///
/// Render mode for the chart.
///
public ChartRenderMode RenderMode
{
get => _renderMode;
set
{
if (_renderMode != value)
{
_renderMode = value;
if (_isInitialized)
{
// Need to reinitialize with new mode
CleanupUIDocument();
CleanupWorldSpace();
_isInitialized = false;
}
}
}
}
public bool RespectUGUILayering
{
get => _respectUGUILayering;
set
{
if (_respectUGUILayering != value)
{
_respectUGUILayering = value;
if (_isInitialized)
{
CleanupUIDocument();
CleanupWorldSpace();
_isInitialized = false;
}
}
}
}
private void Awake()
{
_rectTransform = GetComponent();
_parentCanvas = GetComponentInParent