Skip to content

Tutorial: Build a Tool Belt

In this tutorial, we will see how to build a tool belt. This can be useful to learn how to attach any object to your player.

Prepare the tool

  1. Create an empty object Tools.
  2. Add your tool as a child of it, here we will use a Wrench.

    alt text

  3. Physicalize Wrench with a weldable joint: INTERACT > Physicalize and select Weldable for the Joint Type.

    alt text

Prepare the Tool Belt

  1. Add a empty object ToolBelt to the player in 'Player_1'> Avatar > Armature > Hips. Add a second empty object as a child of it WrenchAttach.
  2. WrenchAttach is the Wrench's localization on the Toolbelt, you can adjust his position according your wish.
  3. Add the component Xde Transform in the Inspector of WrenchAttach, this will be used by your manipulator later to follow the player.

Created the Manipulator

  1. Add a empty child in Tools, named Manipulator, it will be attaching your object to the tool belt.
  2. Physicalize this object with a weldable joint.
  3. Add the component Xde Position Manipulator in the Inspector.
  4. Configure the component:
    • For the Rigid Body, drop the Rigid Body of the Manipulator.
    • For the Device, drop WrenchAttach in the belt that we created earlier.
  5. Go to the Advanced parameter of your Xde Position Manipulator and uncheck OffSet on Attach. As a result, it will not consider the distance existing between your tool and your belt at start, allowing to put it in the right position, the one indicated by your attachment to the belt.

Configure parameters in your Tool

  1. In your tool's inspector Wrench:

    • Drop in the ParentBody of the XdeWeldableJoint your Manipulator.
    • Check the WeldAtStart so it would be automatically attached at start.

    Now your tool is correctly attached to your belt. However it does not yet return to its correct position when you grab the object.

  2. To resolve it:

    • Attached the script below to your tool Wrench.
    • Drop the manipulator in the "_manipulator" Serialized.

Check position

Make sure every transform in your Tools object are set at Position(0,0,0) to avoid any gap.

Script Sample

using UnityEngine;

using XdeEngine.Core;

using xde.unity.math;

public class AttachToBeltUngrabeb : MonoBehaviour
{
    [SerializeField] private GameObject _manipulator_;
    private int grab=0;
    private Quaternion rotationInitiale;

    private void Start()
    {
        rotationInitiale = gameObject.transform.localRotation;
        GetCorrectPosition();
    }
    private void OnEnable()
    {
        foreach (XdeGraspManipulator l_manipulator in FindObjectsByType<XdeGraspManipulator>(FindObjectsSortMode.None))
        {
            l_manipulator.AttachedEvent += AttachedEvent;
            l_manipulator.DetachedEvent += DetachedEvent;
        }
    }
    private void OnDisable()
    {
        foreach (XdeGraspManipulator l_manipulator in FindObjectsByType<XdeGraspManipulator>(FindObjectsSortMode.None))
        {
            l_manipulator.AttachedEvent -= AttachedEvent;
            l_manipulator.DetachedEvent -= DetachedEvent;
        }
    }

    private void DetachedEvent(XdeRigidBody p_rb)
    {
        if (p_rb == GetComponent<XdeRigidBody>())
        {
            grab -= 1;
            if (grab==0)
            {
                WeldJointOnHierarchy(p_rb, true);
                GetCorrectPosition();
            }
        }
    }

    private void AttachedEvent(XdeRigidBody p_rb)
    {
        if (p_rb == GetComponent<XdeRigidBody>())
        {
            WeldJointOnHierarchy(p_rb, false);
            grab += 1;
        }
    }

    private void GetCorrectPosition()
    {
        Displacement l_displacement;
        l_displacement = new Displacement(_manipulator_.transform.position, rotationInitiale );

        this.GetComponent<XdeWeldableJoint>().SetPositionAsync(l_displacement);
    }

    private void WeldJointOnHierarchy(XdeRigidBody p_rb, bool p_weld)
    {
        if (p_rb == null){return;}

        XdeUnitJoint l_unitJoint = p_rb.GetComponent<XdeUnitJoint>();

        if (l_unitJoint){l_unitJoint.Weld(p_weld);}
        else
        {
            XdeWeldableJoint l_weldableJoint = p_rb.GetComponent<XdeWeldableJoint>();

            if (l_weldableJoint)
            {
                if (p_weld)
                {
                    l_weldableJoint.Weld();
                }
                else
                {
                    l_weldableJoint.Unweld();
                }
            }
            else
            {
                var l_fixedJoint = p_rb.GetComponent<XdeFixedJoint>();

                if (l_fixedJoint)
                {
                    WeldJointOnHierarchy(l_fixedJoint.parentBody, p_weld);
                }
            }
        }
    }
}