using System; using System.Collections; using System.Collections.Generic; using System.Linq; using NBC; // using Obi; using UnityEngine; namespace NBF { public class FLine : FGearBase { public LineType LineType; [SerializeField] private bool isLureConnect; /// /// 主线 /// [SerializeField] private Rope fishingRope; /// /// 浮漂和鱼钩线 /// [SerializeField] private Rope bobberRope; public LureController Lure; public BobberController Bobber; public JointPinchController PinchController; public float LinelenghtDiferent; public float Length { get; private set; } protected override void OnInit() { var tipRb = Rod.Asset.LineConnectorRigidbody; if (isLureConnect) { Lure.SetJoint(tipRb); Lure.EnableCollision(false); } else { fishingRope.startAnchor = tipRb; Bobber.SetJoint(tipRb); Lure.SetJoint(Bobber.rbody); Lure.gameObject.SetActive(true); Lure.EnableCollision(false); Lure.SetKinematic(false); } GetComponentsInChildren(includeInactive: true).ToList().ForEach(delegate(Transform i) { i.gameObject.SetActive(true); }); StartCoroutine(LureUseGravity()); } public void InitTest(Rigidbody tipRb) { if (isLureConnect) { Lure.SetJoint(tipRb); Lure.EnableCollision(false); } else { fishingRope.startAnchor = tipRb; Bobber.SetJoint(tipRb); Lure.SetJoint(Bobber.rbody); Lure.gameObject.SetActive(true); Lure.EnableCollision(false); Lure.SetKinematic(false); } GetComponentsInChildren(includeInactive: true).ToList().ForEach(delegate(Transform i) { i.gameObject.SetActive(true); }); StartCoroutine(LureUseGravity()); } private IEnumerator LureUseGravity() { yield return 1; Lure.gameObject.SetActive(false); Lure.gameObject.SetActive(true); yield return 1; Lure.RBody.useGravity = true; } public void SetTargetLength(float value) { Log.Error($"SetObiRopeStretch={value}"); if (value > 3) { // value -= 0.2f; } fishingRope.SetTargetLength(value); } public void SetLureLength(float value) { Log.Error($"SetObiRopeStretch={value}"); bobberRope.SetTargetLength(value); } private void Update() { LinelenghtDiferent = GetLineDistance(); //非钓鱼状态 Rod.PlayerItem.Tension = Mathf.Clamp(LinelenghtDiferent, 0f, 0.05f); } #region Tension private float GetLineDistance() { if (!Bobber.JointRb) { return 0; } // return 0; //第一个节点到竿稍的位置-第一段鱼线长度 return Vector3.Distance(Bobber.transform.position, Bobber.JointRb.transform.position) - fishingRope.GetCurrentLength(); } public float GetTension(float weight) { return weight * GetLineDistance(); } #endregion #region 极限判定 [Header("Limit Detection")] [Min(0f)] // 极限判定的长度容差,允许链路在总长或单段长度上存在少量误差。 [SerializeField] private float lengthLimitTolerance = 0.01f; [Min(0f)] // 达到极限后,只有当前超长值大于该阈值时,才开始进入断线候选计时。 [SerializeField] private float breakStretchThreshold = 0.05f; /// /// 当鱼线达到断线条件时发出的一次性消息。 /// 外部可订阅该事件,在回调中执行切线、播放表现或状态切换。 /// public event Action OnLineBreakRequested; /// /// 当前断线候选状态的累计时间。 /// 只有在处于极限状态,且 CurrentStretchLength 大于断线阈值时才会累加;否则重置为 0。 /// public float LimitStateTime { get; private set; } /// /// 当前拉力极限百分比。 /// 当超长值小于等于 lengthLimitTolerance 时为 0; /// 当超长值大于等于 breakStretchThreshold 时为 100; /// 中间区间按线性比例映射,供 UI 显示使用。 /// public float CurrentBreakStretchPercent => EvaluateBreakStretchPercent(Length); private float EvaluateBreakStretchPercent(float stretchLength) { if (stretchLength <= lengthLimitTolerance) { return 0f; } if (stretchLength >= breakStretchThreshold) { return 100f; } if (breakStretchThreshold <= lengthLimitTolerance) { return 100f; } return Mathf.InverseLerp(lengthLimitTolerance, breakStretchThreshold, stretchLength) * 100f; } #endregion } }