171 lines
5.9 KiB
C#
171 lines
5.9 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using DG.Tweening.Plugins.Core.PathCore;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.FixSystem
|
|
{
|
|
[RequireComponent(typeof(LineRenderer))]
|
|
public class Cable : MonoBehaviour
|
|
{
|
|
private Transform _start;
|
|
private Transform _end;
|
|
|
|
private LineRenderer _lineRenderer;
|
|
private LineRenderer _stiffLineRenderer; // 用于渲染刚性部分
|
|
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 - config.stiffCount;
|
|
|
|
// 创建第二个LineRenderer用于刚性部分
|
|
GameObject stiffObj = new GameObject("StiffLineRenderer");
|
|
stiffObj.transform.SetParent(transform);
|
|
_stiffLineRenderer = stiffObj.AddComponent<LineRenderer>();
|
|
_stiffLineRenderer.positionCount = config.stiffCount;
|
|
|
|
// 复制第一个LineRenderer的属性到第二个
|
|
_stiffLineRenderer.startWidth = _lineRenderer.startWidth;
|
|
_stiffLineRenderer.endWidth = _lineRenderer.startWidth;
|
|
_stiffLineRenderer.material = _lineRenderer.material;
|
|
_stiffLineRenderer.startColor = _lineRenderer.startColor;
|
|
_stiffLineRenderer.endColor = _lineRenderer.startColor;
|
|
_stiffLineRenderer.sortingLayerName = _cableSystem.CableReelRef.GetComponent<SpriteRenderer>().sortingLayerName;
|
|
_stiffLineRenderer.sortingOrder = _cableSystem.CableReelRef.GetComponent<SpriteRenderer>().sortingOrder - 1;
|
|
|
|
// 连线起止点
|
|
_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.stiffCount; i++)
|
|
{
|
|
_stiffLineRenderer.SetPosition(i, points[i] + Vector3.forward * -.3f);
|
|
}
|
|
|
|
// 渲染非刚性部分
|
|
for (int i = 0; i < config.resolution - config.stiffCount; i++)
|
|
{
|
|
_lineRenderer.SetPosition(i, points[i + config.stiffCount] + 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);
|
|
|
|
// 计算出线方向(从转盘出线口到起始点)
|
|
Vector3 dir = (_start.position - _cableSystem.CableReelRef.transform.position).normalized;
|
|
|
|
// 设置刚性部分
|
|
for (int i = 0; i < config.stiffCount; i++)
|
|
{
|
|
float t_stiff = (float)i / (config.stiffCount - 1);
|
|
_points[i] = _start.position + dir * (config.stiffLength * t_stiff);
|
|
}
|
|
|
|
// 设置末端点
|
|
_points[^1] = _end.position;
|
|
|
|
// 只对非刚性部分进行物理模拟
|
|
for (int ik = 0; ik < config.k; ik++)
|
|
{
|
|
// 确保非刚性部分的第一个点与刚性部分的最后一个点重合
|
|
_points[config.stiffCount] = _points[config.stiffCount - 1];
|
|
|
|
for (int i = config.stiffCount + 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 = config.stiffCount + 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;
|
|
}
|
|
public Vector3 GetDirection()
|
|
{
|
|
return _points[^1] - _points[^2];
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public struct CableConfig
|
|
{
|
|
public int resolution;
|
|
public float dstMin;
|
|
public float dstMax;
|
|
public float forceMin;
|
|
public float forceMax;
|
|
public int k;
|
|
public int stiffCount; // 刚性部分点数
|
|
public float stiffLength; // 刚性部分长度
|
|
|
|
public static CableConfig GeneDefaultConfig()
|
|
{
|
|
return new CableConfig
|
|
{
|
|
resolution = 10,
|
|
dstMin = 0.1f,
|
|
dstMax = 1.0f,
|
|
forceMin = 0.1f,
|
|
forceMax = 150f,
|
|
k = 10,
|
|
stiffCount = 3,
|
|
stiffLength = 0.1f
|
|
};
|
|
}
|
|
}
|
|
} |