// using UnityEngine; // // public class FloatBobberController : MonoBehaviour // { // [Header("Water System")] // public bool useKWS = false; // public LayerMask waterLayer; // public float waterRaycastHeight = 10f; // // [Header("Spring Physics")] // public float stiffness = 0.35f; // 弹性力度 // public float damping = 0.82f; // 阻尼 // public float noiseStrength = 0.02f; // 自然颤动 // // [Header("Tilt")] // public Transform lineAttachPoint; // 钓线连接点(让漂倾斜) // public float tiltStrength = 6f; // // private float targetOffsetY = 0f; // private float offsetY = 0f; // private float velocity = 0f; // // private float baseWaterHeight = 0f; // // // 随机噪声 seed // private float noiseSeed; // // void Start() // { // noiseSeed = Random.value * 100f; // } // // void Update() // { // UpdateWaterHeight(); // UpdateSpringPhysics(); // UpdateTilt(); // ApplyFinalPosition(); // } // // // ----------------------------------------------------------- // // 1. 水面高度获取 (支持 KWS 或 Raycast) // // ----------------------------------------------------------- // void UpdateWaterHeight() // { // if (useKWS) // { // // ⭐ 你自己替换为 KWS 的 API // baseWaterHeight = SampleWaterHeight_KWS(); // } // else // { // // 简单射线获取水面高度 // Vector3 start = transform.position + Vector3.up * waterRaycastHeight; // if (Physics.Raycast(start, Vector3.down, out RaycastHit hit, 50f, waterLayer)) // { // baseWaterHeight = hit.point.y; // } // } // } // // float SampleWaterHeight_KWS() // { // // ❗你需要替换成你的 KWS 接口,比如: // // return KWS.GetWaterHeight(transform.position); // return transform.position.y; // 临时占位 // } // // // ----------------------------------------------------------- // // 2. 弹簧-阻尼伪物理 (核心) // // ----------------------------------------------------------- // void UpdateSpringPhysics() // { // // 弹簧吸附:朝向 targetOffsetY // velocity += (targetOffsetY - offsetY) * stiffness; // // // 阻尼 // velocity *= damping; // // // 移动 // offsetY += velocity; // // // 自然轻微噪声 // float noise = (Mathf.PerlinNoise(Time.time * 1.2f, noiseSeed) - 0.5f) * noiseStrength; // offsetY += noise; // } // // // ----------------------------------------------------------- // // 3. 漂倾斜(依据钓线方向) // // ----------------------------------------------------------- // void UpdateTilt() // { // if (lineAttachPoint == null) return; // // Vector3 dir = lineAttachPoint.position - transform.position; // if (dir.magnitude > 0.001f) // { // Quaternion targetRot = Quaternion.LookRotation(dir, Vector3.up); // transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, Time.deltaTime * tiltStrength); // } // } // // // ----------------------------------------------------------- // // 4. 应用最终位置 // // ----------------------------------------------------------- // void ApplyFinalPosition() // { // Vector3 pos = transform.position; // pos.y = baseWaterHeight + offsetY; // transform.position = pos; // } // // // ============================ 触发动作 API ============================ // // /// 小顿口:轻微上升 0.5~1.5 目 // public void TriggerSmallDonk() // { // targetOffsetY = Random.Range(0.3f, 0.9f); // stiffness = 0.40f; // damping = 0.82f; // } // // /// 顿口:快速上升,并轻微过冲 // public void TriggerDonk() // { // targetOffsetY = Random.Range(1.0f, 1.8f); // stiffness = 0.55f; // damping = 0.78f; // } // // /// 顶漂:慢慢上浮几目 // public void TriggerTopLift() // { // targetOffsetY = Random.Range(1.0f, 3.0f); // stiffness = 0.18f; // damping = 0.90f; // } // // /// 黑漂:快速下沉,并保持 // public void TriggerBlackSink() // { // targetOffsetY = Random.Range(-3.0f, -6.0f); // stiffness = 0.45f; // damping = 0.75f; // } // // /// 点动:轻微上下动 // public void TriggerNibble() // { // targetOffsetY = Mathf.Sin(Time.time * Random.Range(6f, 12f)) * 0.1f; // stiffness = 0.25f; // damping = 0.88f; // } // // /// 走漂(水层有流料或者风),水平漂移你用其他脚本控制即可 // public void TriggerDrift(float amount) // { // targetOffsetY = 0f; // offsetY = 0f; // } // // /// 恢复到 Idle 状态 // public void ResetIdle() // { // targetOffsetY = 0f; // stiffness = 0.35f; // damping = 0.85f; // } // } // // // using UnityEngine; // // public class FloatBobberControllerPro : MonoBehaviour // { // [Header("Water Settings")] public float waterLevel = 0f; // 水面高度世界坐标 // public float waterDensity = 1f; // 水密度(默认1即可) // // [Header("Bobber Physical Settings")] public float bobberVolume = 30f; // 浮漂最大浮力(cm³) // public float bobberMass = 1f; // 浮漂自身重量(克) // // [Header("Tackle Weight Settings")] public float sinkerWeight = 2f; // 铅坠重量(克) // public float baitWeight = 0.5f; // 鱼饵重量(克) // public float hookWeight = 0.2f; // 鱼钩重量(克) // // [Header("Physics Behaviour")] public float riseSpeed = 1.2f; // 浮漂上浮速度 // public float fallSpeed = 1.5f; // 浮漂下沉速度 // public float smoothDamping = 8f; // 插值平滑 // // [Header("Random Water Movements")] public float noiseAmplitude = 0.02f; // 微扰幅度 // public float noiseFrequency = 1f; // 微扰频率 // // float velocity = 0f; // float timeNoise = 0f; // // // 用于顿口、顶漂脉冲 // float impulseForce = 0f; // float impulseDecay = 4f; // // void Update() // { // SimulateBobberPhysics(); // } // // void SimulateBobberPhysics() // { // float totalDownwardWeight = bobberMass + sinkerWeight + baitWeight + hookWeight; // // float maxBuoyancy = bobberVolume; // 最大浮力 = 体积 // float netBuoyancy = maxBuoyancy - totalDownwardWeight; // // float targetY; // // // ------------------------- // // 1. 判断浮漂应该沉多少(吃水深度) // // ------------------------- // if (netBuoyancy > 0) // { // float buoyPercent = Mathf.Clamp01(netBuoyancy / maxBuoyancy); // float rise = buoyPercent * 0.1f; // 浮漂露出水面的高度 // // targetY = waterLevel + rise; // // targetY += Mathf.Sin(Time.time * noiseFrequency) * noiseAmplitude; // 微扰模拟波浪 // } // else // { // // 净浮力为负 → 说明浮漂整体被拉下,沉入水中 // float sinkDistance = Mathf.Abs(netBuoyancy) * 0.03f; // targetY = waterLevel - sinkDistance; // } // // // ------------------------- // // 2. 顶漂 & 顿口 脉冲 // // ------------------------- // if (impulseForce != 0f) // { // targetY += impulseForce * Time.deltaTime; // impulseForce = Mathf.Lerp(impulseForce, 0f, Time.deltaTime * impulseDecay); // } // // // ------------------------- // // 3. 平滑过渡到目标位置(核心) // // ------------------------- // float currentY = transform.position.y; // // float newY = Mathf.Lerp( // currentY, // targetY, // Time.deltaTime * smoothDamping // ); // // transform.position = new Vector3( // transform.position.x, // newY, // transform.position.z // ); // } // // // =========================== // // 外部函数:模拟钓鱼动作 // // =========================== // // /// // /// 顿口:浮漂瞬间被向下拉一下(鱼轻轻吸饵) // /// // public void TriggerDownPulse(float strength = 0.8f) // { // impulseForce -= Mathf.Abs(strength); // } // // /// // /// 顶漂:浮漂瞬间向上冒一下(鱼儿托饵) // /// // public void TriggerUpPulse(float strength = 0.8f) // { // impulseForce += Mathf.Abs(strength); // } // // /// // /// 模拟鱼儿吃饵 → 增加下拉力 // /// // public void AddFishPull(float value) // { // sinkerWeight += value; // } // // /// // /// 模拟脱钩 → 拉力消失 // /// // public void RemoveFishPull(float value) // { // sinkerWeight -= value; // } // }