Trail sync with client predictions

This commit is contained in:
Sewmina Dilshan 2022-06-22 19:54:18 +05:30
parent b450cfdf36
commit a18c7028c4
19 changed files with 232 additions and 28 deletions

View File

@ -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:

View File

@ -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

View 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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 661698fa54f409f4d8251cfdd48d8f51
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 050f3527cd45bfc8d862ebc6d9942cc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);
}

Binary file not shown.