Trail sync with client predictions
This commit is contained in:
@@ -71,7 +71,7 @@ TrailRenderer:
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_SortingOrder: 1
|
||||
m_Time: 3.39
|
||||
m_Parameters:
|
||||
serializedVersion: 3
|
||||
@@ -127,7 +127,7 @@ TrailRenderer:
|
||||
shadowBias: 0.5
|
||||
generateLightingData: 0
|
||||
m_MinVertexDistance: 1
|
||||
m_Autodestruct: 1
|
||||
m_Autodestruct: 0
|
||||
m_Emitting: 1
|
||||
--- !u!1 &5431987895376475548
|
||||
GameObject:
|
||||
@@ -142,6 +142,7 @@ GameObject:
|
||||
- component: {fileID: 5431987895376475544}
|
||||
- component: {fileID: 2701406673750748793}
|
||||
- component: {fileID: 5995183602835295541}
|
||||
- component: {fileID: 3057151313563799006}
|
||||
- component: {fileID: -4779029823867914901}
|
||||
m_Layer: 0
|
||||
m_Name: Player
|
||||
@@ -253,6 +254,7 @@ MonoBehaviour:
|
||||
turningSmoothFactor: 0.1
|
||||
joystick: {fileID: 0}
|
||||
joyInput: {x: 0, y: 0}
|
||||
DetourError: {x: 0, y: 0, z: 0}
|
||||
Detour: {x: 0, y: 0, z: 0}
|
||||
RotationDetour: {x: 0, y: 0, z: 0, w: 1}
|
||||
DetourCorrectionFactor: 0.1
|
||||
@@ -269,14 +271,29 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: f3fd3790e46aca946913301ba3099ba0, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
syncMode: 0
|
||||
syncInterval: 0.1
|
||||
trail: {fileID: 1146104764719429896}
|
||||
line: {fileID: 8349033136630816928}
|
||||
positions: []
|
||||
trailPoolParent: {fileID: 8130040756198270646}
|
||||
trailColliderObj: {fileID: 8026949445604271921, guid: 946508cc9b8006d4189d372f21555f92, type: 3}
|
||||
trailsPool: []
|
||||
--- !u!114 &3057151313563799006
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5431987895376475548}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 661698fa54f409f4d8251cfdd48d8f51, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
syncMode: 0
|
||||
syncInterval: 0.1
|
||||
trail: {fileID: 1146104764719429896}
|
||||
line: {fileID: 8349033136630816928}
|
||||
DetourError: {x: 0, y: 1.3, z: 0}
|
||||
positions: []
|
||||
--- !u!61 &-4779029823867914901
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -560,13 +577,13 @@ LineRenderer:
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_SortingOrder: 2
|
||||
m_Positions:
|
||||
- {x: 0, y: 0, z: 0}
|
||||
- {x: 0, y: 0, z: 1}
|
||||
m_Parameters:
|
||||
serializedVersion: 3
|
||||
widthMultiplier: 0.1
|
||||
widthMultiplier: 1
|
||||
widthCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
|
||||
@@ -190,7 +190,7 @@ MonoBehaviour:
|
||||
offlineScene:
|
||||
onlineScene:
|
||||
transport: {fileID: 42724090}
|
||||
networkAddress: 194.233.70.117
|
||||
networkAddress: vps.playpoolstudios.com
|
||||
maxConnections: 100
|
||||
authenticator: {fileID: 0}
|
||||
playerPrefab: {fileID: 5431987895376475548, guid: e811a838f2ebb2f4fb8055331ed295e9, type: 3}
|
||||
@@ -301,6 +301,50 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 43679075}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &332697607
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 332697609}
|
||||
- component: {fileID: 332697608}
|
||||
m_Layer: 0
|
||||
m_Name: GameManager
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &332697608
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 332697607}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 050f3527cd45bfc8d862ebc6d9942cc8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
trailCollidersParent: {fileID: 697893403}
|
||||
--- !u!4 &332697609
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 332697607}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: -16.873886, y: 288.569, z: -13.784264}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 12
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &409497206
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -791,6 +835,36 @@ MonoBehaviour:
|
||||
offset: {x: 0, y: 0, z: -10}
|
||||
target: {fileID: 0}
|
||||
smoothness: 2.5
|
||||
--- !u!1 &697893402
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 697893403}
|
||||
m_Layer: 0
|
||||
m_Name: TrailColliders
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &697893403
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 697893402}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: -0.32395512, y: 1.5178494, z: -3.3579822}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 13
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &710453079
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
80
Assets/Game/Scripts/Minigame/NetworkTrail.cs
Normal file
80
Assets/Game/Scripts/Minigame/NetworkTrail.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Mirror;
|
||||
|
||||
public class NetworkTrail : NetworkBehaviour
|
||||
{
|
||||
public TrailRenderer trail;
|
||||
public LineRenderer line;
|
||||
public bool enableValidation = true;
|
||||
public int maxDetourPoints = 1;
|
||||
public float DetourThreshold = 1;
|
||||
public int Detours;
|
||||
|
||||
public Vector3[] positions;
|
||||
|
||||
void Start()
|
||||
{
|
||||
//trail.gameObject.SetActive(isServer);
|
||||
line.gameObject.SetActive(!isServer);
|
||||
line.transform.parent=null;
|
||||
line.transform.position =Vector3.zero;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if(isServer){
|
||||
positions = new Vector3[trail.positionCount];
|
||||
trail.GetPositions(positions);
|
||||
RpcUpdatePositions(positions);
|
||||
}else{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[ClientRpc]
|
||||
void RpcUpdatePositions(Vector3[] Positions){
|
||||
if(!enableValidation){return;}
|
||||
positions = Positions;
|
||||
line.positionCount = positions.Length;
|
||||
line.SetPositions(positions);
|
||||
|
||||
//Validate With Trail
|
||||
Vector3[] localPositions = new Vector3[trail.positionCount];
|
||||
trail.GetPositions(localPositions);
|
||||
Detours = 0;
|
||||
for(int i=0; i < Positions.Length; i++){
|
||||
bool pointValidated = false;
|
||||
for(int j=1; j < 3; j++){
|
||||
try{
|
||||
if(isCloseEnough(Positions[i], localPositions[i+j])){
|
||||
pointValidated = true;
|
||||
break;
|
||||
}
|
||||
if(isCloseEnough(Positions[i], localPositions[i-j])){
|
||||
pointValidated = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}catch{
|
||||
//No local position, Hence, no validation
|
||||
}
|
||||
}
|
||||
if(!pointValidated){
|
||||
Detours++;
|
||||
}
|
||||
}
|
||||
|
||||
if(Detours > maxDetourPoints){
|
||||
//Too much detours, Set back to servers data
|
||||
trail.SetPositions(Positions);
|
||||
}
|
||||
}
|
||||
|
||||
bool isCloseEnough(Vector3 a, Vector3 b){
|
||||
return Vector3.Distance(a,b) < DetourThreshold;
|
||||
}
|
||||
}
|
||||
11
Assets/Game/Scripts/Minigame/NetworkTrail.cs.meta
Normal file
11
Assets/Game/Scripts/Minigame/NetworkTrail.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 661698fa54f409f4d8251cfdd48d8f51
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17
Assets/Game/Scripts/Minigame/SceneDataHolder.cs
Normal file
17
Assets/Game/Scripts/Minigame/SceneDataHolder.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class SceneDataHolder : MonoBehaviour
|
||||
{
|
||||
public Transform trailCollidersParent;
|
||||
void Awake()
|
||||
{
|
||||
SceneData.holder = this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class SceneData{
|
||||
public static SceneDataHolder holder;
|
||||
}
|
||||
11
Assets/Game/Scripts/Minigame/SceneDataHolder.cs.meta
Normal file
11
Assets/Game/Scripts/Minigame/SceneDataHolder.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 050f3527cd45bfc8d862ebc6d9942cc8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -14,6 +14,7 @@ public class SpaceshipController : NetworkBehaviour
|
||||
|
||||
[Header("Client Prediction")]
|
||||
public SortedDictionary<int, StatePayload> serverStateBuffer = new SortedDictionary<int, StatePayload>();
|
||||
public Vector3 DetourError = new Vector3(0,0.2f,0);
|
||||
public Vector3 Detour = Vector3.zero;
|
||||
public Quaternion RotationDetour = Quaternion.identity;
|
||||
public float DetourCorrectionFactor = 0.5f;
|
||||
@@ -122,7 +123,8 @@ public class SpaceshipController : NetworkBehaviour
|
||||
newRotation = Quaternion.Lerp(newRotation, getTurnAngle(input), turningSmoothFactor * input.magnitude);
|
||||
}
|
||||
|
||||
targetPosition = newPosition;
|
||||
targetPosition = newPosition - DetourError;
|
||||
|
||||
targetRotation = newRotation;
|
||||
}
|
||||
|
||||
@@ -156,7 +158,7 @@ public class SpaceshipController : NetworkBehaviour
|
||||
payloadToCompare = lastServerState;
|
||||
if (lastServerState.Time < time)
|
||||
{
|
||||
Debug.Log("Server doesn't have that data yet\nYou asked for " + time + " best I can do is " + lastServerState.Time);
|
||||
// Debug.Log("Server doesn't have that data yet\nYou asked for " + time + " best I can do is " + lastServerState.Time);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -185,7 +187,7 @@ public class SpaceshipController : NetworkBehaviour
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"RB : {positionDiff.magnitude} [{timeDiff}ms]");
|
||||
// Debug.Log($"RB : {positionDiff.magnitude} [{timeDiff}ms]");
|
||||
RpcRubberBand(joyInput, serverStateBuffer.Values.Last().Position, serverStateBuffer.Values.Last().Rotation, trailMgr.positions, timeInMillis);
|
||||
}
|
||||
|
||||
@@ -231,7 +233,7 @@ public class SpaceshipController : NetworkBehaviour
|
||||
// Vector3 newPosition = position + new Vector3(0, movingSpeed * );
|
||||
|
||||
// Vector3 newPosition = position;
|
||||
Detour = newPosition - transform.position;
|
||||
Detour = newPosition - transform.position - DetourError;
|
||||
|
||||
// RotationDetour = rotation;
|
||||
RotationDetour = Quaternion.Inverse(transform.rotation) * newRotation;
|
||||
|
||||
@@ -5,12 +5,13 @@ using UnityEngine;
|
||||
public class TrailCollider : MonoBehaviour
|
||||
{
|
||||
public Color gizmoColor = Color.red;
|
||||
public TrailMgr trailMgr;
|
||||
public float radius;
|
||||
void Update(){
|
||||
RaycastHit2D hit = Physics2D.CircleCast(transform.position, radius, Vector2.up);
|
||||
if(hit.collider!=null){
|
||||
if(hit.transform == transform.root){return;} // <-- avoid eating myself
|
||||
transform.root.GetComponent<TrailMgr>().OnColliderHit(hit);
|
||||
if(hit.transform.root == trailMgr.transform){return;} // <-- avoid eating myself
|
||||
trailMgr.OnColliderHit(hit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,20 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Mirror;
|
||||
|
||||
public class TrailMgr : NetworkBehaviour
|
||||
public class TrailMgr : MonoBehaviour
|
||||
{
|
||||
public TrailRenderer trail;
|
||||
public LineRenderer line;
|
||||
public Vector3[] positions;
|
||||
public Transform trailPoolParent;
|
||||
public GameObject trailColliderObj;
|
||||
public List<GameObject> trailsPool;
|
||||
|
||||
void Start(){
|
||||
trail.gameObject.SetActive(isServer);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if(!isServer){return;}
|
||||
|
||||
void Update(){
|
||||
positions = new Vector3[trail.positionCount];
|
||||
int length = trail.GetPositions(positions);
|
||||
if(length > trailsPool.Count){
|
||||
@@ -28,6 +22,8 @@ public class TrailMgr : NetworkBehaviour
|
||||
int missingCount = length - trailsPool.Count;
|
||||
for(int i =0; i < missingCount; i++){
|
||||
GameObject newTrail = Instantiate(trailColliderObj, trailPoolParent);
|
||||
// Debug.Log("Spawned new trail obj " + newTrail.name);
|
||||
newTrail.GetComponent<TrailCollider>().trailMgr = this;
|
||||
trailsPool.Add(newTrail);
|
||||
}
|
||||
}
|
||||
@@ -39,17 +35,12 @@ public class TrailMgr : NetworkBehaviour
|
||||
trailsPool[i].SetActive(false);
|
||||
}
|
||||
}
|
||||
RpcUpdateTrail(positions);
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
void RpcUpdateTrail(Vector3[] new_positions){
|
||||
positions = new_positions;
|
||||
line.SetPositions(positions);
|
||||
}
|
||||
|
||||
|
||||
public void OnColliderHit(RaycastHit2D hit){
|
||||
return;
|
||||
Debug.Log($"{hit.collider.name} got hit by my trail");
|
||||
Destroy(hit.transform.gameObject);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user