Files
aibis-dream/Assets/Scripts/FixSystemNew/Cable.cs
T
2024-11-12 14:32:02 +08:00

123 lines
3.5 KiB
C#

using System;
using UnityEngine;
namespace AibisDream.FixSystem
{
[RequireComponent(typeof(LineRenderer))]
public class Cable : MonoBehaviour
{
private Transform _start;
private Transform _end;
private LineRenderer _lineRenderer;
private Vector3[] _points;
private CableSystem _cableSystem;
[SerializeField]
private CableConfig config = CableConfig.GeneDefaultConfig();
private void Start()
{
InitComponentRefs();
InitPoints();
}
private void InitComponentRefs()
{
_cableSystem = transform.parent.GetComponent<CableSystem>();
_lineRenderer = GetComponent<LineRenderer>();
_lineRenderer.positionCount = config.resolution;
// 连线起止点
_start = _cableSystem.CableRootPos;
_end = _cableSystem.PlugRef.transform;
}
private void InitPoints()
{
_points = new Vector3[config.resolution];
for (int i = 0; i < config.resolution; i++)
{
float t = i / (float)(config.resolution - 1);
_points[i] = Vector3.Lerp(_start.position, _end.position, t);
}
}
private void FixedUpdate()
{
DrawLine();
}
void DrawLine()
{
var points = UpdateRope();
for (int i = 0; i < config.resolution; i++)
{
_lineRenderer.SetPosition(i, points[i] + Vector3.forward * -.3f);
}
}
Vector3[] UpdateRope()
{
float t = Mathf.InverseLerp(config.dstMin, config.dstMax, (_start.position - _end.position).magnitude);
float F = Mathf.Lerp(config.forceMin, config.forceMax, t);
_points[0] = _start.position;
_points[^1] = _end.position;
for (int ik = 0; ik < config.k; ik++)
{
for (int i = 1; i < _points.Length - 1; i++)
{
Vector3 offsetPrev = _points[i - 1] - _points[i];
Vector3 offsetNext = _points[i + 1] - _points[i];
Vector3 velocity = offsetPrev.normalized * (offsetPrev.magnitude * F) +
offsetNext.normalized * (offsetNext.magnitude * F);
_points[i] += velocity * Time.deltaTime / config.k;
}
for (int i = 1; i < _points.Length - 1; i++)
{
_points[i] += Vector3.down * (9.8f * Time.deltaTime) / config.k;
}
}
return _points;
}
/// <summary>
/// 为线缆设置末端点
/// </summary>
/// <param name="endPos">末端点</param>
public void SetEndPos(Transform endPos)
{
_end = endPos;
}
}
[Serializable]
public struct CableConfig
{
public int resolution;
public float dstMin;
public float dstMax;
public float forceMin;
public float forceMax;
public int k;
public static CableConfig GeneDefaultConfig()
{
return new CableConfig()
{
resolution = 10,
dstMin = 0.1f,
dstMax = 1.0f,
forceMin = 0.1f,
forceMax = 150f,
k = 10
};
}
}
}