246 lines
8.2 KiB
C#
246 lines
8.2 KiB
C#
// using UnityEngine;
|
|
//
|
|
// [RequireComponent(typeof(LineRenderer))]
|
|
// public class Rope : MonoBehaviour
|
|
// {
|
|
// [Header("Attachment Points")] [SerializeField]
|
|
// public Transform startAttachment; // 绳子起点绑定的Transform
|
|
//
|
|
// [SerializeField] public Transform endAttachment; // 绳子终点绑定的Transform
|
|
//
|
|
// [Header("Verlet Parameters")] [SerializeField]
|
|
// float nodeDistance = 0.35f;
|
|
//
|
|
// [SerializeField] float nodeColliderRadius = 0.2f;
|
|
// [SerializeField] float gravityStrength = 2;
|
|
// [SerializeField] float totalLength = 10f;
|
|
// [SerializeField, Range(0, 1)] float velocityDampen = 0.95f;
|
|
// [SerializeField, Range(0, 0.99f)] float stiffness = 0.8f;
|
|
// [SerializeField] int iterateCollisionsEvery = 1;
|
|
// [SerializeField] int iterations = 10;
|
|
// [SerializeField] int colliderBufferSize = 1;
|
|
//
|
|
// [Header("Line Renderer")] [SerializeField]
|
|
// float ropeWidth = 0.1f;
|
|
//
|
|
// // 私有变量
|
|
// Vector3 gravity;
|
|
//
|
|
// // 数组和缓存
|
|
// Vector3[] currentNodePositions;
|
|
// Vector3[] previousNodePositions;
|
|
// Collider[] colliderHitBuffer;
|
|
// LineRenderer lineRenderer;
|
|
// GameObject nodeTester;
|
|
// SphereCollider nodeCollider;
|
|
// int totalNodes;
|
|
// float lastTotalLength;
|
|
//
|
|
// void Awake()
|
|
// {
|
|
// // 获取组件引用
|
|
// lineRenderer = GetComponent<LineRenderer>();
|
|
// gravity = new Vector3(0, -gravityStrength, 0);
|
|
//
|
|
// // 初始化节点测试器
|
|
// nodeTester = new GameObject("Node Tester");
|
|
// nodeTester.layer = 8;
|
|
// nodeCollider = nodeTester.AddComponent<SphereCollider>();
|
|
// nodeCollider.radius = nodeColliderRadius;
|
|
//
|
|
// // 初始化长度跟踪
|
|
// lastTotalLength = totalLength;
|
|
// InitializeRope();
|
|
// }
|
|
//
|
|
// void InitializeRope()
|
|
// {
|
|
// // 计算节点数量
|
|
// totalNodes = Mathf.FloorToInt(totalLength / nodeDistance) + 1;
|
|
// float remainingLength = totalLength % nodeDistance;
|
|
//
|
|
// if (remainingLength > 0 && totalLength > nodeDistance)
|
|
// {
|
|
// totalNodes++;
|
|
// }
|
|
//
|
|
// // 初始化或调整数组大小
|
|
// System.Array.Resize(ref currentNodePositions, totalNodes);
|
|
// System.Array.Resize(ref previousNodePositions, totalNodes);
|
|
// colliderHitBuffer = new Collider[colliderBufferSize];
|
|
//
|
|
// // 初始化节点位置
|
|
// Vector3 startPos = startAttachment != null ? startAttachment.position : transform.position;
|
|
// for (int i = 0; i < totalNodes; i++)
|
|
// {
|
|
// float distance = (i == totalNodes - 1 && remainingLength > 0) ? remainingLength : nodeDistance;
|
|
//
|
|
// currentNodePositions[i] = startPos;
|
|
// previousNodePositions[i] = startPos;
|
|
// startPos.y -= distance;
|
|
// }
|
|
//
|
|
// // 设置线渲染器
|
|
// lineRenderer.startWidth = ropeWidth;
|
|
// lineRenderer.endWidth = ropeWidth;
|
|
// lineRenderer.positionCount = totalNodes;
|
|
// }
|
|
//
|
|
// void Update()
|
|
// {
|
|
// // 检查长度是否变化
|
|
// if (!Mathf.Approximately(totalLength, lastTotalLength))
|
|
// {
|
|
// AdjustRopeLength();
|
|
// lastTotalLength = totalLength;
|
|
// }
|
|
//
|
|
// DrawRope();
|
|
// }
|
|
//
|
|
// void AdjustRopeLength()
|
|
// {
|
|
// Vector3[] oldPositions = (Vector3[])currentNodePositions.Clone();
|
|
// Vector3[] oldPrevPositions = (Vector3[])previousNodePositions.Clone();
|
|
//
|
|
// InitializeRope();
|
|
//
|
|
// int copyLength = Mathf.Min(oldPositions.Length, currentNodePositions.Length);
|
|
// System.Array.Copy(oldPositions, currentNodePositions, copyLength);
|
|
// System.Array.Copy(oldPrevPositions, previousNodePositions, copyLength);
|
|
//
|
|
// if (currentNodePositions.Length > oldPositions.Length)
|
|
// {
|
|
// Vector3 lastPos = oldPositions[oldPositions.Length - 1];
|
|
// for (int i = oldPositions.Length; i < currentNodePositions.Length; i++)
|
|
// {
|
|
// float distance = (i == currentNodePositions.Length - 1 && (totalLength % nodeDistance) > 0)
|
|
// ? (totalLength % nodeDistance)
|
|
// : nodeDistance;
|
|
//
|
|
// lastPos.y -= distance;
|
|
// currentNodePositions[i] = lastPos;
|
|
// previousNodePositions[i] = lastPos;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// void FixedUpdate()
|
|
// {
|
|
// Simulate();
|
|
//
|
|
// for (int i = 0; i < iterations; i++)
|
|
// {
|
|
// ApplyConstraint();
|
|
//
|
|
// if (i % (iterateCollisionsEvery + 1) == 0)
|
|
// {
|
|
// AdjustCollisions();
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// void Simulate()
|
|
// {
|
|
// float fixedDt = Time.fixedDeltaTime;
|
|
// for (int i = 0; i < totalNodes; i++)
|
|
// {
|
|
// Vector3 velocity = (currentNodePositions[i] - previousNodePositions[i]) * velocityDampen;
|
|
// previousNodePositions[i] = currentNodePositions[i];
|
|
// currentNodePositions[i] += velocity + gravity * fixedDt;
|
|
// }
|
|
// }
|
|
//
|
|
// void ApplyConstraint()
|
|
// {
|
|
// // 绑定到起点Transform
|
|
// if (startAttachment != null)
|
|
// {
|
|
// currentNodePositions[0] = startAttachment.position;
|
|
// }
|
|
//
|
|
// // 绑定到终点Transform
|
|
// if (endAttachment != null)
|
|
// {
|
|
// currentNodePositions[totalNodes - 1] = endAttachment.position;
|
|
// }
|
|
//
|
|
// float halfStiffness = 0.5f * stiffness;
|
|
// int nodeCountMinusOne = totalNodes - 1;
|
|
//
|
|
// for (int i = 0; i < nodeCountMinusOne; i++)
|
|
// {
|
|
// Vector3 node1 = currentNodePositions[i];
|
|
// Vector3 node2 = currentNodePositions[i + 1];
|
|
// Vector3 diff = node1 - node2;
|
|
//
|
|
// float desiredDistance = (i == nodeCountMinusOne - 1 && (totalLength % nodeDistance) > 0)
|
|
// ? (totalLength % nodeDistance)
|
|
// : nodeDistance;
|
|
//
|
|
// float sqrDesiredDistance = desiredDistance * desiredDistance;
|
|
// float sqrDistance = diff.x * diff.x + diff.y * diff.y + diff.z * diff.z;
|
|
//
|
|
// if (Mathf.Abs(sqrDistance - sqrDesiredDistance) > 0.001f)
|
|
// {
|
|
// float distance = Mathf.Sqrt(sqrDistance);
|
|
// float difference = desiredDistance - distance;
|
|
// Vector3 direction = diff / distance;
|
|
//
|
|
// Vector3 adjustment = direction * (difference * halfStiffness);
|
|
//
|
|
// currentNodePositions[i] += adjustment;
|
|
// currentNodePositions[i + 1] -= adjustment;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// void AdjustCollisions()
|
|
// {
|
|
// for (int i = 1; i < totalNodes; i += 2)
|
|
// {
|
|
// int hits = Physics.OverlapSphereNonAlloc(
|
|
// currentNodePositions[i],
|
|
// nodeColliderRadius,
|
|
// colliderHitBuffer,
|
|
// ~(1 << 8));
|
|
//
|
|
// for (int n = 0; n < hits; n++)
|
|
// {
|
|
// if (Physics.ComputePenetration(
|
|
// nodeCollider,
|
|
// currentNodePositions[i],
|
|
// Quaternion.identity,
|
|
// colliderHitBuffer[n],
|
|
// colliderHitBuffer[n].transform.position,
|
|
// colliderHitBuffer[n].transform.rotation,
|
|
// out Vector3 direction,
|
|
// out float distance))
|
|
// {
|
|
// currentNodePositions[i] += direction * distance;
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// void DrawRope()
|
|
// {
|
|
// lineRenderer.positionCount = totalNodes;
|
|
// lineRenderer.SetPositions(currentNodePositions);
|
|
// }
|
|
//
|
|
// void OnDestroy()
|
|
// {
|
|
// if (nodeTester != null)
|
|
// {
|
|
// Destroy(nodeTester);
|
|
// }
|
|
// }
|
|
//
|
|
// // 公开方法用于动态设置绑定点
|
|
// public void SetAttachments(Transform start, Transform end)
|
|
// {
|
|
// startAttachment = start;
|
|
// endAttachment = end;
|
|
// }
|
|
// } |