using System.Collections.Generic; using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Serialization; [System.Serializable] public class RollerProperties : MonoBehaviour { //settings /// rotation direction, used to determine attachment sides for the cables [SerializeField] public bool clockwise = false; [SerializeField] public RollerProperties linkTo = null; [SerializeField] public List listTest; [SerializeField] public RollerProperties[] arrayTest; [SerializeField] public RotationType movement = RotationType.Fixed; [FormerlySerializedAs("fixedAttachmentPoint")] [SerializeField] public bool useFixedAttachmentPoint = false; [SerializeField] public Vector2 attachmentPoint = new Vector2(0, 0); [SerializeField] public float? mass = null; //references protected internal GameObject text; protected internal DistanceJoint2D distanceJoint2D = null; protected internal GameObject linkToGameObject => linkTo.gameObject; //simulation properties protected internal float actualDistance; public (float?, float?) updateDistanceJoints() { Vector2? left = null, right = null; if (linkTo != null) { if (useFixedAttachmentPoint && !linkTo.useFixedAttachmentPoint) { //left = attachmentPoint; right = CableJointsAlgorithm.TangentPointCircle(gameObject, linkToGameObject); } else if (!useFixedAttachmentPoint && linkTo.useFixedAttachmentPoint) { left = CableJointsAlgorithm.TangentPointCircle(linkToGameObject,gameObject); //right = linkTo.GetComponent().attachmentPoint; } else if (!useFixedAttachmentPoint && !linkTo.useFixedAttachmentPoint) { (left, right) = CableJointsAlgorithm.TangentCircleCircle(gameObject, linkToGameObject); } /* else { left = attachmentPoint; right = linkTo.GetComponent().attachmentPoint; }*/ } //TODO: assumes circles are flat for sufficiently small timesteps float? leftSurfaceDist = null, rightSurfaceDist = null; if (left.HasValue) { leftSurfaceDist = CableJointsAlgorithm.CirclePointDistance(gameObject.transform.TransformPoint(distanceJoint2D.anchor), gameObject.transform.TransformPoint(left.Value), gameObject); // leftSurfaceDist = (gameObject.transform.TransformPoint(distanceJoint2D.anchor) - gameObject.transform.TransformPoint(left.Value)).magnitude; distanceJoint2D.anchor = left.Value; } if (right.HasValue) { rightSurfaceDist = CableJointsAlgorithm.CirclePointDistance(linkToGameObject.transform.TransformPoint(distanceJoint2D.connectedAnchor) , linkToGameObject.transform.TransformPoint(right.Value), linkToGameObject); // rightSurfaceDist = (linkTo.transform.TransformPoint(distanceJoint2D.connectedAnchor) - linkTo.transform.TransformPoint(right.Value)).magnitude; distanceJoint2D.connectedAnchor = right.Value; } return (leftSurfaceDist, rightSurfaceDist); } /* VISUALS */ private void Update() { if (text != null) { text.transform.position = transform.position; //text.transform.rotation = transform.rotation; text.GetComponent().text = gameObject.name + "\n" + (clockwise ? "cw" : "ccw") + " - " + movement + "\n" + " Mass: "+GetComponent().mass.ToString("0.00") + " Dist: " + (distanceJoint2D == null ? " - " : distanceJoint2D.distance.ToString("0.00") + "\n"+ "Slack: "+(distanceJoint2D.distance-actualDistance).ToString("0.00")); } } // Update is called once per frame void OnDrawGizmos() { foreach (var distanceJoint in gameObject.GetComponents()) { Gizmos.color = new Color(1, .3f, 0); var cableStart = transform.TransformPoint(distanceJoint.anchor); var cableEnd = distanceJoint.connectedBody.transform.TransformPoint(distanceJoint.connectedAnchor); Gizmos.DrawLine(cableStart, cableEnd); Gizmos.color = Color.yellow; Gizmos.DrawCube(cableStart, new Vector3(0.1f, 0.1f, 0.1f)); Gizmos.color = Color.red; Gizmos.DrawCube(cableEnd, new Vector3(0.1f, 0.1f, 0.1f)); } } public enum RotationType { Fixed, Rotatable, Powered, Free } }