87 lines
3.0 KiB
C#
87 lines
3.0 KiB
C#
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using UnityEngine;
|
|
using UnityEngine.Assertions;
|
|
using Logger = RebootKit.Engine.Foundation.Logger;
|
|
|
|
namespace RebootReality.jelycho.Ropes {
|
|
public class PhysicsRope : MonoBehaviour {
|
|
static readonly Logger s_Logger = new Logger(nameof(PhysicsRope));
|
|
|
|
[Header("Core Settings")]
|
|
[SerializeField] ConfigurableJoint m_JointPrefab;
|
|
[SerializeField] float m_MaxSegmentDistance = 0.5f;
|
|
|
|
[Header("Initialization")]
|
|
[SerializeField] bool m_ConfigureOnStart = true;
|
|
[SerializeField] float m_InitialLength = 2f;
|
|
|
|
readonly List<RopeSegment> m_Segments = new List<RopeSegment>(16);
|
|
float m_RopeLength;
|
|
|
|
public Rigidbody HeadRigidobody {
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
get {
|
|
return m_Segments.Count == 0 ? null : m_Segments[0].rigidbody;
|
|
}
|
|
}
|
|
|
|
public Rigidbody TailRigidobody {
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
get {
|
|
return m_Segments.Count == 0 ? null : m_Segments[m_Segments.Count - 1].rigidbody;
|
|
}
|
|
}
|
|
|
|
void Awake() {
|
|
if (m_ConfigureOnStart) {
|
|
Configure(m_InitialLength);
|
|
}
|
|
}
|
|
|
|
public void Configure(float length) {
|
|
Clear();
|
|
|
|
m_RopeLength = length;
|
|
|
|
Vector3 startPosition = transform.position;
|
|
Vector3 endPosition = startPosition - Vector3.up * m_RopeLength;
|
|
|
|
for (float len = 0.0f; len < m_RopeLength; len += m_MaxSegmentDistance) {
|
|
float t = len / m_RopeLength;
|
|
Vector3 segmentPosition = Vector3.Lerp(startPosition, endPosition, t);
|
|
|
|
ConfigurableJoint joint = Instantiate(m_JointPrefab,
|
|
segmentPosition,
|
|
Quaternion.identity);
|
|
Transform segmentTransform = joint.transform;
|
|
|
|
if (m_Segments.Count == 0) {
|
|
Destroy(joint);
|
|
joint = null;
|
|
} else {
|
|
joint.connectedBody = m_Segments[m_Segments.Count - 1].rigidbody;
|
|
}
|
|
|
|
Rigidbody jointRigidbody = segmentTransform.GetComponent<Rigidbody>();
|
|
Assert.IsNotNull(jointRigidbody, "Joint Prefab must have a Rigidbody component.");
|
|
|
|
m_Segments.Add(new RopeSegment {
|
|
joint = joint,
|
|
rigidbody = jointRigidbody,
|
|
transform = segmentTransform
|
|
});
|
|
}
|
|
}
|
|
|
|
void Clear() {
|
|
m_Segments.Clear();
|
|
}
|
|
|
|
struct RopeSegment {
|
|
public Transform transform;
|
|
public ConfigurableJoint joint;
|
|
public Rigidbody rigidbody;
|
|
}
|
|
}
|
|
} |