Advertisement
Guest User

Untitled

a guest
Jan 20th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.48 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using UnityEngine;
  7. using Cooper.Core;
  8. using Cooper.Maths;
  9.  
  10. namespace Assets.World.Entities.Scripts
  11. {
  12. /// <summary>
  13. /// Entity Interpolation.
  14. /// Le but de ce code est d'interpoler la position d'une entitée entre un point a (xyz) et b (xyz).
  15. /// Pour pouvoir interpoler entre un point a et un point b, on est forcé de connaître b, c'est pourquoi on affiche l'entité dans le
  16. /// passé. (décalé de 1 message de déplacement).
  17. /// entre xyz(t) et xyz(t+1). xyz correspond a la position de l'entitée et t le temps auquel ce message de position a été reçu.
  18. /// Dans ce cas présent, nous n'utilisons donc pas le TickRate d'un serveur.
  19. /// Voici le calcul du ratio utilisé par Vector3.Lerp() = temps écoulé depuis le temps de départ / (temps arrivée - temps départ)
  20. /// on simplifira l'expression par te / (ta - td)
  21. /// La difficultée réside dans le calcul de te , car il s'agit d'une variable dépendant du temps, borné entre ta et td.
  22. /// L'expression de te, (calculer dans FixedUpdate) est : (ta - td) / POSITION_UPDATE_FRAMES_COUNT
  23. /// POSITION_UPDATE_FRAMES_COUNT = fréquence d'envoit de la position par le client.
  24. /// Une autre difficulté est la prise en compte du ping dans les calcul, qui est suceptible de varier et donc d'amener a
  25. /// une interpolation non linéaire.
  26. /// Il faut traiter le cas particulier ou :
  27. /// Previous Position n'existe pas. (ou la définir autrement= basePosition)
  28. /// Il faut traiter le cas particulier ou :
  29. /// On reçoit une nouvelle position alors que le GameObject n'est pas encore arrivé a la destination imposée par Entity.NextPosition.Position.
  30. /// Il faut : Repenser l'architecture de cette interpolation et savoir si les propriétées NextPosition & PreviousPosition
  31. /// sont englobés dans ce script, ou dans Player. En auront nous besoin plus tard, ne pouvons nous pas nous contenter d'utiliser ce
  32. /// script.
  33. /// </summary>
  34. public class EntityInterpolationScript : UnityEntityScript<Player>
  35. {
  36. /// <summary>
  37. /// Le pourcentage de temps entre td et ta
  38. /// </summary>
  39. private float CurrentRatio
  40. {
  41. get
  42. {
  43. return (float)(CurrentTime / TotalTime);
  44. }
  45. }
  46. /// <summary>
  47. /// Le temps total qu'a mit l'entitée a se déplacer entre a et b
  48. /// </summary>
  49. private float TotalTime
  50. {
  51. get
  52. {
  53. return (float)(NextPosition.Time - PreviousPosition.Time).TotalMilliseconds;
  54. }
  55. }
  56. /// <summary>
  57. /// Le temps actuel
  58. /// </summary>
  59. private double CurrentTime
  60. {
  61. get;
  62. set;
  63. }
  64. /// <summary>
  65. /// La position de départ de l'entitée.
  66. /// </summary>
  67. public EntityPositionExtended PreviousPosition
  68. {
  69. get;
  70. private set;
  71. }
  72. /// <summary>
  73. /// La position d'arrivée de l'entitée
  74. /// </summary>
  75. public EntityPositionExtended NextPosition
  76. {
  77. get;
  78. private set;
  79. }
  80. /// <summary>
  81. /// Doit t-on interpoler?
  82. /// Seulement si la position d'arrivée envoyée par le serveur est différente de la position actuelle de l'objet.
  83. /// </summary>
  84. public bool InterpolationRequired
  85. {
  86. get
  87. {
  88. return NextPosition.Position.HasValue && (NextPosition.Position.Value != gameObject.transform.position || NextPosition.Rotation.Value != gameObject.transform.eulerAngles.y);
  89. }
  90. }
  91. public void FixedUpdate()
  92. {
  93. if (InterpolationRequired)
  94. {
  95. CurrentTime += (TotalTime / MainPlayerScript.PositionUpdateFrameCount.Value);
  96. }
  97. }
  98.  
  99. public void Update()
  100. {
  101. if (InterpolationRequired)
  102. {
  103. var result = Vector3.Lerp(PreviousPosition.Position.Value, NextPosition.Position.Value, CurrentRatio);
  104.  
  105. if (float.IsNaN(result.x))
  106. {
  107. return;
  108. }
  109.  
  110. transform.position = result;
  111.  
  112. Quaternion a = Geometry.ModifyQuaternion(transform.rotation, PreviousPosition.Rotation.Value);
  113. Quaternion b = Geometry.ModifyQuaternion(transform.rotation, NextPosition.Rotation.Value);
  114. transform.rotation = Quaternion.Slerp(a, b, CurrentRatio);
  115.  
  116. }
  117. }
  118. /// <summary>
  119. /// Fonction appellée lorsque le client reçoit la nouvelle position de cette entitée.
  120. /// </summary>
  121. /// <param name="position">nouvelle position de l'entitée</param>
  122. public void OnPositionReceived(Vector3 position, float rotation)
  123. {
  124. if (NextPosition.Position == null) // tout première position reçue. (Previous est donc indéfinie)
  125. {
  126. NextPosition = new EntityPositionExtended(position, rotation, DateTime.Now);
  127. }
  128. this.gameObject.transform.position = NextPosition.Position.Value; // Quoi qu'il arrive avec l'interpolation, l'entitée est téléportée au point d'arrivée
  129. this.gameObject.transform.rotation = Geometry.ModifyQuaternion(transform.rotation, NextPosition.Rotation.Value);
  130.  
  131. CurrentTime = 0; // Le compteur de temps repart a 0
  132. PreviousPosition = NextPosition; // La position précédente devient l'ancienne.
  133. NextPosition = new EntityPositionExtended(position, rotation, DateTime.Now);
  134. }
  135. }
  136. /// <summary>
  137. /// Structure représentant une position reçue par le client
  138. /// </summary>
  139. public struct EntityPositionExtended
  140. {
  141. /// <summary>
  142. /// Position de l'entitée
  143. /// </summary>
  144. public Vector3? Position;
  145. /// <summary>
  146. /// Date a laquelle cette position a été reçue.
  147. /// </summary>
  148. ///
  149. public float? Rotation;
  150.  
  151. public DateTime Time;
  152.  
  153. public EntityPositionExtended(Vector3 position, float rotation, DateTime time)
  154. {
  155. this.Position = position;
  156. this.Time = time;
  157. this.Rotation = rotation;
  158. }
  159.  
  160. }
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement