提交测试代码
This commit is contained in:
@@ -1,46 +1,62 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using Gaia;
|
||||
using UnityEngine;
|
||||
using WaveHarmonic.Crest;
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(Rigidbody), typeof(CapsuleCollider))]
|
||||
public class CapsuleBuoyancyStable : MonoBehaviour
|
||||
{
|
||||
[Header("References")]
|
||||
public MonoBehaviour WaterBehaviour; // 实现 IWaterProvider
|
||||
private IWaterProvider Water => WaterBehaviour as IWaterProvider;
|
||||
|
||||
[Header("Buoyancy")]
|
||||
[Tooltip("完全浸没时总浮力 = mass*g*buoyancyScale。>1 更浮。")]
|
||||
[Header("Buoyancy")] [Tooltip("完全浸没时总浮力 = mass*g*buoyancyScale。>1 更浮。")]
|
||||
public float buoyancyScale = 1.6f;
|
||||
|
||||
[Tooltip("沿胶囊轴向采样点数量(建议 7~11)。")]
|
||||
[Range(3, 15)] public int samplePoints = 9;
|
||||
[Tooltip("沿胶囊轴向采样点数量(建议 7~11)。")] [Range(3, 15)]
|
||||
public int samplePoints = 9;
|
||||
|
||||
[Tooltip("浸没比例曲线(0=刚碰水, 1=充分在水下)。")]
|
||||
public AnimationCurve submergenceCurve = AnimationCurve.Linear(0, 0, 1, 1);
|
||||
[Tooltip("浸没比例曲线(0=刚碰水, 1=充分在水下)。")] public AnimationCurve submergenceCurve = AnimationCurve.Linear(0, 0, 1, 1);
|
||||
|
||||
[Header("Damping")]
|
||||
[Tooltip("上浮方向速度阻尼(越大越不弹)。")]
|
||||
[Header("Damping")] [Tooltip("上浮方向速度阻尼(越大越不弹)。")]
|
||||
public float verticalDamping = 3.0f;
|
||||
|
||||
[Tooltip("整体角速度阻尼(只施加一次,不要太大)。")]
|
||||
public float angularDamping = 0.6f;
|
||||
[Tooltip("整体角速度阻尼(只施加一次,不要太大)。")] public float angularDamping = 0.6f;
|
||||
|
||||
[Header("Optional Upright Stabilizer (Recommended for bobber)")]
|
||||
[Tooltip("让胶囊轴向更倾向于对齐世界Up。0=关闭。")]
|
||||
[Header("Optional Upright Stabilizer (Recommended for bobber)")] [Tooltip("让胶囊轴向更倾向于对齐世界Up。0=关闭。")]
|
||||
public float uprightSpring = 0.0f;
|
||||
|
||||
[Tooltip("upright 的角速度阻尼。")]
|
||||
public float uprightDamping = 0.5f;
|
||||
[Tooltip("upright 的角速度阻尼。")] public float uprightDamping = 0.5f;
|
||||
|
||||
[Tooltip("胶囊轴向:0=X,1=Y,2=Z(通常 CapsuleCollider.direction 也一样)。")]
|
||||
public int uprightAxis = 1;
|
||||
|
||||
[Header("Water Drag")]
|
||||
public float extraDragInWater = 0.8f;
|
||||
[Header("Water Drag")] public float extraDragInWater = 0.8f;
|
||||
public float extraAngularDragInWater = 0.8f;
|
||||
|
||||
[Header("Debug")]
|
||||
public bool drawDebug = false;
|
||||
#region Crest5相关信息
|
||||
|
||||
public Transform Water;
|
||||
|
||||
private WaterRenderer _waterRenderer;
|
||||
|
||||
[Tooltip("要瞄准哪一层水的碰撞层。")] [SerializeField]
|
||||
CollisionLayer _Layer = CollisionLayer.AfterAnimatedWaves;
|
||||
|
||||
[Header("波响应")] [Tooltip("用于物理计算的物体宽度。\n\n此值越大,波响应的滤波效果和平滑程度就越高。如果无法对较大波长进行滤波,则应增加 LOD 级别。")] [SerializeField]
|
||||
float _ObjectWidth = 3f;
|
||||
|
||||
readonly SampleFlowHelper _SampleFlowHelper = new();
|
||||
|
||||
/// <summary>
|
||||
/// 查询水面信息点位
|
||||
/// </summary>
|
||||
Vector3[] _QueryPoints;
|
||||
|
||||
Vector3[] _QueryResultDisplacements;
|
||||
Vector3[] _QueryResultVelocities;
|
||||
Vector3[] _QueryResultNormal;
|
||||
|
||||
#endregion
|
||||
|
||||
[Header("Debug")] public bool drawDebug = false;
|
||||
|
||||
Rigidbody _rb;
|
||||
CapsuleCollider _cap;
|
||||
@@ -52,15 +68,30 @@ public class CapsuleBuoyancyStable : MonoBehaviour
|
||||
_cap = GetComponent<CapsuleCollider>();
|
||||
_baseDrag = _rb.linearDamping;
|
||||
_baseAngularDrag = _rb.angularDamping;
|
||||
}
|
||||
|
||||
if (WaterBehaviour != null && Water == null)
|
||||
Debug.LogError($"{name}: WaterBehaviour 没有实现 IWaterProvider。", this);
|
||||
private void Start()
|
||||
{
|
||||
int length = Mathf.Max(3, samplePoints);
|
||||
_QueryPoints = new Vector3[length];
|
||||
_QueryResultDisplacements = new Vector3[length];
|
||||
_QueryResultVelocities = new Vector3[length];
|
||||
_QueryResultNormal = new Vector3[length];
|
||||
if(Water)
|
||||
_waterRenderer = Water.GetComponent<WaterRenderer>();
|
||||
}
|
||||
|
||||
void FixedUpdate()
|
||||
{
|
||||
if (Water == null) return;
|
||||
if (Water)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (!_waterRenderer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
GetWorldCapsule(out Vector3 a, out Vector3 b, out float radius);
|
||||
|
||||
int n = Mathf.Max(3, samplePoints);
|
||||
@@ -70,12 +101,27 @@ public class CapsuleBuoyancyStable : MonoBehaviour
|
||||
float subSum = 0f;
|
||||
int wetCount = 0;
|
||||
|
||||
for (int i = 0; i < _QueryPoints.Length; i++)
|
||||
{
|
||||
float t = (float)i / (n - 1);
|
||||
Vector3 p = Vector3.Lerp(a, b, t);
|
||||
_QueryPoints[i] = p;
|
||||
}
|
||||
|
||||
|
||||
// 查询
|
||||
var collisions = _waterRenderer.AnimatedWavesLod.Provider;
|
||||
collisions.Query(GetHashCode(), _ObjectWidth, _QueryPoints, _QueryResultDisplacements,
|
||||
_QueryResultNormal, _QueryResultVelocities, _Layer);
|
||||
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
float t = (float)i / (n - 1);
|
||||
Vector3 p = Vector3.Lerp(a, b, t);
|
||||
|
||||
float waterH = Water.GetWaterHeight(p);
|
||||
float waterH =
|
||||
_QueryResultDisplacements[i].y + _waterRenderer.SeaLevel; //GaiaConstants.Water.GetWaterHeight(p);
|
||||
float depth = waterH - p.y; // >0 在水下
|
||||
|
||||
float sub = Mathf.InverseLerp(-radius, radius, depth); // 0..1
|
||||
@@ -87,7 +133,8 @@ public class CapsuleBuoyancyStable : MonoBehaviour
|
||||
|
||||
Vector3 buoyDir = Vector3.up;
|
||||
|
||||
Vector3 waterVel = Water.GetWaterVelocity(p);
|
||||
// Vector3 waterVel = GaiaConstants.Water.GetWaterVelocity(p);
|
||||
Vector3 waterVel = _QueryResultVelocities[i];
|
||||
Vector3 pointVel = _rb.GetPointVelocity(p);
|
||||
Vector3 relVel = pointVel - waterVel;
|
||||
|
||||
@@ -184,8 +231,8 @@ public class CapsuleBuoyancyStable : MonoBehaviour
|
||||
a = center - half;
|
||||
b = center + half;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
if (drawDebug)
|
||||
|
||||
Reference in New Issue
Block a user