using System.Collections.Generic; using TMPro; using UnityEngine; public class Controller : MonoBehaviour { private List cableStartingPoints = new(); //Initialize void Awake() { var rotatableSprite = Resources.Load("Rotatable"); var fixedSprite = Resources.Load("Fixed"); var poweredSprite = Resources.Load("Powered"); var freeSprite = Resources.Load("Free"); //prepare rollers var gameObjects = FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None); foreach (GameObject go in gameObjects) { RollerProperties rp = go.GetComponent(); if (rp != null) { if (!rp.useFixedAttachmentPoint) { switch (rp.movement) { case RollerProperties.RotationType.Rotatable: go.GetComponent().sprite = rotatableSprite; break; case RollerProperties.RotationType.Fixed: go.GetComponent().sprite = fixedSprite; break; case RollerProperties.RotationType.Free: go.GetComponent().sprite = freeSprite; break; case RollerProperties.RotationType.Powered: go.GetComponent().sprite = poweredSprite; break; } } //collisions and physics Rigidbody2D rb = go.GetOrAddComponent(); // mass is based on area, if not provided if (rp.mass == null) { rb.useAutoMass = rp.mass == null; } else { rb.mass = rp.mass.Value; } rb.angularDrag = 1; rb.drag = 1; if (rp.movement == RollerProperties.RotationType.Fixed) { rb.bodyType = RigidbodyType2D.Static; } go.AddComponent(); //build list of cable starting objects cableStartingPoints.Add(rp); Debug.Log("Initialized roller: " + go.name); } } //create canvas to display information var canvas = gameObject.AddComponent(); //prepare joints foreach (var go in gameObjects) { RollerProperties[] rpArr = go.GetComponents(); foreach (var rp in rpArr) { if (rp != null) { if (rp.linkTo != null) { var dist = go.AddComponent(); dist.enableCollision = true; dist.connectedBody = rp.linkTo.GetComponent(); dist.maxDistanceOnly = true; dist.autoConfigureDistance = false; rp.distanceJoint2D = dist; //remove linked to objects, so only starting points remain cableStartingPoints.Remove(rp.linkTo); //set fixed points only once if (rp.useFixedAttachmentPoint) { dist.anchor = rp.attachmentPoint; } if (rp.linkTo.useFixedAttachmentPoint) { dist.connectedAnchor = rp.linkTo.attachmentPoint; } //update roller tangent attachments rp.updateDistanceJoints(); rp.actualDistance = dist.distance = dist.ActualDistanceInWorld(); } if (rp.movement is RollerProperties.RotationType.Rotatable or RollerProperties.RotationType.Powered) { var wheel = go.AddComponent(); wheel.anchor = Vector2.zero; if (rp.movement == RollerProperties.RotationType.Powered) { wheel.useMotor = true; wheel.motor = new JointMotor2D() { maxMotorTorque = 10000, motorSpeed = rp.clockwise ? 10 : -10 }; } } //create names on objects GameObject text = new GameObject(go.name + "_text"); text.transform.parent = canvas.transform; var textMeshPro = text.AddComponent(); // textMeshPro.material.shader.GetComponent().enabled = true; // textMeshPro.material.shader.GetComponent().useGraphicAlpha = false; // textMeshPro.material.shader.GetComponent().effectDistance = new Vector2(1, -1); textMeshPro.fontSize = .3f; textMeshPro.color = Color.black; textMeshPro.fontStyle = FontStyles.Bold; textMeshPro.outlineColor = Color.black; textMeshPro.outlineWidth = 0.2f; textMeshPro.horizontalAlignment = HorizontalAlignmentOptions.Center; textMeshPro.verticalAlignment = VerticalAlignmentOptions.Middle; textMeshPro.transform.localScale = new Vector3(100, 100, 1); textMeshPro.fontSize = .03f; textMeshPro.autoSizeTextContainer = true; textMeshPro.fontSizeMin = 0; rp.text = text; } } } Debug.Log("Initialized "+cableStartingPoints.Count+" cables"); var cableNum = 0; //find and report loops of cables foreach (var cable in cableStartingPoints) { List visitedSegments = new(); for (var segment = cable; segment != null; segment = segment.linkTo) { if (visitedSegments.Contains(segment)) { cableStartingPoints = null; Debug.LogError("Fix cable loop in scene with object "+segment.gameObject.name); break; } visitedSegments.Add(segment); } } } private float waitedFrames = 0; // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.T)) { foreach (var go in FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None)) { if (go.GetComponent() != null && go.GetComponent().movement == RollerProperties.RotationType.Powered) { go.GetComponent().useMotor = !go.GetComponent().useMotor; Debug.Log("TOGGLED ALL MOTORS"); } } } if (waitedFrames++ > -1) { CableJointsAlgorithm.TimeStep(cableStartingPoints); waitedFrames = 0; } } }