using UnityEngine;
using UnityEngine.Rendering;
using System.Collections.Generic;
///
/// Câble RJ45 entre deux ports, passant par des points d'accroche.
/// Stocke sa longueur et la référence au toron source.
///
public class CableRJ45 : MonoBehaviour
{
[Header("Connexion")]
public PortRJ45 portSource;
public PortRJ45 portDestination;
public List waypoints = new List();
[Header("Visuel")]
public Color couleurCable = Color.blue;
public float epaisseur = 0.005f;
public int segmentsParSection = 10;
public float mou = 0.15f;
[Header("Métrage")]
public float longueurCable = 0f;
public ToronCable toronSource;
[Header("Etat")]
public bool estPendant = false;
public bool pendantCoteSource = false;
private LineRenderer _lineRenderer;
private Transform _ciblePendante;
///
/// Initialise le câble connecté des deux côtés.
///
public void Initialiser(PortRJ45 source, PortRJ45 destination, List pointsPassage, Color couleur, float longueur, ToronCable toron)
{
portSource = source;
portDestination = destination;
waypoints = new List(pointsPassage);
couleurCable = couleur;
longueurCable = longueur;
toronSource = toron;
estPendant = false;
CreerLineRenderer(couleur);
foreach (var wp in waypoints)
{
if (wp != null) wp.Selectionner();
}
MettreAJourCourbe();
}
///
/// Passe le câble en mode pendant.
///
public void PasserEnModePendant(bool coteSourceDebranche, Transform cible)
{
estPendant = true;
pendantCoteSource = coteSourceDebranche;
_ciblePendante = cible;
if (coteSourceDebranche)
{
if (portSource != null)
{
portSource.DeconnecterCeCote();
portSource = null;
}
}
else
{
if (portDestination != null)
{
portDestination.DeconnecterCeCote();
portDestination = null;
}
}
}
///
/// Reconnecte le bout pendant à un nouveau port.
///
public void ReconnecterBoutLibre(PortRJ45 nouveauPort)
{
if (pendantCoteSource)
{
portSource = nouveauPort;
nouveauPort.Connecter(portDestination, this);
if (portDestination != null)
{
portDestination.portConnecte = nouveauPort;
portDestination.SupprimerMarqueur();
}
}
else
{
portDestination = nouveauPort;
nouveauPort.Connecter(portSource, this);
if (portSource != null)
{
portSource.portConnecte = nouveauPort;
portSource.SupprimerMarqueur();
}
}
estPendant = false;
_ciblePendante = null;
MettreAJourCourbe();
}
public PortRJ45 GetPortFixe()
{
if (pendantCoteSource)
return portDestination;
else
return portSource;
}
void Update()
{
MettreAJourCourbe();
}
private void MettreAJourCourbe()
{
if (_lineRenderer == null) return;
List noeuds = new List();
// Point de départ
if (estPendant && pendantCoteSource)
{
if (_ciblePendante != null)
noeuds.Add(_ciblePendante.position);
else return;
}
else if (portSource != null)
{
noeuds.Add(portSource.GetPointConnexion());
}
else return;
// Waypoints
foreach (var wp in waypoints)
{
if (wp != null)
noeuds.Add(wp.GetPosition());
}
// Point d'arrivée
if (estPendant && !pendantCoteSource)
{
if (_ciblePendante != null)
noeuds.Add(_ciblePendante.position);
else return;
}
else if (portDestination != null)
{
noeuds.Add(portDestination.GetPointConnexion());
}
else return;
// Génère la courbe
List pointsCourbe = new List();
for (int s = 0; s < noeuds.Count - 1; s++)
{
Vector3 debut = noeuds[s];
Vector3 fin = noeuds[s + 1];
float distance = Vector3.Distance(debut, fin);
float mouSection = mou;
if (estPendant)
{
if ((pendantCoteSource && s == 0) || (!pendantCoteSource && s == noeuds.Count - 2))
mouSection = 0.5f;
}
float chute = distance * mouSection;
Vector3 milieu = (debut + fin) / 2f;
Vector3 controle = milieu + Vector3.down * chute;
int nbPts = segmentsParSection;
for (int i = 0; i <= nbPts; i++)
{
if (s > 0 && i == 0) continue;
float t = (float)i / nbPts;
Vector3 point = CalculerBezierQuadratique(debut, controle, fin, t);
pointsCourbe.Add(point);
}
}
_lineRenderer.positionCount = pointsCourbe.Count;
_lineRenderer.SetPositions(pointsCourbe.ToArray());
}
private Vector3 CalculerBezierQuadratique(Vector3 p0, Vector3 p1, Vector3 p2, float t)
{
float u = 1f - t;
return u * u * p0 + 2f * u * t * p1 + t * t * p2;
}
private void CreerLineRenderer(Color couleur)
{
// Cote dedicated server : pas de LineRenderer/Material (Shader.Find retourne null)
if (DedicatedServerMode.IsDedicatedServer)
return;
if (_lineRenderer == null)
_lineRenderer = gameObject.AddComponent();
_lineRenderer.startWidth = epaisseur;
_lineRenderer.endWidth = epaisseur;
_lineRenderer.useWorldSpace = true;
_lineRenderer.shadowCastingMode = ShadowCastingMode.Off;
_lineRenderer.receiveShadows = false;
Material mat = new Material(Shader.Find("Standard"));
mat.color = couleur;
mat.EnableKeyword("_EMISSION");
mat.SetColor("_EmissionColor", couleur * 0.15f);
_lineRenderer.material = mat;
}
///
/// Supprime le câble et rend le métrage au toron.
///
public void SupprimerComplet()
{
// Rend la longueur au toron source
if (toronSource != null && longueurCable > 0)
{
toronSource.RendreLongueur(longueurCable);
}
// Déconnecte les ports
if (portSource != null)
portSource.Deconnecter();
if (portDestination != null)
{
portDestination.estConnecte = false;
portDestination.cable = null;
portDestination.portConnecte = null;
portDestination.SupprimerMarqueur();
}
foreach (var wp in waypoints)
{
if (wp != null) wp.DetacherCable();
}
Debug.Log("Cable supprime, " + longueurCable.ToString("F1") + "m rendus au toron");
Destroy(gameObject);
}
}