Repository navigation
Expand file tree
/
Copy pathObject_SyncPosition.cs
More file actions
132 lines (120 loc) · 3.67 KB
/
Copy pathObject_SyncPosition.cs
File metadata and controls
132 lines (120 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
//Something in this custom script causes bullets to be fired from many locations at once.
public class Object_SyncPosition : NetworkBehaviour {
#region Properties
[SerializeField]
protected Transform target;
#region Setup
[Header("Setup")]
[Range(0,10)] public int SendRate = 2;
[Range(0,2)] public float movementThreshold = 0.2f;
[Range(0,30)] public float angleThreshold = 5;
[Range(0, 10)] public float distanceBeforeSnap = 4;
[Range(0,90)] public float angleBeforeSnap = 40;
#endregion
#region Interpolation
[Header("Interpolation")]
[Range(0,1)] public float movementInterpolation = 0.1f;
[Range(0,1)] public float rotationInterpolation = 0.1f;
#endregion
#region Prediction
public float thresholdMovementPrediction = 0.7f;
public float thresholdRotationPrediction = 15;
#endregion
#region ProtectedProperties
protected Vector3 lastDirectionPerFrame = Vector3.zero;
protected Vector3 lastPositionSent = Vector3.zero;
protected Quaternion lastRotationSent = Quaternion.identity;
protected Quaternion lastRotationDirectionPerFrame = Quaternion.identity;
protected bool send = false;
protected bool sending = false;
protected int count = 0;
#endregion
#endregion
#region Logic
void FixedUpdate () {
if (isLocalPlayer) {
sendInfo();
} else {
recontiliation();
}
}
protected void sendInfo() {
if (send) {
if (count == SendRate) {
count = 0;
send = false;
Vector3 v = target.position;
Quaternion q = target.rotation;
CmdSendPosition(v,q);
} else {
count++;
}
} else {
checkIfSend();
}
}
protected void checkIfSend() {
if (sending) {
send = true;
sending = false;
return;
}
Vector3 v = target.position;
Quaternion q = target.rotation;
float distance = Vector3.Distance(lastPositionSent, v);
float angle = Quaternion.Angle(lastRotationSent, q); ;
if (distance > movementThreshold || angle > angleThreshold) {
send = true;
sending = true;
}
}
protected void recontiliation() {
Vector3 v = target.position;
Quaternion q = target.rotation;
float distance = Vector3.Distance(lastPositionSent, v);
float angle = Vector3.Angle(lastRotationSent.eulerAngles, q.eulerAngles);
if (distance > distanceBeforeSnap) {
target.position = lastPositionSent;
}
if (angle > angleBeforeSnap) {
target.rotation = lastRotationSent;
}
//prediction
v += lastDirectionPerFrame;
q *= lastRotationDirectionPerFrame;
//interpolation
Vector3 vLerp = Vector3.Lerp(v, lastPositionSent, movementInterpolation);
Quaternion qLerp = Quaternion.Lerp(q, lastRotationSent, rotationInterpolation);
target.position = vLerp;
target.rotation = qLerp;
}
#endregion
#region OverNetwork
[Command (channel = 1)]
protected void CmdSendPosition(Vector3 newPos,Quaternion newRot) {
RpcReceivePosition(newPos, newRot);
}
[ClientRpc(channel = 1)]
protected void RpcReceivePosition(Vector3 newPos,Quaternion newRot) {
int frames = (SendRate + 1);
lastDirectionPerFrame = newPos - lastPositionSent;
//right now prediction is made with the new direction and amount of frames
lastDirectionPerFrame /= frames;
if (lastDirectionPerFrame.magnitude > thresholdMovementPrediction) {
lastDirectionPerFrame = Vector3.zero;
}
Vector3 lastEuler = lastRotationSent.eulerAngles;
Vector3 newEuler = newRot.eulerAngles;
if (Quaternion.Angle(lastRotationDirectionPerFrame, newRot) < thresholdRotationPrediction) {
lastRotationDirectionPerFrame = Quaternion.Euler(( newEuler - lastEuler ) / frames);
}else {
lastRotationDirectionPerFrame = Quaternion.identity;
}
lastPositionSent = newPos;
lastRotationSent = newRot;
}
#endregion
}