导入角色动画,和增加角色控制

This commit is contained in:
2025-12-11 19:30:20 +08:00
parent a60a92e7ba
commit 7775fa30bb
1452 changed files with 592217 additions and 42573 deletions

View File

@@ -0,0 +1,123 @@
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class BobberBuoyancy : MonoBehaviour
{
[Header("Water")]
public float waterLevel = 0f; // 水面是 0
public Vector3 waterFlow = Vector3.zero;
[Header("Bobber Size (origin at bottom)")]
public float bobberHeight = 0.18f; // 浮漂总高度(底部原点 → 顶部)
[Header("Buoyancy")]
public float maxBuoyancy = 12f; // 完全浸没浮力
public float buoyancyMultiplier = 1.0f;
public float waterDrag = 0.7f;
public float waterAngularDrag = 0.4f;
[Header("Vertical Damping控制“慢慢上浮”避免弹跳")]
public float verticalDamping = 4.0f; // 数值越大,上浮越慢、越不弹
[Header("Upright")]
public float uprightStrength = 8f; // 站漂恢复力
public float uprightDamping = 1.2f;
[Header("Lay Down (躺漂)")]
public float layDownThreshold = 0.15f; // 低于 15% 浸没 → 转入躺漂模式
public float layDownUprightMultiplier = 0.2f; // 躺漂时保留多少站立力度(越小越“翘头”)
private Rigidbody rb;
private void Awake()
{
rb = GetComponent<Rigidbody>();
rb.useGravity = true;
// 重心稍微靠上,配合 AddForceAtPosition才能让“底在水里、头上翘”
rb.centerOfMass = new Vector3(0, bobberHeight * 0.4f, 0);
}
private void FixedUpdate()
{
ApplyBuoyancy();
ApplyFlowForce();
ApplyOrientationControl();
}
void ApplyBuoyancy()
{
float bottom = rb.position.y; // 原点就是最底部
float depth = waterLevel - bottom; // 浸入深度 = 水面 - 底部
if (depth <= 0f) return; // 完全在水面上方,无浮力
// 当前浸没比例
float submersionRatio = Mathf.Clamp01(depth / bobberHeight);
// 基础浮力(和你之前一致)
float baseForce = maxBuoyancy * submersionRatio * buoyancyMultiplier;
// ⭐ 竖直速度(用你原来习惯的 linearVelocity
float vy = rb.linearVelocity.y;
// ⭐ 阻尼项:速度越快,反向力越大
// 下沉很快 → 给一个向上的阻尼(减缓下沉)
// 向上很快 → 给一个向下的阻尼(防止弹出水面)
float damping = -vy * verticalDamping;
// 总的向上力:基础浮力 + 阻尼修正
float totalUpForce = baseForce + damping;
// 物理上浮力不能把它“往下按”,所以最少为 0
if (totalUpForce < 0f) totalUpForce = 0f;
// ⭐ 浮力作用点 = 浸没体积中心(不动,保持你之前的设计)
float clampedDepth = Mathf.Clamp(depth, 0, bobberHeight);
float centerY = bottom + clampedDepth * 0.5f;
Vector3 buoyancyPoint = new Vector3(rb.position.x, centerY, rb.position.z);
rb.AddForceAtPosition(Vector3.up * totalUpForce, buoyancyPoint, ForceMode.Acceleration);
// 水中阻力(保留原逻辑)
rb.AddForce(-rb.linearVelocity * waterDrag, ForceMode.Acceleration);
rb.AddTorque(-rb.angularVelocity * waterAngularDrag, ForceMode.Acceleration);
}
void ApplyFlowForce()
{
if (waterFlow.sqrMagnitude <= 0.0001f) return;
rb.AddForce((waterFlow - rb.linearVelocity) * 0.3f, ForceMode.Acceleration);
}
void ApplyOrientationControl()
{
float bottom = rb.position.y;
float depth = waterLevel - bottom;
float submersionRatio = Mathf.Clamp01(depth / bobberHeight);
Vector3 up = transform.up;
Vector3 worldUp = Vector3.up;
if (submersionRatio > layDownThreshold)
{
// 深浸 → 正常站漂
Vector3 uprightTorqueVec =
Vector3.Cross(up, worldUp) * uprightStrength
- rb.angularVelocity * uprightDamping;
rb.AddTorque(uprightTorqueVec, ForceMode.Acceleration);
}
else
{
// 浅浸 → “躺漂”,只保留少量站立力,让它自然斜、头上翘
float reduced = uprightStrength * layDownUprightMultiplier;
Vector3 uprightTorqueVec =
Vector3.Cross(up, worldUp) * reduced
- rb.angularVelocity * uprightDamping;
rb.AddTorque(uprightTorqueVec, ForceMode.Acceleration);
}
}
}