ApiKeyChecker.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using UnityEngine;
  2. #if UNITY_EDITOR
  3. using UnityEditor;
  4. #endif
  5. namespace Google.Maps.Examples.Shared {
  6. /// <summary>
  7. /// Script for checking if a <see cref="MapsService.ApiKey"/> has been configured, and informing
  8. /// the user if not.
  9. /// </summary>
  10. /// <remarks>
  11. /// This script is only meant to run in Editor. For the moment it works as a
  12. /// <see cref="GameObject"/> <see cref="Component"/>, so it cannot be placed in an Editor folder,
  13. /// and instead uses precompiler flags to make it run in the Unity Editor only.
  14. /// </remarks>
  15. public sealed class ApiKeyChecker : MonoBehaviour {
  16. /// <summary>
  17. /// Website with instructions for getting an <see cref="MapsService.ApiKey"/>.
  18. /// </summary>
  19. private const string ApiKeyWebsite =
  20. "https://developers.google.com/maps/documentation/gaming/quick_start" +
  21. "#step_5_set_the_api_key_value";
  22. #if UNITY_EDITOR
  23. // Prompt to get ApiKey from website with press of an EditorUtility.DisplayDialog button.
  24. private const string WebsiteSolution = "Get an API Key to try out the Maps SDK for Unity with?";
  25. #else
  26. // Prompt to tell user (developer) to go to website themselves.
  27. private const string WebsiteSolution = "Please get an API Key by going to: " + ApiKeyWebsite;
  28. #endif
  29. /// <summary>
  30. /// On starting a scene, see if there is a <see cref="MapsService"/> <see cref="Component"/>
  31. /// in the scene missing its <see cref="MapsService.ApiKey"/>, printing a detailed error message
  32. /// if so.
  33. /// </summary>
  34. private void Awake() {
  35. MapsService[] mapsServices = FindObjectsOfType<MapsService>();
  36. if (mapsServices.Length != 0) {
  37. ShowError(mapsServices);
  38. }
  39. }
  40. /// <summary>
  41. /// Show an error saying that one or more in-scene <see cref="MapsService"/>
  42. /// <see cref="Component"/> were missing an <see cref="MapsService.ApiKey"/>, and offer
  43. /// potential solutions.
  44. /// </summary>
  45. internal static void ShowError(params MapsService[] mapsServices) {
  46. string mapsServicesWithoutApiKey = "";
  47. string mapsServicesWithApiKey = "";
  48. foreach (MapsService mapsService in mapsServices) {
  49. string apiKey = mapsService.ResolveApiKey();
  50. string messageLine = " " + GameObjectPath(mapsService.gameObject) + "\n";
  51. if (string.IsNullOrEmpty(apiKey)) {
  52. mapsServicesWithoutApiKey += messageLine;
  53. } else {
  54. mapsServicesWithApiKey += messageLine;
  55. }
  56. }
  57. if (mapsServices.Length != 0 && mapsServicesWithoutApiKey.Length == 0) {
  58. // If MapsServices were provided and they all have API keys, there's no error to show.
  59. return;
  60. }
  61. string message;
  62. if (mapsServicesWithoutApiKey.Length == 0) {
  63. message = "No API Key found.\n";
  64. } else {
  65. message = "No API Key found on the MapsService components of these objects:\n\n" +
  66. mapsServicesWithoutApiKey;
  67. }
  68. if (mapsServicesWithApiKey.Length == 0) {
  69. message += "\nThe Maps SDK for Unity needs an API Key to run.\n\n" + WebsiteSolution;
  70. ShowErrorWebsite("API Key Missing", message);
  71. } else {
  72. message += "\nAPI keys were found on MapsService components of the following objects:\n\n" +
  73. mapsServicesWithApiKey +
  74. "\nPlease make sure all Maps Services have their API Keys set.";
  75. ShowErrorNotAll("API Key Missing", message);
  76. }
  77. }
  78. /// <summary>
  79. /// Returns the path of a GameObject; i.e. the names of its parent objects up to the root,
  80. /// separated by slashes.
  81. /// </summary>
  82. private static string GameObjectPath(GameObject gameObject) {
  83. string name = gameObject.name;
  84. if (gameObject.transform.parent != null) {
  85. name = GameObjectPath(gameObject.transform.parent.gameObject) + "/" + name;
  86. }
  87. return name;
  88. }
  89. /// <summary>
  90. /// Show an error linking to website where can get an <see cref="MapsService.ApiKey"/>.
  91. /// </summary>
  92. private static void ShowErrorWebsite(string errorTitle, string errorMessage) {
  93. #if UNITY_EDITOR
  94. // Show EditorUtility.DisplayDialog with two options, 'Yes' and 'Cancel'.
  95. if (EditorUtility.DisplayDialog(errorTitle, errorMessage, "Yes", "Cancel")) {
  96. // Pressing 'Yes' (in response to question 'Get an ApiKey to try out the Maps SDK for Unity
  97. // with?') stops play and opens website where can get an ApiKey.
  98. EditorApplication.isPlaying = false;
  99. Application.OpenURL(ApiKeyWebsite);
  100. } else {
  101. // Pressing 'Cancel' stops play immediately (as cannot run the scene without a ApiKey.
  102. EditorApplication.isPlaying = false;
  103. }
  104. #else
  105. Debug.LogError(errorMessage);
  106. #endif
  107. }
  108. /// <summary>
  109. /// Show an error saying that an <see cref="MapsService.ApiKey"/> was found some, but not all
  110. /// <see cref="MapsService"/>s in this scene.
  111. /// </summary>
  112. private static void ShowErrorNotAll(string errorTitle, string errorMessage) {
  113. #if UNITY_EDITOR
  114. // Show EditorUtility.DisplayDialog and end play session, so when 'Cancel' (only button) is
  115. // pressed, play stops (as the Maps SDK for Unity cannot run without ApiKeys on all elements).
  116. EditorUtility.DisplayDialog(errorTitle, errorMessage, "Cancel");
  117. EditorApplication.isPlaying = false;
  118. #else
  119. Debug.LogError(errorMessage);
  120. #endif
  121. }
  122. }
  123. }