浮力
This commit is contained in:
206
Assets/Scripts/FloatBobberControllerProV4.cs
Normal file
206
Assets/Scripts/FloatBobberControllerProV4.cs
Normal file
@@ -0,0 +1,206 @@
|
||||
using UnityEngine;
|
||||
|
||||
public enum BobberState
|
||||
{
|
||||
LyingDown, // 躺漂
|
||||
RisingUp, // 起漂
|
||||
Standing, // 正常站立
|
||||
Bottom, // 挂底
|
||||
TopLift, // 顶漂
|
||||
DownPull, // 黑漂
|
||||
Nibble // 小顿口
|
||||
}
|
||||
|
||||
public class FloatBobberControllerProV4 : MonoBehaviour
|
||||
{
|
||||
[Header("Environment")]
|
||||
public float waterLevel = 0f;
|
||||
|
||||
[Header("Float Settings")]
|
||||
public float floatLength = 0.20f; // 漂总长度
|
||||
public float buoyancyForce = 0.35f; // 浮力强度
|
||||
public float mass = 0.015f; // 重量
|
||||
public float tiltRecoverySpeed = 3f; // 漂恢复垂直速度
|
||||
public float maxTiltAngle = 60f; // 躺漂最大角度
|
||||
|
||||
[Header("Line Settings")]
|
||||
public float lineTension = 0f; // 动态线张力(由鱼影响)
|
||||
public float bottomDrag = 1.5f; // 铅坠触底时的阻力
|
||||
|
||||
[Header("State Machine")]
|
||||
public BobberState state = BobberState.LyingDown;
|
||||
|
||||
// internal vars
|
||||
private float verticalSpeed = 0f;
|
||||
private float angle = 60f; // 初始躺漂角度
|
||||
private float lastHeight;
|
||||
private float deltaY;
|
||||
|
||||
void Start()
|
||||
{
|
||||
lastHeight = transform.position.y;
|
||||
state = BobberState.LyingDown;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
deltaY = transform.position.y - lastHeight;
|
||||
lastHeight = transform.position.y;
|
||||
|
||||
ApplyPhysics();
|
||||
ProcessStateMachine();
|
||||
ApplyRotation();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 一切物理都由状态机控制
|
||||
// ---------------------------------------------------------------------
|
||||
void ProcessStateMachine()
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case BobberState.LyingDown:
|
||||
LyingDownBehaviour();
|
||||
break;
|
||||
|
||||
case BobberState.RisingUp:
|
||||
RisingUpBehaviour();
|
||||
break;
|
||||
|
||||
case BobberState.Standing:
|
||||
StandingBehaviour();
|
||||
break;
|
||||
|
||||
case BobberState.Bottom:
|
||||
BottomBehaviour();
|
||||
break;
|
||||
|
||||
case BobberState.TopLift:
|
||||
TopLiftBehaviour();
|
||||
break;
|
||||
|
||||
case BobberState.DownPull:
|
||||
DownPullBehaviour();
|
||||
break;
|
||||
|
||||
case BobberState.Nibble:
|
||||
NibbleBehaviour();
|
||||
break;
|
||||
}
|
||||
|
||||
AutoTransition();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 【状态 → 行为】
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void LyingDownBehaviour()
|
||||
{
|
||||
// 浮漂处于平躺,几乎无浮力
|
||||
angle = Mathf.Lerp(angle, maxTiltAngle, Time.deltaTime * 1.5f);
|
||||
|
||||
// 水面浮力很小
|
||||
verticalSpeed += (buoyancyForce * 0.1f - mass * 9.8f) * Time.deltaTime;
|
||||
}
|
||||
|
||||
void RisingUpBehaviour()
|
||||
{
|
||||
// 浮漂正在被浮力慢慢扶正
|
||||
angle = Mathf.Lerp(angle, 0, Time.deltaTime * (tiltRecoverySpeed * 0.7f));
|
||||
|
||||
// 浮力略加强
|
||||
verticalSpeed += (buoyancyForce * 0.5f) * Time.deltaTime;
|
||||
}
|
||||
|
||||
void StandingBehaviour()
|
||||
{
|
||||
// 完全立稳
|
||||
angle = Mathf.Lerp(angle, 0, Time.deltaTime * tiltRecoverySpeed);
|
||||
|
||||
// 浮力与重力平衡,小幅波动
|
||||
verticalSpeed += Mathf.Sin(Time.time * 4f) * 0.001f;
|
||||
}
|
||||
|
||||
void BottomBehaviour()
|
||||
{
|
||||
// 铅坠或饵触底 → 浮漂立不起来
|
||||
angle = Mathf.Lerp(angle, 20f, Time.deltaTime * 2f);
|
||||
|
||||
// 上浮被底部拖住
|
||||
verticalSpeed *= 0.6f;
|
||||
}
|
||||
|
||||
void TopLiftBehaviour()
|
||||
{
|
||||
// 顶漂 → 漂被往上托一点
|
||||
verticalSpeed += 0.02f;
|
||||
}
|
||||
|
||||
void DownPullBehaviour()
|
||||
{
|
||||
// 黑漂 → 往下猛拉
|
||||
verticalSpeed -= 0.05f;
|
||||
}
|
||||
|
||||
void NibbleBehaviour()
|
||||
{
|
||||
// 小顿口 → 轻微波动
|
||||
verticalSpeed += Mathf.Sin(Time.time * 20f) * 0.0015f;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 状态自动切换
|
||||
// ---------------------------------------------------------------------
|
||||
void AutoTransition()
|
||||
{
|
||||
// 1. 浮漂露出 40% 以上 → 起漂或站漂
|
||||
float headHeight = transform.position.y + floatLength;
|
||||
|
||||
if (state == BobberState.LyingDown && headHeight > waterLevel - 0.02f)
|
||||
state = BobberState.RisingUp;
|
||||
|
||||
if (state == BobberState.RisingUp && angle < 12f)
|
||||
state = BobberState.Standing;
|
||||
|
||||
// 2. 挂底判定
|
||||
float tailHeight = transform.position.y - floatLength;
|
||||
if (tailHeight < waterLevel - 0.03f)
|
||||
state = BobberState.Bottom;
|
||||
|
||||
// 3. 顶漂
|
||||
if (deltaY > 0.015f)
|
||||
state = BobberState.TopLift;
|
||||
|
||||
// 4. 黑漂
|
||||
if (deltaY < -0.02f)
|
||||
state = BobberState.DownPull;
|
||||
|
||||
// 5. 小顿口
|
||||
if (Mathf.Abs(deltaY) > 0.003f && Mathf.Abs(deltaY) < 0.015f)
|
||||
state = BobberState.Nibble;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 垂直物理
|
||||
// ---------------------------------------------------------------------
|
||||
void ApplyPhysics()
|
||||
{
|
||||
float submerged = Mathf.Clamp01((waterLevel - transform.position.y) * 8f);
|
||||
float upForce = buoyancyForce * submerged - mass * 9.8f;
|
||||
|
||||
verticalSpeed += upForce * Time.deltaTime;
|
||||
verticalSpeed = Mathf.Clamp(verticalSpeed, -0.2f, 0.2f);
|
||||
|
||||
transform.position += new Vector3(0, verticalSpeed, 0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 倾斜角控制
|
||||
// ---------------------------------------------------------------------
|
||||
void ApplyRotation()
|
||||
{
|
||||
Quaternion q = Quaternion.Euler(angle, 0, 0);
|
||||
transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * 8f);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user