Files
jelito/Assets/jelycho/Code/Ropes/PhysicsRope.cs

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;
}
}
}