Files
Fishing2/Assets/Scripts/FloatBobberController.cs

105 lines
2.9 KiB
C#

using UnityEngine;
public class FloatBobberController : MonoBehaviour
{
[SerializeField] private Rigidbody _rigidbody;
[Header("水属性")] public float waterLevel = 0f;
[Header("浮漂最大浮力")] public float bobberVolume = 30f; // 浮漂最大浮力 (cm³)
public float bobberHeight = 0.25f; // 浮漂长度,用来决定躺漂角度
[Header("配件重量")] public float sinkerWeight = 2f;
public float baitWeight = 0.5f;
public float hookWeight = 0.2f;
[Header("Behaviour")] public float fallSpeed = 8f;
public float riseSpeed = 3f;
// public float smoothDamping = 8f; // 插值平滑
[Header("Noise")] public float noiseAmp = 0.015f;
public float noiseFreq = 1.5f;
float impulseForce = 0f;
float impulseDecay = 4f;
void FixedUpdate()
{
SimulateBobber();
}
void SimulateBobber()
{
if (!_rigidbody.isKinematic) return;
float totalDownwardWeight = 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;
}
else
{
// 净浮力为负 → 说明浮漂整体被拉下,沉入水中
float sinkDistance = Mathf.Abs(netBuoyancy) * 0.03f;
targetY = waterLevel - sinkDistance;
}
targetY += Mathf.Sin(Time.time * noiseFreq) * noiseAmp; // 微扰模拟波浪
// 顿口/顶漂力
if (impulseForce != 0f)
{
targetY += impulseForce * Time.deltaTime;
impulseForce = Mathf.Lerp(impulseForce, 0, Time.deltaTime * impulseDecay);
}
// -----------------------------
// ③ 上浮 / 下沉差速
// -----------------------------
float y = transform.position.y;
float diff = targetY - y;
if (diff > 0) // 上浮
y += diff * Time.deltaTime * riseSpeed;
else
y += diff * Time.deltaTime * fallSpeed;
transform.position = new Vector3(transform.position.x, y, transform.position.z);
}
// ----------------------------------------
// 外部控制接口
// ----------------------------------------
public void TriggerDownPulse(float s = 0.8f)
{
impulseForce -= Mathf.Abs(s);
}
public void TriggerUpPulse(float s = 0.8f)
{
impulseForce += Mathf.Abs(s);
}
public void AddFishPull(float v)
{
sinkerWeight += v;
}
public void ReleaseFishPull(float v)
{
sinkerWeight -= v;
}
}