Files
jelito/Assets/jelycho/Code/Rope.cs
2025-04-18 11:36:40 +02:00

88 lines
2.6 KiB
C#

using System.Collections.Generic;
using RebootKit.Engine.Extensions;
using UnityEngine;
using UnityEngine.Events;
namespace RealityReboot.jelycho {
public class Rope : MonoBehaviour {
[SerializeField] ConfigurableJoint m_JointPrefab;
[SerializeField] float m_SegmentDistance = 0.1f;
readonly List<RopeSegment> m_Segments = new(16);
float m_RopeLength;
public UnityEvent<Rigidbody> FirstSegmentChanged;
public UnityEvent<Rigidbody> LastSegmentChanged;
void Start() {
Clear();
for (int i = 0; i < 2; i++) {
AddSegment();
}
}
void OnDestroy() {
Clear();
}
void OnDrawGizmos() {
Gizmos.color = Color.yellow;
Gizmos.DrawSphere(transform.position, 0.075f);
}
public void GetWorldPositions(List<Vector3> outList) {
outList.Clear();
foreach (RopeSegment segment in m_Segments) {
outList.Add(segment.transform.position);
}
}
void Clear() {
m_Segments.Clear();
transform.DestroyChildren();
}
void AddSegment() {
ConfigurableJoint joint = Instantiate(m_JointPrefab);
RopeSegment segment = new() {
transform = joint.transform,
joint = joint,
rigidbody = joint.gameObject.GetOrAdd<Rigidbody>()
};
if (m_Segments.Count == 0) {
segment.rigidbody.useGravity = false;
segment.rigidbody.isKinematic = true;
Destroy(segment.joint);
segment.joint = null;
segment.rigidbody.position = transform.position;
} else {
RopeSegment previousSegment = m_Segments[m_Segments.Count - 1];
segment.joint.connectedBody = previousSegment.rigidbody;
segment.rigidbody.position = previousSegment.transform.up * -m_SegmentDistance;
}
segment.rigidbody.linearVelocity = Vector3.zero;
segment.rigidbody.angularVelocity = Vector3.zero;
m_Segments.Add(segment);
if (m_Segments.Count == 1) {
FirstSegmentChanged.Invoke(segment.rigidbody);
} else if (m_Segments.Count > 1) {
LastSegmentChanged.Invoke(segment.rigidbody);
}
}
struct RopeSegment {
public Transform transform;
public ConfigurableJoint joint;
public Rigidbody rigidbody;
}
}
}