0
\$\begingroup\$

When the transform is start moving it's like "jumping" to a position near the position it is now and start moving from that position and not the position the transform is currently at.

It was working before but i can't figure out why it's not now. The transform does moving to the target but ot starting moving from it's current position but from a nearby position.

Things to clear :

  • The transform start as child of another object.

  • The target is the destinationTransform variable.

  • The transform is child of fingers of hand of my character and the character have animator so when the character is in idle animation his body is moving including the hands.

This screenshot image show the transform as child before running the game. This is the transform originPosition in the Start() but then when running the game the idle animation make the hand moving so the transform originPosition has changed and keep changing because the idle animation so the originPosition in the Start() is anymore the real originPosition.

originPosition at Start()

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Cinemachine;

public class MoveToTarget : MonoBehaviour
{
    public enum TransitionState
    {
        None,
        MovingTowards,
        Transferring
    }

    public Transform destinationTransform;
    public bool isChild = false;
    public AnimationCurve curve = AnimationCurve.EaseInOut(0.0f, 0.0f, 1.0f, 1.0f);
    public float duration = 10.0f;
    public bool go = false;

    private float t;
    private Transform originTransform;
    private float timer;
    private TransitionState state = TransitionState.MovingTowards;
    private Vector3 originPosition;
    private SphereCollider col;
    private bool enableCollider = true;

    void Start()
    {
        t = 0.0f;

        curve.postWrapMode = WrapMode.Once;
        originPosition = transform.position;
        col = GetComponent<SphereCollider>();
    }

    void Update()
    {
        if (go)
        {
            if (col != null && enableCollider)
            {
                Destroy(col);
                Destroy(transform.GetComponent<Rigidbody>());
                enableCollider = false;
            }

            switch (state)
            {
                case TransitionState.MovingTowards:
                    var v = destinationTransform.position - transform.position;
                    if (v.magnitude < 0.001f)
                    {
                        state = TransitionState.Transferring;
                        originTransform = destinationTransform;
                        timer = 0;
                        return;
                    }

                    t += Time.deltaTime;
                    float s = t / duration;

                    transform.position = Vector3.Lerp(originPosition,
                        destinationTransform.position, curve.Evaluate(s));

                    break;

                case TransitionState.Transferring:
                    timer += Time.deltaTime;
                    this.transform.position = Vector3.Lerp(originTransform.position, destinationTransform.position, timer);

                    if (timer >= 1.0f)
                    {
                        this.transform.parent = destinationTransform;
                        transform.localPosition = new Vector3(0, 0, 0);
                        isChild = true;

                        go = false;

                        state = TransitionState.None;
                        this.enabled = false;
                        return;
                    }
                    break;

                default:
                    this.enabled = false;
                    return;
            }
        }
    }
}
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I found a solution.

I added a new flag boolean variable called updateOriginPosition. Then, I update the originPosition variable in the Update() function once instead of in the Start() function.

void Update()
{
    if (go)
    {
        if (updateOriginPosition == true)
        {
            originPosition = transform.position;
            updateOriginPosition = false;
        }
        // ...
    }
    // ...
}

And the script after the changes.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Cinemachine;

public class MoveToTarget : MonoBehaviour
{
    public enum TransitionState
    {
        None,
        MovingTowards,
        Transferring
    }

    public Transform destinationTransform;
    public bool isChild = false;
    public AnimationCurve curve = AnimationCurve.EaseInOut(0.0f, 0.0f, 1.0f, 1.0f);
    public float duration = 10.0f;
    public bool go = false;

    private float t;
    private Transform originTransform;
    private float timer;
    private TransitionState state = TransitionState.MovingTowards;
    private Vector3 originPosition;
    private SphereCollider col;
    private bool enableCollider = true;
    private bool updateOriginPosition = true;

    void Start()
    {
        t = 0.0f;

        curve.postWrapMode = WrapMode.Once;
        col = GetComponent<SphereCollider>();
    }

    void Update()
    {
        if (go)
        {
            if (updateOriginPosition == true)
            {
                originPosition = transform.position;
                updateOriginPosition = false;
            }

            if (col != null && enableCollider)
            {
                //col.enabled = false;
                //transform.GetComponent<Rigidbody>().isKinematic = true;

                Destroy(col);
                Destroy(transform.GetComponent<Rigidbody>());
                //transform.GetComponent<InteractableItem>().enabledInteraction = false;

                enableCollider = false;
            }

            switch (state)
            {
                case TransitionState.MovingTowards:
                    var v = destinationTransform.position - transform.position;
                    if (v.magnitude < 0.001f)
                    {
                        state = TransitionState.Transferring;
                        originTransform = destinationTransform;
                        timer = 0;
                        return;
                    }

                    t += Time.deltaTime;
                    float s = t / duration;

                    transform.position = Vector3.Lerp(originPosition,
                        destinationTransform.position, curve.Evaluate(s));

                    break;

                case TransitionState.Transferring:
                    timer += Time.deltaTime;
                    this.transform.position = Vector3.Lerp(originTransform.position, destinationTransform.position, timer);

                    if (timer >= 1.0f)
                    {
                        this.transform.parent = destinationTransform;
                        transform.localPosition = new Vector3(0, 0, 0);
                        isChild = true;

                        go = false;

                        state = TransitionState.None;
                        this.enabled = false;
                        return;
                    }
                    break;

                default:
                    this.enabled = false;
                    return;
            }
        }
    }
}
```
\$\endgroup\$
1
  • \$\begingroup\$ If that helped you, please mark it as accepted \$\endgroup\$
    – Arian_ki
    Mar 21, 2022 at 18:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .