I want to lerp weapon / object position to a specific player offset, parented to the fps camera unity

Viewed 90

I have a fps controller structured like this:


this is the hierarchy


Whenever I press e on a pickup weapon prefab, I want to move the weapon to a predefined offset and be the parent of the "Weapons" gameobject under camera.


I have structured the project like this:

  • The weapon pickup prefab has a pickup script that looks like this:

public class WeaponPickup : MonoBehaviour
{
    [SerializeField] private Weapon weapon;

    public void PickUpWeapon(Fighter fighter)
    {
        fighter.EquipWeapon(weapon, transform.position, transform.rotation);
        Destroy(gameObject);
    }
}
  • The Fighter class that is located on the player has the EquipWeapon method that is called from the pickup script

public void EquipWeapon(Weapon weapon, Vector3 pickupPosition, Quaternion pickupRotation)
{
    if (currentWeapon != null)
    {
        currentWeapon.weaponGO.SetActive(false);
    }

    currentWeapon = weapon;
    weaponList.Add(currentWeapon);
    currentWeaponIndex = weaponList.Count - 1;

    currentWeapon.Spawn(pickupPosition, weaponsParent, this);
}
  • I have a scriptable object class that is called Weapon, which has the Spawn method implemented in it:

public void Spawn(Vector3 pickupPosition, Transform weaponParent, Fighter fighter)
{
    if (weaponPrefab != null)
    {
        weaponGO = Instantiate(weaponPrefab);

        fighter.MoveToPos(pickupPosition, weaponParent.TransformPoint(weaponPosition), 1f, weaponGO.transform, weaponParent);
    }
}

--

  • The fighter.MoveToPos calls a corutine that looks like this:

public void MoveToPos(Vector3 startPosition, Vector3 endPosition, float duration, Transform goTransform, Transform weaponParent)
{
    StartCoroutine(LerpPosition(startPosition, endPosition, duration, goTransform, weaponParent));
}

private IEnumerator LerpPosition(Vector3 startPosition, Vector3 endPosition, float duration, Transform goTransform, Transform weaponParent)
{
    float time = 0;
    goTransform.position = startPosition;
    while (time < duration)
    {
        goTransform.position = Vector3.Lerp(startPosition, endPosition, time / duration);
        time += Time.deltaTime;
        yield return null;
    }
    goTransform.position = endPosition;

    goTransform.parent = weaponParent.transform;
}

And the question is when I start the game and pick up the weapon, the weapon appears to lerp from the pickup position to the correct position but then it teleports to a random position.


Other info:

  • WeaponGo in the Weapon class is the refrence to the weapon's gameobject.
  • The lerprotation of the object is not yet implemented.
  • I tried converting every position / Vector3 to world / localPosition and then apply the parenting to the "Weapons" gameobject and it didn't work.

My guess it's that I am not changing correctly the localPosition / world position respectively as the object becomes parented at the end of the lerping.

If you need any other info, please don't hesitate to ask. Any suggestions are greatly appreaciated.

2 Answers

I actually found out what the problem was, I should have used Transform.InverseTransformPoint insted of Transform.TransformPoint.

Huh. At first glance your code looks like it should do what you want. I'd recommend adding some Debug.Log lines to track the local and global positions before and after the parent assignment, out of curiosity. It does seem like it's a local/global positioning issue.

You could try using:

goTransform.SetParent(weaponParent.transform, false);

instead of:

goTransform.parent = weaponParent.transform;

The 'false' bool in SetParent refers is for the 'worldPositionStays' parameter, which seems like it should do the opposite of what your desired result, but since the opposite of your desired result is already happening, maybe that will work?

Related