[Add] FishNet
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
#if FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
using System.Collections.Generic;
|
||||
using FishNet.Object;
|
||||
using GameKit.Dependencies.Utilities;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
public class ColliderRollback : NetworkBehaviour
|
||||
{
|
||||
#region Serialized.
|
||||
#pragma warning disable CS0414
|
||||
/// <summary>
|
||||
/// How to configure the bounding box check.
|
||||
/// </summary>
|
||||
[Tooltip("How to configure the bounding box check.")]
|
||||
[SerializeField]
|
||||
private RollbackManager.BoundingBoxType _boundingBox = RollbackManager.BoundingBoxType.Disabled;
|
||||
/// <summary>
|
||||
/// Physics type to generate a bounding box for.
|
||||
/// </summary>
|
||||
[Tooltip("Physics type to generate a bounding box for.")]
|
||||
[SerializeField]
|
||||
private RollbackPhysicsType _physicsType = RollbackPhysicsType.Physics;
|
||||
/// <summary>
|
||||
/// Size for the bounding box. This is only used when BoundingBox is set to Manual.
|
||||
/// </summary>
|
||||
[Tooltip("Size for the bounding box.. This is only used when BoundingBox is set to Manual.")]
|
||||
[SerializeField]
|
||||
private Vector3 _boundingBoxSize = new(3f, 3f, 3f);
|
||||
/// <summary>
|
||||
/// Center for the bounding box. This is only used when BoundingBox is set to Manual.
|
||||
/// </summary>
|
||||
[Tooltip("Center for the bounding box.. This is only used when BoundingBox is set to Manual.")]
|
||||
[SerializeField]
|
||||
private Vector3 _boundingBoxCenter = new(0f, 0f, 0f);
|
||||
/// <summary>
|
||||
/// Local Rotation for the bounding box. This is only used when BoundingBox is set to Manual.
|
||||
/// </summary>
|
||||
[Tooltip("Center for the bounding box.. This is only used when BoundingBox is set to Manual.")]
|
||||
[SerializeField]
|
||||
private Quaternion _boundingBoxLocalRotation = Quaternion.identity;
|
||||
/// <summary>
|
||||
/// Objects holding colliders which can rollback.
|
||||
/// </summary>
|
||||
[Tooltip("Objects holding colliders which can rollback.")]
|
||||
[SerializeField]
|
||||
private GameObject[] _colliderParents = new GameObject[0];
|
||||
#pragma warning restore CS0414
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8e604e0a2709484193cda1a6d03b5b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/ColliderRollback.Threaded.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,25 @@
|
||||
#if !FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using GameKit.Dependencies.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
public partial class ColliderRollback
|
||||
{
|
||||
internal enum BoundingBoxType
|
||||
{
|
||||
/// <summary>
|
||||
/// Disable this feature.
|
||||
/// </summary>
|
||||
Disabled,
|
||||
/// <summary>
|
||||
/// Manually specify the dimensions of a bounding box.
|
||||
/// </summary>
|
||||
Manual
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83b62057280ff8e4faf4a7344b9f3bda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bf9191e2e07d29749bca3a1ae44e4bc8, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/ColliderRollback.Types.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,43 @@
|
||||
#if !FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
using System.Collections.Generic;
|
||||
using FishNet.Managing;
|
||||
using FishNet.Object;
|
||||
using GameKit.Dependencies.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
public partial class ColliderRollback : NetworkBehaviour
|
||||
{
|
||||
#region Serialized.
|
||||
#pragma warning disable CS0414
|
||||
/// <summary>
|
||||
/// How to configure the bounding box check.
|
||||
/// </summary>
|
||||
[Tooltip("How to configure the bounding box check.")]
|
||||
[SerializeField]
|
||||
private BoundingBoxType _boundingBox = BoundingBoxType.Disabled;
|
||||
/// <summary>
|
||||
/// Physics type to generate a bounding box for.
|
||||
/// </summary>
|
||||
[Tooltip("Physics type to generate a bounding box for.")]
|
||||
[SerializeField]
|
||||
private RollbackPhysicsType _physicsType = RollbackPhysicsType.Physics;
|
||||
/// <summary>
|
||||
/// Size for the bounding box. This is only used when BoundingBox is set to Manual.
|
||||
/// </summary>
|
||||
[Tooltip("Size for the bounding box.. This is only used when BoundingBox is set to Manual.")]
|
||||
[SerializeField]
|
||||
private Vector3 _boundingBoxSize = new(3f, 3f, 3f);
|
||||
/// <summary>
|
||||
/// Objects holding colliders which can rollback.
|
||||
/// </summary>
|
||||
[Tooltip("Objects holding colliders which can rollback.")]
|
||||
[SerializeField]
|
||||
private GameObject[] _colliderParents = new GameObject[0];
|
||||
#pragma warning restore CS0414
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01a271dd97d875347b0cea860df29a9d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bf9191e2e07d29749bca3a1ae44e4bc8, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/ColliderRollback.cs
|
||||
uploadId: 866910
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
#if UNITY_EDITOR && FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using static FishNet.Component.ColliderRollback.ColliderRollback;
|
||||
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
[CustomEditor(typeof(ColliderRollback), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class ColliderRollbackEditor : Editor
|
||||
{
|
||||
private SerializedProperty _boundingBox;
|
||||
private SerializedProperty _physicsType;
|
||||
private SerializedProperty _boundingBoxSize;
|
||||
private SerializedProperty _boundingBoxCenter;
|
||||
private SerializedProperty _boundingBoxLocalRotation;
|
||||
private SerializedProperty _colliderParents;
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
_boundingBox = serializedObject.FindProperty(nameof(_boundingBox));
|
||||
_physicsType = serializedObject.FindProperty(nameof(_physicsType));
|
||||
_boundingBoxSize = serializedObject.FindProperty(nameof(_boundingBoxSize));
|
||||
_boundingBoxCenter = serializedObject.FindProperty(nameof(_boundingBoxCenter));
|
||||
_boundingBoxLocalRotation = serializedObject.FindProperty(nameof(_boundingBoxLocalRotation));
|
||||
_colliderParents = serializedObject.FindProperty(nameof(_colliderParents));
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
ColliderRollback nob = (ColliderRollback)target;
|
||||
|
||||
GUI.enabled = false;
|
||||
EditorGUILayout.ObjectField("Script:", MonoScript.FromMonoBehaviour(nob), typeof(ColliderRollback), false);
|
||||
GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUILayout.PropertyField(_boundingBox);
|
||||
if ((RollbackManager.BoundingBoxType)_boundingBox.intValue != RollbackManager.BoundingBoxType.Disabled)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(_physicsType);
|
||||
EditorGUILayout.PropertyField(_boundingBoxSize);
|
||||
EditorGUILayout.PropertyField(_boundingBoxCenter);
|
||||
EditorGUILayout.PropertyField(_boundingBoxLocalRotation);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
EditorGUILayout.PropertyField(_colliderParents);
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void OnSceneGUI()
|
||||
{
|
||||
ColliderRollback cr = (ColliderRollback)target;
|
||||
RollbackManager.BoundingBoxData bb = cr.GetBoundingBoxData();
|
||||
if (bb.boundingBoxType == RollbackManager.BoundingBoxType.Disabled)
|
||||
return;
|
||||
|
||||
Transform tr = cr.transform;
|
||||
Vector3 centerWS = tr.TransformPoint(bb.center);
|
||||
Quaternion rotWS = tr.rotation * bb.localRotation;
|
||||
Vector3 lossy = tr.lossyScale;
|
||||
Vector3 absScale = new Vector3(Mathf.Abs(lossy.x), Mathf.Abs(lossy.y), Mathf.Abs(lossy.z));
|
||||
Vector3 sizeWS = Vector3.Scale((bb.extends * 2f), absScale);
|
||||
|
||||
Matrix4x4 prevMatrix = Handles.matrix;
|
||||
Color prevColor = Handles.color;
|
||||
|
||||
Handles.matrix = Matrix4x4.TRS(centerWS, rotWS, Vector3.one);
|
||||
Handles.color = Color.green;
|
||||
Handles.DrawWireCube(Vector3.zero, sizeWS);
|
||||
|
||||
Handles.color = new Color(1f, 0.6f, 0f, 1f);
|
||||
Handles.SphereHandleCap(0, Vector3.zero, Quaternion.identity, 0.03f * Mathf.Max(sizeWS.x, sizeWS.y, sizeWS.z), EventType.Repaint);
|
||||
|
||||
Handles.color = prevColor;
|
||||
Handles.matrix = prevMatrix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 519ce5f9fc54f5342a8a4eaf09a947b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/ColliderRollbackEditor.Threaded.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,54 @@
|
||||
#if UNITY_EDITOR && !FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using static FishNet.Component.ColliderRollback.ColliderRollback;
|
||||
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
[CustomEditor(typeof(ColliderRollback), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class ColliderRollbackEditor : Editor
|
||||
{
|
||||
private SerializedProperty _boundingBox;
|
||||
private SerializedProperty _physicsType;
|
||||
private SerializedProperty _boundingBoxSize;
|
||||
private SerializedProperty _colliderParents;
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
_boundingBox = serializedObject.FindProperty(nameof(_boundingBox));
|
||||
_physicsType = serializedObject.FindProperty(nameof(_physicsType));
|
||||
_boundingBoxSize = serializedObject.FindProperty(nameof(_boundingBoxSize));
|
||||
_colliderParents = serializedObject.FindProperty(nameof(_colliderParents));
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
ColliderRollback nob = (ColliderRollback)target;
|
||||
|
||||
GUI.enabled = false;
|
||||
EditorGUILayout.ObjectField("Script:", MonoScript.FromMonoBehaviour(nob), typeof(ColliderRollback), false);
|
||||
GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUILayout.PropertyField(_boundingBox);
|
||||
if ((BoundingBoxType)_boundingBox.intValue != BoundingBoxType.Disabled)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(_physicsType);
|
||||
EditorGUILayout.PropertyField(_boundingBoxSize);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
EditorGUILayout.PropertyField(_colliderParents);
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0fd7d7c980dbbc49b3ab071b1974d33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/ColliderRollbackEditor.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,51 @@
|
||||
#if FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Jobs;
|
||||
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to store where colliders are during the snapshot.
|
||||
/// </summary>
|
||||
public struct ColliderSnapshot
|
||||
{
|
||||
public ColliderSnapshot(Transform t)
|
||||
{
|
||||
t.GetPositionAndRotation(out Vector3 pos, out Quaternion rot);
|
||||
WorldPosition = pos;
|
||||
WorldRotation = rot;
|
||||
}
|
||||
|
||||
public ColliderSnapshot(TransformAccess ta)
|
||||
{
|
||||
ta.GetPositionAndRotation(out Vector3 pos, out Quaternion rot);
|
||||
WorldPosition = pos;
|
||||
WorldRotation = rot;
|
||||
}
|
||||
|
||||
public void SetValues(Transform t)
|
||||
{
|
||||
t.GetPositionAndRotation(out Vector3 pos, out Quaternion rot);
|
||||
WorldPosition = pos;
|
||||
WorldRotation = rot;
|
||||
}
|
||||
|
||||
public void SetValues(TransformAccess ta)
|
||||
{
|
||||
ta.GetPositionAndRotation(out Vector3 pos, out Quaternion rot);
|
||||
WorldPosition = pos;
|
||||
WorldRotation = rot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WorldPosition of transform during snapshot.
|
||||
/// </summary>
|
||||
public float3 WorldPosition;
|
||||
/// <summary>
|
||||
/// WorldRotation of transform during snapshot.
|
||||
/// </summary>
|
||||
public quaternion WorldRotation;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7bdaf4b1542a66d4e80646758ccfd525
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/ColliderSnapshot.Threaded.cs
|
||||
uploadId: 866910
|
||||
+667
@@ -0,0 +1,667 @@
|
||||
#if FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using FishNet.Managing;
|
||||
using Unity.Collections;
|
||||
using Unity.Jobs;
|
||||
using Unity.Jobs.LowLevel.Unsafe;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Jobs;
|
||||
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds all job-friendly data for collider rollback: flattened transform table,
|
||||
/// ring buffers of TRS snapshots, and a persistent rolled-back mask.
|
||||
/// </summary>
|
||||
public sealed partial class RollbackCollection
|
||||
{
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// NetworkManager.
|
||||
/// </summary>
|
||||
private NetworkManager _networkManager;
|
||||
/// <summary>
|
||||
/// True if the collection is configured and has valid buffers.
|
||||
/// </summary>
|
||||
private bool _ready;
|
||||
/// <summary>
|
||||
/// Ring buffer length per rolling entry.
|
||||
/// </summary>
|
||||
private int _maxSnapshots;
|
||||
/// <summary>
|
||||
/// Physics used when rolling back.
|
||||
/// </summary>
|
||||
private RollbackPhysicsType _rollbackPhysics;
|
||||
/// <summary>
|
||||
/// List of ColliderRollback.
|
||||
/// </summary>
|
||||
private readonly List<ColliderRollback> _colliderRollbacks = new();
|
||||
/// <summary>
|
||||
/// Map of ColliderRollback -> index.
|
||||
/// </summary>
|
||||
private readonly Dictionary<ColliderRollback, int> _colliderRollbacksIndices = new();
|
||||
/// <summary>
|
||||
/// Write array for Rollback requests for deferred Rollback.
|
||||
/// </summary>
|
||||
private NativeList<RollbackManager.RollbackRequest> _writeRequests;
|
||||
/// <summary>
|
||||
/// Read array for Rollback requests for deferred Rollback.
|
||||
/// </summary>
|
||||
private NativeList<RollbackManager.RollbackRequest> _readRequests;
|
||||
/// <summary>
|
||||
/// Physics that requested for deferred rollback.
|
||||
/// </summary>
|
||||
private RollbackPhysicsType _requestsRollbackPhysics;
|
||||
/// <summary>
|
||||
/// TransformAccessArray for ColliderRollbacks.
|
||||
/// </summary>
|
||||
private TransformAccessArray _colliderRollbacksTAA;
|
||||
/// <summary>
|
||||
/// TransformAccessArray for RollingColliders.
|
||||
/// </summary>
|
||||
private TransformAccessArray _rollingCollidersTAA;
|
||||
/// <summary>
|
||||
/// Snapshots of ColliderRollbacks: [colliderRollbackIndex].
|
||||
/// </summary>
|
||||
private NativeList<ColliderSnapshot> _colliderRollbacksSnapshots;
|
||||
/// <summary>
|
||||
/// Flattened snapshots ring-buffer of RollingColliders: [rollingColliderIndex * MaxSnapshots + frame].
|
||||
/// </summary>
|
||||
private NativeList<ColliderSnapshot> _rollingCollidersSnapshots;
|
||||
/// <summary>
|
||||
/// ColliderRollbacks-level rolled-back flags (0 = write, 1 = freeze).
|
||||
/// </summary>
|
||||
private NativeList<byte> _colliderRollbacksRolledBackMask;
|
||||
/// <summary>
|
||||
/// Per-colliderRollbacks scene handle to allow filtering in jobs without masks.
|
||||
/// </summary>
|
||||
private NativeList<int> _colliderRollbacksSceneHandles;
|
||||
/// <summary>
|
||||
/// Per-colliderRollbacks number of available history frames for lerp (clamped to MaxSnapshots).
|
||||
/// </summary>
|
||||
private NativeList<int> _colliderRollbacksLerpFrames;
|
||||
/// <summary>
|
||||
/// Per-colliderRollbacks BoundingBoxData.
|
||||
/// </summary>
|
||||
private NativeList<RollbackManager.BoundingBoxData> _colliderRollbacksBoundingBoxData;
|
||||
/// <summary>
|
||||
/// Maps rolling-collider index to its colliderRollbacks index.
|
||||
/// </summary>
|
||||
private NativeList<int> _rollingColliderToColliderRollbacks;
|
||||
/// <summary>x
|
||||
/// Per-rolling write pointer (next frame slot in the ring).
|
||||
/// </summary>
|
||||
private NativeList<int> _rollingCollidersWriteIndices;
|
||||
#endregion
|
||||
|
||||
~RollbackCollection() { Deinitialize(); }
|
||||
/// <summary>
|
||||
/// Initialize ring size based on network timing. Call once on startup or when timing changes.
|
||||
/// </summary>
|
||||
internal void Initialize(NetworkManager networkManager, double tickDelta, float maximumRollbackTime)
|
||||
{
|
||||
_networkManager = networkManager;
|
||||
_maxSnapshots = Mathf.Max(2, Mathf.CeilToInt((float)(maximumRollbackTime / tickDelta)));
|
||||
if (!_writeRequests.IsCreated) _writeRequests = new NativeList<RollbackManager.RollbackRequest>(64, Allocator.Persistent);
|
||||
if (!_readRequests.IsCreated) _readRequests = new NativeList<RollbackManager.RollbackRequest>(64, Allocator.Persistent);
|
||||
if (!_colliderRollbacksTAA.isCreated) _colliderRollbacksTAA = new TransformAccessArray(64);
|
||||
if (!_rollingCollidersTAA.isCreated) _rollingCollidersTAA = new TransformAccessArray(64);
|
||||
if (!_colliderRollbacksSnapshots.IsCreated) _colliderRollbacksSnapshots = new NativeList<ColliderSnapshot>(64, Allocator.Persistent);
|
||||
if (!_rollingCollidersSnapshots.IsCreated) _rollingCollidersSnapshots = new NativeList<ColliderSnapshot>(64, Allocator.Persistent);
|
||||
if (!_colliderRollbacksRolledBackMask.IsCreated) _colliderRollbacksRolledBackMask = new NativeList<byte>(64, Allocator.Persistent);
|
||||
if (!_colliderRollbacksSceneHandles.IsCreated) _colliderRollbacksSceneHandles = new NativeList<int>(64, Allocator.Persistent);
|
||||
if (!_colliderRollbacksLerpFrames.IsCreated) _colliderRollbacksLerpFrames = new NativeList<int>(64, Allocator.Persistent);
|
||||
if (!_colliderRollbacksBoundingBoxData.IsCreated) _colliderRollbacksBoundingBoxData = new NativeList<RollbackManager.BoundingBoxData>(64, Allocator.Persistent);
|
||||
if (!_rollingColliderToColliderRollbacks.IsCreated) _rollingColliderToColliderRollbacks = new NativeList<int>(64, Allocator.Persistent);
|
||||
if (!_rollingCollidersWriteIndices.IsCreated) _rollingCollidersWriteIndices = new NativeList<int>(64, Allocator.Persistent);
|
||||
|
||||
_ready = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// Deinitialize all native buffers and transform access arrays.
|
||||
/// </summary>
|
||||
internal void Deinitialize()
|
||||
{
|
||||
_networkManager = null;
|
||||
if (_writeRequests.IsCreated) _writeRequests.Dispose();
|
||||
if (_readRequests.IsCreated) _readRequests.Dispose();
|
||||
if (_colliderRollbacksTAA.isCreated) _colliderRollbacksTAA.Dispose();
|
||||
if (_rollingCollidersTAA.isCreated) _rollingCollidersTAA.Dispose();
|
||||
if (_colliderRollbacksSnapshots.IsCreated) _colliderRollbacksSnapshots.Dispose();
|
||||
if (_rollingCollidersSnapshots.IsCreated) _rollingCollidersSnapshots.Dispose();
|
||||
if (_colliderRollbacksRolledBackMask.IsCreated) _colliderRollbacksRolledBackMask.Dispose();
|
||||
if (_colliderRollbacksSceneHandles.IsCreated) _colliderRollbacksSceneHandles.Dispose();
|
||||
if (_colliderRollbacksLerpFrames.IsCreated) _colliderRollbacksLerpFrames.Dispose();
|
||||
if (_colliderRollbacksBoundingBoxData.IsCreated) _colliderRollbacksBoundingBoxData.Dispose();
|
||||
if (_rollingColliderToColliderRollbacks.IsCreated) _rollingColliderToColliderRollbacks.Dispose();
|
||||
if (_rollingCollidersWriteIndices.IsCreated) _rollingCollidersWriteIndices.Dispose();
|
||||
|
||||
_colliderRollbacks.Clear();
|
||||
_colliderRollbacksIndices.Clear();
|
||||
_ready = false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Ensure capacities for upcoming additions without reallocations.
|
||||
/// </summary>
|
||||
private void EnsureCapacity(int addRollingColliders, int addColliderRollbacks)
|
||||
{
|
||||
if (!_ready)
|
||||
{
|
||||
_networkManager.LogError("RollbackCollection is not configured. Call Configure(NetworkManager, double, float) first.");
|
||||
return;
|
||||
}
|
||||
|
||||
int newColliderRollbacksCount = _colliderRollbacksTAA.length + Math.Max(0, addColliderRollbacks);
|
||||
int newRollingCollidersCount = _rollingCollidersTAA.length + Math.Max(0, addRollingColliders);
|
||||
|
||||
if (_colliderRollbacksTAA.capacity < newColliderRollbacksCount)
|
||||
_colliderRollbacksTAA.capacity = newColliderRollbacksCount;
|
||||
if (_rollingCollidersTAA.capacity < newRollingCollidersCount)
|
||||
_rollingCollidersTAA.capacity = newRollingCollidersCount;
|
||||
|
||||
if (_colliderRollbacksSnapshots.Capacity < newColliderRollbacksCount)
|
||||
_colliderRollbacksSnapshots.Capacity = newColliderRollbacksCount;
|
||||
if (_rollingCollidersSnapshots.Capacity < newRollingCollidersCount * _maxSnapshots)
|
||||
_rollingCollidersSnapshots.Capacity = newRollingCollidersCount * _maxSnapshots;
|
||||
|
||||
if (_colliderRollbacksRolledBackMask.Capacity < newColliderRollbacksCount)
|
||||
_colliderRollbacksRolledBackMask.Capacity = newColliderRollbacksCount;
|
||||
if (_colliderRollbacksSceneHandles.Capacity < newColliderRollbacksCount)
|
||||
_colliderRollbacksSceneHandles.Capacity = newColliderRollbacksCount;
|
||||
if (_colliderRollbacksLerpFrames.Capacity < newColliderRollbacksCount)
|
||||
_colliderRollbacksLerpFrames.Capacity = newColliderRollbacksCount;
|
||||
if (_colliderRollbacksBoundingBoxData.Capacity < newColliderRollbacksCount)
|
||||
_colliderRollbacksBoundingBoxData.Capacity = newColliderRollbacksCount;
|
||||
if (_rollingColliderToColliderRollbacks.Capacity < newRollingCollidersCount)
|
||||
_rollingColliderToColliderRollbacks.Capacity = newRollingCollidersCount;
|
||||
if (_rollingCollidersWriteIndices.Capacity < newRollingCollidersCount)
|
||||
_rollingCollidersWriteIndices.Capacity = newRollingCollidersCount;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers a ColliderRollback with all its RollingColliders.
|
||||
/// Adds new rolling entries at the end (dense indexing).
|
||||
/// </summary>
|
||||
internal void RegisterColliderRollback(ColliderRollback colliderRollback)
|
||||
{
|
||||
if (!_ready)
|
||||
{
|
||||
_networkManager.LogError("RollbackCollection is not configured. Call Configure(NetworkManager, double, float) first.");
|
||||
return;
|
||||
}
|
||||
if (_colliderRollbacksIndices.ContainsKey(colliderRollback)) return;
|
||||
|
||||
IReadOnlyList<Transform> list = colliderRollback.GetRollingColliders();
|
||||
int addColliders = list.Count;
|
||||
int newColliderRollbacksCount = _colliderRollbacks.Count + 1;
|
||||
int newRollingCollidersCount = _rollingCollidersTAA.length + addColliders;
|
||||
EnsureCapacity(addColliders, 1);
|
||||
|
||||
_colliderRollbacks.Add(colliderRollback);
|
||||
_colliderRollbacksIndices[colliderRollback] = newColliderRollbacksCount - 1;
|
||||
_colliderRollbacksTAA.Add(colliderRollback.transform);
|
||||
_colliderRollbacksSnapshots.ResizeUninitialized(newColliderRollbacksCount);
|
||||
_colliderRollbacksRolledBackMask.Add(0);
|
||||
_colliderRollbacksSceneHandles.Add(colliderRollback.gameObject.scene.handle);
|
||||
_colliderRollbacksLerpFrames.Add(0);
|
||||
_colliderRollbacksBoundingBoxData.Add(colliderRollback.GetBoundingBoxData());
|
||||
|
||||
_rollingCollidersSnapshots.ResizeUninitialized(newRollingCollidersCount * _maxSnapshots);
|
||||
for (int i = 0; i < addColliders; i++)
|
||||
{
|
||||
Transform rollingCollider = list[i];
|
||||
_rollingCollidersWriteIndices.Add(0);
|
||||
_rollingColliderToColliderRollbacks.Add(newColliderRollbacksCount - 1);
|
||||
_rollingCollidersTAA.Add(rollingCollider);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Unregisters a ColliderRollback. Removes all its rolling entries.
|
||||
/// Uses swap-back removal for both rolling entries and the colliderRollbacks, keeping indices dense.
|
||||
/// </summary>
|
||||
internal void UnregisterColliderRollback(ColliderRollback cr)
|
||||
{
|
||||
if (!_ready) return;
|
||||
if (!_colliderRollbacksIndices.Remove(cr, out int colliderRollbacksIndex)) return;
|
||||
int lastColliderRollbacks = _colliderRollbacks.Count - 1;
|
||||
|
||||
// Remove all rolling entries belonging to this colliderRollbacks (scan backwards for stability).
|
||||
for (int i = _rollingColliderToColliderRollbacks.Length - 1; i >= 0; --i)
|
||||
{
|
||||
if (_rollingColliderToColliderRollbacks[i] == colliderRollbacksIndex)
|
||||
RemoveRollingColliderAtSwapBack(i);
|
||||
}
|
||||
|
||||
// Remove the colliderRollbacks by swapping with the last colliderRollbacks.
|
||||
if (colliderRollbacksIndex != lastColliderRollbacks)
|
||||
{
|
||||
ColliderRollback tempCr = _colliderRollbacks[lastColliderRollbacks];
|
||||
_colliderRollbacksIndices[tempCr] = colliderRollbacksIndex;
|
||||
_colliderRollbacks[colliderRollbacksIndex] = tempCr;
|
||||
// Re-tag colliders that belonged to lastColliderRollbacks to now point to colliderRollbacksIndex.
|
||||
for (int i = 0; i < _rollingColliderToColliderRollbacks.Length; i++)
|
||||
{
|
||||
if (_rollingColliderToColliderRollbacks[i] == lastColliderRollbacks)
|
||||
_rollingColliderToColliderRollbacks[i] = colliderRollbacksIndex;
|
||||
}
|
||||
}
|
||||
|
||||
_colliderRollbacksTAA.RemoveAtSwapBack(colliderRollbacksIndex);
|
||||
_colliderRollbacksRolledBackMask.RemoveAtSwapBack(colliderRollbacksIndex);
|
||||
_colliderRollbacksSceneHandles.RemoveAtSwapBack(colliderRollbacksIndex);
|
||||
_colliderRollbacksLerpFrames.RemoveAtSwapBack(colliderRollbacksIndex);
|
||||
_colliderRollbacksBoundingBoxData.RemoveAtSwapBack(colliderRollbacksIndex);
|
||||
_colliderRollbacks.RemoveAt(lastColliderRollbacks);
|
||||
}
|
||||
/// <summary>
|
||||
/// Removes one rolling entry at index by swapping with the last item.
|
||||
/// Updates all parallel structures and GlobalIndex on the moved entry.
|
||||
/// </summary>
|
||||
internal void RemoveRollingColliderAtSwapBack(int rollingColliderIndex)
|
||||
{
|
||||
int last = _rollingCollidersTAA.length - 1;
|
||||
if (last < 0) return;
|
||||
|
||||
_rollingCollidersTAA.RemoveAtSwapBack(rollingColliderIndex);
|
||||
_rollingCollidersWriteIndices.RemoveAtSwapBack(rollingColliderIndex);
|
||||
_rollingColliderToColliderRollbacks.RemoveAtSwapBack(rollingColliderIndex);
|
||||
if (rollingColliderIndex != last)
|
||||
{
|
||||
// Move last snapshots ring over the removed slot.
|
||||
int dst = rollingColliderIndex * _maxSnapshots;
|
||||
int src = last * _maxSnapshots;
|
||||
for (int k = 0; k < _maxSnapshots; k++)
|
||||
_rollingCollidersSnapshots[dst + k] =_rollingCollidersSnapshots[src + k];
|
||||
}
|
||||
_rollingCollidersSnapshots.ResizeUninitialized(_rollingCollidersSnapshots.Length - _maxSnapshots);
|
||||
}
|
||||
/// <summary>
|
||||
/// Populates one snapshot for every non-rolled-back transform using a parallel job.
|
||||
/// Call this once per tick on the server (e.g., from OnPostTick).
|
||||
/// </summary>
|
||||
internal void CreateSnapshots()
|
||||
{
|
||||
if (!_ready) return;
|
||||
|
||||
if (_colliderRollbacksTAA.length > 0 && _rollingCollidersTAA.length > 0)
|
||||
{
|
||||
JobHandle first = new RollbackManager.IncrementGroupsFramesJob
|
||||
{
|
||||
maxSnapshots = _maxSnapshots,
|
||||
colliderRollbacksLerpFrames = _colliderRollbacksLerpFrames.AsArray(),
|
||||
colliderRollbacksRolledBackMask = _colliderRollbacksRolledBackMask.AsArray(),
|
||||
}.Schedule(_colliderRollbacksTAA.length, 64);
|
||||
JobHandle second = new RollbackManager.PopulateColliderRollbackSnapshotsJob
|
||||
{
|
||||
colliderRollbackSnapshots = _colliderRollbacksSnapshots.AsArray(),
|
||||
colliderRollbacksRolledBackMask = _colliderRollbacksRolledBackMask.AsArray()
|
||||
}.Schedule(_colliderRollbacksTAA, first);
|
||||
JobHandle third = new RollbackManager.PopulateRollingColliderSnapshotsJob
|
||||
{
|
||||
maxSnapshots = _maxSnapshots,
|
||||
rollingCollidersSnapshots = _rollingCollidersSnapshots.AsArray(),
|
||||
rollingCollidersWriteIndices = _rollingCollidersWriteIndices.AsArray(),
|
||||
colliderRollbacksRolledBackMask = _colliderRollbacksRolledBackMask.AsArray(),
|
||||
colliderToColliderRollbacks = _rollingColliderToColliderRollbacks.AsArray()
|
||||
}.Schedule(_rollingCollidersTAA, second);
|
||||
third.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
#region Sinlge ColliderRollback
|
||||
/// <summary>
|
||||
/// Computes lerp mode/endFrame/percent based on 'time' and applies rollback to the whole colliderRollbacks.
|
||||
/// </summary>
|
||||
internal void Rollback(ColliderRollback colliderRollback, float time, RollbackPhysicsType rollbackPhysicsType)
|
||||
{
|
||||
if (!_ready) return;
|
||||
if (!_colliderRollbacksIndices.TryGetValue(colliderRollback, out int colliderRollbacksIndex)) return;
|
||||
|
||||
// Already rolled back.
|
||||
if (IsRolledBack(colliderRollback))
|
||||
{
|
||||
_networkManager.LogWarning("Colliders are already rolled back. Returning colliders forward first.");
|
||||
Return(colliderRollback, rollbackPhysicsType);
|
||||
}
|
||||
|
||||
int frames = _colliderRollbacksLerpFrames[colliderRollbacksIndex];
|
||||
if (frames == 0) return;
|
||||
|
||||
/* If time were 0.3f and delta was 0.2f then the
|
||||
* result would be 1.5f. This indicates to lerp between
|
||||
* the first snapshot, and one after. */
|
||||
float decimalFrame = time / (float)_networkManager.TimeManager.TickDelta;
|
||||
|
||||
RollbackManager.FrameRollbackTypes mode;
|
||||
int endFrame;
|
||||
float percent;
|
||||
|
||||
/* Rollback is beyond written quantity.
|
||||
* Set to use the last snapshot. */
|
||||
if (decimalFrame > frames)
|
||||
{
|
||||
mode = RollbackManager.FrameRollbackTypes.Exact;
|
||||
// Be sure to subtract 1 to get last entry in snapshots.
|
||||
endFrame = frames - 1;
|
||||
// Not needed for exact but must be set.
|
||||
percent = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
percent = decimalFrame % 1f;
|
||||
endFrame = Mathf.CeilToInt(decimalFrame);
|
||||
|
||||
/* If the end frame is larger than or equal to 1
|
||||
* then a lerp between two snapshots can occur. If
|
||||
* equal to 1 then the lerp would occur between 0 and 1. */
|
||||
if (endFrame >= 1)
|
||||
{
|
||||
mode = RollbackManager.FrameRollbackTypes.LerpMiddle;
|
||||
}
|
||||
// Rolling back only 1 frame.
|
||||
else
|
||||
{
|
||||
endFrame = 0;
|
||||
mode = RollbackManager.FrameRollbackTypes.LerpFirst;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply to all rolling entries belonging to this colliderRollbacks.
|
||||
for (int i = 0; i < _rollingColliderToColliderRollbacks.Length; i++)
|
||||
if (_rollingColliderToColliderRollbacks[i] == colliderRollbacksIndex)
|
||||
ApplyRollbackIndex(i, endFrame, percent, mode);
|
||||
_colliderRollbacksRolledBackMask[colliderRollbacksIndex] = 1;
|
||||
|
||||
_rollbackPhysics |= rollbackPhysicsType;
|
||||
SyncTransforms(rollbackPhysicsType);
|
||||
}
|
||||
/// <summary>
|
||||
/// Called when a specific colliderRollbacks should return.
|
||||
/// </summary>
|
||||
internal void Return(ColliderRollback colliderRollback, RollbackPhysicsType rollbackPhysicsType)
|
||||
{
|
||||
if (!_ready) return;
|
||||
if (!_colliderRollbacksIndices.TryGetValue(colliderRollback, out int colliderRollbacksIndex)) return;
|
||||
|
||||
if (!IsRolledBack(colliderRollback))
|
||||
return;
|
||||
|
||||
// Iterate dense rolling entries and return only those that belong to this colliderRollbacks.
|
||||
for (int i = 0; i < _rollingColliderToColliderRollbacks.Length; i++)
|
||||
{
|
||||
if (_rollingColliderToColliderRollbacks[i] == colliderRollbacksIndex)
|
||||
{
|
||||
int frames = _colliderRollbacksLerpFrames[colliderRollbacksIndex];
|
||||
if (frames <= 0)
|
||||
continue;
|
||||
|
||||
int writeIdx = _rollingCollidersWriteIndices[i];
|
||||
int baseOffset = i * _maxSnapshots;
|
||||
int lastIdx = (writeIdx - 1 + _maxSnapshots) % _maxSnapshots;
|
||||
|
||||
// Return to the newest (last written) snapshot
|
||||
int snapshotIndex = baseOffset + lastIdx;
|
||||
ColliderSnapshot s = _rollingCollidersSnapshots[snapshotIndex];
|
||||
Transform t = _rollingCollidersTAA[i];
|
||||
t.SetPositionAndRotation(s.WorldPosition, s.WorldRotation);
|
||||
}
|
||||
}
|
||||
_colliderRollbacksRolledBackMask[colliderRollbacksIndex] = 0;
|
||||
|
||||
_rollbackPhysics |= rollbackPhysicsType;
|
||||
SyncTransforms(rollbackPhysicsType);
|
||||
}
|
||||
/// <summary>
|
||||
/// Applies a rollback for a specific global transform index using the provided interpolation mode.
|
||||
/// </summary>
|
||||
/// <param name="rollingColliderIdx">RollingCollider index into the ColliderRollback.</param>
|
||||
/// <param name="mode">Frame interpolation mode.</param>
|
||||
/// <param name="endFrame">Target history frame index (0 = newest).</param>
|
||||
/// <param name="percent">Lerp factor for interpolation modes.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void ApplyRollbackIndex(int rollingColliderIdx, int endFrame, float percent,
|
||||
RollbackManager.FrameRollbackTypes mode)
|
||||
{
|
||||
if (!_ready || rollingColliderIdx < 0 || rollingColliderIdx >= _rollingCollidersTAA.length)
|
||||
return;
|
||||
|
||||
int colliderRollbacksIndex = _rollingColliderToColliderRollbacks[rollingColliderIdx];
|
||||
int writeIdx = _rollingCollidersWriteIndices[rollingColliderIdx];
|
||||
int baseOffset = rollingColliderIdx * _maxSnapshots;
|
||||
int lastIdx = (writeIdx - 1 + _maxSnapshots) % _maxSnapshots;
|
||||
bool isRecycled = _colliderRollbacksLerpFrames[colliderRollbacksIndex] >= _maxSnapshots;
|
||||
|
||||
Transform t = _rollingCollidersTAA[rollingColliderIdx];
|
||||
|
||||
if (mode == RollbackManager.FrameRollbackTypes.Exact)
|
||||
{
|
||||
ColliderSnapshot s = _rollingCollidersSnapshots[BufIndex(baseOffset, endFrame, lastIdx, isRecycled, _maxSnapshots)];
|
||||
t.SetPositionAndRotation(s.WorldPosition, s.WorldRotation);
|
||||
}
|
||||
else if (mode == RollbackManager.FrameRollbackTypes.LerpFirst)
|
||||
{
|
||||
ColliderSnapshot s = _rollingCollidersSnapshots[BufIndex(baseOffset, endFrame, lastIdx, isRecycled, _maxSnapshots)];
|
||||
t.GetPositionAndRotation(out Vector3 curPos, out Quaternion curRot);
|
||||
t.SetPositionAndRotation(Vector3.Lerp(curPos, s.WorldPosition, percent),
|
||||
Quaternion.Lerp(curRot, s.WorldRotation, percent));
|
||||
}
|
||||
else if (mode == RollbackManager.FrameRollbackTypes.LerpMiddle)
|
||||
{
|
||||
ColliderSnapshot s0 = _rollingCollidersSnapshots[BufIndex(baseOffset, endFrame - 1, lastIdx, isRecycled, _maxSnapshots)];
|
||||
ColliderSnapshot s1 = _rollingCollidersSnapshots[BufIndex(baseOffset, endFrame, lastIdx, isRecycled, _maxSnapshots)];
|
||||
t.SetPositionAndRotation(Vector3.Lerp(s0.WorldPosition, s1.WorldPosition, percent),
|
||||
Quaternion.Lerp(s0.WorldRotation, s1.WorldRotation, percent));
|
||||
}
|
||||
return;
|
||||
|
||||
// compute buffer index with negative-safe modulo
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static int BufIndex(int baseOffset, int history, int lastIdx, bool isRecycled, int maxSnapshots)
|
||||
{
|
||||
int idx = baseOffset + lastIdx - history;
|
||||
// If negative value start taking from the back.
|
||||
if (idx < 0)
|
||||
{
|
||||
/* Cannot take from back, snapshots aren't filled yet.
|
||||
* Instead take the oldest snapshot, which in this case
|
||||
* would be index baseOffset. */
|
||||
if (!isRecycled)
|
||||
return baseOffset;
|
||||
// Snapshots filled, take from back.
|
||||
else
|
||||
return idx + maxSnapshots;
|
||||
}
|
||||
// Not a negative value, return as is.
|
||||
else return idx;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets rolled-back state for a colliderRollbacks in O(1). No per-rolling writes.
|
||||
/// </summary>
|
||||
/// <summary>True if the colliderRollbacks is currently rolled back.</summary>
|
||||
public bool IsRolledBack(ColliderRollback cr)
|
||||
=> _ready && _colliderRollbacksIndices.TryGetValue(cr, out int g) && _colliderRollbacksRolledBackMask[g] != 0;
|
||||
#endregion
|
||||
|
||||
#region Job ColliderRollback
|
||||
/// <summary>
|
||||
/// Run rollback for ALL colliderRollbacks in parallel (jobified).
|
||||
/// </summary>
|
||||
internal void Rollback(int sceneHandle, float time, RollbackPhysicsType rollbackPhysicsType)
|
||||
{
|
||||
if (!_ready || _rollingCollidersTAA.length == 0)
|
||||
return;
|
||||
|
||||
Return();
|
||||
JobHandle job = new RollbackManager.ApplyRollbackJob
|
||||
{
|
||||
sceneHandle = sceneHandle,
|
||||
maxSnapshots = _maxSnapshots,
|
||||
decimalFrame = time / (float)_networkManager.TimeManager.TickDelta,
|
||||
colliderToColliderRollbacks = _rollingColliderToColliderRollbacks.AsArray(),
|
||||
colliderRollbacksSceneHandles = _colliderRollbacksSceneHandles.AsArray(),
|
||||
colliderRollbacksLerpFrames = _colliderRollbacksLerpFrames.AsArray(),
|
||||
rollingCollidersWriteIndices = _rollingCollidersWriteIndices.AsArray(),
|
||||
colliderRollbacksRolledBackMask = _colliderRollbacksRolledBackMask.AsArray(),
|
||||
rollingCollidersSnapshots = _rollingCollidersSnapshots.AsArray()
|
||||
}.Schedule(_rollingCollidersTAA);
|
||||
job.Complete();
|
||||
|
||||
_rollbackPhysics |= rollbackPhysicsType;
|
||||
SyncTransforms(rollbackPhysicsType);
|
||||
}
|
||||
/// <summary>
|
||||
/// Run rollback for intersected colliderRollbacks by ray in parallel (jobified).
|
||||
/// </summary>
|
||||
internal void Rollback(RollbackManager.RollbackRequest rollbackRequest)
|
||||
{
|
||||
if (!_ready || _rollingCollidersTAA.length == 0)
|
||||
return;
|
||||
|
||||
Return();
|
||||
JobHandle job = new RollbackManager.ApplyRollbackRaycastJob
|
||||
{
|
||||
sceneHandle = rollbackRequest.sceneHandle,
|
||||
maxSnapshots = _maxSnapshots,
|
||||
decimalFrame = rollbackRequest.time / (float)_networkManager.TimeManager.TickDelta,
|
||||
origin = rollbackRequest.origin,
|
||||
dir = rollbackRequest.direction,
|
||||
distance = rollbackRequest.distance,
|
||||
physicsType = (int)rollbackRequest.rollbackPhysicsType,
|
||||
colliderToColliderRollbacks = _rollingColliderToColliderRollbacks.AsArray(),
|
||||
colliderRollbacksBoundingBoxData = _colliderRollbacksBoundingBoxData.AsArray(),
|
||||
colliderRollbacksSceneHandles = _colliderRollbacksSceneHandles.AsArray(),
|
||||
colliderRollbacksLerpFrames = _colliderRollbacksLerpFrames.AsArray(),
|
||||
rollingCollidersWriteIndices = _rollingCollidersWriteIndices.AsArray(),
|
||||
colliderRollbacksRolledBackMask = _colliderRollbacksRolledBackMask.AsArray(),
|
||||
colliderRollbacksSnapshots = _colliderRollbacksSnapshots.AsArray(),
|
||||
rollingCollidersSnapshots = _rollingCollidersSnapshots.AsArray()
|
||||
}.Schedule(_rollingCollidersTAA);
|
||||
job.Complete();
|
||||
|
||||
_rollbackPhysics |= rollbackRequest.rollbackPhysicsType;
|
||||
SyncTransforms(rollbackRequest.rollbackPhysicsType);
|
||||
}
|
||||
/// <summary>
|
||||
/// Request rollback for deferred rollback for intersected colliderRollbacks by ray in parallel (jobified).
|
||||
/// </summary>
|
||||
internal void RequestRollbackDeferred(RollbackManager.RollbackRequest rollbackRequest)
|
||||
{
|
||||
_writeRequests.Add(rollbackRequest);
|
||||
_requestsRollbackPhysics |= rollbackRequest.rollbackPhysicsType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run rollback for all requests intersected colliderRollbacks by ray in parallel (jobified).
|
||||
/// </summary>
|
||||
/// <returns>Count of requests.</returns>
|
||||
internal int RollbackDeferred()
|
||||
{
|
||||
if (!_ready || _rollingCollidersTAA.length == 0 || _writeRequests.Length == 0)
|
||||
return 0;
|
||||
|
||||
Return();
|
||||
|
||||
(_readRequests, _writeRequests) = (_writeRequests, _readRequests);
|
||||
_writeRequests.Clear();
|
||||
|
||||
int groupCount = _colliderRollbacksTAA.length;
|
||||
int batchSize = ComputeBatchSize(groupCount);
|
||||
|
||||
NativeArray<float> sum = new NativeArray<float>(groupCount, Allocator.TempJob);
|
||||
NativeArray<int> cnt = new NativeArray<int>(groupCount, Allocator.TempJob);
|
||||
try
|
||||
{
|
||||
JobHandle computeHandle = new RollbackManager.ComputeDeferredRollbackSumsJob
|
||||
{
|
||||
tickDelta = (float)_networkManager.TimeManager.TickDelta,
|
||||
requests = _readRequests.AsArray(),
|
||||
colliderRollbacksSceneHandles = _colliderRollbacksSceneHandles.AsArray(),
|
||||
colliderRollbacksLerpFrames = _colliderRollbacksLerpFrames.AsArray(),
|
||||
colliderRollbacksBoundingBoxData = _colliderRollbacksBoundingBoxData.AsArray(),
|
||||
colliderRollbacksSnapshots = _colliderRollbacksSnapshots.AsArray(),
|
||||
sumDecimalFrame = sum,
|
||||
hitCount = cnt
|
||||
}.Schedule(groupCount, batchSize);
|
||||
|
||||
JobHandle applyHandle = new RollbackManager.ApplyDeferredRollbackJob
|
||||
{
|
||||
maxSnapshots = _maxSnapshots,
|
||||
colliderToColliderRollbacks = _rollingColliderToColliderRollbacks.AsArray(),
|
||||
colliderRollbacksLerpFrames = _colliderRollbacksLerpFrames.AsArray(),
|
||||
rollingCollidersWriteIndices = _rollingCollidersWriteIndices.AsArray(),
|
||||
colliderRollbacksRolledBackMask = _colliderRollbacksRolledBackMask.AsArray(),
|
||||
rollingCollidersSnapshots = _rollingCollidersSnapshots.AsArray(),
|
||||
sumDecimalFrame = sum,
|
||||
hitCount = cnt
|
||||
}.Schedule(_rollingCollidersTAA, computeHandle);
|
||||
|
||||
applyHandle.Complete();
|
||||
}
|
||||
finally
|
||||
{
|
||||
sum.Dispose();
|
||||
cnt.Dispose();
|
||||
}
|
||||
|
||||
_rollbackPhysics |= _requestsRollbackPhysics;
|
||||
_requestsRollbackPhysics = 0;
|
||||
SyncTransforms(_rollbackPhysics);
|
||||
return _readRequests.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run Return for ALL colliderRollbacks in parallel (jobified).
|
||||
/// </summary>
|
||||
internal void Return()
|
||||
{
|
||||
if (!_ready || _rollingCollidersTAA.length == 0)
|
||||
return;
|
||||
|
||||
JobHandle job = new RollbackManager.ReturnRollbackAllJob
|
||||
{
|
||||
maxSnapshots = _maxSnapshots,
|
||||
colliderToColliderRollbacks = _rollingColliderToColliderRollbacks.AsArray(),
|
||||
colliderRollbacksLerpFrames = _colliderRollbacksLerpFrames.AsArray(),
|
||||
rollingCollidersWriteIndices = _rollingCollidersWriteIndices.AsArray(),
|
||||
colliderRollbacksRolledBackMask = _colliderRollbacksRolledBackMask.AsArray(),
|
||||
rollingCollidersSnapshots = _rollingCollidersSnapshots.AsArray()
|
||||
}.Schedule(_rollingCollidersTAA);
|
||||
job.Complete();
|
||||
|
||||
SyncTransforms(_rollbackPhysics);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Applies transforms for the specified physics type.
|
||||
/// </summary>
|
||||
/// <param name = "physicsType"></param>
|
||||
private static void SyncTransforms(RollbackPhysicsType physicsType)
|
||||
{
|
||||
if ((physicsType & RollbackPhysicsType.Physics) > 0)
|
||||
Physics.SyncTransforms();
|
||||
if ((physicsType & RollbackPhysicsType.Physics2D) > 0)
|
||||
Physics2D.SyncTransforms();
|
||||
}
|
||||
|
||||
private static int ComputeBatchSize(int length, int minBatch = 1, int maxBatch = 128)
|
||||
{
|
||||
if (length <= 0) return 1;
|
||||
|
||||
// +1: main thread + worker threads
|
||||
int workers = JobsUtility.JobWorkerCount + 1;
|
||||
|
||||
// Aim for ~4 waves of batches across all workers.
|
||||
int targetBatches = Mathf.Max(1, workers * 4);
|
||||
|
||||
// CeilDiv to get iterations per batch
|
||||
int batch = (length + targetBatches - 1) / targetBatches;
|
||||
|
||||
return Mathf.Clamp(batch, minBatch, maxBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a06ebb5c8a2323940b9eab5fea5ae220
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/RollbackCollection.Threaded.cs
|
||||
uploadId: 866910
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
#if FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
using System.Runtime.CompilerServices;
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Jobs;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Jobs;
|
||||
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
public partial class RollbackManager
|
||||
{
|
||||
internal enum DeferredRollbackOrder : byte
|
||||
{
|
||||
PreTick = 0,
|
||||
Tick = 1,
|
||||
PostTick = 2
|
||||
}
|
||||
|
||||
internal enum BoundingBoxType
|
||||
{
|
||||
/// <summary>
|
||||
/// Disable this feature.
|
||||
/// </summary>
|
||||
Disabled,
|
||||
/// <summary>
|
||||
/// Manually specify the dimensions of a bounding box.
|
||||
/// </summary>
|
||||
Manual
|
||||
}
|
||||
|
||||
internal struct BoundingBoxData
|
||||
{
|
||||
public RollbackPhysicsType rollbackPhysicsType;
|
||||
public BoundingBoxType boundingBoxType;
|
||||
public float3 extends;
|
||||
public float3 center;
|
||||
public quaternion localRotation;
|
||||
|
||||
public BoundingBoxData(RollbackPhysicsType rollbackPhysicsType, BoundingBoxType boundingBoxType,
|
||||
float3 extends, float3 center, quaternion localRotation)
|
||||
{
|
||||
this.rollbackPhysicsType = rollbackPhysicsType;
|
||||
this.boundingBoxType = boundingBoxType;
|
||||
this.extends = extends;
|
||||
this.center = center;
|
||||
this.localRotation = localRotation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A deferred rollback request.
|
||||
/// </summary>
|
||||
public struct RollbackRequest
|
||||
{
|
||||
public int sceneHandle;
|
||||
public float3 origin;
|
||||
public float3 direction;
|
||||
public float distance;
|
||||
public float time;
|
||||
public RollbackPhysicsType rollbackPhysicsType;
|
||||
|
||||
public RollbackRequest(int sceneHandle, float3 origin, float3 direction, float distance, float time, RollbackPhysicsType rollbackPhysicsType)
|
||||
{
|
||||
this.sceneHandle = sceneHandle;
|
||||
this.origin = origin;
|
||||
this.direction = direction;
|
||||
this.distance = distance;
|
||||
this.time = time;
|
||||
this.rollbackPhysicsType = rollbackPhysicsType;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b7001cad72b98c4a85dbde737dcaf43
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/RollbackManager.Threaded.Types.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,244 @@
|
||||
#if FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
using FishNet.Managing;
|
||||
using FishNet.Managing.Timing;
|
||||
using FishNet.Transporting;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Unity.Profiling;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
public partial class RollbackManager : MonoBehaviour
|
||||
{
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Tooltip("Maximum time in the past colliders can be rolled back to.")]
|
||||
[SerializeField]
|
||||
private float _maximumRollbackTime = 1.25f;
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Tooltip("When to invoke OnRollbackDeferred.")]
|
||||
[SerializeField]
|
||||
private DeferredRollbackOrder _deferredRollbackOrder = DeferredRollbackOrder.PreTick;
|
||||
/// <summary>
|
||||
/// Maximum time in the past colliders can be rolled back to.
|
||||
/// </summary>
|
||||
internal float MaximumRollbackTime => _maximumRollbackTime;
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Tooltip("Interpolation value for the NetworkTransforms or objects being rolled back.")]
|
||||
[Range(0, 250)]
|
||||
[SerializeField]
|
||||
internal ushort Interpolation = 2;
|
||||
#endregion
|
||||
|
||||
#region Private
|
||||
|
||||
#region Private Profiler Markers
|
||||
|
||||
private static readonly ProfilerMarker _pm_OnPreTick = new("RollbackManager.TimeManager_OnPreTick()");
|
||||
private static readonly ProfilerMarker _pm_OnTick = new("RollbackManager.TimeManager_OnTick()");
|
||||
private static readonly ProfilerMarker _pm_OnPostTick = new("RollbackManager.TimeManager_OnPostTick()");
|
||||
private static readonly ProfilerMarker _pm_CreateSnapshots = new("RollbackManager.CreateSnapshots()");
|
||||
private static readonly ProfilerMarker _pm_Rollback0 = new("RollbackManager.Rollback(int, PreciseTick, RollbackPhysicsType, bool)");
|
||||
private static readonly ProfilerMarker _pm_Rollback1 = new("RollbackManager.Rollback(int, Vector3, Vector3, float, PreciseTick, RollbackPhysicsType, bool)");
|
||||
private static readonly ProfilerMarker _pm_RequestRollbackDeferred = new("RollbackManager.RequestRollbackDeferred(int, Vector3, Vector3, float, PreciseTick, RollbackPhysicsType, bool)");
|
||||
private static readonly ProfilerMarker _pm_RollbackDeferred = new("RollbackManager.RollbackDeferred()");
|
||||
private static readonly ProfilerMarker _pm_Return = new("RollbackManager.Return()");
|
||||
|
||||
private static readonly ProfilerMarker _pm_RegisterColliderRollback = new("RollbackManager.RegisterColliderRollback(ColliderRollback)");
|
||||
private static readonly ProfilerMarker _pm_UnregisterColliderRollback = new("RollbackManager.UnregisterColliderRollback(ColliderRollback)");
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public.
|
||||
/// <summary>
|
||||
/// Called when deferred rollback occured for all requests.
|
||||
/// </summary>
|
||||
public event Action OnRollbackDeferred;
|
||||
/// <summary>
|
||||
/// Called when deferred rollback in past occured for all requests.
|
||||
/// </summary>
|
||||
public event Action OnPostRollbackDeferred;
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this script for use.
|
||||
/// </summary>
|
||||
/// <param name = "manager"></param>
|
||||
internal void InitializeOnce_Internal(NetworkManager manager)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use Rollback(Vector3, Vector3, float, PreciseTick, RollbackPhysicsType.Physics, bool) instead.")] //Remove on V5
|
||||
public void Rollback(Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use Rollback(Scene, Vector3, Vector3, float, PreciseTick, RollbackPhysicsType.Physics, bool) instead.")] //Remove on V5
|
||||
public void Rollback(Scene scene, Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use Rollback(int, Vector3, Vector3, float, PreciseTick, RollbackPhysicsType.Physics, bool) instead.")] //Remove on V5
|
||||
public void Rollback(int sceneHandle, Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use Rollback(Scene, Vector3, Vector3, float, PreciseTick, RollbackPhysicsType.Physics2D, bool) instead.")] //Remove on V5
|
||||
public void Rollback(Scene scene, Vector2 origin, Vector2 normalizedDirection, float distance, PreciseTick pt, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use Rollback(Vector3, Vector3, float, PreciseTick, RollbackPhysicsType.Physics2D, bool) instead.")] //Remove on V5
|
||||
public void Rollback(Vector2 origin, Vector2 normalizedDirection, float distance, PreciseTick pt, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back all colliders.
|
||||
/// </summary>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back all colliders in a scene.
|
||||
/// </summary>
|
||||
/// <param name = "scene">Scene containing colliders.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(Scene scene, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back all colliders in a scene.
|
||||
/// </summary>
|
||||
/// <param name = "sceneHandle">Scene handle containing colliders.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(int sceneHandle, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
using (_pm_Rollback0.Auto())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back colliders hit by a test cast against bounding boxes.
|
||||
/// </summary>
|
||||
/// <param name = "origin">Ray origin.</param>
|
||||
/// <param name = "normalizedDirection">Direction to cast.</param>
|
||||
/// <param name = "distance">Distance of cast.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back colliders hit by a test cast against bounding boxes, in a specific scene.
|
||||
/// </summary>
|
||||
/// <param name = "scene">Scene containing colliders.</param>
|
||||
/// <param name = "origin">Ray origin.</param>
|
||||
/// <param name = "normalizedDirection">Direction to cast.</param>
|
||||
/// <param name = "distance">Distance of cast.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(Scene scene, Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back colliders hit by a test cast against bounding boxes, in a specific scene.
|
||||
/// </summary>
|
||||
/// <param name = "sceneHandle">Scene handle containing colliders.</param>
|
||||
/// <param name = "origin">Ray origin.</param>
|
||||
/// <param name = "normalizedDirection">Direction to cast.</param>
|
||||
/// <param name = "distance">Distance of cast.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(int sceneHandle, Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
using (_pm_Rollback1.Auto())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests deferred rollback for colliders hit by a test cast against bounding boxes.
|
||||
/// </summary>
|
||||
/// <param name = "origin">Ray origin.</param>
|
||||
/// <param name = "normalizedDirection">Direction to cast.</param>
|
||||
/// <param name = "distance">Distance of cast.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void RequestRollbackDeferred(Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests deferred rollback for colliders hit by a test cast against bounding boxes, in a specific scene.
|
||||
/// </summary>
|
||||
/// <param name = "scene">Scene containing colliders.</param>
|
||||
/// <param name = "origin">Ray origin.</param>
|
||||
/// <param name = "normalizedDirection">Direction to cast.</param>
|
||||
/// <param name = "distance">Distance of cast.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void RequestRollbackDeferred(Scene scene, Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests deferred rollback for colliders hit by a test cast against bounding boxes, in a specific scene.
|
||||
/// </summary>
|
||||
/// <param name = "sceneHandle">Scene handle containing colliders.</param>
|
||||
/// <param name = "origin">Ray origin.</param>
|
||||
/// <param name = "normalizedDirection">Direction to cast.</param>
|
||||
/// <param name = "distance">Distance of cast.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void RequestRollbackDeferred(int sceneHandle, Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
using (_pm_RequestRollbackDeferred.Auto())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back for all RollbackRequests.
|
||||
/// </summary>
|
||||
public void RollbackDeferred()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all ColliderRollback objects back to their original position.
|
||||
/// </summary>
|
||||
public void Return()
|
||||
{
|
||||
using (_pm_Return.Auto())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d26b760e7ad25ab409143779624d67c9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/RollbackManager.Threaded.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,187 @@
|
||||
#if !FISHNET_THREADED_COLLIDER_ROLLBACK
|
||||
using FishNet.Connection;
|
||||
using FishNet.Managing;
|
||||
using FishNet.Managing.Scened;
|
||||
using FishNet.Managing.Timing;
|
||||
using FishNet.Transporting;
|
||||
using GameKit.Dependencies.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Unity.Profiling;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
public class RollbackManager : MonoBehaviour
|
||||
{
|
||||
#region Internal.
|
||||
/// <summary>
|
||||
/// Cached value for bounding box layermask.
|
||||
/// </summary>
|
||||
internal int? BoundingBoxLayerNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_boundingBoxLayerNumber == null)
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
if (1 << i == BoundingBoxLayer.value)
|
||||
{
|
||||
_boundingBoxLayerNumber = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _boundingBoxLayerNumber;
|
||||
}
|
||||
}
|
||||
private int? _boundingBoxLayerNumber;
|
||||
#endregion
|
||||
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Tooltip("Layer to use when creating and checking against bounding boxes. This should be different from any layer used.")]
|
||||
[SerializeField]
|
||||
private LayerMask _boundingBoxLayer = 0;
|
||||
/// <summary>
|
||||
/// Layer to use when creating and checking against bounding boxes. This should be different from any layer used.
|
||||
/// </summary>
|
||||
internal LayerMask BoundingBoxLayer => _boundingBoxLayer;
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Tooltip("Maximum time in the past colliders can be rolled back to.")]
|
||||
[SerializeField]
|
||||
private float _maximumRollbackTime = 1.25f;
|
||||
/// <summary>
|
||||
/// Maximum time in the past colliders can be rolled back to.
|
||||
/// </summary>
|
||||
internal float MaximumRollbackTime => _maximumRollbackTime;
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Tooltip("Interpolation value for the NetworkTransforms or objects being rolled back.")]
|
||||
[Range(0, 250)]
|
||||
[SerializeField]
|
||||
internal ushort Interpolation = 2;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this script for use.
|
||||
/// </summary>
|
||||
/// <param name = "manager"></param>
|
||||
internal void InitializeOnce_Internal(NetworkManager manager)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use Rollback(Vector3, Vector3, float, PreciseTick, RollbackPhysicsType.Physics, bool) instead.")] //Remove on V5
|
||||
public void Rollback(Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use Rollback(Scene, Vector3, Vector3, float, PreciseTick, RollbackPhysicsType.Physics, bool) instead.")] //Remove on V5
|
||||
public void Rollback(Scene scene, Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use Rollback(int, Vector3, Vector3, float, PreciseTick, RollbackPhysicsType.Physics, bool) instead.")] //Remove on V5
|
||||
public void Rollback(int sceneHandle, Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use Rollback(Scene, Vector3, Vector3, float, PreciseTick, RollbackPhysicsType.Physics2D, bool) instead.")] //Remove on V5
|
||||
public void Rollback(Scene scene, Vector2 origin, Vector2 normalizedDirection, float distance, PreciseTick pt, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Use Rollback(Vector3, Vector3, float, PreciseTick, RollbackPhysicsType.Physics2D, bool) instead.")] //Remove on V5
|
||||
public void Rollback(Vector2 origin, Vector2 normalizedDirection, float distance, PreciseTick pt, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back all colliders.
|
||||
/// </summary>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back all colliders in a scene.
|
||||
/// </summary>
|
||||
/// <param name = "scene">Scene containing colliders.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(Scene scene, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back all colliders in a scene.
|
||||
/// </summary>
|
||||
/// <param name = "sceneHandle">Scene handle containing colliders.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(int sceneHandle, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back colliders hit by a test cast against bounding boxes.
|
||||
/// </summary>
|
||||
/// <param name = "origin">Ray origin.</param>
|
||||
/// <param name = "normalizedDirection">Direction to cast.</param>
|
||||
/// <param name = "distance">Distance of cast.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back colliders hit by a test cast against bounding boxes, in a specific scene.
|
||||
/// </summary>
|
||||
/// <param name = "scene">Scene containing colliders.</param>
|
||||
/// <param name = "origin">Ray origin.</param>
|
||||
/// <param name = "normalizedDirection">Direction to cast.</param>
|
||||
/// <param name = "distance">Distance of cast.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(Scene scene, Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back colliders hit by a test cast against bounding boxes, in a specific scene.
|
||||
/// </summary>
|
||||
/// <param name = "sceneHandle">Scene handle containing colliders.</param>
|
||||
/// <param name = "origin">Ray origin.</param>
|
||||
/// <param name = "normalizedDirection">Direction to cast.</param>
|
||||
/// <param name = "distance">Distance of cast.</param>
|
||||
/// <param name = "pt">Precise tick received from the client.</param>
|
||||
/// <param name = "physicsType">Type of physics to rollback; this is often what your casts will use.</param>
|
||||
/// <param name = "asOwnerAndClientHost">True if IsOwner of the object the raycast is for. This can be ignored and only provides more accurate results for clientHost.</param>
|
||||
public void Rollback(int sceneHandle, Vector3 origin, Vector3 normalizedDirection, float distance, PreciseTick pt, RollbackPhysicsType physicsType, bool asOwnerAndClientHost = false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all ColliderRollback objects back to their original position.
|
||||
/// </summary>
|
||||
public void Return()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b185516acd802904383e2a5f1a666750
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bf9191e2e07d29749bca3a1ae44e4bc8, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/RollbackManager.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace FishNet.Component.ColliderRollback
|
||||
{
|
||||
/// <summary>
|
||||
/// Which physics to apply after rolling back colliders.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[System.Flags]
|
||||
public enum RollbackPhysicsType
|
||||
{
|
||||
Physics = 1,
|
||||
Physics2D = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82b31e74d64a0c44d8fa2f3b6b08ebca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/Runtime/Plugins/ColliderRollback/Scripts/RollbackPhysicsType.cs
|
||||
uploadId: 866910
|
||||
Reference in New Issue
Block a user