using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Autohand { public class PlaceJoint : PlacePoint { [Tooltip("This is for connecting grabbables together, leave empty if using a static")] public Grabbable localGrabbable; public Rigidbody localRigidbody; public Vector3 anchor; public Vector3 axis = Vector3.right; public bool autoConfigureConnection = true; public Vector3 connectedAnchor; public Vector3 secondaryAxis = Vector3.up; public ConfigurableJointMotion xMotion, yMotion, zMotion; public ConfigurableJointMotion angularXMotion, angularYMotion, angularZMotion; [SerializeField] public SerializedSoftJointLimitSpring linearLimitSpring; [SerializeField] public SerializedSoftJointLimit linearLimit; [SerializeField] public SerializedSoftJointLimitSpring angularXLimitSpring; public SerializedSoftJointLimit lowAngularXLimit; public SerializedSoftJointLimit highAngularXLimit; public SerializedSoftJointLimitSpring angularYZLimitSpring; public SerializedSoftJointLimit angularYLimit; public SerializedSoftJointLimit angularZLimit; public Vector3 targetPosition; public Vector3 targetVelocity; public SerializedJointDrive xDrive; public SerializedJointDrive yDrive; public SerializedJointDrive zDrive; public Vector3 targetAngularVelocity; public RotationDriveMode rotationDriveMode; public SerializedJointDrive angularXDrive; public SerializedJointDrive angularYZDrive; public SerializedJointDrive slerpDrive; public JointProjectionMode projectionMode = JointProjectionMode.PositionAndRotation; public float projectionDistance = 0f; public float projectionAngle = 0; public bool configuredInWorldSpace; public bool swapBodies; public bool enableCollision = false; public bool enablePreprocessing = true; public float breakForce = float.PositiveInfinity; public float breakTorque = float.PositiveInfinity; public float massScale = 1; public float connectedMassScale = 1; [Range(1, 255), Tooltip("The solver iterations to use while a placeJoint is connected, higher is higher quality joint stability but more expensive 1-255")] public int solverIterations = 100; [Range(1, 255), Tooltip("The velocity solver iterations to use while a placeJoint is connected, higher is higher quality joint stability but more expensive 1-255")] public int velocitySolverIterations = 100; Quaternion targetRotation = Quaternion.identity; ConfigurableJoint connectionJoint = null; Vector3 prePlacedPos; Quaternion prePlacedRot; protected void Start() { //base.Start(); base.makePlacedKinematic = false; base.placedJointLink = null; } internal override void Highlight(Grabbable placeObj) { base.Highlight(placeObj); } public override bool CanPlace(Grabbable placeObj, bool checkRoot = true) { return base.CanPlace(placeObj) && placeObj.body != localRigidbody; } //protected override void OnEnable() { // base.OnEnable(); // if(localGrabbable != null) // localGrabbable.OnReleaseEvent += OnReleased; //} //protected override void OnDisable() { // base.OnDisable(); // if(localGrabbable != null) // localGrabbable.OnReleaseEvent -= OnReleased; //} //void OnReleased(Hand hand, Grabbable grab) { // if(localGrabbable != null) { // Remove(); // } //} public override void Place(Grabbable placeObj) { prePlacedPos = placeObj.transform.position; prePlacedRot = placeObj.transform.rotation; base.Place(placeObj); if(connectionJoint == null && placedObject != null) { CreateConnection(placeObj); } if(localGrabbable) { if (localGrabbable.body != null) { localGrabbable.body.velocity = Vector3.zero; localGrabbable.body.angularVelocity = Vector3.zero; } for(int i = 0; i < localGrabbable.jointedBodies.Count; i++) { localGrabbable.jointedBodies[i].velocity = Vector3.zero; localGrabbable.jointedBodies[i].angularVelocity = Vector3.zero; } } } private void FixedUpdate() { if(placedObject != null) { if(connectionJoint == null) Remove(placedObject); } } public override void Remove(Grabbable placeObj) { if(localGrabbable != null && localGrabbable.body != null) localGrabbable.RemoveJointedBody(placeObj.body); placeObj.RemoveJointedBody(localRigidbody); if(connectionJoint != null) { Destroy(connectionJoint); connectionJoint = null; } localRigidbody.solverIterations = Physics.defaultSolverIterations; localRigidbody.solverVelocityIterations = Physics.defaultSolverVelocityIterations; base.Remove(placeObj); } Vector3 pregrabPos; Quaternion pregrabRot; public void CreateConnection(Grabbable connection) { if(localRigidbody != null) { connection.AddJointedBody(localRigidbody); if(localGrabbable != null && localGrabbable.body != null) localGrabbable.AddJointedBody(connection.body); } localRigidbody.solverIterations = solverIterations; localRigidbody.solverVelocityIterations = velocitySolverIterations; connectionJoint = connection.gameObject.AddComponent(); connectionJoint.connectedBody = localRigidbody; connectionJoint.anchor = anchor; connectionJoint.axis = axis; connectionJoint.autoConfigureConnectedAnchor = false; connectionJoint.connectedAnchor = Vector3.zero; connectionJoint.secondaryAxis = secondaryAxis; connectionJoint.xMotion = xMotion; connectionJoint.yMotion = yMotion; connectionJoint.zMotion = zMotion; connectionJoint.angularXMotion = angularXMotion; connectionJoint.angularYMotion = angularYMotion; connectionJoint.angularZMotion = angularZMotion; connectionJoint.linearLimitSpring = linearLimitSpring; connectionJoint.linearLimit = linearLimit; connectionJoint.angularXLimitSpring = angularXLimitSpring; connectionJoint.lowAngularXLimit = lowAngularXLimit; connectionJoint.highAngularXLimit = highAngularXLimit; connectionJoint.angularYZLimitSpring = angularYZLimitSpring; connectionJoint.angularYLimit = angularYLimit; connectionJoint.angularZLimit = angularZLimit; connectionJoint.targetPosition = targetPosition; connectionJoint.targetVelocity = targetVelocity; connectionJoint.xDrive = xDrive; connectionJoint.yDrive = yDrive; connectionJoint.zDrive = zDrive; connectionJoint.targetAngularVelocity = targetAngularVelocity; connectionJoint.rotationDriveMode = rotationDriveMode; connectionJoint.angularXDrive = angularXDrive; connectionJoint.angularYZDrive = angularYZDrive; connectionJoint.slerpDrive = slerpDrive; connectionJoint.projectionMode = projectionMode; connectionJoint.projectionDistance = projectionDistance; connectionJoint.projectionAngle = projectionAngle; connectionJoint.configuredInWorldSpace = configuredInWorldSpace; connectionJoint.swapBodies = swapBodies; connectionJoint.enableCollision = enableCollision; connectionJoint.enablePreprocessing = enablePreprocessing; connectionJoint.breakForce = breakForce; connectionJoint.breakTorque = breakTorque; connectionJoint.massScale = massScale; connectionJoint.connectedMassScale = connectedMassScale; } public void Destroyjoint() { if (connectionJoint != null) { Destroy(connectionJoint); if (localGrabbable != null) localGrabbable.RemoveJointedBody(placedObject.body); } } } }