From 4fd75863e09c14f0f01ccefc49ad87a048795856 Mon Sep 17 00:00:00 2001 From: Tom Simons Date: Mon, 7 Oct 2024 08:27:10 +0200 Subject: [PATCH] started separating credentials ui and logic --- .../3DTiles/RealityMesh (3D Tiles).prefab | 25 +- .../ObjectLibrary/OBJLayerGameObject.prefab | 118 +++++++++ .../OBJLayerGameObject.prefab.meta | 7 + .../CredentialsPropertySection.prefab | 16 +- ...b => CredentialStatusPropertyPanel.prefab} | 45 ++-- ...CredentialStatusPropertyPanel.prefab.meta} | 0 .../GoogleRealityMeshConfigurationAdapter.cs | 4 +- .../Tiles3DContentOverlayInspector.cs | 16 +- .../LayerTypes/ILayerWithCredentials.cs | 2 +- .../LayerTypes/Tile3DLayerGameObject.cs | 17 +- .../CredentialsInputPropertySection.cs | 106 ++++++++ ...> CredentialsInputPropertySection.cs.meta} | 0 .../CredentialsPropertySection.cs | 245 ------------------ .../CredentialsPropertySectionInstantiator.cs | 18 +- .../CredentialsValidationPropertySection.cs | 56 ++++ ...edentialsValidationPropertySection.cs.meta | 11 + .../PropertyPanels/LayerCredentialsHandler.cs | 224 ++++++++++++++++ .../LayerCredentialsHandler.cs.meta | 11 + 18 files changed, 625 insertions(+), 296 deletions(-) create mode 100644 Assets/Prefabs/ObjectLibrary/OBJLayerGameObject.prefab create mode 100644 Assets/Prefabs/ObjectLibrary/OBJLayerGameObject.prefab.meta rename Assets/Prefabs/UI/Sidebar/SpecificComponents/{Reauthenticate.prefab => CredentialStatusPropertyPanel.prefab} (99%) rename Assets/Prefabs/UI/Sidebar/SpecificComponents/{Reauthenticate.prefab.meta => CredentialStatusPropertyPanel.prefab.meta} (100%) create mode 100644 Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsInputPropertySection.cs rename Assets/Scripts/Layers/Properties/PropertyPanels/{CredentialsPropertySection.cs.meta => CredentialsInputPropertySection.cs.meta} (100%) delete mode 100644 Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsPropertySection.cs create mode 100644 Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsValidationPropertySection.cs create mode 100644 Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsValidationPropertySection.cs.meta create mode 100644 Assets/Scripts/Layers/Properties/PropertyPanels/LayerCredentialsHandler.cs create mode 100644 Assets/Scripts/Layers/Properties/PropertyPanels/LayerCredentialsHandler.cs.meta diff --git a/Assets/Prefabs/3DTiles/RealityMesh (3D Tiles).prefab b/Assets/Prefabs/3DTiles/RealityMesh (3D Tiles).prefab index 725a8a0f9..26d3afc9a 100644 --- a/Assets/Prefabs/3DTiles/RealityMesh (3D Tiles).prefab +++ b/Assets/Prefabs/3DTiles/RealityMesh (3D Tiles).prefab @@ -19,6 +19,7 @@ GameObject: - component: {fileID: -5688274655914667246} - component: {fileID: -3892557586120215936} - component: {fileID: 379969814246679949} + - component: {fileID: 6181233540970977359} m_Layer: 6 m_Name: RealityMesh (3D Tiles) m_TagString: Untagged @@ -79,10 +80,12 @@ MonoBehaviour: boundingVolumeType: 0 values: [] BottomLeft: + coordinateSystem: 0 extraLongitudeRotation: 0 extraLattitudeRotation: 0 Points: [] TopRight: + coordinateSystem: 0 extraLongitudeRotation: 0 extraLattitudeRotation: 0 Points: [] @@ -156,10 +159,12 @@ MonoBehaviour: boundingVolumeType: 0 values: [] BottomLeft: + coordinateSystem: 0 extraLongitudeRotation: 0 extraLattitudeRotation: 0 Points: [] TopRight: + coordinateSystem: 0 extraLongitudeRotation: 0 extraLattitudeRotation: 0 Points: [] @@ -329,6 +334,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 284d1c20d5a85488d9fd5444dc075baf, type: 3} m_Name: m_EditorClassIdentifier: + prefabIdentifier: 71fff5c85650fcd4d9f59e4e182b5e95 onShow: m_PersistentCalls: m_Calls: [] @@ -336,7 +342,6 @@ MonoBehaviour: m_PersistentCalls: m_Calls: [] usePropertySections: 1 - openPropertiesOnStart: 1 UnsupportedExtensionsMessage: m_PersistentCalls: m_Calls: [] @@ -352,7 +357,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 630f741154ed48488dc6602ef25dab3a, type: 3} m_Name: m_EditorClassIdentifier: - origin: {fileID: 0} worldTransformShifter: {fileID: -3892557586120215936} referenceCoordinateSystem: 4326 onPreShift: @@ -386,8 +390,23 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: autoApplyCredentials: 1 - propertySectionPrefab: {fileID: -860560823292524916, guid: f241bd5b609aa4447ae89fb4325470ef, + inputPropertySectionPrefab: {fileID: 4139614324750460760, guid: d01d03b127df7b34cacbb24ee8f84d28, type: 3} OnCredentialsPropertySectionInstantiated: m_PersistentCalls: m_Calls: [] +--- !u!114 &6181233540970977359 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7974831043381414785} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e3b2880c796b146d191c4b41da5c526b, type: 3} + m_Name: + m_EditorClassIdentifier: + findKeyInVaultOnURLChange: 1 + keyVault: {fileID: 11400000, guid: dc14abcfb42578a4394b67591fc8ad1e, type: 2} + autoApplyCredentials: 1 diff --git a/Assets/Prefabs/ObjectLibrary/OBJLayerGameObject.prefab b/Assets/Prefabs/ObjectLibrary/OBJLayerGameObject.prefab new file mode 100644 index 000000000..b8ab6c0ca --- /dev/null +++ b/Assets/Prefabs/ObjectLibrary/OBJLayerGameObject.prefab @@ -0,0 +1,118 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3937650689336427930 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3322842894136088838} + - component: {fileID: -18391829949753534} + - component: {fileID: 221556199992705649} + - component: {fileID: 5199055326224624808} + - component: {fileID: -1110989767012178270} + - component: {fileID: -2184178992114909871} + m_Layer: 0 + m_Name: OBJLayerGameObject + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3322842894136088838 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3937650689336427930} + serializedVersion: 2 + 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} +--- !u!114 &-18391829949753534 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3937650689336427930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 630f741154ed48488dc6602ef25dab3a, type: 3} + m_Name: + m_EditorClassIdentifier: + worldTransformShifter: {fileID: 0} + referenceCoordinateSystem: 4979 + onPreShift: + m_PersistentCalls: + m_Calls: [] + onPostShift: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &221556199992705649 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3937650689336427930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 92795e992dcbe4b3c8ada171c5551674, type: 3} + m_Name: + m_EditorClassIdentifier: + prefabIdentifier: 69439623527f94aeba831877c30c088e + onShow: + m_PersistentCalls: + m_Calls: [] + onHide: + m_PersistentCalls: + m_Calls: [] + objectCreated: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &5199055326224624808 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3937650689336427930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 374a4172ed370412f9cd812f206f98f0, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &-1110989767012178270 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3937650689336427930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b8cceefce4ff4530b78245056d126688, type: 3} + m_Name: + m_EditorClassIdentifier: + propertySectionPrefab: {fileID: 0} +--- !u!114 &-2184178992114909871 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3937650689336427930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 853853f6f5bff49d3bc79215e1ebbea8, type: 3} + m_Name: + m_EditorClassIdentifier: + convertToggle: {fileID: 0} diff --git a/Assets/Prefabs/ObjectLibrary/OBJLayerGameObject.prefab.meta b/Assets/Prefabs/ObjectLibrary/OBJLayerGameObject.prefab.meta new file mode 100644 index 000000000..45de85a3a --- /dev/null +++ b/Assets/Prefabs/ObjectLibrary/OBJLayerGameObject.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 69439623527f94aeba831877c30c088e +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/UI/PropertySections/CredentialsPropertySection.prefab b/Assets/Prefabs/UI/PropertySections/CredentialsPropertySection.prefab index 19a687757..5bd580a2c 100644 --- a/Assets/Prefabs/UI/PropertySections/CredentialsPropertySection.prefab +++ b/Assets/Prefabs/UI/PropertySections/CredentialsPropertySection.prefab @@ -465,8 +465,6 @@ MonoBehaviour: headerWithCredentialTypeDropdown: {fileID: 8614721123552596982} credentialTypeDropdown: {fileID: 1208963087933705121} errorMessage: {fileID: 8623644015317721457} - findKeyInVaultOnURLChange: 1 - keyVault: {fileID: 11400000, guid: dc14abcfb42578a4394b67591fc8ad1e, type: 2} --- !u!1001 &8099856209361245446 PrefabInstance: m_ObjectHideFlags: 0 @@ -888,17 +886,17 @@ PrefabInstance: - target: {fileID: 3259352152404739228, guid: 63fccc9491de61645b43763357399bad, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 3259352152404739228, guid: 63fccc9491de61645b43763357399bad, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 3259352152404739228, guid: 63fccc9491de61645b43763357399bad, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 68.32 objectReference: {fileID: 0} - target: {fileID: 3259352152404739228, guid: 63fccc9491de61645b43763357399bad, type: 3} @@ -913,7 +911,7 @@ PrefabInstance: - target: {fileID: 3259352152404739228, guid: 63fccc9491de61645b43763357399bad, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -20 objectReference: {fileID: 0} - target: {fileID: 4190861408758051029, guid: 63fccc9491de61645b43763357399bad, type: 3} @@ -993,7 +991,7 @@ PrefabInstance: - target: {fileID: 5507835546160925638, guid: 63fccc9491de61645b43763357399bad, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 5507835546160925638, guid: 63fccc9491de61645b43763357399bad, type: 3} @@ -1003,7 +1001,7 @@ PrefabInstance: - target: {fileID: 5507835546160925638, guid: 63fccc9491de61645b43763357399bad, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 5507835546160925638, guid: 63fccc9491de61645b43763357399bad, type: 3} @@ -1058,7 +1056,7 @@ PrefabInstance: - target: {fileID: 5507835546160925638, guid: 63fccc9491de61645b43763357399bad, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -105.3429 objectReference: {fileID: 0} - target: {fileID: 5507835546160925638, guid: 63fccc9491de61645b43763357399bad, type: 3} diff --git a/Assets/Prefabs/UI/Sidebar/SpecificComponents/Reauthenticate.prefab b/Assets/Prefabs/UI/Sidebar/SpecificComponents/CredentialStatusPropertyPanel.prefab similarity index 99% rename from Assets/Prefabs/UI/Sidebar/SpecificComponents/Reauthenticate.prefab rename to Assets/Prefabs/UI/Sidebar/SpecificComponents/CredentialStatusPropertyPanel.prefab index 01f173a96..7cb1e9226 100644 --- a/Assets/Prefabs/UI/Sidebar/SpecificComponents/Reauthenticate.prefab +++ b/Assets/Prefabs/UI/Sidebar/SpecificComponents/CredentialStatusPropertyPanel.prefab @@ -35,10 +35,10 @@ RectTransform: - {fileID: 4021479921507654788} m_Father: {fileID: 8214791640540355321} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 172.01585, y: 0} - m_SizeDelta: {x: 308.0317, y: 48.7211} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!222 &3784876728717632333 CanvasRenderer: @@ -3892,8 +3892,9 @@ GameObject: - component: {fileID: 8900216667368085455} - component: {fileID: 1537685062570398413} - component: {fileID: 7740096372769682743} + - component: {fileID: 4139614324750460760} m_Layer: 5 - m_Name: Reauthenticate + m_Name: CredentialStatusPropertyPanel m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -4016,6 +4017,20 @@ MonoBehaviour: m_EditorClassIdentifier: m_HorizontalFit: 0 m_VerticalFit: 2 +--- !u!114 &4139614324750460760 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6130069684234356313} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b8a8ed3eaf9144115a10483962e11053, type: 3} + m_Name: + m_EditorClassIdentifier: + validCredentialsPanel: {fileID: 6362988405208082338} + invalidCredentialsPanel: {fileID: 7898008316363899058} --- !u!1 &6362988405208082338 GameObject: m_ObjectHideFlags: 0 @@ -4035,7 +4050,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!224 &8214791640540355321 RectTransform: m_ObjectHideFlags: 0 @@ -4051,10 +4066,10 @@ RectTransform: - {fileID: 2581016988260149482} m_Father: {fileID: 5507835546160925638} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 172.01585, y: -92.55635} - m_SizeDelta: {x: 344.0317, y: 62.7211} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 62.7211} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &1241544358955960822 CanvasRenderer: @@ -7530,7 +7545,7 @@ PrefabInstance: - target: {fileID: 1518934753131645070, guid: 9b03494031e3bb643997bd5432bc015b, type: 3} propertyPath: m_SizeDelta.y - value: 15.74 + value: 0 objectReference: {fileID: 0} - target: {fileID: 1518934753131645070, guid: 9b03494031e3bb643997bd5432bc015b, type: 3} @@ -7741,22 +7756,22 @@ PrefabInstance: - target: {fileID: 8229404338314957064, guid: 9b03494031e3bb643997bd5432bc015b, type: 3} propertyPath: m_AnchorMax.y - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 8229404338314957064, guid: 9b03494031e3bb643997bd5432bc015b, type: 3} propertyPath: m_AnchorMin.y - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 8229404338314957064, guid: 9b03494031e3bb643997bd5432bc015b, type: 3} propertyPath: m_AnchoredPosition.x - value: 21.924149 + value: 0 objectReference: {fileID: 0} - target: {fileID: 8229404338314957064, guid: 9b03494031e3bb643997bd5432bc015b, type: 3} propertyPath: m_AnchoredPosition.y - value: -18.6494 + value: 0 objectReference: {fileID: 0} - target: {fileID: 8624777396393225214, guid: 9b03494031e3bb643997bd5432bc015b, type: 3} diff --git a/Assets/Prefabs/UI/Sidebar/SpecificComponents/Reauthenticate.prefab.meta b/Assets/Prefabs/UI/Sidebar/SpecificComponents/CredentialStatusPropertyPanel.prefab.meta similarity index 100% rename from Assets/Prefabs/UI/Sidebar/SpecificComponents/Reauthenticate.prefab.meta rename to Assets/Prefabs/UI/Sidebar/SpecificComponents/CredentialStatusPropertyPanel.prefab.meta diff --git a/Assets/Scripts/Configuration/GoogleRealityMesh/GoogleRealityMeshConfigurationAdapter.cs b/Assets/Scripts/Configuration/GoogleRealityMesh/GoogleRealityMeshConfigurationAdapter.cs index b24e7c261..7c7829da5 100644 --- a/Assets/Scripts/Configuration/GoogleRealityMesh/GoogleRealityMeshConfigurationAdapter.cs +++ b/Assets/Scripts/Configuration/GoogleRealityMesh/GoogleRealityMeshConfigurationAdapter.cs @@ -30,9 +30,9 @@ private void Awake() read3DTileset.enabled = true; } - private void CredentialsPropertySectionInstantiated(CredentialsPropertySection credentialsPropertySection) + private void CredentialsPropertySectionInstantiated(CredentialsValidationPropertySection credentialsInputPropertySection) { - credentialsPropertySection.SetInputFieldsValues(key: configuration.ApiKey); + // credentialsInputPropertySection.SetInputFieldsValues(key: configuration.ApiKey); } } } \ No newline at end of file diff --git a/Assets/Scripts/Interface/ContentOverlay/Tiles3DContentOverlayInspector.cs b/Assets/Scripts/Interface/ContentOverlay/Tiles3DContentOverlayInspector.cs index c678099d2..7a586e196 100644 --- a/Assets/Scripts/Interface/ContentOverlay/Tiles3DContentOverlayInspector.cs +++ b/Assets/Scripts/Interface/ContentOverlay/Tiles3DContentOverlayInspector.cs @@ -1,6 +1,8 @@ using Netherlands3D.Twin.Layers; +using Netherlands3D.Twin.Layers.Properties; using UnityEngine; using UnityEngine.Networking; +using UnityEngine.Serialization; namespace Netherlands3D.Twin.UI.LayerInspector { @@ -11,8 +13,8 @@ public class Tiles3DContentOverlayInspector : OverlayInspector [Tooltip("The same URL input is used here, as the one used in the property panel")] [SerializeField] private Tile3DLayerPropertySection tile3DLayerPropertySection; - [Tooltip("The same credentials input is used here, as the one used in the property panel")] [SerializeField] - private CredentialsPropertySection credentialsPropertySection; + [FormerlySerializedAs("credentialsPropertySection")] [Tooltip("The same credentials input is used here, as the one used in the property panel")] + [SerializeField] private LayerCredentialsHandler credentialsHandler; [SerializeField] private RectTransform credentialExplanation; @@ -45,7 +47,7 @@ private void ServerResponseReceived(UnityWebRequest webRequestResult) if (webRequestResult.ReturnedServerError()) { credentialExplanation.gameObject.SetActive(false); - credentialsPropertySection.gameObject.SetActive(false); + credentialsHandler.gameObject.SetActive(false); } } @@ -54,7 +56,7 @@ private void OnEnable() keyVault.OnAuthorizationTypeDetermined.AddListener(DeterminedAuthorizationType); //Hide the credentials section by default. Only activated if we determine the URL needs credentials - credentialsPropertySection.gameObject.SetActive(false); + credentialsHandler.gameObject.SetActive(false); credentialExplanation.gameObject.SetActive(false); } @@ -95,9 +97,9 @@ private void DeterminedAuthorizationType(string url, AuthorizationType authoriza default: //Something went wrong, show the credentials section, starting with a default authentication input type var startingAuthenticationType = keyVault.GetKnownAuthorizationTypeForURL(url); - credentialsPropertySection.LayerWithCredentials = layerGameObjectWithCredentials; - credentialsPropertySection.SetAuthorizationInputType(startingAuthenticationType); - credentialsPropertySection.gameObject.SetActive(true); + // credentialsHandler.LayerWithCredentials = layerGameObjectWithCredentials; + credentialsHandler.SetAuthorizationInputType(startingAuthenticationType); + // credentialsHandler.gameObject.SetActive(true); credentialExplanation.gameObject.SetActive(true); break; } diff --git a/Assets/Scripts/Layers/LayerTypes/ILayerWithCredentials.cs b/Assets/Scripts/Layers/LayerTypes/ILayerWithCredentials.cs index 7e635a4d3..4a61fc7a0 100644 --- a/Assets/Scripts/Layers/LayerTypes/ILayerWithCredentials.cs +++ b/Assets/Scripts/Layers/LayerTypes/ILayerWithCredentials.cs @@ -9,7 +9,7 @@ namespace Netherlands3D.Twin.Layers.LayerTypes { public interface ILayerWithCredentials { - public CredentialsPropertySection PropertySection { get; set; } + // public CredentialsInputPropertySection InputPropertySection { get; set; } public UnityEvent OnServerResponseReceived { get; } public UnityEvent OnURLChanged { get; } diff --git a/Assets/Scripts/Layers/LayerTypes/Tile3DLayerGameObject.cs b/Assets/Scripts/Layers/LayerTypes/Tile3DLayerGameObject.cs index 324ef2922..3dcebffef 100644 --- a/Assets/Scripts/Layers/LayerTypes/Tile3DLayerGameObject.cs +++ b/Assets/Scripts/Layers/LayerTypes/Tile3DLayerGameObject.cs @@ -54,13 +54,13 @@ private void EnableTileset() tileSet.RefreshTiles(); } - private CredentialsPropertySection propertySection; - - public CredentialsPropertySection PropertySection - { - get => propertySection; - set => propertySection = value; - } + // private CredentialsInputPropertySection inputPropertySection; + // + // public CredentialsInputPropertySection InputPropertySection + // { + // get => inputPropertySection; + // set => inputPropertySection = value; + // } protected void Awake() { @@ -71,6 +71,9 @@ protected void Awake() propertySections = GetComponents().ToList(); else propertySections = new(); + + if (!GetComponent()) + gameObject.AddComponent(); } private void OnEnable() diff --git a/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsInputPropertySection.cs b/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsInputPropertySection.cs new file mode 100644 index 000000000..96da1acdf --- /dev/null +++ b/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsInputPropertySection.cs @@ -0,0 +1,106 @@ +using System; +using TMPro; +using UnityEngine; + +namespace Netherlands3D.Twin.Layers.Properties +{ + public class CredentialsInputPropertySection : MonoBehaviour + { + private LayerCredentialsHandler handler; + + [SerializeField] private TMP_InputField userNameInputField; + [SerializeField] private TMP_InputField passwordInputField; + [SerializeField] private TMP_InputField keyTokenOrCodeInputField; + [SerializeField] private TMP_Text keyTokenOrCodeLabel; + + [SerializeField] private Transform headerDefault; + [SerializeField] private Transform headerWithCredentialTypeDropdown; + [SerializeField] private TMP_Dropdown credentialTypeDropdown; + [SerializeField] private Transform errorMessage; + private bool skipFirstCredentialErrorMessage = true; + + private void Awake() + { + handler = GetComponent(); + if (!handler) + handler = gameObject.AddComponent(); + } + + private void OnEnable() + { + errorMessage.gameObject.SetActive(false); + } + + private void OnDisable() + { + } + + public void ShowCredentialsWarning() + { + //First failure from server may be ignored, because we want to give the user a chance to fill in the credentials via the credentials panel + if(skipFirstCredentialErrorMessage) + { + skipFirstCredentialErrorMessage = false; + return; + } + + //For now a standard text is shown. + errorMessage.gameObject.SetActive(true); + } + + public void CloseFailedFeedback() + { + errorMessage.gameObject.SetActive(false); + } + + /// + /// Apply the credentials input fields and start checking our authorization vault + /// + public void ApplyCredentials() + { + errorMessage.gameObject.SetActive(false); + + switch(handler.AuthorizationType) + { + case AuthorizationType.UsernamePassword: + handler.UserName = userNameInputField.text; + handler.PasswordOrKeyOrTokenOrCode = passwordInputField.text; + break; + case AuthorizationType.InferableSingleKey: + handler.PasswordOrKeyOrTokenOrCode = keyTokenOrCodeInputField.text; + break; + } + + handler.ApplyCredentials(); + } + + /// + /// Set the authorization input type and update the UI + /// + public void SetAuthorizationInputType(int type) + { + handler.SetAuthorizationInputType((AuthorizationType)type); + } + + public void SetAuthorizationInputType(AuthorizationType type) + { + handler.SetAuthorizationInputType(type); + + credentialTypeDropdown.value = (int)type; + + //Similar values are not reapplied, so make sure to the dropdown items appear + if (credentialTypeDropdown.TryGetComponent(out DropdownSelection dropdownSelection)) + dropdownSelection.DropdownSelectItem(credentialTypeDropdown.value); + } + + /// + /// Fill the inputs with predefined values + /// + public void SetInputFieldsValues(string username = "", string password = "", string key = "") + { + if(username.Length > 0) userNameInputField.text = username; + if(password.Length > 0) passwordInputField.text = password; + if(key.Length > 0) keyTokenOrCodeInputField.text = key; + } + } +} diff --git a/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsPropertySection.cs.meta b/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsInputPropertySection.cs.meta similarity index 100% rename from Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsPropertySection.cs.meta rename to Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsInputPropertySection.cs.meta diff --git a/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsPropertySection.cs b/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsPropertySection.cs deleted file mode 100644 index e048ed1b1..000000000 --- a/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsPropertySection.cs +++ /dev/null @@ -1,245 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using Netherlands3D.Twin.Layers.LayerTypes; -using TMPro; -using UnityEngine; -using UnityEngine.Networking; -using Netherlands3D.Web; -using System; -using System.Collections.Specialized; -using UnityEngine.Events; - -namespace Netherlands3D.Twin -{ - public class CredentialsPropertySection : MonoBehaviour - { - [SerializeField] private TMP_InputField userNameInputField; - [SerializeField] private TMP_InputField passwordInputField; - [SerializeField] private TMP_InputField keyTokenOrCodeInputField; - [SerializeField] private TMP_Text keyTokenOrCodeLabel; - - [SerializeField] private Transform headerDefault; - [SerializeField] private Transform headerWithCredentialTypeDropdown; - [SerializeField] private TMP_Dropdown credentialTypeDropdown; - [SerializeField] private Transform errorMessage; - private bool skipFirstCredentialErrorMessage = true; - - [Header("Settings")] - [SerializeField] private bool findKeyInVaultOnURLChange = true; - - [Tooltip("KeyVault Scriptable Object")] [SerializeField] private KeyVault keyVault; - private AuthorizationType authorizationType = AuthorizationType.Public; - private StoredAuthorization storedAuthorization; - - private bool autoApplyCredentials = false; - public bool AutoApplyCredentials - { - get => autoApplyCredentials; - set => autoApplyCredentials = value; - } - - private ILayerWithCredentials layerWithCredentials; - public ILayerWithCredentials LayerWithCredentials { - get - { - return layerWithCredentials; - } - set - { - if(layerWithCredentials != null) - { - layerWithCredentials.OnURLChanged.RemoveListener(UrlHasChanged); - layerWithCredentials.OnServerResponseReceived.RemoveListener(HandleServerResponse); - } - layerWithCredentials = value; - - if(layerWithCredentials != null) - { - layerWithCredentials.OnURLChanged.AddListener(UrlHasChanged); - layerWithCredentials.OnServerResponseReceived.AddListener(HandleServerResponse); - - UrlHasChanged(layerWithCredentials.URL); - } - } - } - - private void OnEnable() { - errorMessage.gameObject.SetActive(false); - - keyVault.OnAuthorizationTypeDetermined.AddListener(OnCredentialTypeDetermined); - } - - private void OnDisable() - { - keyVault.OnAuthorizationTypeDetermined.RemoveListener(OnCredentialTypeDetermined); - - if(LayerWithCredentials != null) - LayerWithCredentials.OnURLChanged.RemoveListener(UrlHasChanged); - } - - public void ShowCredentialsWarning() - { - //First failure from server may be ignored, because we want to give the user a chance to fill in the credentials via the credentials panel - if(skipFirstCredentialErrorMessage) - { - skipFirstCredentialErrorMessage = false; - return; - } - - //For now a standard text is shown. - errorMessage.gameObject.SetActive(true); - } - - public void HandleServerResponse(UnityWebRequest webRequest) - { - if(webRequest.ReturnedServerError()) - { - //Disable credentials property section if we get a server error (not tied to credentials) - Debug.LogWarning("Server request failed: " + webRequest); - gameObject.SetActive(false); - } - else if(webRequest.RequiresCredentials()) - { - Debug.LogWarning("Credentials required: " + webRequest); - //Show a credentials warning if the server request failed for another reason (probably tied to credential failure) - ShowCredentialsWarning(); - } - } - - public void CloseFailedFeedback() - { - errorMessage.gameObject.SetActive(false); - - //Gob back to our generic guess field type so we can retry again - authorizationType = AuthorizationType.InferableSingleKey; - SetAuthorizationInputType(authorizationType); - } - - private void UrlHasChanged(string newURL) - { - //New url. If we already got this one in the vault, apply the credentials - if(findKeyInVaultOnURLChange) - { - storedAuthorization = keyVault.GetStoredAuthorization(newURL); - - if(storedAuthorization != null) - { - Debug.Log("Found stored authorization for: " + newURL + " with type: " + storedAuthorization.authorizationType); - authorizationType = storedAuthorization.authorizationType; - userNameInputField.text = storedAuthorization.username; - passwordInputField.text = storedAuthorization.password; - keyTokenOrCodeInputField.text = storedAuthorization.key; - } - else - { - authorizationType = keyVault.GetKnownAuthorizationTypeForURL(newURL); - } - - SetAuthorizationInputType(authorizationType); - - if(AutoApplyCredentials) - ApplyCredentials(); - } - } - - /// - /// Apply the credentials input fields and start checking our authorization vault - /// - public void ApplyCredentials() - { - errorMessage.gameObject.SetActive(false); - - switch(authorizationType) - { - case AuthorizationType.UsernamePassword: - keyVault.TryBasicAuthentication( - LayerWithCredentials.URL, - userNameInputField.text, - passwordInputField.text - ); - break; - case AuthorizationType.InferableSingleKey: - keyVault.TryToFindSpecificCredentialType( - LayerWithCredentials.URL, - keyTokenOrCodeInputField.text - ); - break; - } - } - - private void OnCredentialTypeDetermined(string url, AuthorizationType type) - { - credentialTypeDropdown.value = (int)type; - authorizationType = type; - - switch(type) - { - case AuthorizationType.UsernamePassword: - layerWithCredentials.SetCredentials(userNameInputField.text, passwordInputField.text); - break; - case AuthorizationType.BearerToken: - layerWithCredentials.SetBearerToken(keyTokenOrCodeInputField.text); - break; - case AuthorizationType.Key: - layerWithCredentials.SetKey(keyTokenOrCodeInputField.text); - break; - case AuthorizationType.Code: - layerWithCredentials.SetCode(keyTokenOrCodeInputField.text); - break; - case AuthorizationType.Token: - layerWithCredentials.SetToken(keyTokenOrCodeInputField.text); - break; - case AuthorizationType.Public: - layerWithCredentials.ClearCredentials(); - break; - case AuthorizationType.Unknown: - layerWithCredentials.ClearCredentials(); - ShowCredentialsWarning(); - break; - } - } - - /// - /// Set the authorization input type and update the UI - /// - public void SetAuthorizationInputType(int type) - { - authorizationType = (AuthorizationType)type; - Debug.Log("Force AuthorizationType to: " + authorizationType); - - SetAuthorizationInputType(authorizationType); - } - - /// - /// Fill the inputs with predefined values - /// - public void SetInputFieldsValues(string username = "", string password = "", string key = "") - { - if(username.Length > 0) userNameInputField.text = username; - if(password.Length > 0) passwordInputField.text = password; - if(key.Length > 0) keyTokenOrCodeInputField.text = key; - } - - /// - /// Set the authorization input type and update the UI - /// - public void SetAuthorizationInputType(AuthorizationType type) - { - if( - type == AuthorizationType.Key - || type == AuthorizationType.Token - || type == AuthorizationType.BearerToken - || type == AuthorizationType.Code - ) - type = AuthorizationType.InferableSingleKey; - - credentialTypeDropdown.value = (int)type; - - //Similar values are not reapplied, so make sure to the dropdown items appear - if (credentialTypeDropdown.TryGetComponent(out DropdownSelection dropdownSelection)) - dropdownSelection.DropdownSelectItem(credentialTypeDropdown.value); - - authorizationType = type; - } - } -} diff --git a/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsPropertySectionInstantiator.cs b/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsPropertySectionInstantiator.cs index f25fe9a1a..9634b696a 100644 --- a/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsPropertySectionInstantiator.cs +++ b/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsPropertySectionInstantiator.cs @@ -1,3 +1,4 @@ +using System; using Netherlands3D.Twin.Layers.LayerTypes; using Netherlands3D.Twin.UI.LayerInspector; using UnityEngine; @@ -8,16 +9,19 @@ namespace Netherlands3D.Twin.Layers.Properties public class CredentialsPropertySectionInstantiator : MonoBehaviour, IPropertySectionInstantiator { [SerializeField] private bool autoApplyCredentials = false; - [SerializeField] private CredentialsPropertySection propertySectionPrefab; - [HideInInspector] public UnityEvent OnCredentialsPropertySectionInstantiated = new(); - + [SerializeField] private CredentialsValidationPropertySection inputPropertySectionPrefab; + [HideInInspector] public UnityEvent OnCredentialsPropertySectionInstantiated = new(); + public void AddToProperties(RectTransform properties) { - if (!propertySectionPrefab) return; + if (!inputPropertySectionPrefab) return; + + var settings = Instantiate(inputPropertySectionPrefab, properties); - var settings = Instantiate(propertySectionPrefab, properties); - settings.AutoApplyCredentials = autoApplyCredentials; - settings.LayerWithCredentials = GetComponent(); + settings.Handler = GetComponent(); + if (settings.Handler == null) + gameObject.AddComponent(); + OnCredentialsPropertySectionInstantiated.Invoke(settings); } } diff --git a/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsValidationPropertySection.cs b/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsValidationPropertySection.cs new file mode 100644 index 000000000..c0ce4ca2e --- /dev/null +++ b/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsValidationPropertySection.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Netherlands3D.Twin.Layers.LayerTypes; +using UnityEngine; + +namespace Netherlands3D.Twin.Layers.Properties +{ + public class CredentialsValidationPropertySection : MonoBehaviour + { + private LayerCredentialsHandler handler; + + [SerializeField] private GameObject validCredentialsPanel; + [SerializeField] private GameObject invalidCredentialsPanel; + + public LayerCredentialsHandler Handler + { + get => handler; + set + { + if (handler) + handler.CredentialsAccepted.RemoveListener(OnCredentialsAccepted); + + handler = value; + + OnCredentialsAccepted(handler.HasValidCredentials); + + handler.CredentialsAccepted.AddListener(OnCredentialsAccepted); + } + } + + private void OnEnable() + { + if (handler) + handler.CredentialsAccepted.AddListener(OnCredentialsAccepted); + } + + private void OnDisable() + { + if (handler) + handler.CredentialsAccepted.RemoveListener(OnCredentialsAccepted); + } + + private void OnCredentialsAccepted(bool accepted) + { + validCredentialsPanel.SetActive(accepted); + invalidCredentialsPanel.SetActive(!accepted); + if (accepted) + { + print("accepted"); + } + else + print("rejected"); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsValidationPropertySection.cs.meta b/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsValidationPropertySection.cs.meta new file mode 100644 index 000000000..d8831e554 --- /dev/null +++ b/Assets/Scripts/Layers/Properties/PropertyPanels/CredentialsValidationPropertySection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8a8ed3eaf9144115a10483962e11053 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Layers/Properties/PropertyPanels/LayerCredentialsHandler.cs b/Assets/Scripts/Layers/Properties/PropertyPanels/LayerCredentialsHandler.cs new file mode 100644 index 000000000..f3ecb8706 --- /dev/null +++ b/Assets/Scripts/Layers/Properties/PropertyPanels/LayerCredentialsHandler.cs @@ -0,0 +1,224 @@ +using System; +using Netherlands3D.Twin.Layers.LayerTypes; +using UnityEngine; +using UnityEngine.Networking; +using UnityEngine.Events; + +namespace Netherlands3D.Twin.Layers.Properties +{ + [RequireComponent(typeof(ILayerWithCredentials))] + [RequireComponent(typeof(LayerGameObject))] + public class LayerCredentialsHandler : MonoBehaviour + { + public string UserName { get; set; } + public string PasswordOrKeyOrTokenOrCode { get; set; } + + [Header("Settings")] + [SerializeField] private bool findKeyInVaultOnURLChange = true; + + [Tooltip("KeyVault Scriptable Object")] + [SerializeField] private KeyVault keyVault; + + private AuthorizationType authorizationType = AuthorizationType.Public; + private StoredAuthorization storedAuthorization; + + [SerializeField] private bool autoApplyCredentials = false; + + public bool AutoApplyCredentials + { + get => autoApplyCredentials; + set => autoApplyCredentials = value; + } + + public AuthorizationType AuthorizationType => authorizationType; + + private ILayerWithCredentials layerWithCredentials; + private LayerGameObject layerGameObject; + + // public ILayerWithCredentials LayerWithCredentials + // { + // get { return layerWithCredentials; } + // set + // { + // if (layerWithCredentials != null) + // { + // layerWithCredentials.OnURLChanged.RemoveListener(UrlHasChanged); + // layerWithCredentials.OnServerResponseReceived.RemoveListener(HandleServerResponse); + // } + // + // layerWithCredentials = value; + // + // if (layerWithCredentials != null) + // { + // layerWithCredentials.OnURLChanged.AddListener(UrlHasChanged); + // layerWithCredentials.OnServerResponseReceived.AddListener(HandleServerResponse); + // + // UrlHasChanged(layerWithCredentials.URL); + // } + // } + // } + + public bool HasValidCredentials => layerGameObject && layerGameObject.LayerData.HasValidCredentials; + public UnityEvent CredentialsAccepted => layerGameObject.LayerData.HasValidCredentialsChanged; + + private void Awake() + { + layerWithCredentials = GetComponent(); + layerGameObject = GetComponent(); + } + + private void OnEnable() + { + keyVault.OnAuthorizationTypeDetermined.AddListener(OnCredentialTypeDetermined); + layerWithCredentials.OnURLChanged.AddListener(UrlHasChanged); + layerWithCredentials.OnServerResponseReceived.AddListener(HandleServerResponse); + + UrlHasChanged(layerWithCredentials.URL); + } + + private void OnDisable() + { + keyVault.OnAuthorizationTypeDetermined.RemoveListener(OnCredentialTypeDetermined); + + layerWithCredentials.OnURLChanged.RemoveListener(UrlHasChanged); + layerWithCredentials.OnServerResponseReceived.RemoveListener(HandleServerResponse); + } + + public void HandleServerResponse(UnityWebRequest webRequest) + { + + if (webRequest.result != UnityWebRequest.Result.Success) + { + layerGameObject.LayerData.HasValidCredentials = false; + // CredentialsAccepted.Invoke(false); + } + else + { + layerGameObject.LayerData.HasValidCredentials = true; + // CredentialsAccepted.Invoke(true); + } + + // if(webRequest.ReturnedServerError()) + // { + // //Disable credentials property section if we get a server error (not tied to credentials) + // Debug.LogWarning("Server request failed: " + webRequest); + // gameObject.SetActive(false); + // } + // else + if (webRequest.RequiresCredentials()) + { + Debug.LogWarning("Credentials required: " + webRequest); + //Show a credentials warning if the server request failed for another reason (probably tied to credential failure) + } + } + + public void CloseFailedFeedback() + { + CredentialsAccepted.Invoke(false); + + //Gob back to our generic guess field type so we can retry again + authorizationType = AuthorizationType.InferableSingleKey; + SetAuthorizationInputType(authorizationType); + } + + private void UrlHasChanged(string newURL) + { + //New url. If we already got this one in the vault, apply the credentials + if (findKeyInVaultOnURLChange) + { + storedAuthorization = keyVault.GetStoredAuthorization(newURL); + + if (storedAuthorization != null) + { + Debug.Log("Found stored authorization for: " + newURL + " with type: " + storedAuthorization.authorizationType); + authorizationType = storedAuthorization.authorizationType; + CredentialsAccepted.Invoke(true); + } + else + { + authorizationType = keyVault.GetKnownAuthorizationTypeForURL(newURL); + CredentialsAccepted.Invoke(false); + } + + SetAuthorizationInputType(authorizationType); + + if (AutoApplyCredentials) + ApplyCredentials(); + } + } + + public void ApplyCredentials() + { + switch (authorizationType) + { + case AuthorizationType.UsernamePassword: + keyVault.TryBasicAuthentication( + layerWithCredentials.URL, + UserName, + PasswordOrKeyOrTokenOrCode + ); + break; + case AuthorizationType.InferableSingleKey: + keyVault.TryToFindSpecificCredentialType( + layerWithCredentials.URL, + PasswordOrKeyOrTokenOrCode + ); + break; + } + } + + private void OnCredentialTypeDetermined(string url, AuthorizationType type) + { + // credentialTypeDropdown.value = (int)type; + authorizationType = type; + + switch (type) + { + case AuthorizationType.UsernamePassword: + layerWithCredentials.SetCredentials(UserName, PasswordOrKeyOrTokenOrCode); + break; + case AuthorizationType.BearerToken: + layerWithCredentials.SetBearerToken(PasswordOrKeyOrTokenOrCode); + break; + case AuthorizationType.Key: + layerWithCredentials.SetKey(PasswordOrKeyOrTokenOrCode); + break; + case AuthorizationType.Code: + layerWithCredentials.SetCode(PasswordOrKeyOrTokenOrCode); + break; + case AuthorizationType.Token: + layerWithCredentials.SetToken(PasswordOrKeyOrTokenOrCode); + break; + case AuthorizationType.Public: + layerWithCredentials.ClearCredentials(); + break; + case AuthorizationType.Unknown: + layerWithCredentials.ClearCredentials(); + CredentialsAccepted.Invoke(false); + break; + } + } + + /// + /// Set the authorization input type and update the UI + /// + public void SetAuthorizationInputType(AuthorizationType type) + { + if ( + type == AuthorizationType.Key + || type == AuthorizationType.Token + || type == AuthorizationType.BearerToken + || type == AuthorizationType.Code + ) + type = AuthorizationType.InferableSingleKey; + + // credentialTypeDropdown.value = (int)type; + + //Similar values are not reapplied, so make sure to the dropdown items appear + // if (credentialTypeDropdown.TryGetComponent(out DropdownSelection dropdownSelection)) + // dropdownSelection.DropdownSelectItem(credentialTypeDropdown.value); + + authorizationType = type; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Layers/Properties/PropertyPanels/LayerCredentialsHandler.cs.meta b/Assets/Scripts/Layers/Properties/PropertyPanels/LayerCredentialsHandler.cs.meta new file mode 100644 index 000000000..69168e6cd --- /dev/null +++ b/Assets/Scripts/Layers/Properties/PropertyPanels/LayerCredentialsHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e3b2880c796b146d191c4b41da5c526b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: