This commit is contained in:
BOT Alex 2024-02-27 20:18:39 +01:00
commit 801dcd3d66
3 changed files with 98 additions and 96 deletions

View File

@ -57,7 +57,6 @@ MonoBehaviour:
distBetweenRopePoints: 0.35 distBetweenRopePoints: 0.35
ropeRadius: 0.171 ropeRadius: 0.171
ignoreResolveThreshold: 0 ignoreResolveThreshold: 0
ropeCollidersParent: {fileID: 144529238244638330}
staticColliderMask: staticColliderMask:
serializedVersion: 2 serializedVersion: 2
m_Bits: 1 m_Bits: 1
@ -92,6 +91,11 @@ MonoBehaviour:
m_RotationOrder: 4 m_RotationOrder: 4
ropeMaxLength: 50 ropeMaxLength: 50
ropeMinLength: 20 ropeMinLength: 20
colliderTag: Rope
colliderLayer:
serializedVersion: 2
m_Bits: 64
ropeCollidersParent: {fileID: 144529238244638330}
lineRenderer: {fileID: 901761791259710742} lineRenderer: {fileID: 901761791259710742}
pullAnimationOvershootThreshold: 0.2 pullAnimationOvershootThreshold: 0.2
--- !u!120 &901761791259710742 --- !u!120 &901761791259710742
@ -112,6 +116,8 @@ LineRenderer:
m_ReflectionProbeUsage: 0 m_ReflectionProbeUsage: 0
m_RayTracingMode: 0 m_RayTracingMode: 0
m_RayTraceProcedural: 0 m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_RenderingLayerMask: 1 m_RenderingLayerMask: 1
m_RendererPriority: 0 m_RendererPriority: 0
m_Materials: m_Materials:
@ -220,6 +226,7 @@ AudioSource:
serializedVersion: 4 serializedVersion: 4
OutputAudioMixerGroup: {fileID: 0} OutputAudioMixerGroup: {fileID: 0}
m_audioClip: {fileID: 8300000, guid: fd92966d4cde3244d9a711094cb947f6, type: 3} m_audioClip: {fileID: 8300000, guid: fd92966d4cde3244d9a711094cb947f6, type: 3}
m_Resource: {fileID: 8300000, guid: fd92966d4cde3244d9a711094cb947f6, type: 3}
m_PlayOnAwake: 0 m_PlayOnAwake: 0
m_Volume: 0.107 m_Volume: 0.107
m_Pitch: 1 m_Pitch: 1

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 0400e5e5779425c40ba3164b1e0b5b59
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
using UnityEngine.Assertions;
public class RopeSimulator : MonoBehaviour public class RopeSimulator : MonoBehaviour
{ {
@ -33,9 +34,6 @@ public class RopeSimulator : MonoBehaviour
[SerializeField] [SerializeField]
float ignoreResolveThreshold = 0.08f; float ignoreResolveThreshold = 0.08f;
[SerializeField]
Transform ropeCollidersParent;
[SerializeField] [SerializeField]
LayerMask staticColliderMask; LayerMask staticColliderMask;
@ -54,6 +52,10 @@ public class RopeSimulator : MonoBehaviour
[SerializeField] [SerializeField]
public float ropeMaxLength, ropeMinLength; public float ropeMaxLength, ropeMinLength;
[Header("Rope Colliders")]
[SerializeField] string colliderTag = "Rope";
[SerializeField] LayerMask colliderLayer;
[SerializeField] Transform ropeCollidersParent;
[Header("Rendering")] [Header("Rendering")]
[SerializeField] LineRenderer lineRenderer; [SerializeField] LineRenderer lineRenderer;
@ -72,6 +74,8 @@ public class RopeSimulator : MonoBehaviour
public static RopeSimulator instance; public static RopeSimulator instance;
private bool IsInitialized => start == null || end == null;
private void Awake() private void Awake()
{ {
if (instance == null) if (instance == null)
@ -100,22 +104,23 @@ public class RopeSimulator : MonoBehaviour
// .Build(); // .Build();
// Build rope if rope joints specified in inspector // Build rope if rope joints specified in inspector
if (start != null && end != null) if (IsInitialized)
BuildRope(start, end); BuildRope(start, end);
} }
public void BuildRope(RopeJoint start, RopeJoint end) public void BuildRope(RopeJoint start, RopeJoint end)
{ {
// Sanity check if rope simulator was initialized before Assert.IsNotNull(start);
if (this.start != null) Assert.IsNotNull(end);
// Sanity check if rope simulator was initialized before - we are re-building the rope
if (IsInitialized)
{ {
start.playerInput.ropeLengthExtend -= ExtendRope; this.start.playerInput.ropeLengthExtend -= ExtendRope;
start.playerInput.ropeLengthShrinken -= ShrinkenRope; this.start.playerInput.ropeLengthShrinken -= ShrinkenRope;
}
if (this.end != null) this.end.playerInput.ropeLengthExtend -= ExtendRope;
{ this.end.playerInput.ropeLengthShrinken -= ShrinkenRope;
end.playerInput.ropeLengthExtend -= ExtendRope;
end.playerInput.ropeLengthShrinken -= ShrinkenRope;
} }
this.start = start; this.start = start;
@ -134,12 +139,12 @@ public class RopeSimulator : MonoBehaviour
{ {
int prevSubDivision = (int) subDivision; int prevSubDivision = (int) subDivision;
subDivision -= ropeShrinkSpeed * Time.deltaTime; subDivision -= ropeShrinkSpeed * Time.deltaTime;
if (subDivision < ropeMinLength) subDivision = Mathf.Clamp(subDivision, ropeMinLength, ropeMaxLength);
subDivision = ropeMinLength;
if (prevSubDivision - (int)subDivision <= 0) return; // Only shrinken if the numeric value has changed
if (prevSubDivision - (int) subDivision <= 0) return;
// Shrink from start // Shrink from rope point after start rope joint
rope.sticks.Clear(); rope.sticks.Clear();
rope.points.RemoveAt(1); rope.points.RemoveAt(1);
@ -160,20 +165,14 @@ public class RopeSimulator : MonoBehaviour
{ {
int prevSubDivision = (int)subDivision; int prevSubDivision = (int)subDivision;
subDivision += ropeExtendSpeed * Time.deltaTime; subDivision += ropeExtendSpeed * Time.deltaTime;
if (subDivision > ropeMaxLength) subDivision = Mathf.Clamp(subDivision, ropeMinLength, ropeMaxLength);
subDivision = ropeMaxLength;
// Only extend if the numeric value has changed
if (prevSubDivision - (int) subDivision >= 0) return; if (prevSubDivision - (int) subDivision >= 0) return;
// Max from start // Extend from rope point after start rope point
rope.points.Insert(1, new Point(rope.points[1].position));
rope.sticks.Clear(); rope.sticks.Clear();
rope.points.Insert(1, new Point(rope.points[1].position));
// Ripple existing rope points
//for (int i = 2; i < (int) subDivision; i++)
//{
// rope.points[i].position = rope.points[i + 1].position;
//}
var builder = new RopeBuilder(rope.points, rope.sticks); var builder = new RopeBuilder(rope.points, rope.sticks);
@ -187,12 +186,12 @@ public class RopeSimulator : MonoBehaviour
RebuildRopeColliders(); RebuildRopeColliders();
CreateOrderArray(); CreateOrderArray();
} }
private void OnDestroy() private void OnDestroy()
{ {
if (start == null || end == null) return; // May never have been initialized
if (!IsInitialized) return;
start.playerInput.ropeLengthShrinken -= ShrinkenRope; start.playerInput.ropeLengthShrinken -= ShrinkenRope;
end.playerInput.ropeLengthShrinken -= ShrinkenRope; end.playerInput.ropeLengthShrinken -= ShrinkenRope;
@ -208,16 +207,17 @@ public class RopeSimulator : MonoBehaviour
RopeBuilder builder = new RopeBuilder(); RopeBuilder builder = new RopeBuilder();
builder.AddPoint(new Point(start.position, locked: true)); builder.AddPoint(new Point(start.position, locked: true));
// Build rope points
for (int i = 1; i < (int) subDivision; i++) for (int i = 1; i < (int) subDivision; i++)
{ {
Vector3 pointPos = Vector3.Lerp(start.position, end.position, (float)i / (float)(int)subDivision); Vector3 pointPos = Vector3.Lerp(start.position, end.position, (float)i / Mathf.Floor(subDivision));
//Debug.Log($"pos: {pointPos}, t={i / subDivision}");
Debug.DrawRay(pointPos, (end.position - start.position).normalized); Debug.DrawRay(pointPos, (end.position - start.position).normalized);
builder.AddPoint(new Point(pointPos)); builder.AddPoint(new Point(pointPos));
} }
builder.AddPoint(new Point(end.position, locked: true)); builder.AddPoint(new Point(end.position, locked: true));
// Connect rope points
for (int i = 0; i < (int) subDivision; i++) for (int i = 0; i < (int) subDivision; i++)
{ {
builder.ConnectPointsWithDesiredLength(i, i + 1, desiredLength: distBetweenRopePoints); builder.ConnectPointsWithDesiredLength(i, i + 1, desiredLength: distBetweenRopePoints);
@ -231,7 +231,6 @@ public class RopeSimulator : MonoBehaviour
private void RebuildRopeColliders() private void RebuildRopeColliders()
{ {
// ropeCollidersParent.DestroyChildren(); Did this to avoid unityutils
for (int i = 0; i < ropeCollidersParent.childCount; i++) for (int i = 0; i < ropeCollidersParent.childCount; i++)
{ {
Destroy(ropeCollidersParent.GetChild(i)); Destroy(ropeCollidersParent.GetChild(i));
@ -240,10 +239,10 @@ public class RopeSimulator : MonoBehaviour
foreach (var point in rope.points) foreach (var point in rope.points)
{ {
GameObject ropeCollider = new GameObject("Rope Collider"); GameObject ropeCollider = new GameObject("Rope Collider");
ropeCollider.tag = "Rope"; ropeCollider.tag = colliderTag;
ropeCollider.transform.parent = ropeCollidersParent; ropeCollider.transform.parent = ropeCollidersParent;
ropeCollider.transform.position = point.position; ropeCollider.transform.position = point.position;
ropeCollider.layer = LayerMask.NameToLayer("Rope"); ropeCollider.layer = colliderLayer;
var colliderComponent = ropeCollider.AddComponent<CircleCollider2D>(); var colliderComponent = ropeCollider.AddComponent<CircleCollider2D>();
colliderComponent.radius = ropeRadius; colliderComponent.radius = ropeRadius;
@ -255,13 +254,9 @@ public class RopeSimulator : MonoBehaviour
private void Update() private void Update()
{ {
// Dont update if no rope is initialized if (IsInitialized)
if (start == null || end == null)
return; return;
//Debug.Log($"overshoot: {rope.CalculateLengthOvershoot()}");
//ShrinkenRope(1);
//ExtendRope(0);
colliderToSquezeForce.Clear(); colliderToSquezeForce.Clear();
rope.points.First().position = start.position; rope.points.First().position = start.position;
@ -285,53 +280,8 @@ public class RopeSimulator : MonoBehaviour
// Constrain start transform based on overshoot // Constrain start transform based on overshoot
float overshoot = rope.CalculateLengthOvershoot(); float overshoot = rope.CalculateLengthOvershoot();
if (overshoot > 0) PlayerPullAnimation(overshoot);
{ PullPlayers(overshoot);
if (overshoot > pullAnimationOvershootThreshold)
{
float startDot = Vector2.Dot((start.position - rope.points[1].position).normalized, start.playerInput.movement);
if (startDot > 0.35f)
{
start.playerAnimationHandler?.animator.SetBool("IsPulling", true);
}
float endDot = Vector2.Dot((end.position - rope.points[rope.points.Count - 2].position).normalized, end.playerInput.movement);
if (endDot > 0.35f)
{
end.playerAnimationHandler?.animator.SetBool("IsPulling", true);
}
}
else
{
start.playerAnimationHandler?.animator.SetBool("IsPulling", false);
end.playerAnimationHandler?.animator.SetBool("IsPulling", false);
}
//start.position = prevStartPos;
float divider = !start.locked && !end.locked ? 2f : 1f;
if (!start.locked)
{
Vector2 pullDirection = (rope.points[1].position - start.position).normalized;
Vector2 force = pullDirection * overshoot * (pullForce / divider);
start.body.AddForce(force);
}
else
{
start.body.velocity *= 0;
}
if (!end.locked)
{
Vector2 pullDirection = (rope.points[rope.points.Count - 2].position - end.position).normalized;
Vector2 force = pullDirection * overshoot * (pullForce / divider);
end.body.AddForce(force);
}
else
{
end.body.velocity *= 0;
}
}
// Handle squeze kills // Handle squeze kills
foreach (var collider in colliderToSquezeForce) foreach (var collider in colliderToSquezeForce)
@ -342,7 +292,6 @@ public class RopeSimulator : MonoBehaviour
if (squezeDamageReceiver == null) continue; if (squezeDamageReceiver == null) continue;
float swingMultiplier = InSwingMode ? swingSpeedToDamageMultiplier.Evaluate((start.locked ? end : start).body.velocity.magnitude) : 1f; float swingMultiplier = InSwingMode ? swingSpeedToDamageMultiplier.Evaluate((start.locked ? end : start).body.velocity.magnitude) : 1f;
squezeDamageReceiver.TakeSquezeDamage(collider.Value * squezeDamage * swingMultiplier); squezeDamageReceiver.TakeSquezeDamage(collider.Value * squezeDamage * swingMultiplier);
} }
@ -362,9 +311,62 @@ public class RopeSimulator : MonoBehaviour
} }
} }
private void PlayerPullAnimation(float overshoot)
{
if (overshoot > pullAnimationOvershootThreshold)
{
float startDot = Vector2.Dot((start.position - rope.points[1].position).normalized, start.playerInput.movement);
if (startDot > 0.35f)
{
start.playerAnimationHandler?.animator.SetBool("IsPulling", true);
}
float endDot = Vector2.Dot((end.position - rope.points[rope.points.Count - 2].position).normalized, end.playerInput.movement);
if (endDot > 0.35f)
{
end.playerAnimationHandler?.animator.SetBool("IsPulling", true);
}
}
else
{
start.playerAnimationHandler?.animator.SetBool("IsPulling", false);
end.playerAnimationHandler?.animator.SetBool("IsPulling", false);
}
}
private void PullPlayers(float overshoot)
{
if (overshoot <= 0f) return;
//start.position = prevStartPos;
float divider = !start.locked && !end.locked ? 2f : 1f;
if (!start.locked)
{
Vector2 pullDirection = (rope.points[1].position - start.position).normalized;
Vector2 force = pullDirection * overshoot * (pullForce / divider);
start.body.AddForce(force);
}
else
{
start.body.velocity *= 0;
}
if (!end.locked)
{
Vector2 pullDirection = (rope.points[rope.points.Count - 2].position - end.position).normalized;
Vector2 force = pullDirection * overshoot * (pullForce / divider);
end.body.AddForce(force);
}
else
{
end.body.velocity *= 0;
}
}
private void OnDrawGizmos() private void OnDrawGizmos()
{ {
return; if (IsInitialized) return;
if (!Application.isPlaying) return; if (!Application.isPlaying) return;
foreach (var point in rope.points) foreach (var point in rope.points)