Как вращаться вокруг объекта без использования встроенных функций Unity?

#c# #unity3d

#c# #unity3d

Вопрос:

я хочу вращать куб вокруг трубы размером 1×1 с помощью клавиш со стрелками. (слева и справа).

Проблема в том, что я не могу использовать встроенные функции, которые напрямую устанавливают положение и местоположение преобразования. (Например, transform.LookAt, transform.Rotate или transform.RotateAround). Потому что мне нужны векторные значения эйлера вращения и позиции для нескольких элементов, прежде чем я изменю значение преобразования, которое я хочу повернуть.

Я пробовал разные методы, но пока безуспешно.

Я пытался использовать sin-cos для поворота, но не мог понять, как заставить его работать как для поворота, так и для положения.

  _timer  = Time.deltaTime * _larvaSpeed;
 float x = -Mathf.Cos(_timer) * distanceBetweenCenter;
 float y = Mathf.Sin(_timer) * distanceBetweenCenter;
  

Вот чего я хочу добиться. Нажимая вправо или влево, перемещайте и поворачивайте объект вокруг трубы.

То, что я хочу сделать

Результат, который я хочу. (Если я немного нажал клавишу со стрелкой вправо).

конечный результат

Я был бы признателен за любую помощь. Спасибо!

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

1. соедините этот куб как дочерний элемент с пустым игровым объектом и поверните этот пустой игровой объект

2. Как я уже сказал, мне нужна математика, стоящая за этим.

3. вы можете сделать это, используя некоторую функцию в unity, о математическом способе и математике: вы можете использовать x ^ 2 y ^ 2 = r2 для достижения этой цели, x и y — движущаяся ось, а r — радиус (расстояние между кубом и центром трубы)… все, что вам нужно сделать, это сохранить это уравнение истинным, а «r» всегда постоянным… допустим, мы начинаем с x = 0 и y = 4, на втором кадре уменьшаем y как .1 и, используя это x ^ 2 y ^ 2 = r ^ 2, получаем новое значение x, затем преобразуем.position = (новый x, новый y, z);…… я установлю скрипт на ответ

4. Я был бы очень рад, если бы вы могли показать мне пример того, как задать положение и поворот объекта с помощью вашей математики.

5. Когда я это делал, я просто играл с углами и инспектором во время выполнения. Предполагая, что вы вращаетесь только по одной оси, это нормально. В противном случае это может потребовать дополнительной работы.

Ответ №1:

вот решение, использующее математику круга, и я настоятельно рекомендовал не использовать его, это просто для понимания кругового перемещения с использованием уравнения круга, как @FaTaLL спрашивает в комментариях

Уравнение окружности… (x1 — x2) ^ 2 (y1 — y2) ^ 2 = r ^ 2

x1, y1 — позиция куба

x2, y2 — это позиция канала

r — расстояние между кубом и трубой;

 using UnityEngine;

public class Rotating : MonoBehaviour
{
    public GameObject pipe;
    public float Delta;
    Vector3 nextpos;
    bool compareY;
    bool next;
    int switchx;
    float storeVarAxis;
    float x, y, r;
    private void Start()
    {
        next = true;
        switchx = 1;
        compareY = true;
        x = transform.position.x - pipe.transform.position.x;
        y = transform.position.y - pipe.transform.position.y;
        storeVarAxis = y;
        r = Mathf.Sqrt(x * x   y * y);
    }
    private void Update()
    {
        if (next)
        {
            if (compareY == true)
            {
                y -= Delta * Time.deltaTime;
                if (y <= -storeVarAxis)
                {
                    y = -storeVarAxis;
                    compareY = false;
                    switchx = -1;
                }
            }
            else
            {
                y  = Delta * Time.deltaTime;
                if (y >= storeVarAxis)
                {
                    y = storeVarAxis;
                    compareY = true;
                    switchx = 1;
                }
            }
            float v = r * r - y * y;
            x = Mathf.Sqrt(Mathf.Abs(v));
            nextpos = new Vector3(pipe.transform.position.x   x * switchx, pipe.transform.position.y   y, transform.position.z);
            next = false;
        }
        transform.position = Vector3.MoveTowards(transform.position, nextpos, 1f * Time.deltaTime);
        if(Vector3.Distance(transform.position, nextpos) < .05) transform.position = nextpos;
        if (transform.position.x.Equals(nextpos.x) amp;amp; transform.position.y.Equals(nextpos.y)) next = true;
    }
}
  

что ж, рекомендуемый способ — использовать этот простой скрипт

 using UnityEngine;

public class Rotating : MonoBehaviour
{
    public float speed;
    public GameObject pipe;
    float r, angle;
    Vector3 startpos;
    private void Start()
    {
        r = Mathf.Abs(transform.position.y - pipe.transform.position.y);
        angle = 0;
        transform.position = pipe.transform.position;
        startpos = transform.position;
    }
    void Update()
    {
        angle = angle   speed * Time.deltaTime;
        transform.rotation = Quaternion.EulerAngles(0,0, angle);
        transform.position = startpos   (transform.rotation * new Vector3(r, 0, 0));
    }
}
  

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

1. Ты легенда !!. Это было именно то, что я искал. Спасибо за ваше время и объяснение.

2. всегда в работе!

Ответ №2:

Я думаю, что Quaternion * Vector3 — это то, что вы ищете. К счастью, вращение блока в его собственных локальных координатах — это то же самое вращение, которое вам нужно применить к положению блока.

 public float speed; //how fast to rotate
public float radius; //radius of the cylinder
public float angle; //angle around it

void Update()
{

    if (Input.GetKey(KeyCode.LeftArrow))
    {
        angle = angle   speed * Time.deltaTime;
    }

    if (Input.GetKey(KeyCode.RightArrow))
    {
        angle = angle - speed * Time.deltaTime;
    }


    //figure out the rotation (from euler angles i guess??)
    var quat = Quaternion.EulerAngles(new Vector3(0, angle, 0));

    //ok uh what is the box position?? lets just multiply
    var unrotated_position = new Vector3(radius, 0, 0);
    var rotated_position = quat * unrotated_position;

    this.transform.position = rotated_position;

    //oh yea and also rotate the box in its own local coordinates
    this.transform.rotation = quat;
}
  

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

1. Спасибо за ответ. Ваше решение работает очень хорошо.