Compare commits

..

No commits in common. "0e9b82ca4313f16e9901e8644841af9cff1919ef" and "ad1746d4a2baf1151d30711e26da662105f69b43" have entirely different histories.

16 changed files with 204 additions and 159 deletions

View File

@ -9,6 +9,8 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 3817028170077760731}
- component: {fileID: 4590407122831754579}
- component: {fileID: 8963967235500975272}
m_Layer: 0
m_Name: RopePoint
m_TagString: Untagged
@ -31,3 +33,66 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!58 &4590407122831754579
CircleCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4736158799711156794}
m_Enabled: 1
serializedVersion: 3
m_Density: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 128
m_LayerOverridePriority: 0
m_ForceSendLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ForceReceiveLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ContactCaptureLayers:
serializedVersion: 2
m_Bits: 4294967295
m_CallbackLayers:
serializedVersion: 2
m_Bits: 4294967295
m_IsTrigger: 0
m_UsedByEffector: 0
m_CompositeOperation: 0
m_CompositeOrder: 0
m_Offset: {x: 0, y: 0}
m_Radius: 0.5
--- !u!50 &8963967235500975272
Rigidbody2D:
serializedVersion: 4
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4736158799711156794}
m_BodyType: 1
m_Simulated: 1
m_UseFullKinematicContacts: 0
m_UseAutoMass: 0
m_Mass: 1
m_LinearDrag: 0
m_AngularDrag: 0.05
m_GravityScale: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_Interpolate: 0
m_SleepingMode: 1
m_CollisionDetection: 0
m_Constraints: 0

View File

