Unity — продолжить инерцию объекта после остановки перетаскивания?

#c# #unity3d #physics

#c# #unity3d #физика

Вопрос:

Хорошо, итак, у меня есть объект, вращением которого я управляю с помощью наведения курсора мыши в Unity, вот так:

использование UnityEngine; использование System.Коллекции;

 public class ObjectRotator : MonoBehaviour
{

    private float _sensitivity;
    private Vector3 _mouseReference;
    private Vector3 _mouseOffset;
    private Vector3 _rotation;
    private bool _isRotating;

    void Awake()
    {
        _sensitivity = 0.4f;
        _rotation = Vector3.zero;

    }


    //This include 
    void Update()
    {
        if (_isRotating)
        {

            // offset
            _mouseOffset = (Input.mousePosition - _mouseReference);

            // apply rotation
            _rotation.y = -(_mouseOffset.x   _mouseOffset.y) * _sensitivity;

            // rotate
            transform.Rotate(_rotation);

            // store mouse
            _mouseReference = Input.mousePosition;
        }

    }



    void OnMouseDown()
    {
        EndiTweens();
        // rotating flag
        _isRotating = true;

        // store mouse
        _mouseReference = Input.mousePosition;
    }

    void OnMouseUp()
    {
        // rotating flag
        _isRotating = false;
    }

}
  

Это работает хорошо, за исключением того, что после OnMouseUp() объект полностью останавливается. Я хочу, чтобы он немного «скользил», как будто у него есть инерция. Как я могу это реализовать?

Попробовал это, чтобы перейти к значению остановки:

  //This include 
    void Update()
    {
        if(_isRotating amp;amp; _isStopping)
        {
            // apply rotation
            t  = Time.deltaTime * 1.1f;
            float rotDiff = Mathf.Lerp(2f, 0f, t); //some max
            _rotation.y = transform.rotation.y - rotDiff;


            print(_rotation.y);
            transform.Rotate(_rotation);

            if(t >= 1f)
            {
                _isRotating = false;
                _isStopping = false;
                t = 0f;
            }
        }
        else if (_isRotating)
        {

            // offset
            _mouseOffset = (Input.mousePosition - _mouseReference);

            // apply rotation
            _rotation.y = -(_mouseOffset.x   _mouseOffset.y) * _sensitivity;

            // rotate
            transform.Rotate(_rotation);

            // store mouse
            _mouseReference = Input.mousePosition;
        }

    }

    void EndiTweens()
    {
        iTween[] tweens = GetComponents<iTween>();
        foreach (iTween tween in tweens)
        {
            tween.time = 0;
            tween.SendMessage("Update");
        }

    }

    void OnMouseDown()
    {
        EndiTweens();
        // rotating flag
        _isRotating = true;

        // store mouse
        _mouseReference = Input.mousePosition;
    }

    void OnMouseUp()
    {
        // rotating flag
        _isStopping = true;
       _isRotating = false;
    }
  

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

1. Вам нужно определить скорость мыши и применить ее к объекту. что-то вроде mousedelta / deltatime

2. Как только вы найдете эту скорость, вам нужно будет со временем уменьшить ее. Я думаю, вы обнаружите, что вам не следует устанавливать _isRotating = false в своем OnMouseUp методе. После этого вы захотите продолжить обновление.

Ответ №1:

OnMouseUp вы устанавливаете _isRotating = false . Не устанавливайте для этого флага значение false. Добавьте еще один флаг _isStopping и вычислите скорость вращения, уменьшающуюся в каждом кадре. Установите наименьшую скорость скорости примерно на 0,001, после чего установите скорость на 0 или установите _isRotating = false

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

1. Хорошо, смотрите Мой вопрос о том, что я пробовал. У меня нет скорости, потому что я непосредственно применяю вращение и не имею твердого тела. Итак, я попытался изменить значение разности вращения от максимального до нуля, где объект в конечном итоге остановится. Но теперь ничего из этого не работает

2. @UserDude первая проблема OnMouseUp , которую вы забыли удалить _isRotating = false; , Удалите ее. И это может быть единственной проблемой 🙂