Cluster.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using ExitGames.Client.Photon;
  4. namespace Photon.Pun.Demo.Procedural
  5. {
  6. /// <summary>
  7. /// The Cluster component has references to all Blocks that are part of this Cluster.
  8. /// It provides functions for modifying single Blocks inside this Cluster.
  9. /// It also handles modifications made to the world by other clients.
  10. /// </summary>
  11. public class Cluster : MonoBehaviourPunCallbacks
  12. {
  13. private string propertiesKey;
  14. private Dictionary<int, float> propertiesValue;
  15. public int ClusterId { get; set; }
  16. public Dictionary<int, GameObject> Blocks { get; private set; }
  17. #region UNITY
  18. public void Awake()
  19. {
  20. Blocks = new Dictionary<int, GameObject>();
  21. propertiesValue = new Dictionary<int, float>();
  22. }
  23. /// <summary>
  24. /// Sets the unique key of this Cluster used for storing modifications within the Custom Room Properties.
  25. /// </summary>
  26. private void Start()
  27. {
  28. propertiesKey = "Cluster " + ClusterId;
  29. }
  30. #endregion
  31. #region CLASS FUNCTIONS
  32. /// <summary>
  33. /// Adds a Block to the Cluster.
  34. /// This is called by the WorldGenerator while the generation process is running.
  35. /// In order to modify Blocks directly, we are storing the ID as well as a reference to the certain GameObject.
  36. /// </summary>
  37. public void AddBlock(int blockId, GameObject block)
  38. {
  39. Blocks.Add(blockId, block);
  40. }
  41. /// <summary>
  42. /// Gets called before a new world can be generated.
  43. /// Destroys each Block from this Cluster and removes the data stored in the Custom Room Properties.
  44. /// </summary>
  45. public void DestroyCluster()
  46. {
  47. foreach (GameObject block in Blocks.Values)
  48. {
  49. Destroy(block);
  50. }
  51. Blocks.Clear();
  52. if (PhotonNetwork.IsMasterClient)
  53. {
  54. RemoveClusterFromRoomProperties();
  55. }
  56. }
  57. /// <summary>
  58. /// Decreases a Block's height locally before applying the modification to the Custom Room Properties.
  59. /// </summary>
  60. public void DecreaseBlockHeight(int blockId)
  61. {
  62. float height = Blocks[blockId].transform.localScale.y;
  63. height = Mathf.Max((height - 1.0f), 0.0f);
  64. SetBlockHeightLocal(blockId, height);
  65. }
  66. /// <summary>
  67. /// Increases a Block's height locally before applying the modification to the Custom Room Properties.
  68. /// </summary>
  69. public void IncreaseBlockHeight(int blockId)
  70. {
  71. float height = Blocks[blockId].transform.localScale.y;
  72. height = Mathf.Min((height + 1.0f), 8.0f);
  73. SetBlockHeightLocal(blockId, height);
  74. }
  75. /// <summary>
  76. /// Gets called when a remote client has modified a certain Block within this Cluster.
  77. /// Called by the WorldGenerator or the Cluster itself after the Custom Room Properties have been updated.
  78. /// </summary>
  79. public void SetBlockHeightRemote(int blockId, float height)
  80. {
  81. GameObject block = Blocks[blockId];
  82. Vector3 scale = block.transform.localScale;
  83. Vector3 position = block.transform.localPosition;
  84. block.transform.localScale = new Vector3(scale.x, height, scale.z);
  85. block.transform.localPosition = new Vector3(position.x, height / 2.0f, position.z);
  86. }
  87. /// <summary>
  88. /// Gets called whenever the local client modifies any Block within this Cluster.
  89. /// The modification will be applied to the Block first before it is published to the Custom Room Properties.
  90. /// </summary>
  91. private void SetBlockHeightLocal(int blockId, float height)
  92. {
  93. GameObject block = Blocks[blockId];
  94. Vector3 scale = block.transform.localScale;
  95. Vector3 position = block.transform.localPosition;
  96. block.transform.localScale = new Vector3(scale.x, height, scale.z);
  97. block.transform.localPosition = new Vector3(position.x, height / 2.0f, position.z);
  98. UpdateRoomProperties(blockId, height);
  99. }
  100. /// <summary>
  101. /// Gets called in order to update the Custom Room Properties with the modification made by the local client.
  102. /// </summary>
  103. private void UpdateRoomProperties(int blockId, float height)
  104. {
  105. propertiesValue[blockId] = height;
  106. Hashtable properties = new Hashtable {{propertiesKey, propertiesValue}};
  107. PhotonNetwork.CurrentRoom.SetCustomProperties(properties);
  108. }
  109. /// <summary>
  110. /// Removes the modifications of this Cluster from the Custom Room Properties.
  111. /// </summary>
  112. private void RemoveClusterFromRoomProperties()
  113. {
  114. Hashtable properties = new Hashtable {{propertiesKey, null}};
  115. PhotonNetwork.CurrentRoom.SetCustomProperties(properties);
  116. }
  117. #endregion
  118. #region PUN CALLBACKS
  119. /// <summary>
  120. /// Gets called whenever the Custom Room Properties are updated.
  121. /// When the changed properties contain the previously set PropertiesKey (basically the Cluster ID),
  122. /// the Cluster and its Blocks will be updated accordingly.
  123. /// </summary>
  124. public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
  125. {
  126. if (propertiesThatChanged.ContainsKey(propertiesKey))
  127. {
  128. if (propertiesThatChanged[propertiesKey] == null)
  129. {
  130. propertiesValue = new Dictionary<int, float>();
  131. return;
  132. }
  133. propertiesValue = (Dictionary<int, float>) propertiesThatChanged[propertiesKey];
  134. foreach (KeyValuePair<int, float> pair in propertiesValue)
  135. {
  136. SetBlockHeightRemote(pair.Key, pair.Value);
  137. }
  138. }
  139. }
  140. #endregion
  141. }
  142. }