@ -1,8 +1,15 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Unity.Mathematics;
using Unity.Netcode;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UIElements;
public class EnemySpawner : NetworkBehaviour
{

View File

@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
public class AudioManager : MonoBehaviour

View File

@ -1,6 +1,11 @@
using Netcode.Transports.Facepunch;
using Steamworks;
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using Unity.Netcode.Transports.UTP;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

View File

@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using Unity.VisualScripting.YamlDotNet.Core.Tokens;
using UnityEngine;
public struct MoveData : INetworkSerializable

View File

@ -1,25 +0,0 @@
using Unity.Netcode;
[System.Serializable]
public struct GameState : INetworkSerializable
{
public int tick;
public NetworkRope nrope;
public override int GetHashCode()
{
return tick;
}
public override bool Equals(object obj)
{
GameState other = (GameState) obj;
return this.GetHashCode() == obj.GetHashCode();
}
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
serializer.SerializeValue(ref tick);
nrope.NetworkSerialize(serializer);
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 1cdca75ffd9bfc5b9b1c9ffe1a501dcf

View File

@ -9,8 +9,7 @@
"GUID:c0e1b40f519e6e84b8f4af9930403ecb",
"GUID:3b8ed52f1b5c64994af4c4e0aa4b6c4b",
"GUID:1491147abca9d7d4bb7105af628b223e",
"GUID:068707ae079d6e851b7a76adaa3014f8",
"GUID:f0aa6e1ec272fc041a727a9dfb7c1e67"
"GUID:068707ae079d6e851b7a76adaa3014f8"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@ -137,7 +137,6 @@ public class Rope
} */
}
[System.Serializable]
public struct NetworkRope : INetworkSerializable
{
// For rope points

View File

@ -4,8 +4,6 @@ using System.Linq;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Assertions;
using Utilities;
using UnityUtils;
public class RopeSimulator : NetworkBehaviour
{
@ -66,14 +64,10 @@ public class RopeSimulator : NetworkBehaviour
[SerializeField] float pullAnimationOvershootThreshold = 0.2f;
[Header("Netcode")]
private const float k_serverTickRate = 60f;
private const int k_rngSeed = 6969;
public float k_ropeReconciliateThreshold = 10f;
private const float k_sendRopeDataRPCThreshold = 0.1f;
public float k_ropeReconciliateThreshold = 8f;
private System.Random rng = new System.Random(k_rngSeed);
private int currentTick => NetworkManager.Singleton.NetworkTickSystem.LocalTime.Tick;
[SerializeField] private CircularBuffer<GameState> stateBuffer;
private GameState lastReceivedServerGameState;
private const int k_bufferSize = 512;
private int[] order;
@ -98,20 +92,16 @@ public class RopeSimulator : NetworkBehaviour
{
Destroy(instance);
}
stateBuffer = new(k_bufferSize);
}
private void OnEnable()
{
GameManager.OnPlayersReady += PlayersReady;
NetworkManager.Singleton.NetworkTickSystem.Tick += NetworkTick;
}
private void OnDisable()
{
GameManager.OnPlayersReady -= PlayersReady;
NetworkManager.Singleton.NetworkTickSystem.Tick -= NetworkTick;
}
public void PlayersReady(GameObject[] players)
@ -266,6 +256,11 @@ public class RopeSimulator : NetworkBehaviour
ropeCollider.transform.position = point.position;
ropeCollider.tag = colliderTag;
ropeCollider.layer = LayerMask.NameToLayer("Rope");
ropeCollider.GetComponent<CircleCollider2D>().radius = ropeRadius;
var rigidBody = ropeCollider.GetComponent<Rigidbody2D>();
rigidBody.isKinematic = true;
}
}
@ -282,43 +277,19 @@ public class RopeSimulator : NetworkBehaviour
}
[Rpc(SendTo.NotServer)]
private void ServerToClientGameStateRpc(GameState serverState)
private void ServerRopeDataReceivedRpc(NetworkRope nrope)
{
this.lastReceivedServerGameState = serverState;
Debug.Log($"Received rope data from server: {nrope}");
Rope serverRope = Rope.FromNetworkRope(nrope, distBetweenRopePoints);
Debug.Log($"Received server state. Server tick: {serverState.tick}, client: {currentTick}");
// Not enough information
if (stateBuffer.Get(serverState.tick).Equals(default(GameState))) return;
// TODO: investigate why this is zero at start of game sometimes
if (stateBuffer.Get(serverState.tick).nrope.positions.Length == 0) return;
Debug.Log($"client len: {stateBuffer.Get(serverState.tick).nrope.positions.Length}, server len {serverState.nrope.positions.Length}");
Rope serverRope = Rope.FromNetworkRope(serverState.nrope, distBetweenRopePoints);
Rope oldLocalRope = Rope.FromNetworkRope(stateBuffer.Get(serverState.tick).nrope, distBetweenRopePoints);
float serverLocalRopeDiff = Rope.CalcDiff(serverRope, oldLocalRope);
Debug.Log($"Server to client sync error: {serverLocalRopeDiff}");
float diff = Rope.CalcDiff(this.rope, serverRope);
Debug.Log(diff);
if (diff > k_ropeReconciliateThreshold)
{
// Debug.LogWarning("Reconciliating rope!");
// this.rope = serverRope;
// Debug.Log(Rope.CalcDiff(this.rope, serverRope));
}
private void NetworkTick()
{
stateBuffer.Add(ProcessGame(), currentTick);
// Send to clients if is server
if (IsServer)
ServerToClientGameStateRpc(stateBuffer.Get(currentTick));
}
private GameState ProcessGame()
{
GameState localState = new() {
tick = currentTick,
nrope = Rope.ToNetworkRope(this.rope)
};
return localState;
}
private void Update()
@ -332,6 +303,14 @@ public class RopeSimulator : NetworkBehaviour
rope.points.Last().position = end.position;
float ropeDiff = Simulate(Time.fixedDeltaTime);
if (IsServer)
{
Debug.Log($"Sending rope to client");
NetworkRope nrope = Rope.ToNetworkRope(this.rope);
// Send server rope to client for reconciliation
ServerRopeDataReceivedRpc(nrope);
}
// Update the rope collider positions
for (int i = 0; i < rope.points.Length; i++)
@ -433,22 +412,14 @@ public class RopeSimulator : NetworkBehaviour
private void OnDrawGizmos()
{
if (!IsInitialized) return;
return;
if (IsInitialized) return;
if (!Application.isPlaying) return;
// Local rope
Gizmos.color = Color.green;
foreach (var point in rope.points)
{
Gizmos.DrawSphere(point.position, ropeRadius);
}
// Last received server rope
if (lastReceivedServerGameState.Equals(default(GameState))) return;
Gizmos.color = Color.red;
foreach (var point in Rope.FromNetworkRope(lastReceivedServerGameState.nrope, distBetweenRopePoints).points)
{
//Debug.Log($"pos: {point.position}");
Gizmos.DrawSphere(point.position, ropeRadius);
}
}

View File

@ -1,4 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;

View File

@ -1,7 +1,6 @@
[System.Serializable]
public class CircularBuffer<T> {
public T[] buffer;
public int bufferSize;
T[] buffer;
int bufferSize;
public CircularBuffer(int bufferSize) {
this.bufferSize = bufferSize;

View File

@ -1,50 +0,0 @@
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(CircularBuffer<>))]
public class CircularBufferDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
EditorGUI.indentLevel++;
SerializedProperty bufferSizeProp = property.FindPropertyRelative("bufferSize");
int bufferSize = bufferSizeProp.intValue;
EditorGUI.PropertyField(
new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight, position.width, EditorGUIUtility.singleLineHeight),
bufferSizeProp);
SerializedProperty bufferProp = property.FindPropertyRelative("buffer");
EditorGUI.LabelField(
new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight * 2, position.width, EditorGUIUtility.singleLineHeight),
"Buffer Elements");
float lineHeight = EditorGUIUtility.singleLineHeight;
float bufferHeight = lineHeight * bufferSize;
Rect bufferRect = new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight * 3, position.width, bufferHeight);
EditorGUI.PropertyField(bufferRect, bufferProp, GUIContent.none, true);
EditorGUI.indentLevel--;
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
SerializedProperty bufferSizeProp = property.FindPropertyRelative("bufferSize");
int bufferSize = bufferSizeProp.intValue;
return EditorGUIUtility.singleLineHeight * (bufferSize + 3); // 1 for buffer size, 1 for label, and bufferSize for buffer elements
}
}
#endif

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 53ed82cd9cfbdb1868c0d12e415dd33f

