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); } }