88 lines
2.6 KiB
C#
88 lines
2.6 KiB
C#
using System.Collections.Generic;
|
|
using RebootKit.Engine.Extensions;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
namespace RealityReboot.jelycho.game {
|
|
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;
|
|
}
|
|
}
|
|
} |