using UnityEngine; namespace AibisDream.FixSystem { public class CableReel : MonoBehaviour { [Header("转盘设置")] [SerializeField] private float torqueStrength = 200f; // 扭矩强度 [SerializeField] private float angularDamping = 5f; // 角速度阻尼 [SerializeField] private float maxHalfAngle = 60f; // 单侧最大转角(总范围约 2× 此值 ≈ 120°) [SerializeField] private float returnSpeed = 4f; // 闲置回正速度 private CablePanel cablePanel; private float angularVelocity; // 角速度 private float currentAngle; // 当前角度 public Vector3 outletPos { get; private set; } // 出线口位置 private SpriteRenderer spriteRenderer; private float reelRadius; // 转盘半径 private void Start() { // 获取CablePanel引用 cablePanel = transform.GetComponentInParent(); currentAngle = transform.eulerAngles.z; // 获取SpriteRenderer并计算半径 spriteRenderer = GetComponent(); if (spriteRenderer != null) { // 使用sprite的bounds来计算半径 reelRadius = spriteRenderer.bounds.extents.y; // 使用y方向的半高作为半径 } else { Debug.LogWarning("CableReel没有SpriteRenderer组件!"); reelRadius = 0.5f; // 默认值 } // 初始化出线口位置 UpdateOutletPosition(); } private void UpdateOutletPosition() { // 更新出线口位置(圆形本地坐标 (0, -radius) 转成世界坐标) outletPos = transform.TransformPoint(new Vector3(0, -reelRadius, 0)); } public void ResetRotation() { // 重置角度和角速度 currentAngle = 0; angularVelocity = 0; transform.rotation = Quaternion.identity; UpdateOutletPosition(); } /// 遗留兼容(旧 CableSystem 场景仍在调用)。 public void UpdateRotation() { if (cablePanel == null || cablePanel.PlugRef == null) return; UpdateRotation(true); } /// 拖拽/插接中朝拉力方向施加扭矩;闲置时缓动回正。 public void UpdateRotation(bool active, float tautness = 1f) { if (cablePanel == null || cablePanel.PlugRef == null) return; if (!active) { angularVelocity = 0f; currentAngle = Mathf.LerpAngle(currentAngle, 0f, returnSpeed * Time.deltaTime); ApplyRotation(); return; } // 线缆还有余量时不驱动转盘,避免"还没拉紧就先转" if (tautness <= 0f) { angularVelocity *= Mathf.Exp(-angularDamping * Time.deltaTime); ApplyRotation(); return; } Vector2 center = transform.position; Vector2 outlet = outletPos; Vector2 force = (Vector2)cablePanel.PlugRef.transform.position - outlet; Vector2 r = outlet - center; float torque = (r.x * force.y - r.y * force.x) * tautness; angularVelocity += torque * torqueStrength * Time.deltaTime; angularVelocity *= Mathf.Exp(-angularDamping * Time.deltaTime); currentAngle += angularVelocity * Time.deltaTime; currentAngle = Mathf.Clamp(currentAngle, -maxHalfAngle, maxHalfAngle); if (currentAngle <= -maxHalfAngle && angularVelocity < 0f) angularVelocity = 0f; if (currentAngle >= maxHalfAngle && angularVelocity > 0f) angularVelocity = 0f; ApplyRotation(); } private void ApplyRotation() { transform.rotation = Quaternion.Euler(0, 0, currentAngle); UpdateOutletPosition(); } } }