some work on rope and utilities
This commit is contained in:
parent
d8f8cdc37a
commit
ed46e8ae97
|
@ -2,13 +2,11 @@
|
||||||
"name": "Project.Scripts.Multiplayer",
|
"name": "Project.Scripts.Multiplayer",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [
|
"references": [
|
||||||
"GUID:bcf1cb15035164f59bdb33e59e5dd367",
|
|
||||||
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
||||||
"GUID:2aa43b0c797e0d444a7e82e75d4f2082",
|
"GUID:2aa43b0c797e0d444a7e82e75d4f2082",
|
||||||
"GUID:3b8ed52f1b5c64994af4c4e0aa4b6c4b",
|
"GUID:3b8ed52f1b5c64994af4c4e0aa4b6c4b",
|
||||||
"GUID:1491147abca9d7d4bb7105af628b223e",
|
"GUID:1491147abca9d7d4bb7105af628b223e",
|
||||||
"GUID:75469ad4d38634e559750d17036d5f7c",
|
"GUID:75469ad4d38634e559750d17036d5f7c",
|
||||||
"GUID:dfa0fc7c5444edd619a15e6f8c8f242a",
|
|
||||||
"GUID:42d1898a72cfe6848ae89835fb20acd2",
|
"GUID:42d1898a72cfe6848ae89835fb20acd2",
|
||||||
"GUID:ff1c299121c93f34ca827a253fc30a61",
|
"GUID:ff1c299121c93f34ca827a253fc30a61",
|
||||||
"GUID:1eb4e3e6c04cdc848bab71651b1e2ecd",
|
"GUID:1eb4e3e6c04cdc848bab71651b1e2ecd",
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
"GUID:ddd4dba7c768b564a879069c52854fc5",
|
"GUID:ddd4dba7c768b564a879069c52854fc5",
|
||||||
"GUID:c0e1b40f519e6e84b8f4af9930403ecb",
|
"GUID:c0e1b40f519e6e84b8f4af9930403ecb",
|
||||||
"GUID:3b8ed52f1b5c64994af4c4e0aa4b6c4b",
|
"GUID:3b8ed52f1b5c64994af4c4e0aa4b6c4b",
|
||||||
"GUID:1491147abca9d7d4bb7105af628b223e"
|
"GUID:1491147abca9d7d4bb7105af628b223e",
|
||||||
|
"GUID:068707ae079d6e851b7a76adaa3014f8"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
|
|
|
@ -24,4 +24,5 @@ public class Rope
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Unity.Netcode;
|
using Unity.Netcode;
|
||||||
|
@ -64,7 +63,12 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
[Header("Animaion")]
|
[Header("Animaion")]
|
||||||
[SerializeField] float pullAnimationOvershootThreshold = 0.2f;
|
[SerializeField] float pullAnimationOvershootThreshold = 0.2f;
|
||||||
|
|
||||||
int[] order;
|
[Header("Netcode")]
|
||||||
|
private const int k_rngSeed = 6969;
|
||||||
|
private System.Random rng = new System.Random(k_rngSeed);
|
||||||
|
private NetworkTimer networkTimer;
|
||||||
|
|
||||||
|
private int[] order;
|
||||||
|
|
||||||
public float Overshoot => rope.CalculateLengthOvershoot();
|
public float Overshoot => rope.CalculateLengthOvershoot();
|
||||||
public bool InSwingMode => start.locked || end.locked;
|
public bool InSwingMode => start.locked || end.locked;
|
||||||
|
@ -80,6 +84,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
// TODO: also true in single player mode
|
// TODO: also true in single player mode
|
||||||
private bool ShouldSimulate => IsHost;
|
private bool ShouldSimulate => IsHost;
|
||||||
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
|
@ -300,7 +305,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
rope.points.First().position = start.position;
|
rope.points.First().position = start.position;
|
||||||
rope.points.Last().position = end.position;
|
rope.points.Last().position = end.position;
|
||||||
|
|
||||||
Simulate();
|
Simulate(Time.fixedDeltaTime);
|
||||||
|
|
||||||
// Update the rope collider positions
|
// Update the rope collider positions
|
||||||
for (int i = 0; i < rope.points.Count; i++)
|
for (int i = 0; i < rope.points.Count; i++)
|
||||||
|
@ -417,7 +422,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulate()
|
void Simulate(float dt)
|
||||||
{
|
{
|
||||||
Assert.IsTrue(ShouldSimulate, "Should not simulate rope on client!");
|
Assert.IsTrue(ShouldSimulate, "Should not simulate rope on client!");
|
||||||
|
|
||||||
|
@ -427,7 +432,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
{
|
{
|
||||||
Vector3 positionBeforeUpdate = p.position;
|
Vector3 positionBeforeUpdate = p.position;
|
||||||
p.position += p.position - p.prevPosition;
|
p.position += p.position - p.prevPosition;
|
||||||
p.position.z -= gravity * Time.deltaTime * Time.deltaTime;
|
p.position.z -= gravity * dt * dt;
|
||||||
p.prevPosition = positionBeforeUpdate;
|
p.prevPosition = positionBeforeUpdate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,9 +443,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
{
|
{
|
||||||
Stick stick = rope.sticks[order[s]];
|
Stick stick = rope.sticks[order[s]];
|
||||||
if (stick.dead)
|
if (stick.dead)
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 stickCentre = (stick.A.position + stick.B.position) / 2;
|
Vector3 stickCentre = (stick.A.position + stick.B.position) / 2;
|
||||||
Vector3 stickDir = (stick.A.position - stick.B.position).normalized;
|
Vector3 stickDir = (stick.A.position - stick.B.position).normalized;
|
||||||
|
@ -464,6 +467,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
private void TryMovePointToPosition(Point point, Vector3 position)
|
private void TryMovePointToPosition(Point point, Vector3 position)
|
||||||
{
|
{
|
||||||
Assert.IsTrue(ShouldSimulate);
|
Assert.IsTrue(ShouldSimulate);
|
||||||
|
|
||||||
Vector2 moveDir = new Vector2(position.x, position.y) - new Vector2(point.position.x, point.position.y);
|
Vector2 moveDir = new Vector2(position.x, position.y) - new Vector2(point.position.x, point.position.y);
|
||||||
int stepsRequired = (int) Mathf.Ceil(moveDir.magnitude / collisionCheckDist);
|
int stepsRequired = (int) Mathf.Ceil(moveDir.magnitude / collisionCheckDist);
|
||||||
moveDir.Normalize();
|
moveDir.Normalize();
|
||||||
|
@ -531,7 +535,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
{
|
{
|
||||||
order[i] = i;
|
order[i] = i;
|
||||||
}
|
}
|
||||||
ShuffleArray(order, new System.Random());
|
ShuffleArray(order, rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T[] ShuffleArray<T>(T[] array, System.Random prng)
|
public static T[] ShuffleArray<T>(T[] array, System.Random prng)
|
||||||
|
@ -541,7 +545,6 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
while (elementsRemainingToShuffle > 1)
|
while (elementsRemainingToShuffle > 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Choose a random element from array
|
// Choose a random element from array
|
||||||
randomIndex = prng.Next(0, elementsRemainingToShuffle);
|
randomIndex = prng.Next(0, elementsRemainingToShuffle);
|
||||||
T chosenElement = array[randomIndex];
|
T chosenElement = array[randomIndex];
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d48856ef91909169cb2161e0aed7193e
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class CircularBuffer<T> {
|
||||||
|
T[] buffer;
|
||||||
|
int bufferSize;
|
||||||
|
|
||||||
|
public CircularBuffer(int bufferSize) {
|
||||||
|
this.bufferSize = bufferSize;
|
||||||
|
buffer = new T[bufferSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(T item, int index) => buffer[index % bufferSize] = item;
|
||||||
|
public T Get(int index) => buffer[index % bufferSize];
|
||||||
|
public void Clear() => buffer = new T[bufferSize];
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 82749b4844b9f18ffa95eeaabc003f4e
|
|
@ -0,0 +1,23 @@
|
||||||
|
public class NetworkTimer {
|
||||||
|
float timer;
|
||||||
|
public float MinTimeBetweenTicks { get; }
|
||||||
|
public int CurrentTick { get; private set; }
|
||||||
|
|
||||||
|
public NetworkTimer(float serverTickRate) {
|
||||||
|
MinTimeBetweenTicks = 1f / serverTickRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(float deltaTime) {
|
||||||
|
timer += deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ShouldTick() {
|
||||||
|
if (timer >= MinTimeBetweenTicks) {
|
||||||
|
timer -= MinTimeBetweenTicks;
|
||||||
|
CurrentTick++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5eefe3926a904f2ebb22193055448eee
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"name": "Project.Scripts.Utilities"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 068707ae079d6e851b7a76adaa3014f8
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,77 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Utilities {
|
||||||
|
public abstract class Timer {
|
||||||
|
protected float initialTime;
|
||||||
|
protected float Time { get; set; }
|
||||||
|
public bool IsRunning { get; protected set; }
|
||||||
|
|
||||||
|
public float Progress => Time / initialTime;
|
||||||
|
|
||||||
|
public Action OnTimerStart = delegate { };
|
||||||
|
public Action OnTimerStop = delegate { };
|
||||||
|
|
||||||
|
protected Timer(float value) {
|
||||||
|
initialTime = value;
|
||||||
|
IsRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start() {
|
||||||
|
Time = initialTime;
|
||||||
|
if (!IsRunning) {
|
||||||
|
IsRunning = true;
|
||||||
|
OnTimerStart.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop() {
|
||||||
|
if (IsRunning) {
|
||||||
|
IsRunning = false;
|
||||||
|
OnTimerStop.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Resume() => IsRunning = true;
|
||||||
|
public void Pause() => IsRunning = false;
|
||||||
|
|
||||||
|
public abstract void Tick(float deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CountdownTimer : Timer {
|
||||||
|
public CountdownTimer(float value) : base(value) { }
|
||||||
|
|
||||||
|
public override void Tick(float deltaTime) {
|
||||||
|
if (IsRunning && Time > 0) {
|
||||||
|
Time -= deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsRunning && Time <= 0) {
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsFinished => Time <= 0;
|
||||||
|
|
||||||
|
public void Reset() => Time = initialTime;
|
||||||
|
|
||||||
|
public void Reset(float newTime) {
|
||||||
|
initialTime = newTime;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StopwatchTimer : Timer {
|
||||||
|
public StopwatchTimer() : base(0) { }
|
||||||
|
|
||||||
|
public override void Tick(float deltaTime) {
|
||||||
|
if (IsRunning) {
|
||||||
|
Time += deltaTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset() => Time = 0;
|
||||||
|
|
||||||
|
public float GetTime() => Time;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 79ecfa1b4cbfadfdfb6120c79507b4cd
|
Loading…
Reference in New Issue