Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

312 Zeilen
8.7 KiB

  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.EventSystems;
  4. [RequireComponent(typeof(BoxCollider2D))]
  5. public class WorldMapCameraOperator : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler, IBeginPinchHandler, IPinchHandler, IEndPinchHandler, IEventSystemHandler
  6. {
  7. private void Awake()
  8. {
  9. this._pinching = false;
  10. this._animationMode = WorldMapCameraOperator.AnimationMode.None;
  11. this._cameraZ = this._cameraToOperate.transform.position.z;
  12. }
  13. private void Start()
  14. {
  15. this.RestrictCameraBounds();
  16. }
  17. private void LateUpdate()
  18. {
  19. this.SoftRestrictCameraZoom(Time.deltaTime);
  20. if (this._animationMode == WorldMapCameraOperator.AnimationMode.None)
  21. {
  22. return;
  23. }
  24. Transform transform = this._cameraToOperate.transform;
  25. float num = this._cameraToOperate.orthographicSize * 2f;
  26. float num2 = num * this._cameraToOperate.aspect;
  27. if (this._animationMode == WorldMapCameraOperator.AnimationMode.Velocity)
  28. {
  29. this._animationVelocity *= 0.95f;
  30. Vector3 zero = Vector3.zero;
  31. zero.x = -this._animationVelocity.x * Time.deltaTime / (float)this._cameraToOperate.pixelWidth * num2;
  32. zero.y = -this._animationVelocity.y * Time.deltaTime / (float)this._cameraToOperate.pixelHeight * num;
  33. transform.localPosition += zero;
  34. if (this._animationVelocity.magnitude < 5f)
  35. {
  36. this._animationMode = WorldMapCameraOperator.AnimationMode.None;
  37. }
  38. }
  39. else if (this._animationMode == WorldMapCameraOperator.AnimationMode.Destination)
  40. {
  41. float num3 = this._destinationAnimationCurve.Evaluate((Time.time - this._animationStartTime) / this._destinationAnimationDuration);
  42. Vector3 position = transform.position;
  43. if (num3 >= 1f)
  44. {
  45. position.x = this._animationDestination.x;
  46. position.y = this._animationDestination.y;
  47. this._animationMode = WorldMapCameraOperator.AnimationMode.None;
  48. }
  49. else
  50. {
  51. position = Vector2.Lerp(this._animationSource, this._animationDestination, num3);
  52. position.z = this._cameraZ;
  53. }
  54. transform.position = position;
  55. }
  56. this.RestrictCameraBounds();
  57. }
  58. public void OnPointerClick(PointerEventData eventData)
  59. {
  60. }
  61. public void OnPointerDown(PointerEventData eventData)
  62. {
  63. if (this._animationMode != WorldMapCameraOperator.AnimationMode.None)
  64. {
  65. this._animationMode = WorldMapCameraOperator.AnimationMode.None;
  66. }
  67. }
  68. public void OnPointerUp(PointerEventData eventData)
  69. {
  70. }
  71. public void OnBeginPinch(PinchEventData pinchEvent)
  72. {
  73. this._pinching = true;
  74. this._pinchingOrthoSize = this._cameraToOperate.orthographicSize;
  75. if (this._animationMode != WorldMapCameraOperator.AnimationMode.None)
  76. {
  77. this._animationMode = WorldMapCameraOperator.AnimationMode.None;
  78. }
  79. }
  80. public void OnPinch(PinchEventData pinchEvent)
  81. {
  82. this._pinchingOrthoSize /= pinchEvent.ScaleDelta;
  83. float num = this.CalculateZoomOffset(this._pinchingOrthoSize);
  84. float num2 = this._minZoom - this._maxZoom;
  85. if (num < 0f)
  86. {
  87. num2 /= 2f;
  88. }
  89. float num3 = this.DampenOffset(num, num2);
  90. float orthographicSize = this._pinchingOrthoSize + num - num3;
  91. Transform transform = this._cameraToOperate.transform;
  92. float num4 = this._cameraToOperate.orthographicSize * 2f;
  93. float num5 = num4 * this._cameraToOperate.aspect;
  94. Vector2 zero = Vector2.zero;
  95. zero.x = transform.localPosition.x - num5 * 0.5f + pinchEvent.Center.x / (float)this._cameraToOperate.pixelWidth * num5;
  96. zero.y = transform.localPosition.y - num4 * 0.5f + pinchEvent.Center.y / (float)this._cameraToOperate.pixelHeight * num4;
  97. Vector3 zero2 = Vector3.zero;
  98. zero2.x = -pinchEvent.Delta.x / (float)this._cameraToOperate.pixelWidth * num5;
  99. zero2.y = -pinchEvent.Delta.y / (float)this._cameraToOperate.pixelHeight * num4;
  100. zero2.x += (transform.localPosition.x - zero.x) * (1f - pinchEvent.ScaleDelta);
  101. zero2.y += (transform.localPosition.y - zero.y) * (1f - pinchEvent.ScaleDelta);
  102. transform.localPosition += zero2;
  103. this._cameraToOperate.orthographicSize = orthographicSize;
  104. this.RestrictCameraBounds();
  105. }
  106. public void OnEndPinch(PinchEventData pinchEvent)
  107. {
  108. if (this._animationMode == WorldMapCameraOperator.AnimationMode.None && pinchEvent.Velocity.magnitude >= 30f)
  109. {
  110. this._animationVelocity = pinchEvent.Velocity;
  111. this._animationMode = WorldMapCameraOperator.AnimationMode.Velocity;
  112. }
  113. this._pinching = false;
  114. }
  115. public void Init()
  116. {
  117. }
  118. public void ScrollTo(Transform t, bool animated)
  119. {
  120. this.ScrollTo(t.position, animated);
  121. }
  122. public void ScrollTo(GameObject go, bool animated)
  123. {
  124. Collider2D component = go.GetComponent<Collider2D>();
  125. Vector2 position;
  126. if (component != null)
  127. {
  128. position = component.bounds.center;
  129. }
  130. else
  131. {
  132. position = go.transform.position;
  133. }
  134. this.ScrollTo(position, animated);
  135. }
  136. public void ScrollTo(Vector2 position, bool animated)
  137. {
  138. if (this._pinching)
  139. {
  140. return;
  141. }
  142. Transform transform = this._cameraToOperate.transform;
  143. if (animated)
  144. {
  145. this._animationSource = transform.position;
  146. this._animationDestination = position;
  147. this._animationStartTime = Time.time;
  148. this._animationMode = WorldMapCameraOperator.AnimationMode.Destination;
  149. }
  150. else
  151. {
  152. this._animationMode = WorldMapCameraOperator.AnimationMode.None;
  153. Vector3 position2 = transform.position;
  154. position2.x = position.x;
  155. position2.y = position.y;
  156. transform.position = position2;
  157. this.RestrictCameraBounds();
  158. }
  159. }
  160. public Vector3 CameraWorldPosition
  161. {
  162. get
  163. {
  164. return this._cameraToOperate.transform.position;
  165. }
  166. }
  167. private void SoftRestrictCameraZoom(float deltaTime)
  168. {
  169. if (!this._pinching)
  170. {
  171. float num = this._cameraToOperate.orthographicSize;
  172. float num2 = this.CalculateZoomOffset(num);
  173. if (!Mathf.Approximately(num2, 0f))
  174. {
  175. float num3 = 0f;
  176. num = Mathf.SmoothDamp(num, num + num2, ref num3, this._zoomElasticity, float.PositiveInfinity, deltaTime);
  177. num += num3;
  178. this._cameraToOperate.orthographicSize = num;
  179. }
  180. }
  181. }
  182. private void RestrictCameraBounds()
  183. {
  184. Transform transform = this._cameraToOperate.transform;
  185. float num = this._cameraToOperate.orthographicSize * 2f;
  186. float num2 = num * this._cameraToOperate.aspect;
  187. Bounds bounds = this._cameraBounds.bounds;
  188. if (num2 > bounds.size.x)
  189. {
  190. num2 = bounds.size.x;
  191. num = num2 / this._cameraToOperate.aspect;
  192. this._cameraToOperate.orthographicSize = num * 0.5f;
  193. }
  194. if (num > bounds.size.y)
  195. {
  196. num = bounds.size.y;
  197. num2 = num * this._cameraToOperate.aspect;
  198. this._cameraToOperate.orthographicSize = num * 0.5f;
  199. }
  200. Vector3 position = transform.position;
  201. if (position.x - num2 * 0.5f < bounds.min.x)
  202. {
  203. position.x = bounds.min.x + num2 * 0.5f;
  204. }
  205. if (position.x + num2 * 0.5f > bounds.max.x)
  206. {
  207. position.x = bounds.max.x - num2 * 0.5f;
  208. }
  209. if (position.y - num * 0.5f < bounds.min.y)
  210. {
  211. position.y = bounds.min.y + num * 0.5f;
  212. }
  213. if (position.y + num * 0.5f > bounds.max.y)
  214. {
  215. position.y = bounds.max.y - num * 0.5f;
  216. }
  217. transform.position = position;
  218. }
  219. private float CalculateZoomOffset(float orthoSize)
  220. {
  221. float result = 0f;
  222. if (orthoSize < this._maxZoom)
  223. {
  224. result = this._maxZoom - orthoSize;
  225. }
  226. else if (orthoSize > this._minZoom)
  227. {
  228. result = this._minZoom - orthoSize;
  229. }
  230. return result;
  231. }
  232. private float DampenOffset(float overStretching, float zoomRange)
  233. {
  234. if (Mathf.Approximately(overStretching, 0f))
  235. {
  236. return 0f;
  237. }
  238. return (1f - 1f / (Mathf.Abs(overStretching) / (this._zoomStiffness * zoomRange) + 1f)) * zoomRange * Mathf.Sign(overStretching);
  239. }
  240. private const float VelocityReductionFactor = 0.95f;
  241. private const float VelocityStartMagnitudeThreshold = 30f;
  242. private const float VelocityEndMagnitudeThreshold = 5f;
  243. [SerializeField]
  244. private Camera _cameraToOperate;
  245. [SerializeField]
  246. private float _destinationAnimationDuration = 0.6f;
  247. [SerializeField]
  248. private AnimationCurve _destinationAnimationCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
  249. [SerializeField]
  250. private float _minZoom = 500f;
  251. [SerializeField]
  252. private float _maxZoom = 200f;
  253. [SerializeField]
  254. private float _zoomElasticity = 0.6f;
  255. [SerializeField]
  256. private float _zoomStiffness = 1.5f;
  257. [SerializeField]
  258. private BoxCollider2D _cameraBounds;
  259. private bool _pinching;
  260. private float _pinchingOrthoSize;
  261. private WorldMapCameraOperator.AnimationMode _animationMode;
  262. private Vector2 _animationVelocity;
  263. private Vector2 _animationSource;
  264. private Vector2 _animationDestination;
  265. private float _animationStartTime;
  266. private float _cameraZ;
  267. private enum AnimationMode
  268. {
  269. None,
  270. Velocity,
  271. Destination
  272. }
  273. }