diff --git a/Assets/Main.unity b/Assets/Main.unity
index 678f68f..c1b03fc 100644
--- a/Assets/Main.unity
+++ b/Assets/Main.unity
@@ -151,6 +151,143 @@ Transform:
- {fileID: 520906050}
m_Father: {fileID: 465598214}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &139439301
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 139439302}
+ - component: {fileID: 139439304}
+ - component: {fileID: 139439303}
+ m_Layer: 5
+ m_Name: Title
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &139439302
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 139439301}
+ 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: 1173268650}
+ 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: 24.2}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &139439303
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 139439301}
+ 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: Ready, Set Ride!
+ m_isRightToLeft: 0
+ m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
+ m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, 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: 24
+ m_fontSizeBase: 24
+ m_fontWeight: 400
+ m_enableAutoSizing: 0
+ m_fontSizeMin: 18
+ m_fontSizeMax: 72
+ m_fontStyle: 0
+ m_HorizontalAlignment: 1
+ m_VerticalAlignment: 256
+ 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!222 &139439304
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 139439301}
+ m_CullTransparentMesh: 1
--- !u!1 &203844586
GameObject:
m_ObjectHideFlags: 0
@@ -271,13 +408,13 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 203844586}
serializedVersion: 2
- m_LocalRotation: {x: 0.30044645, y: 0.3693323, z: -0.12753193, w: 0.87009263}
+ m_LocalRotation: {x: 0.28604206, y: -0.30899116, z: 0.09801777, w: 0.9017189}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 604712594}
- m_LocalEulerAnglesHint: {x: 38.1, y: 46, z: 0}
+ m_LocalEulerAnglesHint: {x: 35.2, y: -37.83, z: 0}
--- !u!1001 &283971856
PrefabInstance:
m_ObjectHideFlags: 0
@@ -769,6 +906,258 @@ Transform:
- {fileID: 924830808}
m_Father: {fileID: 76224412}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &587767517
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 587767518}
+ - component: {fileID: 587767521}
+ - component: {fileID: 587767520}
+ - component: {fileID: 587767519}
+ m_Layer: 5
+ m_Name: Info
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &587767518
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 587767517}
+ 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: 1173268650}
+ 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: 50}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &587767519
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 587767517}
+ 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: 'Display
+
+ Current Fps
+ 30
+
+
+
+ FMCR
+
+ Distance
+ 65
+
+ Horizontal -7.5
+
+ Vertical
+ 15
+
+'
+ m_isRightToLeft: 0
+ m_fontAsset: {fileID: 11400000, guid: 52d992bef73842844aaf4142ab3f3f5d, type: 2}
+ m_sharedMaterial: {fileID: 6824989588225411414, guid: 52d992bef73842844aaf4142ab3f3f5d, 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: 14
+ m_fontSizeBase: 14
+ m_fontWeight: 400
+ m_enableAutoSizing: 0
+ m_fontSizeMin: 18
+ m_fontSizeMax: 72
+ m_fontStyle: 0
+ m_HorizontalAlignment: 1
+ m_VerticalAlignment: 256
+ m_textAlignment: 65535
+ m_characterSpacing: 0
+ m_characterHorizontalScale: 1
+ m_wordSpacing: 0
+ m_lineSpacing: 12
+ 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 &587767520
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 587767517}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 705242ff475ca7b4bbc7341c5c7218ac, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: UltraCombos.GiantMuseum.Runtime::UltraCombos.DebugMonitorHUD
+ displayText: {fileID: 587767519}
+ refreshRate: 30
+ entries:
+ - target: {fileID: 476511607}
+ groupLabel: Display
+ fields:
+ - CurrentFps
+ - target: {fileID: 465598213}
+ groupLabel: FMCR
+ fields:
+ - distance
+ - horizontal
+ - vertical
+--- !u!222 &587767521
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 587767517}
+ m_CullTransparentMesh: 1
+--- !u!1 &588558984
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 588558985}
+ - component: {fileID: 588558987}
+ - component: {fileID: 588558986}
+ m_Layer: 5
+ m_Name: Output
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &588558985
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 588558984}
+ 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: 2020615927}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0.5, y: 0.5}
+ m_AnchorMax: {x: 0.5, y: 0.5}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 1080, y: 1920}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &588558986
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 588558984}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.RawImage
+ 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_Texture: {fileID: 8400000, guid: de3934cb10406bb4daa84cabd7a9a4d8, type: 2}
+ m_UVRect:
+ serializedVersion: 2
+ x: 0
+ y: 0
+ width: 1
+ height: 1
+--- !u!222 &588558987
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 588558984}
+ m_CullTransparentMesh: 1
--- !u!1 &604712593
GameObject:
m_ObjectHideFlags: 0
@@ -1466,6 +1855,70 @@ BoxCollider:
serializedVersion: 3
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
+--- !u!1 &1173268649
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1173268650}
+ - component: {fileID: 1173268651}
+ m_Layer: 5
+ m_Name: Group
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &1173268650
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1173268649}
+ 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: 139439302}
+ - {fileID: 587767518}
+ m_Father: {fileID: 1788175773}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 1}
+ m_AnchorMax: {x: 0, y: 1}
+ m_AnchoredPosition: {x: 32, y: -32}
+ m_SizeDelta: {x: 301.5, y: 0}
+ m_Pivot: {x: 0, y: 1}
+--- !u!114 &1173268651
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1173268649}
+ 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: 0
+ m_Right: 0
+ m_Top: 0
+ m_Bottom: 0
+ m_ChildAlignment: 0
+ m_Spacing: 16.7
+ m_ChildForceExpandWidth: 1
+ m_ChildForceExpandHeight: 1
+ m_ChildControlWidth: 1
+ m_ChildControlHeight: 0
+ m_ChildScaleWidth: 0
+ m_ChildScaleHeight: 0
+ m_ReverseArrangement: 0
--- !u!1 &1182891853
GameObject:
m_ObjectHideFlags: 0
@@ -1482,7 +1935,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
- m_IsActive: 1
+ m_IsActive: 0
--- !u!114 &1182891854
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -1765,6 +2218,8 @@ RectTransform:
m_Children:
- {fileID: 403055229}
- {fileID: 1889754489}
+ - {fileID: 2020615927}
+ - {fileID: 1173268650}
m_Father: {fileID: 303688530}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@@ -1830,7 +2285,7 @@ Canvas:
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_VertexColorAlwaysGammaSpace: 0
- m_AdditionalShaderChannelsFlag: 0
+ m_AdditionalShaderChannelsFlag: 25
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 0
@@ -1871,7 +2326,7 @@ RectTransform:
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
- m_SizeDelta: {x: 608.58, y: 0}
+ m_SizeDelta: {x: 533, y: -64}
m_Pivot: {x: 1, y: 0.5}
--- !u!114 &1889754490
MonoBehaviour:
@@ -1974,6 +2429,96 @@ Transform:
m_CorrespondingSourceObject: {fileID: 2259651201424232592, guid: 2419b212eec718e4c8153284ca64a8a5, type: 3}
m_PrefabInstance: {fileID: 1992328036}
m_PrefabAsset: {fileID: 0}
+--- !u!1 &2020615926
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2020615927}
+ - component: {fileID: 2020615930}
+ - component: {fileID: 2020615929}
+ - component: {fileID: 2020615928}
+ m_Layer: 5
+ m_Name: RawImage (1)
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &2020615927
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2020615926}
+ 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: 588558985}
+ m_Father: {fileID: 1788175773}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 1, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: -535, y: 0}
+ m_SizeDelta: {x: 756, y: -64}
+ m_Pivot: {x: 1, y: 0.5}
+--- !u!114 &2020615928
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2020615926}
+ 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: 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 &2020615929
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2020615926}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Mask
+ m_ShowMaskGraphic: 0
+--- !u!222 &2020615930
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2020615926}
+ m_CullTransparentMesh: 1
--- !u!1 &2116198337
GameObject:
m_ObjectHideFlags: 0
diff --git a/Packages/com.ultracombos.giant-museum/Editor/DebugMonitorHUDEditor.cs b/Packages/com.ultracombos.giant-museum/Editor/DebugMonitorHUDEditor.cs
new file mode 100644
index 0000000..6911c53
--- /dev/null
+++ b/Packages/com.ultracombos.giant-museum/Editor/DebugMonitorHUDEditor.cs
@@ -0,0 +1,308 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using UnityEditor;
+using UnityEngine;
+
+namespace UltraCombos
+{
+ [CustomEditor(typeof(DebugMonitorHUD))]
+ public class DebugMonitorHUDEditor : Editor
+ {
+ // ── Supported member types ────────────────────────────────────────────────
+
+ private static readonly HashSet supportedTypes = new()
+ {
+ typeof(bool), typeof(int), typeof(float),
+ typeof(string), typeof(Vector2), typeof(Vector3), typeof(Color)
+ };
+
+ private static bool IsSupported(Type t) => supportedTypes.Contains(t) || t.IsEnum;
+
+ // ── Cached SerializedProperties ───────────────────────────────────────────
+
+ private SerializedProperty displayTextProp;
+ private SerializedProperty refreshRateProp;
+
+ private void OnEnable()
+ {
+ displayTextProp = serializedObject.FindProperty("displayText");
+ refreshRateProp = serializedObject.FindProperty("refreshRate");
+ }
+
+ // ── Inspector ─────────────────────────────────────────────────────────────
+
+ public override void OnInspectorGUI()
+ {
+ var hud = (DebugMonitorHUD)target;
+ serializedObject.Update();
+
+ EditorGUILayout.LabelField("Display", EditorStyles.boldLabel);
+ EditorGUILayout.PropertyField(displayTextProp, new GUIContent("Display Text",
+ "The TextMeshProUGUI component that will show the monitored values."));
+
+ EditorGUILayout.Space(4);
+ EditorGUILayout.LabelField("General", EditorStyles.boldLabel);
+ EditorGUILayout.PropertyField(refreshRateProp, new GUIContent("Refresh Rate"));
+
+ serializedObject.ApplyModifiedProperties();
+
+ EditorGUILayout.Space(10);
+ EditorGUILayout.LabelField("Entries", EditorStyles.boldLabel);
+
+ for (var i = 0; i < hud.entries.Count; i++)
+ {
+ var removed = DrawEntry(hud, hud.entries[i], i);
+ if (removed)
+ {
+ Undo.RecordObject(hud, "Remove Entry");
+ hud.entries.RemoveAt(i);
+ EditorUtility.SetDirty(hud);
+ i--;
+ }
+ EditorGUILayout.Space(2);
+ }
+
+ EditorGUILayout.Space(4);
+
+ if (GUILayout.Button("+ Add Entry", GUILayout.Height(26)))
+ {
+ Undo.RecordObject(hud, "Add Entry");
+ hud.entries.Add(new DebugMonitorHUD.Entry());
+ EditorUtility.SetDirty(hud);
+ }
+ }
+
+ // ── Draw one Entry — returns true when the user clicked Remove ─────────────
+
+ private static bool DrawEntry(DebugMonitorHUD hud, DebugMonitorHUD.Entry entry, int index)
+ {
+ var removed = false;
+
+ using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
+ {
+ // Header row
+ using (new EditorGUILayout.HorizontalScope())
+ {
+ var title = string.IsNullOrEmpty(entry.groupLabel)
+ ? $"Entry {index}"
+ : $"Entry {index} — {entry.groupLabel}";
+ EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
+ GUILayout.FlexibleSpace();
+ if (GUILayout.Button("✕", GUILayout.Width(22), GUILayout.Height(18)))
+ {
+ removed = true;
+ }
+ }
+
+ // Group label
+ EditorGUI.BeginChangeCheck();
+ var newLabel = EditorGUILayout.TextField("Group Label", entry.groupLabel);
+ if (EditorGUI.EndChangeCheck())
+ {
+ Undo.RecordObject(hud, "Edit Group Label");
+ entry.groupLabel = newLabel;
+ EditorUtility.SetDirty(hud);
+ }
+
+ // Target object
+ EditorGUI.BeginChangeCheck();
+ var newTarget = EditorGUILayout.ObjectField(
+ new GUIContent("Target",
+ "Drag any Component or ScriptableObject here.\n" +
+ "Dropping a GameObject picks its first non-Transform Component."),
+ entry.target,
+ typeof(UnityEngine.Object),
+ allowSceneObjects: true);
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ Undo.RecordObject(hud, "Set Target");
+
+ if (newTarget is GameObject go)
+ {
+ var comps = go.GetComponents();
+ newTarget = comps.FirstOrDefault(c => c is not Transform) ??
+ comps.FirstOrDefault() ??
+ (UnityEngine.Object)go;
+ }
+
+ entry.target = newTarget;
+ entry.fields.Clear();
+ EditorUtility.SetDirty(hud);
+ }
+
+ // Member selection
+ if (entry.target != null)
+ {
+ DrawMemberSelection(hud, entry);
+ }
+ }
+
+ return removed;
+ }
+
+ // ── Member checkboxes ─────────────────────────────────────────────────────
+
+ private static void DrawMemberSelection(DebugMonitorHUD hud, DebugMonitorHUD.Entry entry)
+ {
+ var type = entry.target.GetType();
+ var members = CollectMembers(type);
+
+ if (members.Count == 0)
+ {
+ EditorGUILayout.HelpBox(
+ "No displayable fields or properties found on this object.\n" +
+ "Supported types: bool · int · float · string · Vector2 · Vector3 · Color · Enum\n" +
+ "Fields must be public or [SerializeField]. Properties must be public with a getter.",
+ MessageType.Info);
+ return;
+ }
+
+ EditorGUILayout.Space(4);
+
+ // Select All / None
+ using (new EditorGUILayout.HorizontalScope())
+ {
+ EditorGUILayout.LabelField("Members to Display", EditorStyles.boldLabel);
+ GUILayout.FlexibleSpace();
+
+ if (GUILayout.Button("All", GUILayout.Width(36)))
+ {
+ Undo.RecordObject(hud, "Select All Members");
+ entry.fields = members.Select(m => m.Name).ToList();
+ EditorUtility.SetDirty(hud);
+ }
+ if (GUILayout.Button("None", GUILayout.Width(38)))
+ {
+ Undo.RecordObject(hud, "Deselect All Members");
+ entry.fields.Clear();
+ EditorUtility.SetDirty(hud);
+ }
+ }
+
+ // Per-member toggles
+ EditorGUI.indentLevel++;
+
+ foreach (var mi in members)
+ {
+ var isSelected = entry.fields.Contains(mi.Name);
+ var niceName = ObjectNames.NicifyVariableName(mi.Name);
+ var memberType = GetMemberType(mi);
+ var typeName = FriendlyType(memberType);
+ var hasRange = mi.GetCustomAttribute() != null;
+ var isProperty = mi is PropertyInfo;
+ var suffix = (isProperty ? ", prop" : string.Empty) +
+ (hasRange ? ", Range" : string.Empty);
+
+ var label = new GUIContent(
+ $"{niceName} ({typeName}{suffix})",
+ tooltip: $"{(isProperty ? "Property" : "Field")}: {mi.Name}\nType: {memberType.FullName}");
+
+ EditorGUI.BeginChangeCheck();
+ var next = EditorGUILayout.ToggleLeft(label, isSelected);
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ Undo.RecordObject(hud, next ? "Add Member" : "Remove Member");
+ if (next)
+ {
+ entry.fields.Add(mi.Name);
+ }
+ else
+ {
+ entry.fields.Remove(mi.Name);
+ }
+ EditorUtility.SetDirty(hud);
+ }
+ }
+
+ EditorGUI.indentLevel--;
+ }
+
+ // ── Reflection helpers ────────────────────────────────────────────────────
+
+ private static List CollectMembers(Type type)
+ {
+ const BindingFlags fieldFlags =
+ BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+ const BindingFlags propFlags =
+ BindingFlags.Public | BindingFlags.Instance;
+
+ var result = new List();
+
+ for (var t = type; t != null && !IsUnityBuiltIn(t); t = t.BaseType)
+ {
+ foreach (var fi in t.GetFields(fieldFlags | BindingFlags.DeclaredOnly))
+ {
+ // Skip compiler-generated backing fields (e.g. k__BackingField).
+ if (fi.Name[0] == '<')
+ {
+ continue;
+ }
+ var exposed = fi.IsPublic || fi.GetCustomAttribute() != null;
+ if (!exposed)
+ {
+ continue;
+ }
+ if (fi.GetCustomAttribute() != null)
+ {
+ continue;
+ }
+ if (!IsSupported(fi.FieldType))
+ {
+ continue;
+ }
+ if (!result.Any(r => r.Name == fi.Name))
+ {
+ result.Add(fi);
+ }
+ }
+
+ foreach (var pi in t.GetProperties(propFlags | BindingFlags.DeclaredOnly))
+ {
+ // Must have a getter and no index parameters.
+ if (!pi.CanRead || pi.GetIndexParameters().Length > 0)
+ {
+ continue;
+ }
+ if (pi.GetCustomAttribute() != null)
+ {
+ continue;
+ }
+ if (!IsSupported(pi.PropertyType))
+ {
+ continue;
+ }
+ if (!result.Any(r => r.Name == pi.Name))
+ {
+ result.Add(pi);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private static Type GetMemberType(MemberInfo mi) =>
+ mi is FieldInfo fi ? fi.FieldType : ((PropertyInfo)mi).PropertyType;
+
+ private static bool IsUnityBuiltIn(Type t) =>
+ t.Namespace != null &&
+ t.Namespace.StartsWith("UnityEngine", StringComparison.Ordinal);
+
+ private static string FriendlyType(Type t)
+ {
+ if (t == typeof(float)) { return "float"; }
+ if (t == typeof(int)) { return "int"; }
+ if (t == typeof(bool)) { return "bool"; }
+ if (t == typeof(string)) { return "string"; }
+ if (t == typeof(Vector2)) { return "Vector2"; }
+ if (t == typeof(Vector3)) { return "Vector3"; }
+ if (t == typeof(Color)) { return "Color"; }
+ if (t.IsEnum) { return t.Name; }
+ return t.Name;
+ }
+ }
+}
diff --git a/Packages/com.ultracombos.giant-museum/Editor/DebugMonitorHUDEditor.cs.meta b/Packages/com.ultracombos.giant-museum/Editor/DebugMonitorHUDEditor.cs.meta
new file mode 100644
index 0000000..826aa64
--- /dev/null
+++ b/Packages/com.ultracombos.giant-museum/Editor/DebugMonitorHUDEditor.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: b9de48d136769a442bc787083085d69d
\ No newline at end of file
diff --git a/Packages/com.ultracombos.giant-museum/Editor/DebugSettingsGUIEditor.cs b/Packages/com.ultracombos.giant-museum/Editor/DebugSettingsGUIEditor.cs
index 46243e5..c589baf 100644
--- a/Packages/com.ultracombos.giant-museum/Editor/DebugSettingsGUIEditor.cs
+++ b/Packages/com.ultracombos.giant-museum/Editor/DebugSettingsGUIEditor.cs
@@ -10,7 +10,7 @@ namespace UltraCombos
[CustomEditor(typeof(DebugSettingsGUI))]
public class DebugSettingsGUIEditor : Editor
{
- // ── Supported field types ─────────────────────────────────────────────────
+ // ── Supported member types ────────────────────────────────────────────────
private static readonly HashSet supportedTypes = new()
{
@@ -27,7 +27,7 @@ namespace UltraCombos
private void OnEnable()
{
- toggleKeyProp = serializedObject.FindProperty("toggleKey");
+ toggleKeyProp = serializedObject.FindProperty("toggleKey");
initialRectProp = serializedObject.FindProperty("initialRect");
}
@@ -39,7 +39,7 @@ namespace UltraCombos
serializedObject.Update();
EditorGUILayout.LabelField("General", EditorStyles.boldLabel);
- EditorGUILayout.PropertyField(toggleKeyProp, new GUIContent("Toggle Key"));
+ EditorGUILayout.PropertyField(toggleKeyProp, new GUIContent("Toggle Key"));
EditorGUILayout.PropertyField(initialRectProp, new GUIContent("Initial Rect"));
serializedObject.ApplyModifiedProperties();
@@ -102,9 +102,7 @@ namespace UltraCombos
EditorUtility.SetDirty(gui);
}
- // Target object.
- // Drag any Component or ScriptableObject here.
- // Dropping a GameObject picks its first non-Transform Component automatically.
+ // Target object
EditorGUI.BeginChangeCheck();
var newTarget = EditorGUILayout.ObjectField(
new GUIContent("Target",
@@ -131,29 +129,29 @@ namespace UltraCombos
EditorUtility.SetDirty(gui);
}
- // Field selection
+ // Member selection
if (entry.target != null)
{
- DrawFieldSelection(gui, entry);
+ DrawMemberSelection(gui, entry);
}
}
return removed;
}
- // ── Field checkboxes ──────────────────────────────────────────────────────
+ // ── Member checkboxes ─────────────────────────────────────────────────────
- private static void DrawFieldSelection(DebugSettingsGUI gui, DebugSettingsGUI.Entry entry)
+ private static void DrawMemberSelection(DebugSettingsGUI gui, DebugSettingsGUI.Entry entry)
{
var type = entry.target.GetType();
- var fields = CollectFields(type);
+ var members = CollectMembers(type);
- if (fields.Count == 0)
+ if (members.Count == 0)
{
EditorGUILayout.HelpBox(
- "No displayable fields found on this object.\n" +
+ "No displayable fields or properties found on this object.\n" +
"Supported types: bool · int · float · string · Vector2 · Vector3 · Color · Enum\n" +
- "Fields must be public or marked [SerializeField].",
+ "Fields must be public or [SerializeField]. Properties must be public with a getter.",
MessageType.Info);
return;
}
@@ -163,50 +161,54 @@ namespace UltraCombos
// Select All / None
using (new EditorGUILayout.HorizontalScope())
{
- EditorGUILayout.LabelField("Fields to Display", EditorStyles.boldLabel);
+ EditorGUILayout.LabelField("Members to Display", EditorStyles.boldLabel);
GUILayout.FlexibleSpace();
if (GUILayout.Button("All", GUILayout.Width(36)))
{
- Undo.RecordObject(gui, "Select All Fields");
- entry.fields = fields.Select(f => f.Name).ToList();
+ Undo.RecordObject(gui, "Select All Members");
+ entry.fields = members.Select(m => m.Name).ToList();
EditorUtility.SetDirty(gui);
}
if (GUILayout.Button("None", GUILayout.Width(38)))
{
- Undo.RecordObject(gui, "Deselect All Fields");
+ Undo.RecordObject(gui, "Deselect All Members");
entry.fields.Clear();
EditorUtility.SetDirty(gui);
}
}
- // Per-field toggles
+ // Per-member toggles
EditorGUI.indentLevel++;
- foreach (var fi in fields)
+ foreach (var mi in members)
{
- var isSelected = entry.fields.Contains(fi.Name);
- var niceName = ObjectNames.NicifyVariableName(fi.Name);
- var typeName = FriendlyType(fi.FieldType);
- var hasRange = fi.GetCustomAttribute() != null;
+ var isSelected = entry.fields.Contains(mi.Name);
+ var niceName = ObjectNames.NicifyVariableName(mi.Name);
+ var memberType = GetMemberType(mi);
+ var typeName = FriendlyType(memberType);
+ var hasRange = mi.GetCustomAttribute() != null;
+ var isProperty = mi is PropertyInfo;
+ var suffix = (isProperty ? ", prop" : string.Empty) +
+ (hasRange ? ", Range" : string.Empty);
var label = new GUIContent(
- $"{niceName} ({typeName}{(hasRange ? ", Range" : string.Empty)})",
- tooltip: $"Field: {fi.Name}\nType: {fi.FieldType.FullName}");
+ $"{niceName} ({typeName}{suffix})",
+ tooltip: $"{(isProperty ? "Property" : "Field")}: {mi.Name}\nType: {memberType.FullName}");
EditorGUI.BeginChangeCheck();
var next = EditorGUILayout.ToggleLeft(label, isSelected);
if (EditorGUI.EndChangeCheck())
{
- Undo.RecordObject(gui, next ? "Add Field" : "Remove Field");
+ Undo.RecordObject(gui, next ? "Add Member" : "Remove Member");
if (next)
{
- entry.fields.Add(fi.Name);
+ entry.fields.Add(mi.Name);
}
else
{
- entry.fields.Remove(fi.Name);
+ entry.fields.Remove(mi.Name);
}
EditorUtility.SetDirty(gui);
}
@@ -217,17 +219,24 @@ namespace UltraCombos
// ── Reflection helpers ────────────────────────────────────────────────────
- private static List CollectFields(Type type)
+ private static List CollectMembers(Type type)
{
- const BindingFlags flags =
+ const BindingFlags fieldFlags =
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+ const BindingFlags propFlags =
+ BindingFlags.Public | BindingFlags.Instance;
- var result = new List();
+ var result = new List();
- for (var t = type; t != null && t != typeof(UnityEngine.Object); t = t.BaseType)
+ for (var t = type; t != null && !IsUnityBuiltIn(t); t = t.BaseType)
{
- foreach (var fi in t.GetFields(flags | BindingFlags.DeclaredOnly))
+ foreach (var fi in t.GetFields(fieldFlags | BindingFlags.DeclaredOnly))
{
+ // Skip compiler-generated backing fields (e.g. k__BackingField).
+ if (fi.Name[0] == '<')
+ {
+ continue;
+ }
var exposed = fi.IsPublic || fi.GetCustomAttribute() != null;
if (!exposed)
{
@@ -246,11 +255,39 @@ namespace UltraCombos
result.Add(fi);
}
}
+
+ foreach (var pi in t.GetProperties(propFlags | BindingFlags.DeclaredOnly))
+ {
+ // Must have a getter and no index parameters.
+ if (!pi.CanRead || pi.GetIndexParameters().Length > 0)
+ {
+ continue;
+ }
+ if (pi.GetCustomAttribute() != null)
+ {
+ continue;
+ }
+ if (!IsSupported(pi.PropertyType))
+ {
+ continue;
+ }
+ if (!result.Any(r => r.Name == pi.Name))
+ {
+ result.Add(pi);
+ }
+ }
}
return result;
}
+ private static Type GetMemberType(MemberInfo mi) =>
+ mi is FieldInfo fi ? fi.FieldType : ((PropertyInfo)mi).PropertyType;
+
+ private static bool IsUnityBuiltIn(Type t) =>
+ t.Namespace != null &&
+ t.Namespace.StartsWith("UnityEngine", StringComparison.Ordinal);
+
private static string FriendlyType(Type t)
{
if (t == typeof(float)) { return "float"; }
diff --git a/Packages/com.ultracombos.giant-museum/Runtime/DebugMonitorHUD.cs b/Packages/com.ultracombos.giant-museum/Runtime/DebugMonitorHUD.cs
new file mode 100644
index 0000000..9761eca
--- /dev/null
+++ b/Packages/com.ultracombos.giant-museum/Runtime/DebugMonitorHUD.cs
@@ -0,0 +1,285 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+using System.Text;
+using TMPro;
+using UnityEngine;
+
+namespace UltraCombos
+{
+ ///
+ /// Read-only runtime monitor that renders selected component fields and properties
+ /// into a single TextMeshProUGUI component using TMP rich-text colour tags.
+ /// Drag the target TextMeshProUGUI into the Display Text field in the Inspector.
+ ///
+ [ExecuteAlways]
+ public class DebugMonitorHUD : MonoBehaviour
+ {
+ // ── Data ──────────────────────────────────────────────────────────────────
+
+ [Serializable]
+ public class Entry
+ {
+ public UnityEngine.Object target;
+ public string groupLabel = string.Empty;
+
+ /// Field/property names written by the custom Editor.
+ public List fields = new();
+ }
+
+ [Header("Display")]
+ [SerializeField] private TextMeshProUGUI displayText;
+
+ [Header("General")]
+ [Tooltip("How many times per second the text is refreshed. 0 = every frame.")]
+ [Range(0f, 60f)]
+ public float refreshRate = 20f;
+
+ [Header("Entries")]
+ public List entries = new();
+
+ // ── Runtime state ─────────────────────────────────────────────────────────
+
+ private float nextRefreshTime;
+ private readonly StringBuilder stringBuilder = new();
+
+ // ── TMP colour tokens ─────────────────────────────────────────────────────
+
+ private const string colHeader = "#FFC940";
+ private const string colLabel = "#AAAAAA";
+ private const string colFloat = "#7EC8E3";
+ private const string colInt = "#7EC8E3";
+ private const string colBoolTrue = "#7EE37E";
+ private const string colBoolFalse = "#E37E7E";
+ private const string colString = "#E3D47E";
+ private const string colEnum = "#C8A0E3";
+ private const string colVec = "#E3C87E";
+ private const string colColor = "#E3E3E3";
+ private const string colReadonly = "#666666";
+
+ // ── Unity callbacks ───────────────────────────────────────────────────────
+
+ private void Update()
+ {
+ if (displayText == null)
+ {
+ return;
+ }
+
+ if (refreshRate > 0f && Time.unscaledTime < nextRefreshTime)
+ {
+ return;
+ }
+
+ nextRefreshTime = Time.unscaledTime + (refreshRate > 0f ? 1f / refreshRate : 0f);
+ RebuildText();
+ }
+
+ // ── Text building ─────────────────────────────────────────────────────────
+
+ private void RebuildText()
+ {
+ stringBuilder.Clear();
+
+ var first = true;
+ foreach (var entry in entries)
+ {
+ if (entry == null || entry.target == null || entry.fields.Count == 0)
+ {
+ continue;
+ }
+
+ if (!first)
+ {
+ stringBuilder.AppendLine();
+ }
+ first = false;
+
+ AppendEntry(entry);
+ }
+
+ displayText.SetText(stringBuilder);
+ }
+
+ private void AppendEntry(Entry entry)
+ {
+ if (!string.IsNullOrEmpty(entry.groupLabel))
+ {
+ stringBuilder
+ .Append("')
+ .Append(entry.groupLabel)
+ .AppendLine("");
+ }
+
+ var type = entry.target.GetType();
+ const BindingFlags fieldFlags =
+ BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+ const BindingFlags propFlags =
+ BindingFlags.Public | BindingFlags.Instance;
+
+ foreach (var name in entry.fields)
+ {
+ // Resolve by name — check fields first, then properties.
+ var mi = (MemberInfo)type.GetField(name, fieldFlags) ??
+ type.GetProperty(name, propFlags);
+ if (mi == null)
+ {
+ continue;
+ }
+
+ try
+ {
+ AppendMember(entry.target, mi);
+ }
+ catch
+ {
+ // Skip members that throw during reflection.
+ }
+ }
+ }
+
+ private void AppendMember(object obj, MemberInfo mi)
+ {
+ var label = NicifyName(mi.Name);
+ var val = GetMemberValue(mi, obj);
+ var ftype = GetMemberType(mi);
+
+ stringBuilder
+ .Append("')
+ .Append(label)
+ .Append(" ");
+
+ AppendValue(val, ftype);
+ stringBuilder.AppendLine();
+ }
+
+ private void AppendValue(object val, Type ftype)
+ {
+ if (ftype == typeof(bool))
+ {
+ var b = (bool)val;
+ stringBuilder
+ .Append("')
+ .Append(b ? "true" : "false")
+ .Append("");
+ return;
+ }
+
+ if (ftype == typeof(float))
+ {
+ stringBuilder
+ .Append("')
+ .Append(((float)val).ToString("G5", CultureInfo.InvariantCulture))
+ .Append("");
+ return;
+ }
+
+ if (ftype == typeof(int))
+ {
+ stringBuilder
+ .Append("')
+ .Append(((int)val).ToString(CultureInfo.InvariantCulture))
+ .Append("");
+ return;
+ }
+
+ if (ftype == typeof(string))
+ {
+ stringBuilder
+ .Append("\"")
+ .Append(val as string ?? string.Empty)
+ .Append("\"");
+ return;
+ }
+
+ if (ftype == typeof(Vector2))
+ {
+ var v = (Vector2)val;
+ stringBuilder
+ .Append("(")
+ .Append(v.x.ToString("G4", CultureInfo.InvariantCulture)).Append(", ")
+ .Append(v.y.ToString("G4", CultureInfo.InvariantCulture))
+ .Append(")");
+ return;
+ }
+
+ if (ftype == typeof(Vector3))
+ {
+ var v = (Vector3)val;
+ stringBuilder
+ .Append("(")
+ .Append(v.x.ToString("G4", CultureInfo.InvariantCulture)).Append(", ")
+ .Append(v.y.ToString("G4", CultureInfo.InvariantCulture)).Append(", ")
+ .Append(v.z.ToString("G4", CultureInfo.InvariantCulture))
+ .Append(")");
+ return;
+ }
+
+ if (ftype == typeof(Color))
+ {
+ var c = (Color)val;
+ var hex = ColorUtility.ToHtmlStringRGBA(c);
+ // Coloured swatch character followed by the hex value.
+ stringBuilder
+ .Append("■ ")
+ .Append("#").Append(hex).Append("");
+ return;
+ }
+
+ if (ftype.IsEnum)
+ {
+ stringBuilder
+ .Append("')
+ .Append(val?.ToString() ?? "?")
+ .Append("");
+ return;
+ }
+
+ // Fallback: display the ToString() value as read-only italic text.
+ stringBuilder
+ .Append("")
+ .Append(val?.ToString() ?? "(null)")
+ .Append("");
+ }
+
+ // ── Reflection helpers ────────────────────────────────────────────────────
+
+ private static Type GetMemberType(MemberInfo mi) =>
+ mi is FieldInfo fi ? fi.FieldType : ((PropertyInfo)mi).PropertyType;
+
+ private static object GetMemberValue(MemberInfo mi, object obj) =>
+ mi is FieldInfo fi ? fi.GetValue(obj) : ((PropertyInfo)mi).GetValue(obj);
+
+ /// Converts a camelCase or _prefixed field name to a readable label.
+ private static string NicifyName(string s)
+ {
+ var start = 0;
+ while (start < s.Length && s[start] == '_')
+ {
+ start++;
+ }
+ if (s.Length > start + 1 && s[start] == 'm' && s[start + 1] == '_')
+ {
+ start += 2;
+ }
+
+ var sb = new StringBuilder();
+ for (var i = start; i < s.Length; i++)
+ {
+ var c = s[i];
+ if (i == start)
+ {
+ sb.Append(char.ToUpper(c));
+ continue;
+ }
+ if (char.IsUpper(c) && !char.IsUpper(s[i - 1]))
+ {
+ sb.Append(' ');
+ }
+ sb.Append(c);
+ }
+ return sb.ToString();
+ }
+ }
+}
diff --git a/Packages/com.ultracombos.giant-museum/Runtime/DebugMonitorHUD.cs.meta b/Packages/com.ultracombos.giant-museum/Runtime/DebugMonitorHUD.cs.meta
new file mode 100644
index 0000000..f243a58
--- /dev/null
+++ b/Packages/com.ultracombos.giant-museum/Runtime/DebugMonitorHUD.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 705242ff475ca7b4bbc7341c5c7218ac
\ No newline at end of file
diff --git a/Packages/com.ultracombos.giant-museum/Runtime/DebugSettingsGUI.cs b/Packages/com.ultracombos.giant-museum/Runtime/DebugSettingsGUI.cs
index 07ce2b8..701719b 100644
--- a/Packages/com.ultracombos.giant-museum/Runtime/DebugSettingsGUI.cs
+++ b/Packages/com.ultracombos.giant-museum/Runtime/DebugSettingsGUI.cs
@@ -9,8 +9,8 @@ namespace UltraCombos
{
///
/// Runtime settings panel. Press the configured toggle key (default F1) to show or hide.
- /// Drag any Component into the Entries list via the Inspector, select the fields to expose,
- /// and the panel lets you tweak them live at runtime.
+ /// Drag any Component into the Entries list via the Inspector, select the fields or
+ /// properties to expose, and the panel lets you tweak them live at runtime.
///
public class DebugSettingsGUI : MonoBehaviour
{
@@ -22,7 +22,7 @@ namespace UltraCombos
public UnityEngine.Object target;
public string groupLabel = string.Empty;
- /// Field names written by the custom Editor.
+ /// Field/property names written by the custom Editor.
public List fields = new();
}
@@ -107,66 +107,70 @@ namespace UltraCombos
}
var type = entry.target.GetType();
- const BindingFlags flags =
+ const BindingFlags fieldFlags =
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+ const BindingFlags propFlags =
+ BindingFlags.Public | BindingFlags.Instance;
foreach (var name in entry.fields)
{
- var fi = type.GetField(name, flags);
- if (fi == null)
+ // Resolve by name — check fields first, then properties.
+ var mi = (MemberInfo)type.GetField(name, fieldFlags) ??
+ type.GetProperty(name, propFlags);
+ if (mi == null)
{
continue;
}
try
{
- DrawField(entry.target, fi);
+ DrawMember(entry.target, mi);
}
catch
{
- // Skip fields that throw during reflection.
+ // Skip members that throw during reflection.
}
}
}
// ── Per-type drawing ──────────────────────────────────────────────────────
- private void DrawField(object obj, FieldInfo fi)
+ private void DrawMember(object obj, MemberInfo mi)
{
- var val = fi.GetValue(obj);
- var ftype = fi.FieldType;
- var label = NicifyName(fi.Name);
+ var val = GetMemberValue(mi, obj);
+ var ftype = GetMemberType(mi);
+ var label = NicifyName(mi.Name);
if (ftype == typeof(bool))
{
- DrawBool(obj, fi, (bool)val, label);
+ DrawBool(obj, mi, (bool)val, label);
}
else if (ftype == typeof(float))
{
- DrawFloat(obj, fi, (float)val, label);
+ DrawFloat(obj, mi, (float)val, label);
}
else if (ftype == typeof(int))
{
- DrawInt(obj, fi, (int)val, label);
+ DrawInt(obj, mi, (int)val, label);
}
else if (ftype == typeof(string))
{
- DrawString(obj, fi, (string)val, label);
+ DrawString(obj, mi, (string)val, label);
}
else if (ftype == typeof(Vector2))
{
- DrawVector2(obj, fi, (Vector2)val, label);
+ DrawVector2(obj, mi, (Vector2)val, label);
}
else if (ftype == typeof(Vector3))
{
- DrawVector3(obj, fi, (Vector3)val, label);
+ DrawVector3(obj, mi, (Vector3)val, label);
}
else if (ftype == typeof(Color))
{
- DrawColor(obj, fi, (Color)val, label);
+ DrawColor(obj, mi, (Color)val, label);
}
else if (ftype.IsEnum)
{
- DrawEnum(obj, fi, val, ftype, label);
+ DrawEnum(obj, mi, val, ftype, label);
}
else
{
@@ -179,7 +183,7 @@ namespace UltraCombos
}
}
- private void DrawBool(object obj, FieldInfo fi, bool val, string label)
+ private void DrawBool(object obj, MemberInfo mi, bool val, string label)
{
using (new GUILayout.HorizontalScope())
{
@@ -187,14 +191,14 @@ namespace UltraCombos
var next = GUILayout.Toggle(val, val ? "✓" : string.Empty);
if (next != val)
{
- fi.SetValue(obj, next);
+ SetMemberValue(mi, obj, next);
}
}
}
- private void DrawFloat(object obj, FieldInfo fi, float val, string label)
+ private void DrawFloat(object obj, MemberInfo mi, float val, string label)
{
- var range = fi.GetCustomAttribute();
+ var range = mi.GetCustomAttribute();
using (new GUILayout.HorizontalScope())
{
GUILayout.Label(label, labelStyle, GUILayout.Width(150));
@@ -213,14 +217,14 @@ namespace UltraCombos
if (!Mathf.Approximately(next, val))
{
- fi.SetValue(obj, next);
+ SetMemberValue(mi, obj, next);
}
}
}
- private void DrawInt(object obj, FieldInfo fi, int val, string label)
+ private void DrawInt(object obj, MemberInfo mi, int val, string label)
{
- var range = fi.GetCustomAttribute();
+ var range = mi.GetCustomAttribute();
using (new GUILayout.HorizontalScope())
{
GUILayout.Label(label, labelStyle, GUILayout.Width(150));
@@ -239,12 +243,12 @@ namespace UltraCombos
if (next != val)
{
- fi.SetValue(obj, next);
+ SetMemberValue(mi, obj, next);
}
}
}
- private void DrawString(object obj, FieldInfo fi, string val, string label)
+ private void DrawString(object obj, MemberInfo mi, string val, string label)
{
using (new GUILayout.HorizontalScope())
{
@@ -252,12 +256,12 @@ namespace UltraCombos
var next = GUILayout.TextField(val ?? string.Empty);
if (next != val)
{
- fi.SetValue(obj, next);
+ SetMemberValue(mi, obj, next);
}
}
}
- private void DrawVector2(object obj, FieldInfo fi, Vector2 val, string label)
+ private void DrawVector2(object obj, MemberInfo mi, Vector2 val, string label)
{
using (new GUILayout.HorizontalScope())
{
@@ -269,12 +273,12 @@ namespace UltraCombos
var next = new Vector2(x, y);
if (next != val)
{
- fi.SetValue(obj, next);
+ SetMemberValue(mi, obj, next);
}
}
}
- private void DrawVector3(object obj, FieldInfo fi, Vector3 val, string label)
+ private void DrawVector3(object obj, MemberInfo mi, Vector3 val, string label)
{
using (new GUILayout.HorizontalScope())
{
@@ -288,12 +292,12 @@ namespace UltraCombos
var next = new Vector3(x, y, z);
if (next != val)
{
- fi.SetValue(obj, next);
+ SetMemberValue(mi, obj, next);
}
}
}
- private void DrawColor(object obj, FieldInfo fi, Color val, string label)
+ private void DrawColor(object obj, MemberInfo mi, Color val, string label)
{
GUILayout.Label(label, headerStyle);
using (new GUILayout.VerticalScope(subBoxStyle))
@@ -305,7 +309,7 @@ namespace UltraCombos
var next = new Color(r, g, b, a);
if (next != val)
{
- fi.SetValue(obj, next);
+ SetMemberValue(mi, obj, next);
}
}
}
@@ -321,7 +325,7 @@ namespace UltraCombos
}
}
- private void DrawEnum(object obj, FieldInfo fi, object val, Type type, string label)
+ private void DrawEnum(object obj, MemberInfo mi, object val, Type type, string label)
{
var names = Enum.GetNames(type);
var values = Enum.GetValues(type);
@@ -336,7 +340,7 @@ namespace UltraCombos
var next = GUILayout.SelectionGrid(cur, names, names.Length);
if (next != cur)
{
- fi.SetValue(obj, values.GetValue(next));
+ SetMemberValue(mi, obj, values.GetValue(next));
}
}
else
@@ -351,12 +355,30 @@ namespace UltraCombos
{
cur = (cur + 1) % names.Length;
}
- fi.SetValue(obj, values.GetValue(Mathf.Clamp(cur, 0, values.Length - 1)));
+ SetMemberValue(mi, obj, values.GetValue(Mathf.Clamp(cur, 0, values.Length - 1)));
}
}
}
- // ── Helpers ───────────────────────────────────────────────────────────────
+ // ── Reflection helpers ────────────────────────────────────────────────────
+
+ private static Type GetMemberType(MemberInfo mi) =>
+ mi is FieldInfo fi ? fi.FieldType : ((PropertyInfo)mi).PropertyType;
+
+ private static object GetMemberValue(MemberInfo mi, object obj) =>
+ mi is FieldInfo fi ? fi.GetValue(obj) : ((PropertyInfo)mi).GetValue(obj);
+
+ private static void SetMemberValue(MemberInfo mi, object obj, object val)
+ {
+ if (mi is FieldInfo fi)
+ {
+ fi.SetValue(obj, val);
+ }
+ else if (mi is PropertyInfo pi && pi.CanWrite)
+ {
+ pi.SetValue(obj, val);
+ }
+ }
private static float ParseFloat(string s, float fallback)
=> float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var v) ? v : fallback;
diff --git a/Packages/com.ultracombos.giant-museum/Runtime/DisplayConfig.cs b/Packages/com.ultracombos.giant-museum/Runtime/DisplayConfig.cs
index 4b9847b..b92fc0d 100644
--- a/Packages/com.ultracombos.giant-museum/Runtime/DisplayConfig.cs
+++ b/Packages/com.ultracombos.giant-museum/Runtime/DisplayConfig.cs
@@ -19,7 +19,7 @@ namespace UltraCombos
[SerializeField] private bool exitOnEsc = true;
private float timestamp = 0;
- [field: SerializeField, ReadOnly] public float CurrentFps { get; private set; } = 30.0f;
+ [field: SerializeField, ReadOnly] public float CurrentFps { get; private set; } = 60.0f;
[Header("Event")]
public UnityEvent onQuit = new UnityEvent();
diff --git a/Packages/com.ultracombos.giant-museum/Runtime/UltraCombos.GiantMuseum.Runtime.asmdef b/Packages/com.ultracombos.giant-museum/Runtime/UltraCombos.GiantMuseum.Runtime.asmdef
index 0476dc7..8f63e98 100644
--- a/Packages/com.ultracombos.giant-museum/Runtime/UltraCombos.GiantMuseum.Runtime.asmdef
+++ b/Packages/com.ultracombos.giant-museum/Runtime/UltraCombos.GiantMuseum.Runtime.asmdef
@@ -2,7 +2,8 @@
"name": "UltraCombos.GiantMuseum.Runtime",
"rootNamespace": "UltraCombos",
"references": [
- "GUID:75469ad4d38634e559750d17036d5f7c"
+ "GUID:75469ad4d38634e559750d17036d5f7c",
+ "Unity.TextMeshPro"
],
"includePlatforms": [],
"excludePlatforms": [],
diff --git a/Unity-25014-ReadySetRide.slnx b/Unity-25014-ReadySetRide.slnx
index 3cf89bf..a1edd40 100644
--- a/Unity-25014-ReadySetRide.slnx
+++ b/Unity-25014-ReadySetRide.slnx
@@ -22,11 +22,12 @@
+
-
+
@@ -34,7 +35,6 @@
-