View File

@ -1,11 +1,10 @@
{
"dependencies": {
"com.unity.2d.animation": "10.1.1",
"com.unity.2d.pixel-perfect": "5.0.3",
"com.unity.2d.spriteshape": "10.0.3",
"com.unity.2d.tilemap": "1.0.0",
"com.unity.ai.navigation": "2.0.0",
"com.unity.cinemachine": "2.9.7",
"com.unity.collab-proxy": "2.2.0",
"com.unity.feature.2d": "2.0.0",
"com.unity.ide.rider": "3.0.27",
"com.unity.ide.visualstudio": "2.0.22",
"com.unity.inputsystem": "1.7.0",
"com.unity.multiplayer.playmode": "0.6.0",
@ -16,6 +15,7 @@
"com.unity.timeline": "1.8.6",
"com.unity.toolchain.linux-x86_64": "2.0.6",
"com.unity.ugui": "2.0.0",
"com.unity.visualscripting": "1.9.1",
"com.unity.modules.accessibility": "1.0.0",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",

View File

@ -1,11 +1,11 @@
{
"dependencies": {
"com.unity.2d.animation": {
"version": "10.1.1",
"depth": 0,
"version": "10.1.0",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.2d.common": "9.0.4",
"com.unity.2d.common": "9.0.3",
"com.unity.2d.sprite": "1.0.0",
"com.unity.collections": "1.2.4",
"com.unity.modules.animation": "1.0.0",
@ -13,10 +13,22 @@
},
"url": "https://packages.unity.com"
},
"com.unity.2d.common": {
"version": "9.0.4",
"com.unity.2d.aseprite": {
"version": "1.1.1",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.2d.sprite": "1.0.0",
"com.unity.2d.common": "6.0.6",
"com.unity.mathematics": "1.2.6",
"com.unity.modules.animation": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.2d.common": {
"version": "9.0.3",
"depth": 2,
"source": "registry",
"dependencies": {
"com.unity.2d.sprite": "1.0.0",
"com.unity.mathematics": "1.1.0",
@ -28,11 +40,21 @@
},
"com.unity.2d.pixel-perfect": {
"version": "5.0.3",
"depth": 0,
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.2d.psdimporter": {
"version": "9.0.1",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.2d.common": "9.0.2",
"com.unity.2d.sprite": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.2d.sprite": {
"version": "1.0.0",
"depth": 1,
@ -40,25 +62,37 @@
"dependencies": {}
},
"com.unity.2d.spriteshape": {
"version": "10.0.3",
"depth": 0,
"version": "10.0.2",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.mathematics": "1.1.0",
"com.unity.2d.common": "9.0.4",
"com.unity.2d.common": "9.0.2",
"com.unity.modules.physics2d": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.2d.tilemap": {
"version": "1.0.0",
"depth": 0,
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.uielements": "1.0.0"
}
},
"com.unity.2d.tilemap.extras": {
"version": "4.0.2",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.modules.tilemap": "1.0.0",
"com.unity.2d.tilemap": "1.0.0",
"com.unity.ugui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.ai.navigation": {
"version": "2.0.0",
"depth": 0,
@ -87,6 +121,13 @@
},
"url": "https://packages.unity.com"
},
"com.unity.collab-proxy": {
"version": "2.2.0",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.collections": {
"version": "1.4.0",
"depth": 3,
@ -105,6 +146,30 @@
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.feature.2d": {
"version": "2.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.2d.animation": "10.1.0",
"com.unity.2d.pixel-perfect": "5.0.3",
"com.unity.2d.psdimporter": "9.0.1",
"com.unity.2d.sprite": "1.0.0",
"com.unity.2d.spriteshape": "10.0.2",
"com.unity.2d.tilemap": "1.0.0",
"com.unity.2d.tilemap.extras": "4.0.2",
"com.unity.2d.aseprite": "1.1.1"
}
},
"com.unity.ide.rider": {
"version": "3.0.27",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.22",
"depth": 0,
@ -291,6 +356,16 @@
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.visualscripting": {
"version": "1.9.1",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.modules.accessibility": {
"version": "1.0.0",
"depth": 0,