105 lines
2.9 KiB
C#
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;
|
|
}
|
|
} |