Как я могу медленно перемещать гладкий объект, чтобы он был дочерним для другого объекта?

#c# #unity3d

#c# #unity3d

Вопрос:

 if(crate.gameObject.GetComponent<UnlockCrate>().HasOpened())
                    {
                        primaryTarget = navi;

                        var rig_f_middle = GameObject.Find("rig_f_middle.02.R");
                        navi.transform.parent = rig_f_middle.transform;
                        navi.transform.localPosition = new Vector3(0, 0, 0);
                        navi.transform.rotation = rig_f_middle.transform.parent.rotation;
                        navi.transform.localScale = new Vector3(0.0005999999f, 0.0006000001f, 0.0006f);
                        primaryTarget = null;                       
                    }
  

Это просто меняет положение navi, но вместо этого я хочу, чтобы оно двигалось плавно и медленно, чтобы быть дочерним элементом rig_f_middle.

На скриншоте NAVI находится почти на вершине иерархии и является дочерним по отношению к другому объекту, и он должен плавно медленно перемещаться к нижнему выбранному rig_f_middle.02.R (в моем коде это rig_f_middle).

NAVI и rig_f_middle.02.R

Таким образом, NAVI переместится в руку игрока, и игрок будет держать NAVI.

Это то, что я пробовал :

 if(crate.gameObject.GetComponent<UnlockCrate>().HasOpened())
                    {
                        primaryTarget = navi;

                        var rig_f_middle = GameObject.Find("rig_f_middle.02.R");
                        StartCoroutine(MoveNavi(navi.transform, rig_f_middle.transform, navi.transform.position, rig_f_middle.transform.position, 0.1f));                        
                        navi.transform.localScale = new Vector3(0.0005999999f, 0.0006000001f, 0.0006f);

                    }
  

Затем в сопрограмме :

 IEnumerator MoveNavi(Transform navi, Transform rig_f_middle, Vector3 a, Vector3 b, float speed)
    {
        float step = (speed / (a - b).magnitude) * Time.fixedDeltaTime;
        float t = 0;
        while (t <= 1.0f)
        {
            t  = step;
            navi.position = Vector3.Lerp(a, b, t);

            if(Vector3.Distance(a, b) < 0.05f)
            {
                navi.parent = rig_f_middle.transform;
                navi.localPosition = new Vector3(0, 0, 0);
                navi.localRotation = rig_f_middle.parent.localRotation;
            }

            yield return new WaitForFixedUpdate();
        }
        navi.position = b;
    }
  

Объект NAVI движется нормально, а затем, когда расстояние меньше 0,05f, он делает его дочерним, но проблем немного :

  • NAVI после того, как он стал дочерним, его положение и поворот никогда не устанавливались на 0,0,0, я пробовал это :

    navi.localPosition = новый Вектор3(0, 0, 0); navi.localRotation = rig_f_middle.parent.localRotation;

  • Когда NAVI приближается и находится под рукой, происходит своего рода скачок / сбой, когда он становится дочерним.

Если это необходимо, я добавлю завершенный скрипт.

Ответ №1:

После того, как объект будет дочерним, он будет перемещаться вместе с родительским. Вы не можете постепенно становиться дочерним. Однако вы можете изначально выбрать не дочерний, затем плавно перемещаться к предполагаемой родительской позиции, и как только расстояние будет меньше 0,05 или что-то в этом роде, вы можете использовать его дочерним.

Вы можете плавно перемещаться, используя Vector3.MoveTowards. https://docs.unity3d.com/ScriptReference/Vector3.MoveTowards.html

Вы можете проверить расстояние с помощью Vector3.Distance. https://docs.unity3d.com/ScriptReference/Vector3.Distance.html

Комментарии:

1. Я обновил свой вопрос тем, что я пробовал, я использую сопрограмму и Lerp вместо MoveTowards по какой-то причине я не добился успеха с MoveTowards. а также добавлены две проблемы, с которыми я сталкиваюсь сейчас.

2. Вероятно, вы не хотите устанавливать локальное вращение объекта на локальное вращение родительского объекта. Если вы установите локальное вращение объекта на значение Quaternion.identity, то оно будет равно 0, что делает его таким же вращением, как и родительский. Что касается скачка / сбоя, это, вероятно, потому, что единицы 0.05f могут быть слишком далеко. Но поскольку вы используете Lerp, это легко исправить. Вместо проверки расстояния просто проверьте, если t> = 1.0f, чтобы узнать, завершено ли оно.