BuildingTexturer.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using UnityEngine;
  2. using Random = UnityEngine.Random;
  3. namespace Google.Maps.Examples.Shared {
  4. /// <summary>
  5. /// Script that takes multiple building materials and randomly assigns them to any given building.
  6. /// </summary>
  7. public sealed class BuildingTexturer : MonoBehaviour {
  8. [Tooltip(
  9. "Materials to apply to buildings walls. The specific Materials chosen must use a " +
  10. "Shader that is set up to work with Nine Slicing. For more info on how this is achieved, " +
  11. "examine the Shader: " +
  12. "Assets/GoogleMaps/Examples/Materials/NineSlicing/BuildingWalls.shader.")]
  13. public Material[] WallMaterials;
  14. [Tooltip(
  15. "Materials to apply to roofs (must be the same number of Materials as Building Wall " +
  16. "Materials array, as we will try to match given Walls to given Roofs (e.g. if a building " +
  17. "is given Building Wall Material 2, then it will also be given Building Roof Material 2).")]
  18. public Material[] RoofMaterials;
  19. /// <summary>
  20. /// Verify given <see cref="Material"/> arrays are valid (not empty nor containing any null
  21. /// entries, and both arrays of the same length).
  22. /// </summary>
  23. private void Awake() {
  24. // Verify that at least one Wall Material and at least one Roof Material has been given.
  25. if (WallMaterials.Length == 0) {
  26. Debug.LogError(ExampleErrors.EmptyArray(this, WallMaterials, "Wall Materials"));
  27. return;
  28. }
  29. if (RoofMaterials.Length == 0) {
  30. Debug.LogError(ExampleErrors.EmptyArray(this, RoofMaterials, "Roof Materials"));
  31. return;
  32. }
  33. // Verify that the same number of Wall and Roof Materials have been given.
  34. if (WallMaterials.Length != RoofMaterials.Length) {
  35. Debug.LogErrorFormat(
  36. "Incorrect number of Building Roof Materials defined for {0}.{1}: {2} " +
  37. "Building Wall Materials were given, but {3} Building Roof Materials were given." +
  38. "\n{1} needs the same number of Building Roof Materials as Building Wall " +
  39. "Materials, i.e. {2} of each.",
  40. name,
  41. GetType(),
  42. WallMaterials.Length,
  43. RoofMaterials.Length);
  44. return;
  45. }
  46. // Verify that no null Materials have been given.
  47. for (int i = 0; i < WallMaterials.Length; i++) {
  48. if (WallMaterials[i] == null) {
  49. Debug.LogError(ExampleErrors.NullArrayElement(this, WallMaterials, "Wall Materials", i));
  50. return;
  51. }
  52. if (RoofMaterials[i] == null) {
  53. Debug.LogError(ExampleErrors.NullArrayElement(this, RoofMaterials, "Roof Materials", i));
  54. return;
  55. }
  56. }
  57. // If have reached this point then have verified that all required parts are present and
  58. // properly set up.
  59. }
  60. /// <summary>
  61. /// Assign a randomly chosen Wall and Roof <see cref="Material"/> to a given building.
  62. /// </summary>
  63. /// <param name="building">Building to assign <see cref="Material"/>s to.</param>
  64. /// <param name="index">
  65. /// Optional index of Wall and Roof <see cref="Material"/> pair to apply. If this value is not
  66. /// set a random <see cref="Material"/> pair will be used.
  67. /// </param>
  68. internal void AssignNineSlicedMaterials(GameObject building, int? index = null) {
  69. // If a specific Material index was given, verify it is a valid index for a Wall and Roof
  70. // Material pair.
  71. if (index.HasValue) {
  72. if (index.Value < 0 || index.Value >= WallMaterials.Length) {
  73. Debug.LogError(
  74. ExampleErrors.InvalidArrayIndex(this, WallMaterials, "Wall Materials", index.Value));
  75. return;
  76. }
  77. } else {
  78. // Pick a random Material index to use for both Wall and Roof Materials. Not that the same
  79. // index will work for both arrays of Materials, as we have already verified that the Wall
  80. // and Roof Material arrays are the same length.
  81. index = Random.Range(0, WallMaterials.Length);
  82. }
  83. // Replace building MeshRenderer's sharedMaterials array with chosen Materials. Note that this
  84. // must be done by creating a new array of Materials, rather than altering the entries of this
  85. // MeshRenderer's sharedMaterials array, as altering the existing array will not actually
  86. // change the MeshRenderer's Materials.
  87. MeshRenderer buildingMeshRenderer = building.GetComponent<MeshRenderer>();
  88. buildingMeshRenderer.sharedMaterials =
  89. new Material[] { WallMaterials[index.Value], RoofMaterials[index.Value] };
  90. }
  91. }
  92. }