Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug Joints added in runtime not working in build

Discussion in 'Physics' started by Adriano21, Jun 29, 2023.

  1. Adriano21

    Adriano21

    Joined:
    Jan 19, 2021
    Posts:
    6
    Hello everyone.
    I have this strange problem that has been blocking me for days, I'm trying to add a ConfigurableJoint or a SpringJoint to the player in runtime but in the editor it works perfectly and in the build it doesn't work.

    The function is called by a grappling hook.
    I tried moving everything to FixedUpdate, changing the solverIteration, timesteps, unity version and build platform but nothing worked.

    I leave you the code of the joint.

    Code (CSharp):
    1. public void ActivateSwing()
    2.     {
    3.         CanSwing = true;
    4.  
    5.         // Calculate angle between player and tether point and rotate the player around it
    6.         var dir = (TetherTransform.position - transform.position);
    7.         var angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
    8.         //transform.rotation = Quaternion.AngleAxis(angle - 90, Vector3.forward);
    9.  
    10.         // Fire Rope (Extra check, every thing here runs only once per tethering action)
    11.         if (CanSwing)
    12.         {
    13.             Debug.Log("Swing");
    14.             text.text = "Swing";
    15.             // Get the vector to the closest Tether point as long as there are points
    16.  
    17.             closestTether = LastShot.transform.position - transform.position;
    18.  
    19.             // Move pressed indicator position to tetherTransform pos
    20.             //indicatorGameObject.transform.position = new Vector3(TetherTransform.position.x, TetherTransform.position.y + indicatorPressedOffset, 0);
    21.             //indicatorSphere.transform.position = new Vector3(TetherTransform.position.x, TetherTransform.position.y, 0);
    22.  
    23.             // Shoot a ray out towards that position      
    24.             LayerMask ignorePlayer = ~(1 << LayerMask.NameToLayer("Player"));
    25.             Physics.Raycast(transform.position, closestTether, out RaycastHit hit, maxTetherDistance, ignorePlayer);
    26.             if (hit.collider)
    27.             {
    28.                 if (hit.collider.tag == "ValidSurface" || hit.collider.tag == "Tether Points")
    29.                 {
    30.                     Debug.Log("Valid");
    31.                     text.text = "Valid";
    32.                     Transform rampinoPos = FindObjectOfType<Rampino>().transform;
    33.                     // Move the anchor to the correct position
    34.                     anchor.transform.position = rampinoPos.position;
    35.                     //anchor.transform.position = new Vector3(hit.point.x, hit.point.y, 0);
    36.                     // Zero out any rotation of anchor
    37.                     anchor.transform.rotation = Quaternion.identity;
    38.                     if (joint != null)
    39.                     {
    40.                         Destroy(joint);
    41.                         Destroy(anchorJoint);
    42.                     }
    43.                     // Create HingeJoints
    44.                     joint = gameObject.AddComponent<ConfigurableJoint>();
    45.                     joint.axis = Vector3.forward;
    46.                     joint.anchor = Vector3.zero;
    47.                     joint.connectedBody = anchor.GetComponent<Rigidbody>();
    48.                     JointDrive drive = new JointDrive();
    49.                     drive.positionSpring = 10;
    50.                     drive.maximumForce = 999;
    51.                     joint.xDrive = drive;
    52.                     joint.yDrive = drive;
    53.                    
    54.                     joint.autoConfigureConnectedAnchor = false;
    55.                    
    56.                     rb.WakeUp();
    57.                     // Create anchor HingeJoint
    58.                     //anchorJoint = anchor.AddComponent<HingeJoint>();
    59.                     //anchorJoint.axis = Vector3.forward;
    60.                     //anchorJoint.anchor = Vector3.zero;
    61.                     Lr.enabled = true; // show rope
    62.                 }
    63.             }
    64.         }
    65.         else
    66.         {
    67.             DeactivateSwing();
    68.         }
    69.     }
    If you need, I'll leave you the project link

    A thousand thanks
     

    Attached Files:

  2. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    449
    "it doesn't work"

    How doesn't it work?
     
  3. Adriano21

    Adriano21

    Joined:
    Jan 19, 2021
    Posts:
    6
    it does nothing, it sticks to the desired point and the line renderer also appears but it is as if the physics of the joint were not active, I also put a text to check if the creation of the joint was called and the code works
     
  4. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    449
    There's nothing wrong in theory about what you're doing, they can be added just like this at runtime.

    ConfigurableJoints are Free in every aspect upon creation. Try to increase your positionSpring to get a more powerful drive. How strong this needs to be is relative to the mass of the rigidbody it needs to move.
     
  5. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    449
    If its working when you create it in Editor, take a screenshot of your component values in Editor, then one by one make sure you have each and every one of those values set in your creation code. Then when your script-created joint is running in the editor, take another screenshot of it in the editor, and compare your screenshots for values to find what is different.
     
  6. Adriano21

    Adriano21

    Joined:
    Jan 19, 2021
    Posts:
    6
    i increased the positionSpring from 10 to 1000 and it still does nothing. I'll check with the screenshots and see if anything has changed
     
  7. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    449
    You don't seem to be setting
    joint.targetPosition
    . This should be expressed in the joint's local space.
     
  8. Adriano21

    Adriano21

    Joined:
    Jan 19, 2021
    Posts:
    6
    Thanks so much for the tips.
    After setting the targetPosition and taking the screenshots I noticed that the positionSpring was not set, I changed the code and now in the build the connected object moves but in a very strange and abnormal way, I leave you the modified code


    Code (CSharp):
    1. public void CreateJoint()
    2.     {
    3.         // Add ConfigurableJoint component to the game object
    4.         ConfigurableJoint joint = gameObject.AddComponent<ConfigurableJoint>();
    5.  
    6.         // Set the connected body
    7.         Rigidbody anchorRigidbody = tetherTransform.GetComponent<Rigidbody>();
    8.         if (anchorRigidbody != null)
    9.         {
    10.             joint.connectedBody = anchorRigidbody;
    11.         }
    12.         else
    13.         {
    14.             Debug.LogError("No Rigidbody component found on the anchor object.");
    15.            
    16.         }
    17.  
    18.         // Set the anchor position and rotation
    19.         joint.anchor = Vector3.zero;
    20.         //joint.anchor = transform.InverseTransformPoint(tetherTransform.position);
    21.         joint.connectedAnchor = Vector3.zero;
    22.         //joint.connectedAnchor = tetherTransform.InverseTransformPoint(transform.position);
    23.  
    24.         // Set other joint properties as desired
    25.         joint.autoConfigureConnectedAnchor = false;
    26.         joint.axis = Vector3.right;
    27.         joint.targetPosition = Vector3.zero;
    28.         joint.targetVelocity = Vector3.zero;
    29.         joint.xMotion = ConfigurableJointMotion.Free;
    30.         joint.yMotion = ConfigurableJointMotion.Free;
    31.         joint.zMotion = ConfigurableJointMotion.Free;
    32.         joint.angularXMotion = ConfigurableJointMotion.Free;
    33.         joint.angularYMotion = ConfigurableJointMotion.Free;
    34.         joint.angularZMotion = ConfigurableJointMotion.Free;
    35.         joint.rotationDriveMode = RotationDriveMode.XYAndZ;
    36.         joint.projectionMode = JointProjectionMode.PositionAndRotation;
    37.         joint.projectionDistance = .1f;
    38.         joint.projectionAngle = 180.0f;
    39.  
    40.         // Apply additional settings or constraints as needed
    41.  
    42.         // Optionally, you can also set the drive settings for rotational motion
    43.         JointDrive xDrive = new JointDrive();
    44.         xDrive.positionSpring = 10;
    45.         xDrive.positionDamper = 0;
    46.         xDrive.maximumForce = 999;
    47.         joint.xDrive = xDrive;
    48.  
    49.         JointDrive yzDrive = new JointDrive();
    50.         yzDrive.positionSpring = 10;
    51.         yzDrive.positionDamper = 0;
    52.         yzDrive.maximumForce = 999;
    53.         joint.yDrive = yzDrive;
    54.     }
     
  9. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    449
    Joint target positions are complicated, and one thing that really gave me the most headache was realizing that joints work the way that their local space is initialized at the point where they are enabled. So, when the joint first becomes active, the relative position of itself and its connected body are permanently glued in place, and from that on everything works using these initial positions as a reference.

    This means that if you want stuff to work exactly as they are in editor, your rigidbody transforms need to be exactly in the same place.
     
  10. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    449
    "Target Position and Velocity
    These are the values that the linear drives try to reach in local space. If both of them are zeroed out then what you have is a spring joint, with the target position being the offset." ( https://wirewhiz.com/the-complete-guide-to-unitys-configurable-joints/#5 )

    So if your target position is zero, the linear drive will try to move the attached body to your joint using targetVelocity. If you want the target position to have an offset, this needs to be set with targetPosition.
     
  11. Adriano21

    Adriano21

    Joined:
    Jan 19, 2021
    Posts:
    6
    Sorry for the late reply.
    I think I understand what you mean even if I don't know exactly how to fix this thing, I think I'm doing something wrong, perhaps in the unity settings because seeing the documentation or many graplin guns tutorials I notice that they do almost everything like I do but I still have strange and abnormal movement and physics in the build only. Thanks for the advice, I'll make other attempts and update you hoping to figure out what's wrong
     
  12. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    449
    To learn how the joints move, I recommend just make a test scene and create a cube with kinematic rigidbody, and add a ConfigurableJoint on it. Then adda a sphere with a rigidbody on it, and attach this rigidbody to the joint's connectedBody. Then hit play mode and start adjusting the parameters in play mode, and drag the cube with the mouse. This is often the best way to reach the results you want.