No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GridInformation.cs 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace UnityEngine.Tilemaps
  5. {
  6. [Serializable]
  7. internal enum GridInformationType
  8. {
  9. Integer,
  10. String,
  11. Float,
  12. Double,
  13. UnityObject,
  14. Color
  15. }
  16. /// <summary>
  17. /// A simple MonoBehaviour that stores and provides information based on Grid positions and keywords.
  18. /// </summary>
  19. [Serializable]
  20. [HelpURL("https://docs.unity3d.com/Packages/com.unity.2d.tilemap.extras@latest/index.html?subfolder=/manual/GridInformation.html")]
  21. [AddComponentMenu("Tilemap/Grid Information")]
  22. public class GridInformation : MonoBehaviour, ISerializationCallbackReceiver
  23. {
  24. [Serializable]
  25. internal struct GridInformationValue
  26. {
  27. public GridInformationType type;
  28. public object data;
  29. }
  30. [Serializable]
  31. internal struct GridInformationKey : IEquatable<GridInformationKey>
  32. {
  33. public Vector3Int position;
  34. public String name;
  35. public bool Equals(GridInformationKey key)
  36. {
  37. return position == key.position && name == key.name;
  38. }
  39. public override int GetHashCode()
  40. {
  41. return HashCode.Combine(position.GetHashCode(), name.GetHashCode());
  42. }
  43. }
  44. private Dictionary<GridInformationKey, GridInformationValue> m_PositionProperties = new Dictionary<GridInformationKey, GridInformationValue>();
  45. internal Dictionary<GridInformationKey, GridInformationValue> PositionProperties
  46. {
  47. get { return m_PositionProperties; }
  48. }
  49. [SerializeField]
  50. [HideInInspector]
  51. private List<GridInformationKey> m_PositionIntKeys = new List<GridInformationKey>();
  52. [SerializeField]
  53. [HideInInspector]
  54. private List<int> m_PositionIntValues = new List<int>();
  55. [SerializeField]
  56. [HideInInspector]
  57. private List<GridInformationKey> m_PositionStringKeys = new List<GridInformationKey>();
  58. [SerializeField]
  59. [HideInInspector]
  60. private List<String> m_PositionStringValues = new List<String>();
  61. [SerializeField]
  62. [HideInInspector]
  63. private List<GridInformationKey> m_PositionFloatKeys = new List<GridInformationKey>();
  64. [SerializeField]
  65. [HideInInspector]
  66. private List<float> m_PositionFloatValues = new List<float>();
  67. [SerializeField]
  68. [HideInInspector]
  69. private List<GridInformationKey> m_PositionDoubleKeys = new List<GridInformationKey>();
  70. [SerializeField]
  71. [HideInInspector]
  72. private List<Double> m_PositionDoubleValues = new List<Double>();
  73. [SerializeField]
  74. [HideInInspector]
  75. private List<GridInformationKey> m_PositionObjectKeys = new List<GridInformationKey>();
  76. [SerializeField]
  77. [HideInInspector]
  78. private List<Object> m_PositionObjectValues = new List<Object>();
  79. [SerializeField]
  80. [HideInInspector]
  81. private List<GridInformationKey> m_PositionColorKeys = new List<GridInformationKey>();
  82. [SerializeField]
  83. [HideInInspector]
  84. private List<Color> m_PositionColorValues = new List<Color>();
  85. /// <summary>
  86. /// Callback before serializing this GridInformation
  87. /// </summary>
  88. void ISerializationCallbackReceiver.OnBeforeSerialize()
  89. {
  90. Grid grid = GetComponentInParent<Grid>();
  91. if (grid == null)
  92. return;
  93. m_PositionIntKeys.Clear();
  94. m_PositionIntValues.Clear();
  95. m_PositionStringKeys.Clear();
  96. m_PositionStringValues.Clear();
  97. m_PositionFloatKeys.Clear();
  98. m_PositionFloatValues.Clear();
  99. m_PositionDoubleKeys.Clear();
  100. m_PositionDoubleValues.Clear();
  101. m_PositionObjectKeys.Clear();
  102. m_PositionObjectValues.Clear();
  103. m_PositionColorKeys.Clear();
  104. m_PositionColorValues.Clear();
  105. foreach (var kvp in m_PositionProperties)
  106. {
  107. switch (kvp.Value.type)
  108. {
  109. case GridInformationType.Integer:
  110. m_PositionIntKeys.Add(kvp.Key);
  111. m_PositionIntValues.Add((int)kvp.Value.data);
  112. break;
  113. case GridInformationType.String:
  114. m_PositionStringKeys.Add(kvp.Key);
  115. m_PositionStringValues.Add(kvp.Value.data as String);
  116. break;
  117. case GridInformationType.Float:
  118. m_PositionFloatKeys.Add(kvp.Key);
  119. m_PositionFloatValues.Add((float)kvp.Value.data);
  120. break;
  121. case GridInformationType.Double:
  122. m_PositionDoubleKeys.Add(kvp.Key);
  123. m_PositionDoubleValues.Add((double)kvp.Value.data);
  124. break;
  125. case GridInformationType.Color:
  126. m_PositionColorKeys.Add(kvp.Key);
  127. m_PositionColorValues.Add((Color)kvp.Value.data);
  128. break;
  129. default:
  130. m_PositionObjectKeys.Add(kvp.Key);
  131. m_PositionObjectValues.Add(kvp.Value.data as Object);
  132. break;
  133. }
  134. }
  135. }
  136. /// <summary>
  137. /// Callback after deserializing this GridInformation
  138. /// </summary>
  139. void ISerializationCallbackReceiver.OnAfterDeserialize()
  140. {
  141. m_PositionProperties.Clear();
  142. for (int i = 0; i != Math.Min(m_PositionIntKeys.Count, m_PositionIntValues.Count); i++)
  143. {
  144. GridInformationValue positionValue;
  145. positionValue.type = GridInformationType.Integer;
  146. positionValue.data = m_PositionIntValues[i];
  147. m_PositionProperties.Add(m_PositionIntKeys[i], positionValue);
  148. }
  149. for (int i = 0; i != Math.Min(m_PositionStringKeys.Count, m_PositionStringValues.Count); i++)
  150. {
  151. GridInformationValue positionValue;
  152. positionValue.type = GridInformationType.String;
  153. positionValue.data = m_PositionStringValues[i];
  154. m_PositionProperties.Add(m_PositionStringKeys[i], positionValue);
  155. }
  156. for (int i = 0; i != Math.Min(m_PositionFloatKeys.Count, m_PositionFloatValues.Count); i++)
  157. {
  158. GridInformationValue positionValue;
  159. positionValue.type = GridInformationType.Float;
  160. positionValue.data = m_PositionFloatValues[i];
  161. m_PositionProperties.Add(m_PositionFloatKeys[i], positionValue);
  162. }
  163. for (int i = 0; i != Math.Min(m_PositionDoubleKeys.Count, m_PositionDoubleValues.Count); i++)
  164. {
  165. GridInformationValue positionValue;
  166. positionValue.type = GridInformationType.Double;
  167. positionValue.data = m_PositionDoubleValues[i];
  168. m_PositionProperties.Add(m_PositionDoubleKeys[i], positionValue);
  169. }
  170. for (int i = 0; i != Math.Min(m_PositionObjectKeys.Count, m_PositionObjectValues.Count); i++)
  171. {
  172. GridInformationValue positionValue;
  173. positionValue.type = GridInformationType.UnityObject;
  174. positionValue.data = m_PositionObjectValues[i];
  175. m_PositionProperties.Add(m_PositionObjectKeys[i], positionValue);
  176. }
  177. for (int i = 0; i != Math.Min(m_PositionColorKeys.Count, m_PositionColorValues.Count); i++)
  178. {
  179. GridInformationValue positionValue;
  180. positionValue.type = GridInformationType.Color;
  181. positionValue.data = m_PositionColorValues[i];
  182. m_PositionProperties.Add(m_PositionColorKeys[i], positionValue);
  183. }
  184. }
  185. /// <summary>
  186. /// This is not supported.
  187. /// </summary>
  188. /// <param name="position">Position to store information for</param>
  189. /// <param name="name">Property name to store information for</param>
  190. /// <param name="positionProperty">The information to be stored at the position</param>
  191. /// <typeparam name="T">Type of the information to set</typeparam>
  192. /// <returns>Whether the information was set</returns>
  193. /// <exception cref="NotImplementedException">This is not implemented as only concrete Types are supported</exception>
  194. public bool SetPositionProperty<T>(Vector3Int position, String name, T positionProperty)
  195. {
  196. throw new NotImplementedException("Storing this type is not accepted in GridInformation");
  197. }
  198. /// <summary>
  199. /// Stores int information at the given position with the given property name
  200. /// </summary>
  201. /// <param name="position">Position to store information for</param>
  202. /// <param name="name">Property name to store information for</param>
  203. /// <param name="positionProperty">The information to be stored at the position</param>
  204. /// <returns>Whether the information was set</returns>
  205. public bool SetPositionProperty(Vector3Int position, String name, int positionProperty)
  206. {
  207. return SetPositionProperty(position, name, GridInformationType.Integer, positionProperty);
  208. }
  209. /// <summary>
  210. /// Stores string information at the given position with the given property name
  211. /// </summary>
  212. /// <param name="position">Position to store information for</param>
  213. /// <param name="name">Property name to store information for</param>
  214. /// <param name="positionProperty">The information to be stored at the position</param>
  215. /// <returns>Whether the information was set</returns>
  216. public bool SetPositionProperty(Vector3Int position, String name, string positionProperty)
  217. {
  218. return SetPositionProperty(position, name, GridInformationType.String, positionProperty);
  219. }
  220. /// <summary>
  221. /// Stores float information at the given position with the given property name
  222. /// </summary>
  223. /// <param name="position">Position to store information for</param>
  224. /// <param name="name">Property name to store information for</param>
  225. /// <param name="positionProperty">The information to be stored at the position</param>
  226. /// <returns>Whether the information was set</returns>
  227. public bool SetPositionProperty(Vector3Int position, String name, float positionProperty)
  228. {
  229. return SetPositionProperty(position, name, GridInformationType.Float, positionProperty);
  230. }
  231. /// <summary>
  232. /// Stores double information at the given position with the given property name
  233. /// </summary>
  234. /// <param name="position">Position to store information for</param>
  235. /// <param name="name">Property name to store information for</param>
  236. /// <param name="positionProperty">The information to be stored at the position</param>
  237. /// <returns>Whether the information was set</returns>
  238. public bool SetPositionProperty(Vector3Int position, String name, double positionProperty)
  239. {
  240. return SetPositionProperty(position, name, GridInformationType.Double, positionProperty);
  241. }
  242. /// <summary>
  243. /// Stores UnityEngine.Object information at the given position with the given property name
  244. /// </summary>
  245. /// <param name="position">Position to store information for</param>
  246. /// <param name="name">Property name to store information for</param>
  247. /// <param name="positionProperty">The information to be stored at the position</param>
  248. /// <returns>Whether the information was set</returns>
  249. public bool SetPositionProperty(Vector3Int position, String name, UnityEngine.Object positionProperty)
  250. {
  251. return SetPositionProperty(position, name, GridInformationType.UnityObject, positionProperty);
  252. }
  253. /// <summary>
  254. /// Stores color information at the given position with the given property name
  255. /// </summary>
  256. /// <param name="position">Position to store information for</param>
  257. /// <param name="name">Property name to store information for</param>
  258. /// <param name="positionProperty">The information to be stored at the position</param>
  259. /// <returns>Whether the information was set</returns>
  260. public bool SetPositionProperty(Vector3Int position, String name, Color positionProperty)
  261. {
  262. return SetPositionProperty(position, name, GridInformationType.Color, positionProperty);
  263. }
  264. private bool SetPositionProperty(Vector3Int position, String name, GridInformationType dataType, System.Object positionProperty)
  265. {
  266. Grid grid = GetComponentInParent<Grid>();
  267. if (grid != null && positionProperty != null)
  268. {
  269. GridInformationKey positionKey;
  270. positionKey.position = position;
  271. positionKey.name = name;
  272. GridInformationValue positionValue;
  273. positionValue.type = dataType;
  274. positionValue.data = positionProperty;
  275. m_PositionProperties[positionKey] = positionValue;
  276. return true;
  277. }
  278. return false;
  279. }
  280. /// <summary>
  281. /// Retrieves information stored at the given position with the given property name as the given Type
  282. /// </summary>
  283. /// <param name="position">Position to retrieve information for</param>
  284. /// <param name="name">Property name to retrieve information for</param>
  285. /// <param name="defaultValue">Default value if property does not exist at the given position</param>
  286. /// <typeparam name="T">Type of the information to retrieve</typeparam>
  287. /// <returns>The information stored at the position</returns>
  288. /// <exception cref="InvalidCastException">Thrown when information to be retrieved is not the given Type</exception>
  289. public T GetPositionProperty<T>(Vector3Int position, String name, T defaultValue) where T : UnityEngine.Object
  290. {
  291. GridInformationKey positionKey;
  292. positionKey.position = position;
  293. positionKey.name = name;
  294. GridInformationValue positionValue;
  295. if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
  296. {
  297. if (positionValue.type != GridInformationType.UnityObject)
  298. throw new InvalidCastException("Value stored in GridInformation is not of the right type");
  299. return positionValue.data as T;
  300. }
  301. return defaultValue;
  302. }
  303. /// <summary>
  304. /// Retrieves int information stored at the given position with the given property name
  305. /// </summary>
  306. /// <param name="position">Position to retrieve information for</param>
  307. /// <param name="name">Property name to retrieve information for</param>
  308. /// <param name="defaultValue">Default int if property does not exist at the given position</param>
  309. /// <returns>The int stored at the position</returns>
  310. /// <exception cref="InvalidCastException">Thrown when information to be retrieved is not a int</exception>
  311. public int GetPositionProperty(Vector3Int position, String name, int defaultValue)
  312. {
  313. GridInformationKey positionKey;
  314. positionKey.position = position;
  315. positionKey.name = name;
  316. GridInformationValue positionValue;
  317. if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
  318. {
  319. if (positionValue.type != GridInformationType.Integer)
  320. throw new InvalidCastException("Value stored in GridInformation is not of the right type");
  321. return (int)positionValue.data;
  322. }
  323. return defaultValue;
  324. }
  325. /// <summary>
  326. /// Retrieves string information stored at the given position with the given property name
  327. /// </summary>
  328. /// <param name="position">Position to retrieve information for</param>
  329. /// <param name="name">Property name to retrieve information for</param>
  330. /// <param name="defaultValue">Default string if property does not exist at the given position</param>
  331. /// <returns>The string stored at the position</returns>
  332. /// <exception cref="InvalidCastException">Thrown when information to be retrieved is not a string</exception>
  333. public string GetPositionProperty(Vector3Int position, String name, string defaultValue)
  334. {
  335. GridInformationKey positionKey;
  336. positionKey.position = position;
  337. positionKey.name = name;
  338. GridInformationValue positionValue;
  339. if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
  340. {
  341. if (positionValue.type != GridInformationType.String)
  342. throw new InvalidCastException("Value stored in GridInformation is not of the right type");
  343. return (string)positionValue.data;
  344. }
  345. return defaultValue;
  346. }
  347. /// <summary>
  348. /// Retrieves float information stored at the given position with the given property name
  349. /// </summary>
  350. /// <param name="position">Position to retrieve information for</param>
  351. /// <param name="name">Property name to retrieve information for</param>
  352. /// <param name="defaultValue">Default float if property does not exist at the given position</param>
  353. /// <returns>The float stored at the position</returns>
  354. /// <exception cref="InvalidCastException">Thrown when information to be retrieved is not a float</exception>
  355. public float GetPositionProperty(Vector3Int position, String name, float defaultValue)
  356. {
  357. GridInformationKey positionKey;
  358. positionKey.position = position;
  359. positionKey.name = name;
  360. GridInformationValue positionValue;
  361. if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
  362. {
  363. if (positionValue.type != GridInformationType.Float)
  364. throw new InvalidCastException("Value stored in GridInformation is not of the right type");
  365. return (float)positionValue.data;
  366. }
  367. return defaultValue;
  368. }
  369. /// <summary>
  370. /// Retrieves double information stored at the given position with the given property name
  371. /// </summary>
  372. /// <param name="position">Position to retrieve information for</param>
  373. /// <param name="name">Property name to retrieve information for</param>
  374. /// <param name="defaultValue">Default double if property does not exist at the given position</param>
  375. /// <returns>The double stored at the position</returns>
  376. /// <exception cref="InvalidCastException">Thrown when information to be retrieved is not a double</exception>
  377. public double GetPositionProperty(Vector3Int position, String name, double defaultValue)
  378. {
  379. GridInformationKey positionKey;
  380. positionKey.position = position;
  381. positionKey.name = name;
  382. GridInformationValue positionValue;
  383. if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
  384. {
  385. if (positionValue.type != GridInformationType.Double)
  386. throw new InvalidCastException("Value stored in GridInformation is not of the right type");
  387. return (double)positionValue.data;
  388. }
  389. return defaultValue;
  390. }
  391. /// <summary>
  392. /// Retrieves Color information stored at the given position with the given property name
  393. /// </summary>
  394. /// <param name="position">Position to retrieve information for</param>
  395. /// <param name="name">Property name to retrieve information for</param>
  396. /// <param name="defaultValue">Default color if property does not exist at the given position</param>
  397. /// <returns>The color stored at the position</returns>
  398. /// <exception cref="InvalidCastException">Thrown when information to be retrieved is not a Color</exception>
  399. public Color GetPositionProperty(Vector3Int position, String name, Color defaultValue)
  400. {
  401. GridInformationKey positionKey;
  402. positionKey.position = position;
  403. positionKey.name = name;
  404. GridInformationValue positionValue;
  405. if (m_PositionProperties.TryGetValue(positionKey, out positionValue))
  406. {
  407. if (positionValue.type != GridInformationType.Color)
  408. throw new InvalidCastException("Value stored in GridInformation is not of the right type");
  409. return (Color)positionValue.data;
  410. }
  411. return defaultValue;
  412. }
  413. /// <summary>
  414. /// Erases information stored at the given position with the given property name
  415. /// </summary>
  416. /// <param name="position">Position to erase</param>
  417. /// <param name="name">Property name to erase</param>
  418. /// <returns>Whether the information was erased</returns>
  419. public bool ErasePositionProperty(Vector3Int position, String name)
  420. {
  421. GridInformationKey positionKey;
  422. positionKey.position = position;
  423. positionKey.name = name;
  424. return m_PositionProperties.Remove(positionKey);
  425. }
  426. /// <summary>
  427. /// Clears all information stored
  428. /// </summary>
  429. public virtual void Reset()
  430. {
  431. m_PositionProperties.Clear();
  432. }
  433. /// <summary>
  434. /// Gets all positions with information with the given property name
  435. /// </summary>
  436. /// <param name="propertyName">Property name to search for</param>
  437. /// <returns>An array of all positions with the property name</returns>
  438. public Vector3Int[] GetAllPositions(string propertyName)
  439. {
  440. return m_PositionProperties.Keys.ToList().FindAll(x => x.name == propertyName).Select(x => x.position).ToArray();
  441. }
  442. }
  443. }