修改rope脚本
This commit is contained in:
175
Assets/Scripts/ThirdParty/Rope/Rope.cs
vendored
175
Assets/Scripts/ThirdParty/Rope/Rope.cs
vendored
@@ -36,13 +36,6 @@ namespace NBF
|
||||
}
|
||||
}
|
||||
|
||||
public struct OnSplitParams
|
||||
{
|
||||
public int minParticleIndex;
|
||||
public int maxParticleIndex;
|
||||
public Measurements preSplitMeasurements;
|
||||
}
|
||||
|
||||
public struct EditorColors
|
||||
{
|
||||
public Color ropeSegments;
|
||||
@@ -80,9 +73,8 @@ namespace NBF
|
||||
{
|
||||
[Tooltip("使用简单线渲染而非完整网格渲染。适用于细绳如鱼线,性能更好。")]
|
||||
public bool useSimpleLineRenderer;
|
||||
|
||||
[Tooltip("简单线渲染的宽度。")]
|
||||
public float simpleLineWidth;
|
||||
|
||||
[Tooltip("简单线渲染的宽度。")] public float simpleLineWidth;
|
||||
}
|
||||
|
||||
[Space] public RenderingSettings rendering = new RenderingSettings()
|
||||
@@ -91,13 +83,6 @@ namespace NBF
|
||||
simpleLineWidth = 0.02f
|
||||
};
|
||||
|
||||
// public CustomMeshSettings customMesh = new CustomMeshSettings()
|
||||
// {
|
||||
// mesh = null,
|
||||
// rotation = 90.0f,
|
||||
// scale = Vector3.one,
|
||||
// stretch = false,
|
||||
// };
|
||||
|
||||
[Tooltip("用于初始放置绳子在世界中的生成点。目前,连续的生成点对被视为线性线段。")] [DisableInPlayMode]
|
||||
public List<float3> spawnPoints = new List<float3>();
|
||||
@@ -157,7 +142,7 @@ namespace NBF
|
||||
solverIterations = 2,
|
||||
};
|
||||
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public struct CollisionSettings
|
||||
{
|
||||
@@ -218,7 +203,7 @@ namespace NBF
|
||||
protected bool initialized;
|
||||
protected bool computingSimulationFrame;
|
||||
protected bool simulationDisabledPrevFrame;
|
||||
protected bool wasSplit;
|
||||
|
||||
protected float timeSinceFixedUpdate;
|
||||
protected JobHandle simulationFrameHandle;
|
||||
|
||||
@@ -380,7 +365,6 @@ namespace NBF
|
||||
/// </summary>
|
||||
/// <param name="particleIndex">模拟粒子的索引</param>
|
||||
/// <param name="position">世界空间中的期望位置</param>
|
||||
/// <param name="maxImpulseStrength">可使用的最大允许冲量强度。如果为零,则不应用限制。</param>
|
||||
public void SetPositionAt(int particleIndex, float3 position)
|
||||
{
|
||||
if (!Initialize() || particleIndex < 0 || particleIndex >= positions.Length)
|
||||
@@ -606,91 +590,10 @@ namespace NBF
|
||||
|
||||
return positions.GetLengthOfCurve(isLoop);
|
||||
}
|
||||
|
||||
protected Rope InstantiateSplitRope(int minIdx, int maxIdx, string identifier)
|
||||
{
|
||||
var count = maxIdx - minIdx + 1;
|
||||
if (minIdx < 0 || maxIdx > positions.Length - 1 || count < 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 创建两个大致放置在新绳子位置的生成点(这将创建漂亮的双切线)
|
||||
var targetLength = _measurements.realCurveLength * ((float)count / _measurements.particleCount);
|
||||
var point0 = positions[minIdx];
|
||||
var point1 = positions[maxIdx];
|
||||
var delta = point1 - point0;
|
||||
var simplifiedLength = math.length(delta);
|
||||
point1 += math.normalizesafe(delta) * (targetLength - simplifiedLength);
|
||||
|
||||
var rope = Instantiate(gameObject, Vector3.zero, Quaternion.identity).GetComponent<Rope>();
|
||||
rope.name = identifier;
|
||||
rope.isLoop = false;
|
||||
rope.spawnPoints = new List<float3>()
|
||||
{
|
||||
point0,
|
||||
point1,
|
||||
};
|
||||
|
||||
if (rope.Initialize())
|
||||
{
|
||||
// 现在更新模拟粒子以完全匹配原始绳子
|
||||
for (int i = 0; i < rope.positions.Length; i++)
|
||||
{
|
||||
var sourceIdx = minIdx + i;
|
||||
if (sourceIdx >= positions.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
rope.positions[i] = positions[sourceIdx];
|
||||
rope.prevPositions[i] = prevPositions[sourceIdx];
|
||||
}
|
||||
|
||||
// 使新绳子与旧绳子大小相同
|
||||
rope._measurements.realCurveLength = rope.GetCurrentLength();
|
||||
rope._measurements.particleSpacing = _measurements.particleSpacing;
|
||||
|
||||
var param = new OnSplitParams()
|
||||
{
|
||||
minParticleIndex = minIdx,
|
||||
maxParticleIndex = maxIdx,
|
||||
preSplitMeasurements = _measurements,
|
||||
};
|
||||
|
||||
rope.SendMessage("OnRopeSplit", param, SendMessageOptions.DontRequireReceiver);
|
||||
}
|
||||
|
||||
return rope;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 在特定模拟粒子处分割绳子并返回新实例化游戏对象的绳子组件。确保
|
||||
/// 提供的数组正好有2个槽位。将向每个新创建的绳子发送Unity消息'OnRopeSplit(Rope.OnSplitParams)'。
|
||||
/// 计算真实曲线
|
||||
/// </summary>
|
||||
/// <param name="particleIndex">分割点的模拟粒子索引</param>
|
||||
/// <param name="outNewRopes">如果不为null,一个正好有2个元素的数组,其中将返回新的绳子游戏对象</param>
|
||||
public void SplitAt(int particleIndex, Rope[] outNewRopes = null)
|
||||
{
|
||||
if (!Initialize() || (outNewRopes != null && outNewRopes.Length != 2) || wasSplit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wasSplit = true;
|
||||
|
||||
var fst = InstantiateSplitRope(0, particleIndex, name + "_split0");
|
||||
var snd = InstantiateSplitRope(particleIndex + 1, positions.Length - 1, name + "_split1");
|
||||
|
||||
Destroy(gameObject);
|
||||
|
||||
if (outNewRopes != null)
|
||||
{
|
||||
outNewRopes[0] = fst;
|
||||
outNewRopes[1] = snd;
|
||||
}
|
||||
}
|
||||
|
||||
protected void ComputeRealCurve(Allocator allocator, out Measurements measurements,
|
||||
out NativeArray<float3> points)
|
||||
{
|
||||
@@ -800,7 +703,7 @@ namespace NBF
|
||||
{
|
||||
lineRenderer = gameObject.AddComponent<LineRenderer>();
|
||||
}
|
||||
|
||||
|
||||
lineRenderer.useWorldSpace = true;
|
||||
lineRenderer.loop = isLoop;
|
||||
lineRenderer.widthMultiplier = rendering.simpleLineWidth;
|
||||
@@ -809,7 +712,7 @@ namespace NBF
|
||||
lineRenderer.receiveShadows = false;
|
||||
lineRenderer.alignment = LineAlignment.View;
|
||||
}
|
||||
|
||||
|
||||
// 状态
|
||||
ComputeRealCurve(Allocator.Persistent, out _measurements, out positions);
|
||||
|
||||
@@ -957,6 +860,9 @@ namespace NBF
|
||||
|
||||
protected Collider[] collisionQueryBuffer = new Collider[MaxCollisionPlanesPerParticle];
|
||||
|
||||
/// <summary>
|
||||
/// 更新碰撞平面
|
||||
/// </summary>
|
||||
public void UpdateCollisionPlanes()
|
||||
{
|
||||
if (!collisions.enabled)
|
||||
@@ -1059,6 +965,9 @@ namespace NBF
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 准备刚体连接
|
||||
/// </summary>
|
||||
protected void PrepareRigidbodyConnections()
|
||||
{
|
||||
Profiler.BeginSample(nameof(PrepareRigidbodyConnections));
|
||||
@@ -1116,6 +1025,9 @@ namespace NBF
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用刚体反馈
|
||||
/// </summary>
|
||||
protected void ApplyRigidbodyFeedback()
|
||||
{
|
||||
Profiler.BeginSample(nameof(ApplyRigidbodyFeedback));
|
||||
@@ -1179,6 +1091,9 @@ namespace NBF
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安排下一个模拟帧
|
||||
/// </summary>
|
||||
protected void ScheduleNextSimulationFrame()
|
||||
{
|
||||
Profiler.BeginSample(nameof(ScheduleNextSimulationFrame));
|
||||
@@ -1240,6 +1155,9 @@ namespace NBF
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间表插值
|
||||
/// </summary>
|
||||
protected void ScheduleInterpolation()
|
||||
{
|
||||
if (interpolation == RopeInterpolation.None)
|
||||
@@ -1302,6 +1220,9 @@ namespace NBF
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 完成先前的模拟帧
|
||||
/// </summary>
|
||||
protected void CompletePreviousSimulationFrame()
|
||||
{
|
||||
if (!computingSimulationFrame)
|
||||
@@ -1317,46 +1238,6 @@ namespace NBF
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
protected static void FillMeshFrames(ref NativeArray<float3> positions, ref NativeArray<float3> bitangents,
|
||||
Matrix4x4[] meshFrames, float spacing, bool isLoop, float rotationOffset, Vector3 scaleMultiplier,
|
||||
bool stretch)
|
||||
{
|
||||
var scale = scaleMultiplier * 0.5f * spacing;
|
||||
if (stretch)
|
||||
{
|
||||
scale.z = scaleMultiplier.z * 0.5f;
|
||||
}
|
||||
|
||||
var currentRotation = 0.0f;
|
||||
for (var i = 0; i < positions.Length; i++) // 在这里使用positions数组,希望编译器能优化掉边界检查...
|
||||
{
|
||||
var tangent = Vector3.zero;
|
||||
if (isLoop)
|
||||
{
|
||||
tangent = positions[(i + 1) % positions.Length] - positions[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
tangent = i < positions.Length - 1
|
||||
? positions[i + 1] - positions[i]
|
||||
: positions[i] - positions[i - 1];
|
||||
}
|
||||
|
||||
var frameScale = stretch
|
||||
? new Vector3(scale.x, scale.y, scale.z * tangent.magnitude)
|
||||
: scale;
|
||||
tangent.Normalize();
|
||||
|
||||
var frameRotation = Quaternion.LookRotation(tangent, bitangents[i]) *
|
||||
Quaternion.Euler(0.0f, 0.0f, currentRotation);
|
||||
currentRotation += rotationOffset;
|
||||
|
||||
customMeshFrames[i] = Matrix4x4.TRS(positions[i], frameRotation, frameScale);
|
||||
}
|
||||
}
|
||||
|
||||
protected static Matrix4x4[] customMeshFrames;
|
||||
|
||||
protected void SubmitToRenderer()
|
||||
{
|
||||
if (material == null)
|
||||
@@ -1502,6 +1383,8 @@ namespace NBF
|
||||
}
|
||||
#endif
|
||||
|
||||
#region Jobs
|
||||
|
||||
[BurstCompile]
|
||||
private struct SimulateJob : IJob
|
||||
{
|
||||
@@ -1807,5 +1690,7 @@ namespace NBF
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user