1- using MLAPI . MonoBehaviours . Core ;
1+ using System . Collections . Generic ;
2+ using MLAPI . MonoBehaviours . Core ;
23using MLAPI . NetworkingManagerComponents . Binary ;
34using System . IO ;
45using UnityEngine ;
@@ -11,11 +12,16 @@ namespace MLAPI.MonoBehaviours.Prototyping
1112 [ AddComponentMenu ( "MLAPI/NetworkedTransform" ) ]
1213 public class NetworkedTransform : NetworkedBehaviour
1314 {
14- /// <summary>
15- /// Sends per second
16- /// </summary>
17- [ Range ( 0f , 120f ) ]
18- public float SendsPerSecond = 20 ;
15+ public class ClientSendInfo
16+ {
17+ public uint clientId ;
18+ public float lastSent ;
19+ public Vector3 ? lastMissedPosition ;
20+ public Quaternion ? lastMissedRotation ;
21+ }
22+
23+ [ Range ( 0 , 120 ) ]
24+ public float FixedSendsPerSecond = 20f ;
1925 /// <summary>
2026 /// Is the sends per second assumed to be the same across all instances
2127 /// </summary>
@@ -43,7 +49,6 @@ public class NetworkedTransform : NetworkedBehaviour
4349 /// The min degrees to rotate before a send it sent
4450 /// </summary>
4551 public float MinDegrees = 1.5f ;
46- private float timeForLerp ;
4752 private float lerpT ;
4853 private Vector3 lerpStartPos ;
4954 private Quaternion lerpStartRot ;
@@ -53,15 +58,10 @@ public class NetworkedTransform : NetworkedBehaviour
5358 private float lastSendTime ;
5459 private Vector3 lastSentPos ;
5560 private Quaternion lastSentRot ;
56- /// <summary>
57- /// Should proximity be enabled
58- /// </summary>
59- public bool EnableProximity = false ;
60- /// <summary>
61- /// The distance to use for proximity
62- /// </summary>
63- [ Tooltip ( "If enable proximity is turned on, on clients within this range will be recieving position updates from the server" ) ]
64- public float ProximityRange = 50 ;
61+
62+ public bool EnableRange ;
63+ public AnimationCurve DistanceSendrate = AnimationCurve . Constant ( 0 , 500 , 20 ) ;
64+ private readonly Dictionary < uint , ClientSendInfo > clientSendInfo = new Dictionary < uint , ClientSendInfo > ( ) ;
6565
6666 private static byte [ ] positionUpdateBuffer = new byte [ 24 ] ;
6767
@@ -77,6 +77,11 @@ private void OnValidate()
7777 MinMeters = 0 ;
7878 }
7979
80+ private float GetTimeForLerp ( Vector3 pos1 , Vector3 pos2 )
81+ {
82+ return 1f / DistanceSendrate . Evaluate ( Vector3 . Distance ( pos1 , pos2 ) ) ;
83+ }
84+
8085 /// <summary>
8186 /// Registers message handlers
8287 /// </summary>
@@ -90,10 +95,6 @@ public override void NetworkStart()
9095 {
9196 RegisterMessageHandler ( "MLAPI_OnRecieveTransformFromServer" , OnRecieveTransformFromServer ) ;
9297 }
93- if ( AssumeSyncedSends )
94- {
95- timeForLerp = 1f / SendsPerSecond ;
96- }
9798
9899 lastSentRot = transform . rotation ;
99100 lastSentPos = transform . position ;
@@ -110,7 +111,7 @@ private void Update()
110111 if ( isOwner || isLocalPlayer || ( OwnerClientId == NetworkingManager . singleton . NetworkConfig . NetworkTransport . InvalidDummyId && isServer ) )
111112 {
112113 //We own the object OR we are server and the object is not owned by anyone OR we are the object.
113- if ( NetworkingManager . singleton . NetworkTime - lastSendTime >= timeForLerp && ( Vector3 . Distance ( transform . position , lastSentPos ) > MinMeters || Quaternion . Angle ( transform . rotation , lastSentRot ) > MinDegrees ) )
114+ if ( NetworkingManager . singleton . NetworkTime - lastSendTime >= ( 1f / FixedSendsPerSecond ) && ( Vector3 . Distance ( transform . position , lastSentPos ) > MinMeters || Quaternion . Angle ( transform . rotation , lastSentRot ) > MinDegrees ) )
114115 {
115116 lastSendTime = NetworkingManager . singleton . NetworkTime ;
116117 lastSentPos = transform . position ;
@@ -145,11 +146,21 @@ private void Update()
145146 //Snap, set T to 1 (100% of the lerp)
146147 lerpT = 1f ;
147148 }
148- lerpT += Time . unscaledDeltaTime / timeForLerp ;
149+
150+ if ( isServer || ! EnableRange )
151+ lerpT += Time . unscaledDeltaTime / FixedSendsPerSecond ;
152+ else
153+ {
154+ Vector3 myPos = NetworkingManager . singleton . ConnectedClients [ NetworkingManager . singleton . LocalClientId ] . PlayerObject . transform . position ;
155+ lerpT += Time . unscaledDeltaTime / GetTimeForLerp ( transform . position , myPos ) ;
156+ }
157+
149158 transform . position = Vector3 . Lerp ( lerpStartPos , lerpEndPos , lerpT ) ;
150159 transform . rotation = Quaternion . Slerp ( lerpStartRot , lerpEndRot , lerpT ) ;
151160 }
152161 }
162+
163+ if ( isServer ) CheckForMissedSends ( ) ;
153164 }
154165
155166 private void OnRecieveTransformFromServer ( uint clientId , BitReader reader )
@@ -219,14 +230,38 @@ private void OnRecieveTransformFromClient(uint clientId, BitReader reader)
219230 writer . Write ( yRot ) ;
220231 writer . Write ( zRot ) ;
221232 }
222- if ( EnableProximity )
233+ if ( EnableRange )
223234 {
224235 // For instead of Foreach?! TODO!!!
225- for ( uint i = 0 ; i < NetworkingManager . singleton . ConnectedClients . Count ; i ++ )
236+ for ( int i = 0 ; i < NetworkingManager . singleton . ConnectedClientsList . Count ; i ++ )
226237 {
227- if ( Vector3 . Distance ( NetworkingManager . singleton . ConnectedClients [ i ] . PlayerObject . transform . position , transform . position ) <= ProximityRange )
238+ if ( ! clientSendInfo . ContainsKey ( NetworkingManager . singleton . ConnectedClientsList [ i ] . ClientId ) )
239+ {
240+ clientSendInfo . Add ( NetworkingManager . singleton . ConnectedClientsList [ i ] . ClientId , new ClientSendInfo ( )
241+ {
242+ clientId = NetworkingManager . singleton . ConnectedClientsList [ i ] . ClientId ,
243+ lastMissedPosition = null ,
244+ lastMissedRotation = null ,
245+ lastSent = 0
246+ } ) ;
247+ }
248+
249+ ClientSendInfo info = clientSendInfo [ NetworkingManager . singleton . ConnectedClientsList [ i ] . ClientId ] ;
250+ Vector3 receiverPosition = NetworkingManager . singleton . ConnectedClientsList [ i ] . PlayerObject . transform . position ;
251+ Vector3 senderPosition = NetworkingManager . singleton . ConnectedClients [ OwnerClientId ] . PlayerObject . transform . position ;
252+
253+ if ( NetworkingManager . singleton . NetworkTime - info . lastSent >= GetTimeForLerp ( receiverPosition , senderPosition ) )
254+ {
255+ info . lastSent = NetworkingManager . singleton . NetworkTime ;
256+ info . lastMissedPosition = null ;
257+ info . lastMissedRotation = null ;
258+
259+ SendToClientTarget ( NetworkingManager . singleton . ConnectedClientsList [ i ] . ClientId , "MLAPI_OnRecieveTransformFromServer" , "MLAPI_POSITION_UPDATE" , positionUpdateBuffer , true ) ;
260+ }
261+ else
228262 {
229- SendToClientTarget ( NetworkingManager . singleton . ConnectedClients [ i ] . ClientId , "MLAPI_OnRecieveTransformFromServer" , "MLAPI_POSITION_UPDATE" , positionUpdateBuffer , true ) ;
263+ info . lastMissedPosition = new Vector3 ( xPos , yPos , zPos ) ;
264+ info . lastMissedRotation = Quaternion . Euler ( xRot , yRot , zRot ) ;
230265 }
231266 }
232267 }
@@ -239,6 +274,25 @@ private void OnRecieveTransformFromClient(uint clientId, BitReader reader)
239274 }
240275 }
241276
277+ private void CheckForMissedSends ( )
278+ {
279+ for ( int i = 0 ; i < NetworkingManager . singleton . ConnectedClientsList . Count ; i ++ )
280+ {
281+ ClientSendInfo info = clientSendInfo [ NetworkingManager . singleton . ConnectedClientsList [ i ] . ClientId ] ;
282+ Vector3 receiverPosition = NetworkingManager . singleton . ConnectedClientsList [ i ] . PlayerObject . transform . position ;
283+ Vector3 senderPosition = NetworkingManager . singleton . ConnectedClients [ OwnerClientId ] . PlayerObject . transform . position ;
284+
285+ if ( NetworkingManager . singleton . NetworkTime - info . lastSent >= GetTimeForLerp ( receiverPosition , senderPosition ) )
286+ {
287+ info . lastSent = NetworkingManager . singleton . NetworkTime ;
288+ info . lastMissedPosition = null ;
289+ info . lastMissedRotation = null ;
290+
291+ SendToClientTarget ( NetworkingManager . singleton . ConnectedClientsList [ i ] . ClientId , "MLAPI_OnRecieveTransformFromServer" , "MLAPI_POSITION_UPDATE" , positionUpdateBuffer , true ) ;
292+ }
293+ }
294+ }
295+
242296 public void Teleport ( Vector3 position , Quaternion rotation )
243297 {
244298 if ( InterpolateServer && isServer || isClient )
0 commit comments