Search Unity

Drag Rigidbody script works, but passes through collider

Discussion in 'iOS and tvOS' started by Holocene, Aug 5, 2010.

  1. Holocene

    Holocene

    Joined:
    Feb 21, 2009
    Posts:
    347
    This "Drag Rigidbody" script works very well except for the fact that the dragged object can be pulled through a box collider if dragged too far. Any ideas why? It seemed to attenuate if I ramped up its mass to 10 - but I read that makes physics unstable.

    Any ideas?

    Thanks.




    Code (csharp):
    1.  
    2.  
    3. var spring : float = 50.0;
    4. var damper : float = 5.0;
    5. var drag : float = 10.0;
    6. var angularDrag : float = 5.0;
    7. var raycastDistance : float = 1000;
    8. var maxDistance : float = 0.2;
    9. var minDistance : float = 0;
    10. var attachToCenterOfMass : boolean = false;
    11. var mainCamera : Camera;
    12.  
    13. private var dragger : GameObject;
    14. private var springJoint : SpringJoint;
    15. private var touch : iPhoneTouch;
    16.  
    17.  
    18. function Start() {
    19.    
    20.    if (!mainCamera) {
    21.       mainCamera = Camera.main;
    22.    }
    23.  
    24. }
    25.  
    26.  
    27. //function Update() {
    28. function FixedUpdate() {
    29.    
    30.    // Make sure the user thouched the screen at least once and then iterate through all the available touches to find a suitable one.
    31.    var touchCount : int = iPhoneInput.touchCount;
    32.    if (!touchCount) {
    33.       return;
    34.    }
    35.    
    36.    var hit : RaycastHit;
    37.    for (var i : int = 0; i < touchCount; i++) {
    38.       touch = iPhoneInput.GetTouch(i);
    39.  
    40.       // We need to actually hit an object, so lets cast a ray to the position of the touch.
    41.       if (
    42.         Physics.Raycast(mainCamera.ScreenPointToRay(touch.position),hit,raycastDistance)
    43.         touch.phase != iPhoneTouchPhase.Ended
    44.         touch.phase != iPhoneTouchPhase.Canceled    
    45.       ) {
    46.      
    47.          // We need to hit a rigidbody that is not kinematic, and if found we make it accessible to gravity
    48.          if (!hit.rigidbody || hit.rigidbody.isKinematic) {
    49.             return;
    50.          }
    51.          hit.rigidbody.useGravity = true;
    52.          
    53.                (GameObject.Find("Main Camera").GetComponent("TOUCH_TO_MOVE_CONSTRAINED_YAXIS_FRICTION")as Behaviour ).enabled = false;
    54.                Debug.Log(" Disable ");
    55.  
    56.          
    57.          
    58.          
    59.          
    60.          if (!springJoint) {
    61.             // gotta find a way to destroy this object at some point 'cause once the rigidbody is out of touch it'll just linger there needlessley and possibly consume resources.
    62.             dragger = new GameObject("Rigidbody dragger");
    63.             springJoint = dragger.AddComponent(SpringJoint);
    64.             dragger.rigidbody.isKinematic = true;
    65.          }
    66.          springJoint.transform.position = hit.point;
    67.  
    68.          if (attachToCenterOfMass) {
    69.             springJoint.anchor = springJoint.transform.InverseTransformPoint(hit.rigidbody.transform.position + transform.TransformDirection(hit.rigidbody.centerOfMass));
    70.          }
    71.          else {
    72.             springJoint.anchor = Vector3.zero;
    73.          }
    74.    
    75.          springJoint.spring = spring;
    76.          springJoint.damper = damper;
    77.          springJoint.maxDistance = maxDistance;
    78.          springJoint.minDistance = minDistance;
    79.          springJoint.connectedBody = hit.rigidbody;
    80.    
    81.          StartCoroutine("DragObject",hit.distance);
    82.          break;
    83.       }
    84.    }  
    85.    
    86. }
    87.  
    88.  
    89. function DragObject(distance : float) {
    90.  
    91.    var oldDrag : float = springJoint.connectedBody.drag;
    92.    var oldAngularDrag : float = springJoint.connectedBody.angularDrag;
    93.    springJoint.connectedBody.drag = drag;
    94.    springJoint.connectedBody.angularDrag = angularDrag;
    95.    
    96.    var ray : Ray;
    97.    while (
    98.      touch.phase != iPhoneTouchPhase.Ended
    99.      touch.phase != iPhoneTouchPhase.Canceled
    100.    )
    101.    
    102.    
    103.  
    104.    
    105.    
    106.    {
    107.       ray = mainCamera.ScreenPointToRay(touch.position);
    108.       springJoint.transform.position = ray.GetPoint(distance);
    109.       yield;
    110.    }
    111.    
    112.    if (springJoint.connectedBody) {
    113.       springJoint.connectedBody.drag = oldDrag;
    114.       springJoint.connectedBody.angularDrag = oldAngularDrag;
    115.       springJoint.connectedBody = null;
    116.    }
    117. Destroy(dragger);
    118. // This is used stop my camera from moving.
    119.    (GameObject.Find("Main Camera").GetComponent("TOUCH_TO_MOVE_CONSTRAINED_YAXIS_FRICTION")as Behaviour ).enabled = true;
    120.                Debug.Log(" Enabled ");
    121. }
    122.  
    123.  
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You can try this instead.

    --Eric
     
  3. Holocene

    Holocene

    Joined:
    Feb 21, 2009
    Posts:
    347
    Thanks Eric, I'll have a look!
     
  4. Holocene

    Holocene

    Joined:
    Feb 21, 2009
    Posts:
    347
    Hi, Eric,

    I wanted to thank you for writing such an elegant solution for the drag rigidbody script. We have much
    to learn from you!

    Best,

    Greg
     
  5. vishesh-l

    vishesh-l

    Joined:
    Feb 14, 2010
    Posts:
    27
    hey,sorry to bring up an old thread, but i used ure script Eric, actually i wanted to drag a kinematic body, so i made the object kinematic.
    Of course it throws a ton of errors(the same error),yet the funny thing is it works perfectly.
    So,my question is, is it possible to modify this script to drag kinematic bodies?
    It works actually,even after unity throws errors,
    heres the error :
    "Actor::setAngularVelocity: Actor must be (non-kinematic) dynamic!
    UnityEngine.Rigidbody:set_angularVelocity(Vector3)
    racket:FixedUpdate() (at Assets/racket.js:62)"