diff --git a/Assets/Code/GameState/UI/PartyGuiView.cs b/Assets/Code/GameState/UI/PartyGuiView.cs index c41dafc..c282b5c 100644 --- a/Assets/Code/GameState/UI/PartyGuiView.cs +++ b/Assets/Code/GameState/UI/PartyGuiView.cs @@ -1,8 +1,6 @@ using Jovian.Logger; -using System; using System.Collections.Generic; using Jovian.PopupSystem; -using Jovian.PopupSystem.UI; using Nox.UI; using UnityEngine; using Object = UnityEngine.Object; @@ -72,40 +70,32 @@ namespace Nox.Game.UI { slot.portrait.sprite = portraitsHolder.portraits[idx]; } - // Name - if(slot.nameText != null) { - slot.nameText.text = member.Name; - } - UpdateSlotStats(slot, member); activeSlots.Add(slot); } // Initialize all popup triggers under the container - if(popupSystem != null) { - popupSystem.InitializeTriggersInChildren(portraitsContainer, trigger => { - var slot = trigger.GetComponentInParent(); - if(slot == null) { - return; - } - var slotIndex = activeSlots.IndexOf(slot); - if(slotIndex < 0 || slotIndex >= trackedParty.members.Count) { - return; - } - var member = trackedParty.members[slotIndex]; - trigger.Initialize(popupSystem, builder => BuildCharacterPopup(builder, member)); - }); - } + popupSystem?.InitializeTriggersInChildren(portraitsContainer, (trigger, view) => { + var slot = trigger.GetComponentInParent(); + if(slot == null) { + return; + } + var slotIndex = activeSlots.IndexOf(slot); + if(slotIndex < 0 || slotIndex >= trackedParty.members.Count) { + return; + } + var member = trackedParty.members[slotIndex]; + view.SetContent(builder => BuildCharacterPopup(builder, member)); + }); } private void BuildCharacterPopup(PopupContentBuilder builder, CharacterDefinition member) { - GlobalLogger.LogInfo($"Building character popup for {member.Name}", LogCategory.UI); - // Header - builder.AddHeader(member.Name); - builder.AddText($"{member.Race} {member.Class}", "#CCCCCC"); - builder.AddText($"Role: {member.Role}"); - builder.AddSeparator(); + builder + .AddHeader(member.Name) + .AddText($"{member.Race} {member.Class}", "#CCCCCC") + .AddText($"Role: {member.Role}") + .AddSeparator(); // Stats if(member.Stats?.stats != null) { @@ -155,16 +145,10 @@ namespace Nox.Game.UI { if(slot.healthBar != null) { slot.healthBar.fillAmount = Mathf.Clamp01(health / 100f); } - if(slot.healthText != null) { - slot.healthText.text = health.ToString(); - } if(slot.manaBar != null) { slot.manaBar.fillAmount = Mathf.Clamp01(mana / 100f); } - if(slot.manaText != null) { - slot.manaText.text = mana.ToString(); - } } public void Dispose() { diff --git a/Assets/Code/GameState/UI/PartyMemberSlot.cs b/Assets/Code/GameState/UI/PartyMemberSlot.cs index af8ebec..bc4ec19 100644 --- a/Assets/Code/GameState/UI/PartyMemberSlot.cs +++ b/Assets/Code/GameState/UI/PartyMemberSlot.cs @@ -1,4 +1,3 @@ -using TMPro; using UnityEngine; using UnityEngine.UI; @@ -7,8 +6,5 @@ namespace Nox.Game.UI { public Image portrait; public Image healthBar; public Image manaBar; - public TextMeshProUGUI nameText; - public TextMeshProUGUI healthText; - public TextMeshProUGUI manaText; } } diff --git a/Assets/Prefabs/UI/CharacterCreation.meta b/Assets/Prefabs/UI/CharacterCreation.meta new file mode 100644 index 0000000..cbc5fed --- /dev/null +++ b/Assets/Prefabs/UI/CharacterCreation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 75a4a222ad797a54aac8ff58761899cf +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/UI/Attribute.prefab b/Assets/Prefabs/UI/CharacterCreation/Attribute.prefab similarity index 100% rename from Assets/Prefabs/UI/Attribute.prefab rename to Assets/Prefabs/UI/CharacterCreation/Attribute.prefab diff --git a/Assets/Prefabs/UI/Attribute.prefab.meta b/Assets/Prefabs/UI/CharacterCreation/Attribute.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/Attribute.prefab.meta rename to Assets/Prefabs/UI/CharacterCreation/Attribute.prefab.meta diff --git a/Assets/Prefabs/UI/AttributersHolder.prefab b/Assets/Prefabs/UI/CharacterCreation/AttributersHolder.prefab similarity index 100% rename from Assets/Prefabs/UI/AttributersHolder.prefab rename to Assets/Prefabs/UI/CharacterCreation/AttributersHolder.prefab diff --git a/Assets/Prefabs/UI/AttributersHolder.prefab.meta b/Assets/Prefabs/UI/CharacterCreation/AttributersHolder.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/AttributersHolder.prefab.meta rename to Assets/Prefabs/UI/CharacterCreation/AttributersHolder.prefab.meta diff --git a/Assets/Prefabs/UI/CharacterCreationReference.prefab b/Assets/Prefabs/UI/CharacterCreation/CharacterCreationReference.prefab similarity index 100% rename from Assets/Prefabs/UI/CharacterCreationReference.prefab rename to Assets/Prefabs/UI/CharacterCreation/CharacterCreationReference.prefab diff --git a/Assets/Prefabs/UI/CharacterCreationReference.prefab.meta b/Assets/Prefabs/UI/CharacterCreation/CharacterCreationReference.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/CharacterCreationReference.prefab.meta rename to Assets/Prefabs/UI/CharacterCreation/CharacterCreationReference.prefab.meta diff --git a/Assets/Prefabs/UI/DistributePointsHolder.prefab b/Assets/Prefabs/UI/CharacterCreation/DistributePointsHolder.prefab similarity index 100% rename from Assets/Prefabs/UI/DistributePointsHolder.prefab rename to Assets/Prefabs/UI/CharacterCreation/DistributePointsHolder.prefab diff --git a/Assets/Prefabs/UI/DistributePointsHolder.prefab.meta b/Assets/Prefabs/UI/CharacterCreation/DistributePointsHolder.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/DistributePointsHolder.prefab.meta rename to Assets/Prefabs/UI/CharacterCreation/DistributePointsHolder.prefab.meta diff --git a/Assets/Prefabs/UI/Dropdown.prefab b/Assets/Prefabs/UI/CharacterCreation/Dropdown.prefab similarity index 100% rename from Assets/Prefabs/UI/Dropdown.prefab rename to Assets/Prefabs/UI/CharacterCreation/Dropdown.prefab diff --git a/Assets/Prefabs/UI/Dropdown.prefab.meta b/Assets/Prefabs/UI/CharacterCreation/Dropdown.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/Dropdown.prefab.meta rename to Assets/Prefabs/UI/CharacterCreation/Dropdown.prefab.meta diff --git a/Assets/Prefabs/UI/PortraitHolder.prefab b/Assets/Prefabs/UI/CharacterCreation/PortraitHolder.prefab similarity index 100% rename from Assets/Prefabs/UI/PortraitHolder.prefab rename to Assets/Prefabs/UI/CharacterCreation/PortraitHolder.prefab diff --git a/Assets/Prefabs/UI/PortraitHolder.prefab.meta b/Assets/Prefabs/UI/CharacterCreation/PortraitHolder.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/PortraitHolder.prefab.meta rename to Assets/Prefabs/UI/CharacterCreation/PortraitHolder.prefab.meta diff --git a/Assets/Prefabs/UI/PortraitSelectionButton.prefab b/Assets/Prefabs/UI/CharacterCreation/PortraitSelectionButton.prefab similarity index 100% rename from Assets/Prefabs/UI/PortraitSelectionButton.prefab rename to Assets/Prefabs/UI/CharacterCreation/PortraitSelectionButton.prefab diff --git a/Assets/Prefabs/UI/PortraitSelectionButton.prefab.meta b/Assets/Prefabs/UI/CharacterCreation/PortraitSelectionButton.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/PortraitSelectionButton.prefab.meta rename to Assets/Prefabs/UI/CharacterCreation/PortraitSelectionButton.prefab.meta diff --git a/Assets/Prefabs/UI/Stat.prefab b/Assets/Prefabs/UI/CharacterCreation/Stat.prefab similarity index 100% rename from Assets/Prefabs/UI/Stat.prefab rename to Assets/Prefabs/UI/CharacterCreation/Stat.prefab diff --git a/Assets/Prefabs/UI/Stat.prefab.meta b/Assets/Prefabs/UI/CharacterCreation/Stat.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/Stat.prefab.meta rename to Assets/Prefabs/UI/CharacterCreation/Stat.prefab.meta diff --git a/Assets/Prefabs/UI/StatsHolder.prefab b/Assets/Prefabs/UI/CharacterCreation/StatsHolder.prefab similarity index 100% rename from Assets/Prefabs/UI/StatsHolder.prefab rename to Assets/Prefabs/UI/CharacterCreation/StatsHolder.prefab diff --git a/Assets/Prefabs/UI/StatsHolder.prefab.meta b/Assets/Prefabs/UI/CharacterCreation/StatsHolder.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/StatsHolder.prefab.meta rename to Assets/Prefabs/UI/CharacterCreation/StatsHolder.prefab.meta diff --git a/Assets/Prefabs/UI/InGameGui.meta b/Assets/Prefabs/UI/InGameGui.meta new file mode 100644 index 0000000..36190f7 --- /dev/null +++ b/Assets/Prefabs/UI/InGameGui.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b57e33c3f937ba146a2a13d68b0ce173 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/UI/GUI.prefab b/Assets/Prefabs/UI/InGameGui/GUI.prefab similarity index 100% rename from Assets/Prefabs/UI/GUI.prefab rename to Assets/Prefabs/UI/InGameGui/GUI.prefab diff --git a/Assets/Prefabs/UI/GUI.prefab.meta b/Assets/Prefabs/UI/InGameGui/GUI.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/GUI.prefab.meta rename to Assets/Prefabs/UI/InGameGui/GUI.prefab.meta diff --git a/Assets/Prefabs/UI/HeroPortrait.prefab b/Assets/Prefabs/UI/InGameGui/HeroPortrait.prefab similarity index 97% rename from Assets/Prefabs/UI/HeroPortrait.prefab rename to Assets/Prefabs/UI/InGameGui/HeroPortrait.prefab index 7424b7e..b10b134 100644 --- a/Assets/Prefabs/UI/HeroPortrait.prefab +++ b/Assets/Prefabs/UI/InGameGui/HeroPortrait.prefab @@ -92,7 +92,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!224 &7663002820715980796 RectTransform: m_ObjectHideFlags: 0 @@ -229,7 +229,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!224 &8741529769002405325 RectTransform: m_ObjectHideFlags: 0 @@ -408,7 +408,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image m_Material: {fileID: 0} - m_Color: {r: 0.6156863, g: 0.6509804, b: 0.63529414, a: 1} + m_Color: {r: 0.9818833, g: 1, b: 0, a: 1} m_RaycastTarget: 0 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 @@ -442,7 +442,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!224 &32220060764936852 RectTransform: m_ObjectHideFlags: 0 @@ -599,8 +599,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.041302264} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -0.19400787, y: -0.000015258789} - m_SizeDelta: {x: -0.38810003, y: 0} + m_AnchoredPosition: {x: -0.0000076293945, y: -0.000015258789} + m_SizeDelta: {x: 0.000022888, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &713960887884573537 CanvasRenderer: @@ -720,9 +720,6 @@ MonoBehaviour: portrait: {fileID: 1445432521138085750} healthBar: {fileID: 4550488616099254946} manaBar: {fileID: 4614622083837966787} - nameText: {fileID: 7895725010274726425} - healthText: {fileID: 2204466678496895551} - manaText: {fileID: 1991527881912334546} --- !u!114 &3828666794624103248 MonoBehaviour: m_ObjectHideFlags: 0 @@ -778,8 +775,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.041302264} m_AnchorMax: {x: 1, y: 0.041302264} - m_AnchoredPosition: {x: -0.19399261, y: -1.4669495} - m_SizeDelta: {x: -0.3880005, y: 2.6903992} + m_AnchoredPosition: {x: -0.19453812, y: -2.3094025} + m_SizeDelta: {x: -0.38894, y: 4.3752} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &2223287144791830491 CanvasRenderer: @@ -802,7 +799,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image m_Material: {fileID: 0} - m_Color: {r: 0.48627454, g: 0.06666667, b: 0.08627451, a: 1} + m_Color: {r: 0.19131038, g: 0.06666666, b: 0.4862745, a: 1} m_RaycastTarget: 0 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 diff --git a/Assets/Prefabs/UI/HeroPortrait.prefab.meta b/Assets/Prefabs/UI/InGameGui/HeroPortrait.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/HeroPortrait.prefab.meta rename to Assets/Prefabs/UI/InGameGui/HeroPortrait.prefab.meta diff --git a/Assets/Prefabs/UI/IngameLogSystem.meta b/Assets/Prefabs/UI/IngameLogSystem.meta new file mode 100644 index 0000000..f35e46d --- /dev/null +++ b/Assets/Prefabs/UI/IngameLogSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 80b7de964780c3a4d91efbe9df16d961 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/UI/LogContainer.prefab b/Assets/Prefabs/UI/IngameLogSystem/LogContainer.prefab similarity index 100% rename from Assets/Prefabs/UI/LogContainer.prefab rename to Assets/Prefabs/UI/IngameLogSystem/LogContainer.prefab diff --git a/Assets/Prefabs/UI/LogContainer.prefab.meta b/Assets/Prefabs/UI/IngameLogSystem/LogContainer.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/LogContainer.prefab.meta rename to Assets/Prefabs/UI/IngameLogSystem/LogContainer.prefab.meta diff --git a/Assets/Prefabs/UI/LogEntry.prefab b/Assets/Prefabs/UI/IngameLogSystem/LogEntry.prefab similarity index 100% rename from Assets/Prefabs/UI/LogEntry.prefab rename to Assets/Prefabs/UI/IngameLogSystem/LogEntry.prefab diff --git a/Assets/Prefabs/UI/LogEntry.prefab.meta b/Assets/Prefabs/UI/IngameLogSystem/LogEntry.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/LogEntry.prefab.meta rename to Assets/Prefabs/UI/IngameLogSystem/LogEntry.prefab.meta diff --git a/Assets/Prefabs/UI/PopupSystem.meta b/Assets/Prefabs/UI/PopupSystem.meta new file mode 100644 index 0000000..f640475 --- /dev/null +++ b/Assets/Prefabs/UI/PopupSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b7ddc322bd65e7e46abca4c4c6540bb6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/UI/PopupHeader.prefab b/Assets/Prefabs/UI/PopupSystem/PopupHeader.prefab similarity index 100% rename from Assets/Prefabs/UI/PopupHeader.prefab rename to Assets/Prefabs/UI/PopupSystem/PopupHeader.prefab diff --git a/Assets/Prefabs/UI/PopupHeader.prefab.meta b/Assets/Prefabs/UI/PopupSystem/PopupHeader.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/PopupHeader.prefab.meta rename to Assets/Prefabs/UI/PopupSystem/PopupHeader.prefab.meta diff --git a/Assets/Prefabs/UI/PopupIcon.prefab b/Assets/Prefabs/UI/PopupSystem/PopupIcon.prefab similarity index 100% rename from Assets/Prefabs/UI/PopupIcon.prefab rename to Assets/Prefabs/UI/PopupSystem/PopupIcon.prefab diff --git a/Assets/Prefabs/UI/PopupIcon.prefab.meta b/Assets/Prefabs/UI/PopupSystem/PopupIcon.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/PopupIcon.prefab.meta rename to Assets/Prefabs/UI/PopupSystem/PopupIcon.prefab.meta diff --git a/Assets/Prefabs/UI/PopupSystem/PopupReferencePrefab.prefab b/Assets/Prefabs/UI/PopupSystem/PopupReferencePrefab.prefab new file mode 100644 index 0000000..15f696e --- /dev/null +++ b/Assets/Prefabs/UI/PopupSystem/PopupReferencePrefab.prefab @@ -0,0 +1,297 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1599460330468667833 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 623181081371217224} + - component: {fileID: 1835601435911948781} + - component: {fileID: 695849844002832445} + - component: {fileID: 3081303906751693297} + - component: {fileID: -4214546602618600400} + - component: {fileID: 7236468329886607693} + m_Layer: 5 + m_Name: PopupReferencePrefab + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &623181081371217224 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1599460330468667833} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8899521584296352500} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 300, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!225 &1835601435911948781 +CanvasGroup: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1599460330468667833} + m_Enabled: 1 + m_Alpha: 1 + m_Interactable: 1 + m_BlocksRaycasts: 1 + m_IgnoreParentGroups: 0 +--- !u!114 &695849844002832445 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1599460330468667833} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: bc25da4712d7cc4419eb6f364e032431, type: 3} + m_Name: + m_EditorClassIdentifier: Jovian.PopupSystem::Jovian.PopupSystem.UI.PopupReference + content: {fileID: 176628901263125209} + canvasGroup: {fileID: 1835601435911948781} + background: {fileID: 8899521584296352500} + headerPrefab: {fileID: 6612787789151041457, guid: dfc1bc0bd5b4905409615c3e770a5b77, type: 3} + textPrefab: {fileID: 2506259255305457008, guid: bfa97c92d1878cc448ddc7dc456f4b17, type: 3} + statPrefab: {fileID: 1843470073663794312, guid: 5882db210c62d8647858933649f64c29, type: 3} + imagePrefab: {fileID: 7093821785826926595, guid: 5e715f4b614d02b4fa0b4d3fcfe3c053, type: 3} + separatorPrefab: {fileID: 4190588985333916705, guid: 7ccdfa1a2079db044be4b1684303ec7f, type: 3} +--- !u!223 &3081303906751693297 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1599460330468667833} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 2 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 100 + m_TargetDisplay: 0 +--- !u!114 &-4214546602618600400 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1599460330468667833} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.CanvasScaler + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 1920, y: 1080} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0.5 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!114 &7236468329886607693 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1599460330468667833} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.ContentSizeFitter + m_HorizontalFit: 0 + m_VerticalFit: 2 +--- !u!1 &3774543863822571266 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 176628901263125209} + - component: {fileID: 2618782962856630769} + - component: {fileID: 4695064839375127024} + - component: {fileID: 8584485639437491102} + - component: {fileID: 7537071497970891545} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &176628901263125209 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3774543863822571266} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8899521584296352500} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &2618782962856630769 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3774543863822571266} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.VerticalLayoutGroup + m_Padding: + m_Left: 8 + m_Right: 8 + m_Top: 8 + m_Bottom: 8 + m_ChildAlignment: 0 + m_Spacing: 3.82 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 1 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!222 &4695064839375127024 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3774543863822571266} + m_CullTransparentMesh: 1 +--- !u!114 &8584485639437491102 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3774543863822571266} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 0.1509434, g: 0.116711326, b: 0.088999644, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 52125a3c3df558448a5af5a04dbf8d2d, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &7537071497970891545 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3774543863822571266} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.ContentSizeFitter + m_HorizontalFit: 0 + m_VerticalFit: 2 +--- !u!1 &7921791084240859601 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8899521584296352500} + - component: {fileID: 4414385109869753182} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8899521584296352500 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7921791084240859601} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 176628901263125209} + m_Father: {fileID: 623181081371217224} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: -0.000015258789, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!222 &4414385109869753182 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7921791084240859601} + m_CullTransparentMesh: 1 diff --git a/Assets/Prefabs/UI/PopupReferencePrefab.prefab.meta b/Assets/Prefabs/UI/PopupSystem/PopupReferencePrefab.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/PopupReferencePrefab.prefab.meta rename to Assets/Prefabs/UI/PopupSystem/PopupReferencePrefab.prefab.meta diff --git a/Assets/Prefabs/UI/PopupSeparator.prefab b/Assets/Prefabs/UI/PopupSystem/PopupSeparator.prefab similarity index 100% rename from Assets/Prefabs/UI/PopupSeparator.prefab rename to Assets/Prefabs/UI/PopupSystem/PopupSeparator.prefab diff --git a/Assets/Prefabs/UI/PopupSeparator.prefab.meta b/Assets/Prefabs/UI/PopupSystem/PopupSeparator.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/PopupSeparator.prefab.meta rename to Assets/Prefabs/UI/PopupSystem/PopupSeparator.prefab.meta diff --git a/Assets/Prefabs/UI/PopupStat.prefab b/Assets/Prefabs/UI/PopupSystem/PopupStat.prefab similarity index 100% rename from Assets/Prefabs/UI/PopupStat.prefab rename to Assets/Prefabs/UI/PopupSystem/PopupStat.prefab diff --git a/Assets/Prefabs/UI/PopupStat.prefab.meta b/Assets/Prefabs/UI/PopupSystem/PopupStat.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/PopupStat.prefab.meta rename to Assets/Prefabs/UI/PopupSystem/PopupStat.prefab.meta diff --git a/Assets/Prefabs/UI/PopupText.prefab b/Assets/Prefabs/UI/PopupSystem/PopupText.prefab similarity index 100% rename from Assets/Prefabs/UI/PopupText.prefab rename to Assets/Prefabs/UI/PopupSystem/PopupText.prefab diff --git a/Assets/Prefabs/UI/PopupText.prefab.meta b/Assets/Prefabs/UI/PopupSystem/PopupText.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/PopupText.prefab.meta rename to Assets/Prefabs/UI/PopupSystem/PopupText.prefab.meta diff --git a/Packages/com.jovian.popup-system/README.md b/Packages/com.jovian.popup-system/README.md index e38f6bb..d48f602 100644 --- a/Packages/com.jovian.popup-system/README.md +++ b/Packages/com.jovian.popup-system/README.md @@ -27,21 +27,26 @@ See the [Prefab Setup](#prefab-setup) section below for step-by-step instruction using Jovian.PopupSystem; using Jovian.PopupSystem.UI; -// Create the system. viewPrefab is a reference to your PopupReference prefab. -var popup = new PopupSystem(settings, viewPrefab); +// Create the system. Pass the scene Canvas as canvasRoot to auto-scan all PopupTrigger components. +var popup = new PopupSystem(settings, viewPrefab, canvasRoot); // Register categories you intend to use. popup.RegisterCategory(PopupCategory.Item); popup.RegisterCategory(PopupCategory.Character); -// Show a popup anchored to a UI element. -popup.Show(PopupCategory.Item, builder => { +// Option A: Set content on auto-scanned triggers by name. +var trigger = popup.GetTrigger("ItemSlot"); +trigger?.SetContent(builder => { builder .AddHeader("Health Potion") .AddSeparator() .AddText("Restores a moderate amount of health.") - .AddStat("Heal Amount", 50) - .AddStat("Uses", "3 / 3"); + .AddStat("Heal Amount", 50); +}); + +// Option B: Show a popup directly from code. +popup.Show(PopupCategory.Item, builder => { + builder.AddHeader("Iron Sword").AddStat("Damage", 12); }, anchorRect, AnchorSide.Right); // Tick each frame (typically in Update or a game-state loop). @@ -139,35 +144,69 @@ All elements are drawn from a grow-only pool inside `PopupReference`. No allocat | `anchorSide` | AnchorSide | Which side of this element to anchor the popup. | | `positionMode` | PopupPositionMode | `AnchorToElement` or `FollowMouse`. | -### Initialization +### Approach 1: Auto-scanned triggers (recommended for static UI) -`PopupTrigger` must be initialized from code before it will respond to pointer events: +When you pass a `canvasRoot` to the `PopupSystem` constructor, it auto-scans all `PopupTrigger` components and binds them. You only need to set content: + +```csharp +var popup = new PopupSystem(settings, viewPrefab, canvasRoot); +popup.RegisterCategory(PopupCategory.Character); + +// Find a trigger by its GameObject name and set content +var trigger = popup.GetTrigger("HeroPortrait"); +trigger?.SetContent(builder => { + builder.AddHeader("Kael").AddStat("Health", 55); +}); + +// Or set content on all triggers of a category +foreach(var t in popup.GetTriggers(PopupCategory.Item)) { + t.SetContent(builder => builder.AddHeader("Item")); +} +``` + +### Approach 2: Dynamic triggers (for runtime-created UI) + +For UI elements instantiated at runtime (inventory slots, party portraits), use `InitializeTriggersInChildren` after instantiation: + +```csharp +// After instantiating slot prefabs under a container: +popup.InitializeTriggersInChildren(slotsContainer, trigger => { + var slotData = trigger.GetComponentInParent(); + trigger.SetContent(builder => { + builder.AddHeader(slotData.itemName); + }); +}); +``` + +This scans, binds, and registers all triggers under the parent, then calls the callback on each. + +### Approach 3: Full manual initialization + +For complete control, bypass auto-scan and initialize triggers directly: ```csharp var trigger = button.GetComponent(); trigger.Initialize(popupSystem, builder => { - builder - .AddHeader("Attack") - .AddStat("Damage", 25); + builder.AddHeader("Attack").AddStat("Damage", 25); }); -``` -You can also override the category at initialization time: - -```csharp +// Or with a category override: trigger.Initialize(popupSystem, PopupCategory.Skill, builder => { builder.AddHeader("Fireball"); }); ``` -To change content without re-initializing: +### Updating content + +To change content on an already-initialized trigger without re-binding: ```csharp -trigger.UpdateContent(builder => { - builder - .AddHeader("Attack") - .AddStat("Damage", newDamageValue); +trigger.SetContent(builder => { + builder.AddHeader("Attack").AddStat("Damage", newDamageValue); }); + +// UpdateContent is an alias for SetContent +trigger.UpdateContent(builder => { ... }); ``` ## Code-Only Triggers @@ -226,12 +265,14 @@ Settings-based priorities (from `PopupSettings.categoryPriorities`) take precede The popup system is designed to be created per game state, not as a global singleton. Each game state owns its own `IPopupSystem` instance: ```csharp -// In your game state constructor or initialization: -var popupSystem = new PopupSystem(popupSettings, popupViewPrefab); +// In your game state initialization: +var guiCanvas = guiReferences.GetComponentInParent().transform; +var popupSystem = new PopupSystem(popupSettings, popupViewPrefab, guiCanvas); popupSystem.RegisterCategory(PopupCategory.Character, priority: 10); popupSystem.RegisterCategory(PopupCategory.Item, priority: 5); -// Pass to views/play modes via constructor DI +// All PopupTrigger components under guiCanvas are auto-scanned and bound. +// Pass popupSystem to views/play modes via constructor DI. // In your game state's Tick/Update: popupSystem.Tick(Time.deltaTime); @@ -318,54 +359,68 @@ var popup = new PopupSystem(settings, viewPrefab, () => new ScalePopupAnimator() ## Prefab Setup -Build the `PopupReference` prefab with the following hierarchy: +Build the `PopupReference` prefab with the following hierarchy. Reference prefabs are included in the `Samples~/Prefabs` folder. + +``` +PopupReferencePrefab Canvas, CanvasGroup, CanvasScaler, PopupReference + Background Image (popup background), ContentSizeFitter (V=Preferred) + Content VerticalLayoutGroup (Control Child Size Width, Child Force Expand Width) +``` ### Step 1: Root GameObject -1. Create a new GameObject named `PopupReference`. -2. Add a `Canvas` component. Set **Render Mode** to **Screen Space - Overlay**. Set **Sort Order** to match `PopupSettings.sortingOrder` (default 100). -3. Add a `CanvasGroup` component. -4. Add a `PopupReference` component (from `Jovian.PopupSystem.UI`). +1. Create a new GameObject named `PopupReferencePrefab` +2. Add a `Canvas` component. Set **Render Mode** to **Screen Space - Overlay** +3. Add a `CanvasScaler` with **Scale With Screen Size**, reference resolution matching your project (e.g. 1920x1080). This is needed for prefab editing; at runtime the nested Canvas inherits the parent's scaler +4. Add a `CanvasGroup` component +5. Add a `PopupReference` component (from `Jovian.PopupSystem.UI`) +6. Set anchors to a single point (e.g. Min 0,1 Max 0,1), Pivot (0,1) for top-left origin +7. Do **not** add a `ContentSizeFitter` to the root ### Step 2: Background -1. Create a child GameObject named `Background`. -2. Add a `RectTransform` and an `Image` component. Set the image color/sprite to your desired popup background. -3. Add a `ContentSizeFitter` with **Vertical Fit** set to **Preferred Size**. +1. Create a child GameObject named `Background` +2. Add an `Image` component. Set the image sprite/color to your desired popup background +3. Add a `ContentSizeFitter` with **Horizontal Fit = Unconstrained** and **Vertical Fit = Preferred Size** +4. Stretch the RectTransform to fill the root (anchors 0,0 to 1,1, offsets 0) or use point anchors with the ContentSizeFitter driving the size ### Step 3: Content container -1. Create a child of `Background` named `Content`. -2. Add a `RectTransform`. Stretch it to fill the background with appropriate padding. -3. Add a `VerticalLayoutGroup`. Configure padding and spacing to taste. -4. Add a `ContentSizeFitter` with **Vertical Fit** set to **Preferred Size**. +1. Create a child of `Background` named `Content` +2. Stretch the RectTransform to fill the Background (anchors 0,0 to 1,1, offsets for padding) +3. Add a `VerticalLayoutGroup`: + - **Control Child Size**: Width checked, Height unchecked + - **Child Force Expand**: Width checked, Height unchecked + - **Spacing**: 2 (or to taste) + - **Padding**: as needed +4. Do **not** add a `ContentSizeFitter` to Content. The VerticalLayoutGroup reports its preferred size to the parent Background's ContentSizeFitter ### Step 4: Element prefabs -Create these as child prefabs (or separate prefabs). Each must be a prefab reference, not an in-hierarchy instance: +Create these as separate prefabs. Do not add `ContentSizeFitter` to any element prefab: | Prefab | Component | Notes | |---|---|---| -| Header | `TMP_Text` | Bold, larger font size | -| Text | `TMP_Text` | Regular body text | -| Stat | `RectTransform` with `HorizontalLayoutGroup` | Must have exactly two `TMP_Text` children: label and value | -| Image | `Image` | For icons or artwork | -| Separator | `Image` | Thin horizontal line | +| PopupHeader | `TMP_Text` | Bold, larger font size. Add `LayoutElement` if you need minimum height | +| PopupText | `TMP_Text` | Regular body text, rich text enabled | +| PopupStat | `RectTransform` with `HorizontalLayoutGroup` | Must have exactly two `TMP_Text` children: label (left) and value (right) | +| PopupIcon | `Image` | For icons or artwork. Add `LayoutElement` with preferred height | +| PopupSeparator | `Image` | Thin horizontal line. Add `LayoutElement` with preferred height = 1 or 2 | ### Step 5: Wire references On the `PopupReference` component, assign: -- **Content** - the Content RectTransform -- **Canvas Group** - the root CanvasGroup -- **Background** - the Background RectTransform -- **Header Prefab** - your header TMP_Text prefab -- **Text Prefab** - your body text TMP_Text prefab -- **Stat Prefab** - your stat row RectTransform prefab -- **Image Prefab** - your image prefab -- **Separator Prefab** - your separator Image prefab +- **Content**: the Content RectTransform +- **Canvas Group**: the root CanvasGroup +- **Background**: the Background RectTransform +- **Header Prefab**: your PopupHeader prefab +- **Text Prefab**: your PopupText prefab +- **Stat Prefab**: your PopupStat prefab +- **Image Prefab**: your PopupIcon prefab +- **Separator Prefab**: your PopupSeparator prefab -Save as a prefab. The `maxPopupWidth` from `PopupSettings` is applied at runtime to constrain the popup's horizontal size. +Save as a prefab. The `maxPopupWidth` from `PopupSettings` is applied at runtime to constrain the popup's horizontal size. At runtime, when parented under a scene Canvas, the popup's own Canvas becomes a nested override Canvas inheriting the parent's scaling. ## Optimization Notes @@ -379,6 +434,19 @@ The popup system is designed for minimal runtime allocation: - Layout rebuilds only occur when content changes (dirty flag), not on every position update - Each registered category gets its own `IPopupAnimator` instance, preventing state corruption during concurrent show/hide animations +## Samples + +The `Samples~` folder contains ready-to-use reference material: + +- **Prefabs**: PopupReferencePrefab and all element prefabs (header, text, stat, icon, separator) with correct component setup +- **Settings**: Pre-configured PopupSettings asset with sensible defaults +- **Scripts**: Three example scripts demonstrating different integration patterns: + - `PopupSystemExample` -- auto-scanned triggers with `GetTrigger` and `GetTriggers` + - `DynamicTriggersExample` -- runtime-instantiated UI with `InitializeTriggersInChildren` + - `CodeOnlyPopupExample` -- showing popups from code (anchored, fixed position, follow mouse) + +Import via Unity Package Manager: select the package, expand Samples, click Import. + ## API Reference ### Core Types @@ -386,7 +454,7 @@ The popup system is designed for minimal runtime allocation: | Type | Namespace | Description | |---|---|---| | `IPopupSystem` | `Jovian.PopupSystem` | Main interface for showing/hiding popups. | -| `PopupSystem` | `Jovian.PopupSystem` | Concrete implementation. Constructor: `(PopupSettings, PopupReference, Func)`. | +| `PopupSystem` | `Jovian.PopupSystem` | Concrete implementation. Constructor: `(PopupSettings, PopupReference, Transform canvasParent, Func)`. Auto-scans triggers under canvasParent. Methods: `ScanTriggers`, `GetTrigger`, `GetTriggers`, `InitializeTriggersInChildren`. | | `PopupSettings` | `Jovian.PopupSystem` | ScriptableObject with all configuration fields. | | `PopupCategory` | `Jovian.PopupSystem` | Readonly struct identifying a popup channel. | | `PopupContentBuilder` | `Jovian.PopupSystem` | Fluent struct for building popup content in callbacks. | diff --git a/Packages/com.jovian.popup-system/Runtime/FadePopupAnimator.cs b/Packages/com.jovian.popup-system/Runtime/FadePopupAnimator.cs index ac20b40..4ce532e 100644 --- a/Packages/com.jovian.popup-system/Runtime/FadePopupAnimator.cs +++ b/Packages/com.jovian.popup-system/Runtime/FadePopupAnimator.cs @@ -2,33 +2,37 @@ using System; using UnityEngine; namespace Jovian.PopupSystem { + /// + /// Default popup animator that fades CanvasGroup alpha. Each category gets its own instance + /// so concurrent show/hide animations don't corrupt each other. + /// public sealed class FadePopupAnimator : IPopupAnimator { private CanvasGroup target; - private float duration; + private float timer; private float elapsed; private float startAlpha; private float endAlpha; - private Action onComplete; + private Action onFinish; public bool IsAnimating => target != null; public void Show(CanvasGroup canvasGroup, float duration, Action onComplete) { target = canvasGroup; - this.duration = Mathf.Max(duration, 0.001f); + timer = Mathf.Max(duration, 0.001f); elapsed = 0f; startAlpha = 0f; endAlpha = 1f; - this.onComplete = onComplete; + onFinish = onComplete; canvasGroup.alpha = 0f; } public void Hide(CanvasGroup canvasGroup, float duration, Action onComplete) { target = canvasGroup; - this.duration = Mathf.Max(duration, 0.001f); + timer = Mathf.Max(duration, 0.001f); elapsed = 0f; startAlpha = canvasGroup.alpha; endAlpha = 0f; - this.onComplete = onComplete; + onFinish = onComplete; } public void Tick(float deltaTime) { @@ -37,15 +41,16 @@ namespace Jovian.PopupSystem { } elapsed += deltaTime; - var t = Mathf.Clamp01(elapsed / duration); + var t = Mathf.Clamp01(elapsed / timer); target.alpha = Mathf.Lerp(startAlpha, endAlpha, t); - if(t >= 1f) { - var callback = onComplete; - target = null; - onComplete = null; - callback?.Invoke(); + if(!(t >= 1f)) { + return; } + var callback = onFinish; + target = null; + onFinish = null; + callback?.Invoke(); } } } diff --git a/Packages/com.jovian.popup-system/Runtime/IPopupAnimator.cs b/Packages/com.jovian.popup-system/Runtime/IPopupAnimator.cs index a92552e..1c82210 100644 --- a/Packages/com.jovian.popup-system/Runtime/IPopupAnimator.cs +++ b/Packages/com.jovian.popup-system/Runtime/IPopupAnimator.cs @@ -2,10 +2,36 @@ using System; using UnityEngine; namespace Jovian.PopupSystem { + /// + /// Interface for popup show/hide animations. Each registered category gets its own instance + /// to prevent state corruption during concurrent animations. Driven by float timers in + /// , not coroutines. + /// public interface IPopupAnimator { + /// + /// Begins a show animation on the given CanvasGroup. Typically fades alpha from 0 to 1. + /// + /// The CanvasGroup to animate. + /// Animation duration in seconds. + /// Callback invoked when the animation finishes. May be null. void Show(CanvasGroup canvasGroup, float duration, Action onComplete); + + /// + /// Begins a hide animation on the given CanvasGroup. Typically fades alpha to 0. + /// + /// The CanvasGroup to animate. + /// Animation duration in seconds. + /// Callback invoked when the animation finishes. May be null. void Hide(CanvasGroup canvasGroup, float duration, Action onComplete); + + /// + /// Advances the animation by deltaTime. Call every frame from . + /// void Tick(float deltaTime); + + /// + /// True if an animation is currently in progress. + /// bool IsAnimating { get; } } } diff --git a/Packages/com.jovian.popup-system/Runtime/IPopupSystem.cs b/Packages/com.jovian.popup-system/Runtime/IPopupSystem.cs index bbfb97c..5e384e1 100644 --- a/Packages/com.jovian.popup-system/Runtime/IPopupSystem.cs +++ b/Packages/com.jovian.popup-system/Runtime/IPopupSystem.cs @@ -1,18 +1,79 @@ using System; +using System.Collections.Generic; using Jovian.PopupSystem.UI; using UnityEngine; namespace Jovian.PopupSystem { + /// + /// Core interface for the popup system. Created per game state, not as a singleton. + /// Manages category registration, trigger discovery, popup display, and lifecycle. + /// public interface IPopupSystem { - void InitializeTriggersInChildren(Transform parent, Action configureTrigger); + /// + /// Scans all components under the given parent and binds them + /// to this system. Each trigger receives a for behavior. + /// + void ScanTriggers(Transform parent); + + /// + /// Scans all components under the given parent, binds them, + /// and invokes the configure callback with both the trigger (for hierarchy queries) and + /// its view (for setting content). + /// + void InitializeTriggersInChildren(Transform parent, Action configureTrigger); + + /// + /// Returns the for the first registered trigger whose + /// GameObject name matches. Returns null if not found. + /// + PopupTriggerView GetTriggerHandler(string gameObjectName); + + /// + /// Returns all instances registered under the given category. + /// + IReadOnlyList GetTriggerHandlers(PopupCategory category); + + /// + /// Registers a popup category. Each category gets its own instance + /// (lazily created on first show) and its own . + /// + /// The category to register. + /// Fallback priority if not defined in . Higher dismisses lower. void RegisterCategory(PopupCategory category, int priority = 0); + + /// + /// Shows a popup for the given category after the configured delay. The build callback + /// populates content via . Optionally anchors to a + /// RectTransform or follows the mouse if no anchor is provided. + /// void Show(PopupCategory category, Action buildContent, RectTransform anchor = null, AnchorSide? anchorSide = null); + + /// + /// Shows a popup for the given category at a fixed screen position. + /// void ShowAtPosition(PopupCategory category, Action buildContent, Vector2 screenPosition); + + /// + /// Hides the popup for the given category with a fade-out animation. + /// void Hide(PopupCategory category); + + /// + /// Hides all visible popups across all categories. + /// void HideAll(); + + /// + /// Drives delay timers, animations, and follow-mouse positioning. Call every frame. + /// void Tick(float deltaTime); + + /// + /// Destroys all popup view GameObjects and clears registered categories. + /// Call when the owning game state exits. + /// void Dispose(); } } diff --git a/Packages/com.jovian.popup-system/Runtime/PopupCategory.cs b/Packages/com.jovian.popup-system/Runtime/PopupCategory.cs index 06ea863..a26322a 100644 --- a/Packages/com.jovian.popup-system/Runtime/PopupCategory.cs +++ b/Packages/com.jovian.popup-system/Runtime/PopupCategory.cs @@ -2,6 +2,10 @@ using System; using UnityEngine; namespace Jovian.PopupSystem { + /// + /// Value type identifying a popup channel. Each category gets its own popup view instance. + /// Compared by string ID using ordinal comparison. Define custom categories as static fields. + /// [Serializable] public struct PopupCategory : IEquatable { [SerializeField] string id; diff --git a/Packages/com.jovian.popup-system/Runtime/PopupContentBuilder.cs b/Packages/com.jovian.popup-system/Runtime/PopupContentBuilder.cs index be08a06..b08876b 100644 --- a/Packages/com.jovian.popup-system/Runtime/PopupContentBuilder.cs +++ b/Packages/com.jovian.popup-system/Runtime/PopupContentBuilder.cs @@ -2,25 +2,42 @@ using Jovian.PopupSystem.UI; using UnityEngine; namespace Jovian.PopupSystem { + /// + /// Fluent API struct for building popup content. Operates directly on cached elements + /// inside a — no intermediate allocations. Received in + /// the build callback passed to . + /// public struct PopupContentBuilder { readonly PopupReference view; + /// + /// Creates a builder targeting the given popup reference. + /// public PopupContentBuilder(PopupReference view) { this.view = view; } + /// + /// Adds a header text element (bold, larger font). + /// public PopupContentBuilder AddHeader(string text) { var header = view.GetHeader(); header.text = text; return this; } + /// + /// Adds a body text element. + /// public PopupContentBuilder AddText(string text) { var label = view.GetText(); label.text = text; return this; } + /// + /// Adds a colored body text element. Hex color can be with or without the # prefix. + /// public PopupContentBuilder AddText(string text, string hexColor) { var label = view.GetText(); var prefix = hexColor.Length > 0 && hexColor[0] == '#' ? "" : "#"; @@ -28,6 +45,9 @@ namespace Jovian.PopupSystem { return this; } + /// + /// Adds a stat row with a label and integer value. + /// public PopupContentBuilder AddStat(string label, int value) { var (labelText, valueText) = view.GetStat(); labelText.text = label; @@ -35,6 +55,9 @@ namespace Jovian.PopupSystem { return this; } + /// + /// Adds a stat row with a label and string value. + /// public PopupContentBuilder AddStat(string label, string value) { var (labelText, valueText) = view.GetStat(); labelText.text = label; @@ -42,6 +65,9 @@ namespace Jovian.PopupSystem { return this; } + /// + /// Adds an image element with the given sprite and optional height. + /// public PopupContentBuilder AddImage(Sprite sprite, float height = 64f) { var image = view.GetImage(); image.sprite = sprite; @@ -50,6 +76,9 @@ namespace Jovian.PopupSystem { return this; } + /// + /// Adds a horizontal separator line. + /// public PopupContentBuilder AddSeparator() { view.GetSeparator(); return this; diff --git a/Packages/com.jovian.popup-system/Runtime/PopupSettings.cs b/Packages/com.jovian.popup-system/Runtime/PopupSettings.cs index d51f461..5d0f5a7 100644 --- a/Packages/com.jovian.popup-system/Runtime/PopupSettings.cs +++ b/Packages/com.jovian.popup-system/Runtime/PopupSettings.cs @@ -3,6 +3,10 @@ using System.Collections.Generic; using UnityEngine; namespace Jovian.PopupSystem { + /// + /// ScriptableObject holding all popup system configuration. Create via + /// Assets > Create > Jovian > Popup System > Popup Settings. + /// [CreateAssetMenu(fileName = "PopupSettings", menuName = "Jovian/Popup System/Popup Settings")] public class PopupSettings : ScriptableObject { [Header("General")] @@ -26,6 +30,9 @@ namespace Jovian.PopupSystem { [Header("Per-Category Overrides")] public List categoryDelayOverrides = new(); + /// + /// Returns the configured priority for a category, or 0 if not configured. + /// public int GetPriority(PopupCategory category) { foreach(var cp in categoryPriorities) { if(cp.category == category) { @@ -35,6 +42,9 @@ namespace Jovian.PopupSystem { return 0; } + /// + /// Returns the configured delay override for a category, or the default popupDelay. + /// public float GetDelay(PopupCategory category) { foreach(var cd in categoryDelayOverrides) { if(cd.category == category) { diff --git a/Packages/com.jovian.popup-system/Runtime/PopupSystem.cs b/Packages/com.jovian.popup-system/Runtime/PopupSystem.cs index 4ad45e8..69180b8 100644 --- a/Packages/com.jovian.popup-system/Runtime/PopupSystem.cs +++ b/Packages/com.jovian.popup-system/Runtime/PopupSystem.cs @@ -2,23 +2,44 @@ using System; using System.Collections.Generic; using Jovian.PopupSystem.UI; using UnityEngine; +using UnityEngine.UI; using Object = UnityEngine.Object; namespace Jovian.PopupSystem { + /// + /// Core implementation of . Created per game state, not as a singleton. + /// Manages category registration, trigger discovery, popup lifecycle, priority dismissal, and + /// tick-driven delay timers and animations. Pass a canvasParent to auto-scan triggers on construction. + /// public sealed class PopupSystem : IPopupSystem { readonly PopupSettings settings; readonly PopupReference viewPrefab; readonly Func animatorFactory; readonly Transform canvasParent; readonly Dictionary categories = new(); + readonly List registeredTriggers = new(); + /// + /// Creates a new popup system instance. + /// + /// Configuration ScriptableObject with delays, priorities, and display settings. + /// The PopupReference prefab to instantiate per category. + /// Optional parent Canvas transform. When provided, popup views are parented + /// here (inheriting CanvasScaler) and all PopupTrigger components are auto-scanned. + /// Optional factory for custom animators. Defaults to FadePopupAnimator. public PopupSystem(PopupSettings settings, PopupReference viewPrefab, Transform canvasParent = null, Func animatorFactory = null) { this.settings = settings; this.viewPrefab = viewPrefab; this.canvasParent = canvasParent; this.animatorFactory = animatorFactory ?? (() => new FadePopupAnimator()); + + // Auto-scan if a parent was provided + if(canvasParent != null) { + ScanTriggers(canvasParent); + } } + /// public void RegisterCategory(PopupCategory category, int priority = 0) { if(categories.ContainsKey(category)) { return; @@ -34,6 +55,7 @@ namespace Jovian.PopupSystem { }; } + /// public void Show(PopupCategory category, Action buildContent, RectTransform anchor = null, AnchorSide? anchorSide = null) { if(!categories.TryGetValue(category, out var state)) { @@ -50,6 +72,7 @@ namespace Jovian.PopupSystem { state.isPending = true; } + /// public void ShowAtPosition(PopupCategory category, Action buildContent, Vector2 screenPosition) { if(!categories.TryGetValue(category, out var state)) { @@ -65,6 +88,7 @@ namespace Jovian.PopupSystem { state.isPending = true; } + /// public void Hide(PopupCategory category) { if(!categories.TryGetValue(category, out var state)) { return; @@ -78,12 +102,14 @@ namespace Jovian.PopupSystem { } } + /// public void HideAll() { foreach(var kvp in categories) { Hide(kvp.Key); } } + /// public void Tick(float deltaTime) { foreach(var kvp in categories) { kvp.Value.animator.Tick(deltaTime); @@ -112,13 +138,55 @@ namespace Jovian.PopupSystem { } } - public void InitializeTriggersInChildren(Transform parent, Action configureTrigger) { + /// + public void ScanTriggers(Transform parent) { var triggers = parent.GetComponentsInChildren(true); foreach(var trigger in triggers) { - configureTrigger(trigger); + if(!registeredTriggers.Contains(trigger)) { + BindTrigger(trigger); + } } } + /// + public PopupTriggerView GetTriggerHandler(string gameObjectName) { + foreach(var trigger in registeredTriggers) { + if(trigger != null && trigger.gameObject.name == gameObjectName) { + return trigger.Handler; + } + } + return null; + } + + /// + public IReadOnlyList GetTriggerHandlers(PopupCategory category) { + var result = new List(); + foreach(var trigger in registeredTriggers) { + if(trigger != null && trigger.Category == category && trigger.Handler != null) { + result.Add(trigger.Handler); + } + } + return result; + } + + /// + public void InitializeTriggersInChildren(Transform parent, Action configureTrigger) { + var triggers = parent.GetComponentsInChildren(true); + foreach(var trigger in triggers) { + if(!registeredTriggers.Contains(trigger)) { + BindTrigger(trigger); + } + configureTrigger(trigger, trigger.Handler); + } + } + + private void BindTrigger(PopupTrigger trigger) { + var handler = new PopupTriggerView(this); + trigger.Bind(handler); + registeredTriggers.Add(trigger); + } + + /// public void Dispose() { foreach(var kvp in categories) { if(kvp.Value.view != null) { @@ -135,6 +203,15 @@ namespace Jovian.PopupSystem { var builder = new PopupContentBuilder(state.view); state.pendingBuild?.Invoke(builder); + // Activate before layout rebuild so Unity has an active hierarchy to calculate + state.view.CanvasGroup.alpha = 0f; + state.view.SetVisible(true); + + // Force full layout rebuild so positioning has correct size on first show + Canvas.ForceUpdateCanvases(); + LayoutRebuilder.ForceRebuildLayoutImmediate(state.view.Content); + LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)state.view.transform); + if(state.pendingScreenPos.HasValue) { state.view.SetFixedPosition(state.pendingScreenPos.Value, settings.screenEdgePadding); state.isFollowMouse = false; @@ -148,7 +225,6 @@ namespace Jovian.PopupSystem { state.isFollowMouse = true; } - state.view.SetVisible(true); state.view.UpdatePosition(); state.animator.Show(state.view.CanvasGroup, settings.fadeDuration, null); } diff --git a/Packages/com.jovian.popup-system/Runtime/PopupTriggerView.cs b/Packages/com.jovian.popup-system/Runtime/PopupTriggerView.cs new file mode 100644 index 0000000..68931fc --- /dev/null +++ b/Packages/com.jovian.popup-system/Runtime/PopupTriggerView.cs @@ -0,0 +1,54 @@ +using System; +using Jovian.PopupSystem.UI; +using UnityEngine; + +namespace Jovian.PopupSystem { + /// + /// Handles popup behavior for a . Holds the content callback and + /// forwards pointer events to the . This is the behavior layer; + /// the MonoBehaviour trigger is the reference holder that forwards events here. + /// + public sealed class PopupTriggerView { + readonly IPopupSystem popupSystem; + Action contentCallback; + + /// + /// Creates a new trigger view bound to the given popup system. + /// + public PopupTriggerView(IPopupSystem popupSystem) { + this.popupSystem = popupSystem; + } + + /// + /// Sets the content builder callback that will be invoked when the popup is shown. + /// + public void SetContent(Action callback) { + contentCallback = callback; + } + + /// + /// Called by when the pointer enters. Reads the trigger's + /// category, anchor side, and position mode to show the popup. + /// + public void OnPointerEnter(PopupTrigger trigger) { + if(popupSystem == null || contentCallback == null) { + return; + } + + if(trigger.PositionMode == PopupPositionMode.AnchorToElement) { + popupSystem.Show(trigger.Category, contentCallback, (RectTransform)trigger.transform, trigger.AnchorSide); + } + else { + popupSystem.Show(trigger.Category, contentCallback); + } + } + + /// + /// Called by when the pointer exits. Hides the popup + /// for the trigger's category. + /// + public void OnPointerExit(PopupTrigger trigger) { + popupSystem?.Hide(trigger.Category); + } + } +} diff --git a/Packages/com.jovian.popup-system/Runtime/PopupTriggerView.cs.meta b/Packages/com.jovian.popup-system/Runtime/PopupTriggerView.cs.meta new file mode 100644 index 0000000..4a8141d --- /dev/null +++ b/Packages/com.jovian.popup-system/Runtime/PopupTriggerView.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1e2351b6a4b8bf046923790d4d09141c \ No newline at end of file diff --git a/Packages/com.jovian.popup-system/Runtime/UI/PopupReference.cs b/Packages/com.jovian.popup-system/Runtime/UI/PopupReference.cs index b64b414..f688d86 100644 --- a/Packages/com.jovian.popup-system/Runtime/UI/PopupReference.cs +++ b/Packages/com.jovian.popup-system/Runtime/UI/PopupReference.cs @@ -5,6 +5,10 @@ using UnityEngine.InputSystem; using UnityEngine.UI; namespace Jovian.PopupSystem.UI { + /// + /// MonoBehaviour reference holder for a popup view. Manages the grow-only element cache, + /// screen positioning, and visibility. One instance per registered . + /// public class PopupReference : MonoBehaviour { [SerializeField] RectTransform content; [SerializeField] CanvasGroup canvasGroup; @@ -52,6 +56,7 @@ namespace Jovian.PopupSystem.UI { public RectTransform Content => content; public bool IsVisible => isVisible; + /// Constrains the popup's horizontal size to the given maximum width in pixels. public void SetMaxWidth(float maxPopupWidth) { maxWidth = maxPopupWidth; if(maxWidth > 0f) { @@ -62,6 +67,7 @@ namespace Jovian.PopupSystem.UI { } } + /// Shows or hides the popup GameObject. Resets alpha to 0 when hiding. public void SetVisible(bool visible) { isVisible = visible; gameObject.SetActive(visible); @@ -70,6 +76,7 @@ namespace Jovian.PopupSystem.UI { } } + /// Deactivates all cached content elements and marks layout as dirty. public void ClearContent() { DeactivateRange(headerCache, ref headerIndex); DeactivateRange(textCache, ref textIndex); @@ -91,14 +98,17 @@ namespace Jovian.PopupSystem.UI { // --- Element access (grow-only) --- + /// Returns the next available header element from the cache, or creates one. public TMP_Text GetHeader() { return GetOrCreate(headerCache, headerPrefab, ref headerIndex); } + /// Returns the next available text element from the cache, or creates one. public TMP_Text GetText() { return GetOrCreate(textCache, textPrefab, ref textIndex); } + /// Returns the next available stat row (label + value pair) from the cache, or creates one. public (TMP_Text label, TMP_Text value) GetStat() { if(statIndex < statCache.Count) { var existing = statCache[statIndex]; @@ -118,10 +128,12 @@ namespace Jovian.PopupSystem.UI { return (entry.label, entry.value); } + /// Returns the next available image element from the cache, or creates one. public Image GetImage() { return GetOrCreate(imageCache, imagePrefab, ref imageIndex); } + /// Returns the next available separator element from the cache, or creates one. public Image GetSeparator() { return GetOrCreate(separatorCache, separatorPrefab, ref separatorIndex); } @@ -145,6 +157,7 @@ namespace Jovian.PopupSystem.UI { // --- Positioning --- + /// Configures the popup to anchor to a target element on the specified side. public void SetAnchorMode(RectTransform target, AnchorSide side, float edgePadding) { positionMode = PopupPositionMode.AnchorToElement; anchorTarget = target; @@ -152,12 +165,14 @@ namespace Jovian.PopupSystem.UI { screenEdgePadding = edgePadding; } + /// Configures the popup to follow the mouse cursor with the given offset. public void SetFollowMouseMode(Vector2 offset, float edgePadding) { positionMode = PopupPositionMode.FollowMouse; followOffset = offset; screenEdgePadding = edgePadding; } + /// Positions the popup at a fixed screen coordinate with edge clamping. public void SetFixedPosition(Vector2 screenPos, float edgePadding) { positionMode = PopupPositionMode.AnchorToElement; anchorTarget = null; @@ -165,6 +180,7 @@ namespace Jovian.PopupSystem.UI { PositionAtScreenPoint(screenPos); } + /// Updates the popup position based on the current mode (follow mouse or anchored). public void UpdatePosition() { if(positionMode == PopupPositionMode.FollowMouse) { PositionAtScreenPoint(Mouse.current.position.ReadValue() + followOffset); diff --git a/Packages/com.jovian.popup-system/Runtime/UI/PopupTrigger.cs b/Packages/com.jovian.popup-system/Runtime/UI/PopupTrigger.cs index d645141..a1635d8 100644 --- a/Packages/com.jovian.popup-system/Runtime/UI/PopupTrigger.cs +++ b/Packages/com.jovian.popup-system/Runtime/UI/PopupTrigger.cs @@ -1,54 +1,48 @@ -using System; using UnityEngine; using UnityEngine.EventSystems; namespace Jovian.PopupSystem.UI { + /// + /// Reference holder MonoBehaviour for popup triggers. Attach to any UI element with a + /// Graphic component (Image, TMP_Text, etc.) that has Raycast Target enabled. + /// Configure category, anchor side, and position mode in the Inspector. + /// Forwards pointer events to the bound . + /// public class PopupTrigger : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler { [SerializeField] PopupCategory category; [SerializeField] AnchorSide anchorSide = AnchorSide.Below; [SerializeField] PopupPositionMode positionMode = PopupPositionMode.AnchorToElement; - IPopupSystem popupSystem; - Action contentCallback; - bool initialized; + PopupTriggerView handler; + /// The popup category this trigger belongs to. public PopupCategory Category => category; - public void Initialize(IPopupSystem popupSystem, Action contentCallback) { - this.popupSystem = popupSystem; - this.contentCallback = contentCallback; - initialized = true; - } - - public void Initialize(IPopupSystem popupSystem, PopupCategory category, Action contentCallback) { - this.popupSystem = popupSystem; - this.category = category; - this.contentCallback = contentCallback; - initialized = true; - } - - public void UpdateContent(Action contentCallback) { - this.contentCallback = contentCallback; + /// Which side of this element the popup anchors to. + public AnchorSide AnchorSide => anchorSide; + + /// Whether the popup anchors to this element or follows the mouse. + public PopupPositionMode PositionMode => positionMode; + + /// The bound behavior handler. Null until is called. + public PopupTriggerView Handler => handler; + + /// + /// Binds a to this trigger. Called automatically + /// by or . + /// + public void Bind(PopupTriggerView view) { + handler = view; } + /// Forwards pointer enter to the bound handler. public void OnPointerEnter(PointerEventData eventData) { - if(!initialized || popupSystem == null || contentCallback == null) { - return; - } - - if(positionMode == PopupPositionMode.AnchorToElement) { - popupSystem.Show(category, contentCallback, (RectTransform)transform, anchorSide); - } - else { - popupSystem.Show(category, contentCallback); - } + handler?.OnPointerEnter(this); } + /// Forwards pointer exit to the bound handler. public void OnPointerExit(PointerEventData eventData) { - if(!initialized || popupSystem == null) { - return; - } - popupSystem.Hide(category); + handler?.OnPointerExit(this); } } } diff --git a/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupHeader.prefab b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupHeader.prefab new file mode 100644 index 0000000..74de254 --- /dev/null +++ b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupHeader.prefab @@ -0,0 +1,160 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &7034836061828108288 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1241885294582312999} + - component: {fileID: 1942692710355281447} + - component: {fileID: 6612787789151041457} + - component: {fileID: 743893275569378137} + m_Layer: 5 + m_Name: PopupHeader + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1241885294582312999 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7034836061828108288} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 741.369, y: -210.32233} + m_SizeDelta: {x: 214.8432, y: 16} + m_Pivot: {x: 0, y: 1} +--- !u!222 &1942692710355281447 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7034836061828108288} + m_CullTransparentMesh: 1 +--- !u!114 &6612787789151041457 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7034836061828108288} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: New Text + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a0ee74bf6f853704a8a568d5ef638ee9, type: 2} + m_sharedMaterial: {fileID: 9074173216178389243, guid: a0ee74bf6f853704a8a568d5ef638ee9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 16 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 5 + m_fontSizeMax: 16 + m_fontStyle: 17 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &743893275569378137 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7034836061828108288} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement + m_IgnoreLayout: 0 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: 1 + m_FlexibleHeight: 1 + m_LayoutPriority: 1 diff --git a/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupIcon.prefab b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupIcon.prefab new file mode 100644 index 0000000..5590a8d --- /dev/null +++ b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupIcon.prefab @@ -0,0 +1,98 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &5887814251614319338 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3721371113883694790} + - component: {fileID: 5474191059961008429} + - component: {fileID: 7093821785826926595} + - component: {fileID: 6531872381202374245} + m_Layer: 5 + m_Name: PopupIcon + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3721371113883694790 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5887814251614319338} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 989.9083, y: -555.6331} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5474191059961008429 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5887814251614319338} + m_CullTransparentMesh: 1 +--- !u!114 &7093821785826926595 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5887814251614319338} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: ea02ea44fa86ee445be0f7ca82098b75, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &6531872381202374245 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5887814251614319338} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement + m_IgnoreLayout: 0 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 diff --git a/Assets/Prefabs/UI/PopupReferencePrefab.prefab b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupReferencePrefab.prefab similarity index 100% rename from Assets/Prefabs/UI/PopupReferencePrefab.prefab rename to Packages/com.jovian.popup-system/Samples~/Prefabs/PopupReferencePrefab.prefab diff --git a/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupSeparator.prefab b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupSeparator.prefab new file mode 100644 index 0000000..239dd2d --- /dev/null +++ b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupSeparator.prefab @@ -0,0 +1,98 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &6770634903822758885 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6952702389074691349} + - component: {fileID: 8646545094697898389} + - component: {fileID: 4190588985333916705} + - component: {fileID: 4150277454754236166} + m_Layer: 5 + m_Name: PopupSeparator + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6952702389074691349 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6770634903822758885} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 5.3594} + m_Pivot: {x: 0, y: 1} +--- !u!222 &8646545094697898389 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6770634903822758885} + m_CullTransparentMesh: 1 +--- !u!114 &4190588985333916705 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6770634903822758885} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image + m_Material: {fileID: 0} + m_Color: {r: 1, g: 0.61809045, b: 0.15566039, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &4150277454754236166 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6770634903822758885} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement + m_IgnoreLayout: 0 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: 1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 diff --git a/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupStat.prefab b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupStat.prefab new file mode 100644 index 0000000..650e19e --- /dev/null +++ b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupStat.prefab @@ -0,0 +1,376 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3992841297615171806 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 292870618973774166} + - component: {fileID: 4060824052845831606} + - component: {fileID: 572642145995679888} + m_Layer: 5 + m_Name: label + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &292870618973774166 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3992841297615171806} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1843470073663794312} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 177.619, y: 25.6566} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4060824052845831606 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3992841297615171806} + m_CullTransparentMesh: 1 +--- !u!114 &572642145995679888 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3992841297615171806} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: New Text + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a0ee74bf6f853704a8a568d5ef638ee9, type: 2} + m_sharedMaterial: {fileID: 9074173216178389243, guid: a0ee74bf6f853704a8a568d5ef638ee9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 16 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 5 + m_fontSizeMax: 16 + m_fontStyle: 17 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &6246834368258800846 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1843470073663794312} + - component: {fileID: 7829576473989485776} + - component: {fileID: 5426390226938478828} + - component: {fileID: 2356989198378852018} + m_Layer: 0 + m_Name: PopupStat + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1843470073663794312 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6246834368258800846} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 292870618973774166} + - {fileID: 8849778187297648043} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 835.73267, y: -543.18} + m_SizeDelta: {x: 308.5346, y: 25.640076} + m_Pivot: {x: 0, y: 1} +--- !u!114 &7829576473989485776 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6246834368258800846} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.HorizontalLayoutGroup + m_Padding: + m_Left: 18 + m_Right: 10 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 0 + m_Spacing: 5.4 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 1 + m_ChildControlWidth: 0 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!114 &5426390226938478828 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6246834368258800846} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.ContentSizeFitter + m_HorizontalFit: 0 + m_VerticalFit: 0 +--- !u!114 &2356989198378852018 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6246834368258800846} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement + m_IgnoreLayout: 0 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: 1 + m_FlexibleHeight: 1 + m_LayoutPriority: 1 +--- !u!1 &9078345592336978365 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8849778187297648043} + - component: {fileID: 7828883841352225497} + - component: {fileID: 6763883082192230688} + m_Layer: 5 + m_Name: value + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8849778187297648043 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9078345592336978365} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1843470073663794312} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 178.0124, y: 25.64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7828883841352225497 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9078345592336978365} + m_CullTransparentMesh: 1 +--- !u!114 &6763883082192230688 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9078345592336978365} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: New Text + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a0ee74bf6f853704a8a568d5ef638ee9, type: 2} + m_sharedMaterial: {fileID: 9074173216178389243, guid: a0ee74bf6f853704a8a568d5ef638ee9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 16 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 1.5 + m_fontSizeMax: 16 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} diff --git a/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupText.prefab b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupText.prefab new file mode 100644 index 0000000..ea0a248 --- /dev/null +++ b/Packages/com.jovian.popup-system/Samples~/Prefabs/PopupText.prefab @@ -0,0 +1,184 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3157287847714375358 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3436634297340404643} + - component: {fileID: 386873398398603487} + - component: {fileID: 2506259255305457008} + - component: {fileID: 8858913019524689709} + - component: {fileID: 6923921070612219825} + m_Layer: 5 + m_Name: PopupText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3436634297340404643 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3157287847714375358} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 705.51843, y: -303.7433} + m_SizeDelta: {x: 133.05402, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!222 &386873398398603487 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3157287847714375358} + m_CullTransparentMesh: 1 +--- !u!114 &2506259255305457008 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3157287847714375358} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: New Text New TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew + TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew + TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew + TextNew TextNew Text New TextNew TextNew TextNew TextNew TextNew TextNew TextNew + TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew + TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew + TextNew TextNew TextNew Text New TextNew TextNew TextNew TextNew TextNew TextNew + TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew + TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew TextNew + TextNew TextNew TextNew Text + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: a0ee74bf6f853704a8a568d5ef638ee9, type: 2} + m_sharedMaterial: {fileID: 9074173216178389243, guid: a0ee74bf6f853704a8a568d5ef638ee9, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 12 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 1 + m_fontSizeMin: 1.5 + m_fontSizeMax: 12 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_characterHorizontalScale: 1 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &8858913019524689709 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3157287847714375358} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.LayoutElement + m_IgnoreLayout: 0 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: 1 + m_FlexibleHeight: 1 + m_LayoutPriority: 1 +--- !u!114 &6923921070612219825 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3157287847714375358} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.ContentSizeFitter + m_HorizontalFit: 0 + m_VerticalFit: 2 diff --git a/Packages/com.jovian.popup-system/Samples~/README.md b/Packages/com.jovian.popup-system/Samples~/README.md index fb45dbf..806f184 100644 --- a/Packages/com.jovian.popup-system/Samples~/README.md +++ b/Packages/com.jovian.popup-system/Samples~/README.md @@ -1,3 +1,37 @@ -# Samples +# Popup System Samples -This folder is reserved for sample scenes and scripts demonstrating the Popup System. +## Contents + +### Prefabs + +Reference prefabs for the popup system. Copy these into your project as a starting point. + +| Prefab | Description | +|---|---| +| `PopupReferencePrefab` | Main popup container with Canvas, CanvasGroup, Background, and Content | +| `PopupHeader` | Header text element (TMP_Text, bold, larger font) | +| `PopupText` | Body text element (TMP_Text, regular) | +| `PopupStat` | Stat row element (HorizontalLayoutGroup with label + value TMP_Text) | +| `PopupIcon` | Image element for icons or artwork | +| `PopupSeparator` | Horizontal divider line (Image, thin) | + +### Settings + +| Asset | Description | +|---|---| +| `PopupSettings` | Pre-configured PopupSettings ScriptableObject with sensible defaults | + +### Scripts + +| Script | Description | +|---|---| +| `PopupSystemExample` | Basic setup with auto-scanned triggers, GetTrigger by name, and GetTriggers by category | +| `DynamicTriggersExample` | Setting up triggers on dynamically instantiated UI using InitializeTriggersInChildren | +| `CodeOnlyPopupExample` | Showing popups from code without PopupTrigger (anchored, fixed position, follow mouse) | + +## How to use + +1. Import the samples via the Unity Package Manager (select the package, expand Samples, click Import) +2. Copy the prefabs into your project's Prefabs folder +3. Create a PopupSettings asset or use the provided one +4. Reference the example scripts for integration patterns diff --git a/Packages/com.jovian.popup-system/Samples~/Scripts/CodeOnlyPopupExample.cs b/Packages/com.jovian.popup-system/Samples~/Scripts/CodeOnlyPopupExample.cs new file mode 100644 index 0000000..689a8f3 --- /dev/null +++ b/Packages/com.jovian.popup-system/Samples~/Scripts/CodeOnlyPopupExample.cs @@ -0,0 +1,63 @@ +using Jovian.PopupSystem; +using Jovian.PopupSystem.UI; +using UnityEngine; + +/// +/// Example: Showing popups from code without PopupTrigger components. +/// +/// Use this approach for confirmation dialogs, tutorial tips, or any popup +/// that is triggered by game logic rather than hover events. +/// +public class CodeOnlyPopupExample : MonoBehaviour { + [SerializeField] PopupSettings popupSettings; + [SerializeField] PopupReference popupReferencePrefab; + [SerializeField] Transform canvasRoot; + [SerializeField] RectTransform targetElement; + + IPopupSystem popupSystem; + + void Start() { + popupSystem = new PopupSystem(popupSettings, popupReferencePrefab, canvasRoot); + popupSystem.RegisterCategory(PopupCategory.General, priority: 1); + } + + void Update() { + popupSystem?.Tick(Time.deltaTime); + + // Show anchored to an element on key press + if(Input.GetKeyDown(KeyCode.Alpha1)) { + popupSystem.Show(PopupCategory.General, builder => { + builder + .AddHeader("Anchored Popup") + .AddText("This popup is anchored to a UI element."); + }, targetElement, AnchorSide.Right); + } + + // Show at a fixed screen position + if(Input.GetKeyDown(KeyCode.Alpha2)) { + popupSystem.ShowAtPosition(PopupCategory.General, builder => { + builder + .AddHeader("Fixed Position") + .AddText("This popup appears at the center of the screen."); + }, new Vector2(Screen.width * 0.5f, Screen.height * 0.5f)); + } + + // Show following the mouse + if(Input.GetKeyDown(KeyCode.Alpha3)) { + popupSystem.Show(PopupCategory.General, builder => { + builder + .AddHeader("Follow Mouse") + .AddText("This popup follows the cursor."); + }); + } + + // Hide on key press + if(Input.GetKeyDown(KeyCode.Escape)) { + popupSystem.HideAll(); + } + } + + void OnDestroy() { + popupSystem?.Dispose(); + } +} diff --git a/Packages/com.jovian.popup-system/Samples~/Scripts/DynamicTriggersExample.cs b/Packages/com.jovian.popup-system/Samples~/Scripts/DynamicTriggersExample.cs new file mode 100644 index 0000000..f61d9e7 --- /dev/null +++ b/Packages/com.jovian.popup-system/Samples~/Scripts/DynamicTriggersExample.cs @@ -0,0 +1,50 @@ +using Jovian.PopupSystem; +using Jovian.PopupSystem.UI; +using UnityEngine; + +/// +/// Example: Using PopupSystem with dynamically instantiated UI elements. +/// +/// When UI elements are created at runtime (e.g. inventory slots, party member portraits), +/// use InitializeTriggersInChildren to scan and bind triggers after instantiation. +/// +public class DynamicTriggersExample : MonoBehaviour { + [SerializeField] PopupSettings popupSettings; + [SerializeField] PopupReference popupReferencePrefab; + [SerializeField] Transform canvasRoot; + [SerializeField] Transform slotsContainer; + [SerializeField] GameObject slotPrefab; + + IPopupSystem popupSystem; + + void Start() { + popupSystem = new PopupSystem(popupSettings, popupReferencePrefab, canvasRoot); + popupSystem.RegisterCategory(PopupCategory.Item, priority: 5); + + // Simulate creating dynamic UI slots + for(int i = 0; i < 5; i++) { + Instantiate(slotPrefab, slotsContainer); + } + + // Scan the container for any PopupTrigger components on the new slots. + // Each trigger is automatically bound to the popup system. + // The configure callback lets you set content per trigger. + popupSystem.InitializeTriggersInChildren(slotsContainer, trigger => { + var slotName = trigger.gameObject.name; + trigger.SetContent(builder => { + builder + .AddHeader(slotName) + .AddSeparator() + .AddText("This is a dynamically created slot."); + }); + }); + } + + void Update() { + popupSystem?.Tick(Time.deltaTime); + } + + void OnDestroy() { + popupSystem?.Dispose(); + } +} diff --git a/Packages/com.jovian.popup-system/Samples~/Scripts/PopupSystemExample.cs b/Packages/com.jovian.popup-system/Samples~/Scripts/PopupSystemExample.cs new file mode 100644 index 0000000..619cba0 --- /dev/null +++ b/Packages/com.jovian.popup-system/Samples~/Scripts/PopupSystemExample.cs @@ -0,0 +1,70 @@ +using Jovian.PopupSystem; +using Jovian.PopupSystem.UI; +using UnityEngine; + +/// +/// Example: Setting up PopupSystem with auto-scanned triggers. +/// +/// 1. Attach this to a GameObject in your scene. +/// 2. Assign the PopupSettings asset and PopupReference prefab. +/// 3. Set canvasRoot to the root Canvas that contains your UI and PopupTrigger components. +/// 4. Place PopupTrigger components on any UI elements that should show popups on hover. +/// 5. The system auto-scans triggers on creation. Use SetContent() to provide data. +/// +public class PopupSystemExample : MonoBehaviour { + [SerializeField] PopupSettings popupSettings; + [SerializeField] PopupReference popupReferencePrefab; + [SerializeField] Transform canvasRoot; + + IPopupSystem popupSystem; + + void Start() { + // Create the system. Passing canvasRoot auto-scans all PopupTrigger components. + popupSystem = new PopupSystem(popupSettings, popupReferencePrefab, canvasRoot); + + // Register categories before showing popups. + popupSystem.RegisterCategory(PopupCategory.Character, priority: 10); + popupSystem.RegisterCategory(PopupCategory.Item, priority: 5); + popupSystem.RegisterCategory(PopupCategory.General, priority: 1); + + // Option A: Set content on an auto-scanned trigger by GameObject name. + var characterTrigger = popupSystem.GetTrigger("CharacterPortrait"); + if(characterTrigger != null) { + characterTrigger.SetContent(builder => { + builder + .AddHeader("Kael") + .AddText("Human Warrior", "CCCCCC") + .AddSeparator() + .AddStat("Health", 55) + .AddStat("Mana", 42) + .AddStat("Level", 1) + .AddSeparator() + .AddStat("Might", 8) + .AddStat("Reflex", 2) + .AddStat("Knowledge", 5) + .AddStat("Perception", 1); + }); + } + + // Option B: Set content on all triggers of a category. + foreach(var trigger in popupSystem.GetTriggers(PopupCategory.Item)) { + trigger.SetContent(builder => { + builder + .AddHeader("Health Potion") + .AddSeparator() + .AddText("Restores a moderate amount of health.") + .AddStat("Heal Amount", 50); + }); + } + } + + void Update() { + // Tick drives delay timers and animations. + popupSystem?.Tick(Time.deltaTime); + } + + void OnDestroy() { + // Clean up all popup views. + popupSystem?.Dispose(); + } +} diff --git a/Packages/com.jovian.popup-system/Samples~/Settings/PopupSettings.asset b/Packages/com.jovian.popup-system/Samples~/Settings/PopupSettings.asset new file mode 100644 index 0000000..300fcc1 --- /dev/null +++ b/Packages/com.jovian.popup-system/Samples~/Settings/PopupSettings.asset @@ -0,0 +1,28 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e38e313f3665d464b82b22699b2a4634, type: 3} + m_Name: PopupSettings + m_EditorClassIdentifier: Jovian.PopupSystem::Jovian.PopupSystem.PopupSettings + popupDelay: 0.4 + fadeDuration: 0.2 + defaultAnchorSide: 3 + screenEdgePadding: 10 + maxPopupWidth: 400 + sortingOrder: 100 + followMouseOffset: {x: 15, y: -15} + touchHoldDuration: 0.6 + gamepadFocusTrigger: 1 + categoryPriorities: + - category: + id: Character + priority: 0 + categoryDelayOverrides: []