using UnityEngine; namespace NBF { public enum FLineLogicNodeType { Start, Bobber, Weight, End } /// /// 硬线节点组件 - 可选,用于更方便的管理 /// [RequireComponent(typeof(Rigidbody))] public class FLineLogicNode : MonoBehaviour { [Header("节点设置")] public FLineLogicNodeType NodeType = FLineLogicNodeType.Bobber; [SerializeField] private bool isKinematic = false; [SerializeField] private float mass = 1f; [Header("到下一个节点的段配置")] [SerializeField, Min(0.01f)] private float nextSegmentMaxLength = 1f; [SerializeField, Min(0f)] private float nextSegmentMinLength = 0f; private Rigidbody rb; private FLine parentCable; public Rigidbody Rigidbody { get { if (!rb) { rb = GetComponent(); } return rb; } } public float NextSegmentMaxLength { get => nextSegmentMaxLength; set => nextSegmentMaxLength = Mathf.Max(0.01f, value); } public float NextSegmentMinLength { get => nextSegmentMinLength; set => nextSegmentMinLength = Mathf.Max(0f, value); } void Awake() { rb = Rigidbody; InitializeNode(); } void OnValidate() { mass = Mathf.Max(0.0001f, mass); nextSegmentMaxLength = Mathf.Max(0.01f, nextSegmentMaxLength); nextSegmentMinLength = Mathf.Max(0f, nextSegmentMinLength); } private void InitializeNode() { if (Rigidbody) { Rigidbody.isKinematic = isKinematic; Rigidbody.mass = Mathf.Max(0.0001f, mass); Rigidbody.useGravity = !isKinematic; } } public void AttachToCable(FLine cable) { parentCable = cable; // // 计算到前一个节点的距离 // var bodies = parentCable.GetConnectedBodies(); // int myIndex = bodies.IndexOf(rb); // // if (myIndex > 0 && bodies[myIndex - 1] != null) // { // float distanceToPrevious = Vector3.Distance( // transform.position, // bodies[myIndex - 1].position // ); // parentCable.SetSegmentLength(myIndex - 1, distanceToPrevious); // } } /// /// 固定/释放此节点 /// public void SetFixed(bool fixed_) { if (Rigidbody) { isKinematic = fixed_; Rigidbody.isKinematic = fixed_; Rigidbody.useGravity = !fixed_; } } /// /// 施加力到此节点(会影响相邻节点) /// public void ApplyForce(Vector3 force, ForceMode mode = ForceMode.Force) { if (parentCable) { parentCable.ApplyForceAtBody(Rigidbody, force, mode); } else if (Rigidbody) { Rigidbody.AddForce(force, mode); } } public void SetSegmentLengths(float maxLength, float minLength) { NextSegmentMaxLength = maxLength; NextSegmentMinLength = minLength; } public bool TryGetAdjacentBodies(out Rigidbody previousBody, out Rigidbody nextBody) { previousBody = null; nextBody = null; return parentCable && parentCable.TryGetAdjacentBodies(this, out previousBody, out nextBody); } } }