public (Vector2, float) VirtualMove(Object2D realUser, Object2D virtualUser, Space2D virtualSpace)
    {
        Transform2D virtualUserTransform = virtualUser.transform;

        if (!initializing)
        {
            ResetCurrentState(virtualUserTransform);
            initializing = false;
        }

        if (episode.IsNotEnd())
        {
            if (isFirst)
            {
                isFirst         = false;
                targetPosition  = episode.GetTarget(virtualUserTransform, virtualSpace);
                initialToTarget = targetPosition - virtualUserTransform.localPosition;
                float InitialAngle    = Vector2.SignedAngle(virtualUserTransform.forward, initialToTarget);
                float initialDistance = Vector2.Distance(virtualUserTransform.localPosition, targetPosition);

                virtualTargetDirection = Matrix3x3.CreateRotation(InitialAngle) * virtualUser.transform.forward; // target을 향하는 direction(forward)를 구함
                //realTargetDirection = Matrix3x3.CreateRotation(InitialAngle) * realUser.transform.forward;

                virtualTargetPosition = virtualUser.transform.localPosition + virtualTargetDirection * initialDistance; // target에 도달하는 position을 구함
                //realTargetPosition = realUser.transform.localPosition + realTargetDirection * initialDistance;

                maxRotTime      = Mathf.Abs(InitialAngle) / rotationSpeed;
                maxTransTime    = initialDistance / translationSpeed;
                remainRotTime   = 0;
                remainTransTime = 0;

                initialAngleDirection = Mathf.Sign(InitialAngle);
            }

            float distance = (targetPosition - virtualUserTransform.localPosition).magnitude;
            float angle    = Vector2.SignedAngle(virtualUserTransform.forward, initialToTarget);

            if (remainRotTime < maxRotTime)
            {
                virtualUser.Rotate(initialAngleDirection * rotationSpeed * Time.fixedDeltaTime);
                remainRotTime += Time.fixedDeltaTime;
            }
            else if (remainTransTime < maxTransTime)
            {
                if (isFirst2) // 방향을 동기화
                {
                    isFirst2 = false;
                    SyncDirection(virtualUser, virtualTargetDirection);
                }
                else
                {
                    virtualUser.Translate(virtualUserTransform.forward * translationSpeed * Time.fixedDeltaTime, Space.World);
                    remainTransTime += Time.fixedDeltaTime;
                }
            }
            else
            {
                if (isFirst3) // 위치를 동기화
                {
                    isFirst3 = false;
                    SyncPosition(virtualUser, virtualTargetPosition);
                }
                else
                {
                    episode.DeleteTarget();

                    //Debug.Log(string.Format("realUser: {0}", realUser.transform));
                    //Debug.Log(string.Format("virtualUser: {0}", virtualUser.transform));

                    isFirst  = true;
                    isFirst2 = true;
                    isFirst3 = true;
                }
            }
        }

        UpdateCurrentState(virtualUserTransform);

        return(GetDelta(virtualUserTransform.forward));
    }