2015-12-02 6 views
2

В настоящее время у меня есть скрипт, который перемещает GameObject относительно другого GameObject, как показано в .gif ниже.Генерация динамического вращения

Dynamic Movement *Only*

То, что я до сих пор не понял, как сделать то же самое GameObject вращения относительно позиции другого GameObject таким образом, что она всегда заканчивается с первоначальным вращением, как показано на следующее изображение:

Dynamic Rotation

Итак, теперь, когда у меня есть «Динамическое движение» (как в GIF), как я могу создать «Dynamic Rotation» (как на картинке)?

У меня нет опыта для выполнения такой задачи, и поиск в Интернете тоже не помог, поэтому я бы очень благодарен за готовность к развертыванию скрипта. Спасибо за ответ.

+0

Сколько раз вы хотите повернуть его? только 1 (360 градусов) или 2 экскурсии (720 градусов) или это зависит от расстояния? –

+0

Я хочу повернуть сейчас на 360 градусов, но я хочу, чтобы этот вариант был легко адаптирован позже. –

ответ

0

Одна из возможностей, которая помогла мне в подобных ситуациях, - это функция transform.LookAt. Это позволяет вам всегда сталкиваться с вашей целью. Вы бы поставили что-то вроде transform.LookAt(target.transform) в свой метод Update, и вы всегда будете сталкиваться со своей целью. Как только вы достигнете своей цели, вы можете установить ее на постоянное значение, так как могут возникнуть некоторые проблемы со странными вращениями, если вы не находитесь точно в том же месте, что и ваша цель.

+0

Открытая баунти стоит +200 репутации для готового к развертыванию скрипта! –

0
  • Я предполагаю, что в вашей игре есть метатель, камень и цель. Thrower бросает камень на цель, а скала должна обернуться на 360 градусов.

    private float mag = 0 ;//will be total distance 
    private Vector3 throwerPos ; 
    private Boolean isThrown = false;// you have to set this true whenever you throw a rock. 
    
    void Update() 
    { 
    . 
    . 
    if(isThrown) 
    { 
        mag = (target.position -thrower.position).magnitude;//get distance whenever you throw it. 
        throwerPos = thrower.position; 
        rotateIt(); 
    } 
    } 
    
    void rotateIt() 
    { 
    float currMag = (rock.position - throwerPos).magnitute ;//get current distance between rock and thrower and rotate it depends on distance at the throwing time 
        angle= Mathf.MoveTowards(0,360,currMag/mag); 
        rock.getComponent<Transform>().eulerAngles = new Vector3(
        rock.getComponent<Transform>().eulerAngles.x, 
        rock.getComponent<Transform>().eulerAngles.y, 
        angle); 
        if(angle == 360) 
        { 
         rock.getComponent<Transform>().eulerAngles.z=0; 
         isThrown = false; 
        } 
    } 
    

    Я не выполнял этот код, это может не сработать. Это всего лишь идея. Думаю, есть много способов добиться этого.

+0

В какой GameObject я прикрепляю этот код? –

+0

Рок. Просто используйте getcomponent ... вместо rock.getcom .. это псевдокод. Вам нужно настроить его для своей игры. –

1

Если я правильно понимаю, вы просто хотите убедиться, что объект переворачивает определенное количество времени в воздухе во время полета. Вы можете использовать что-то вроде этого:

using UnityEngine; 
using System.Collections; 

public class RotaionManager : MonoBehaviour { 

    // Motion start point 
    public Transform origin; 
    // Motion end point 
    public Transform destination; 

    // Start and en anle - 360 for single full rotation 
    public float startAngle = 0; 
    public float endAngle = 360; 

    void Update() { 

     // Distance to origin 
     var dstOrigin = Vector3.Distance(origin.position, transform.position); 
     // Distance to destination 
     var dstDestination = Vector3.Distance(destination.position, transform.position); 
     // Parameter 
     float t = (dstDestination + dstOrigin == 0 ? 0 : (dstOrigin/(dstDestination + dstOrigin))); 
     // The angle at current t 
     float angle = Mathf.Lerp(startAngle, endAngle, t); 

     // Rotate the object by the angle, then make sure it also faces destination 
     transform.rotation = Quaternion.LookRotation(destination.position - origin.position) * Quaternion.Euler(angle, 0, 0); 

    } 
} 

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

Посмотрите на образец проекта: https://www.dropbox.com/s/g00srsjlqjx1jcz/RotationProj.zip?dl=0

EDIT

Это может быть лучше использовать расстояние от объекта проекции на вектор исходного назначения вместо сырого расстояния, он выглядит лучше на крутых путях ,Функция обновления будет выглядеть следующим образом:

void Update() { 

    // Projection of object on line between origin and destination 
    var projection = Vector3.Project(transform.position - origin.position, origin.position - destination.position) + origin.position; 
    // Distance to origin 
    var dstOrigin = Vector3.Distance(origin.position, projection); 
    // Distance to destination 
    var dstDestination = Vector3.Distance(destination.position, projection); 
    // Parameter 
    float t = (dstDestination + dstOrigin == 0 ? 0 : (dstOrigin/(dstDestination + dstOrigin))); 
    // The angle at current t 
    float angle = Mathf.Lerp(startAngle, endAngle, t); 

    // Rotate the object by the angle, then make sure it also faces destination 
    transform.rotation = Quaternion.LookRotation(destination.position - origin.position) * Quaternion.Euler(angle, 0, 0); 

} 

Я также обновил пример проекта

EDIT

Другой способ сделать это, который может выглядеть лучше, может быть игнорировать Y координаты начальной и конечной точек, а также проекции. Это выглядит немного лучше в некоторых случаях. Код будет выглядеть следующим образом:

void Update() { 

    Vector3 op = origin.position; op.y = 0; 
    Vector3 dp = destination.position; dp.y = 0; 
    // Projection of object on line between origin and destination 
    var projection = Vector3.Project(transform.position - origin.position, op - dp) + op; 
    // Distance to origin 
    var dstOrigin = Vector3.Distance(op, projection); 
    // Distance to destination 
    var dstDestination = Vector3.Distance(dp, projection); 
    // Parameter 
    float t = (dstDestination + dstOrigin == 0 ? 0 : (dstOrigin/(dstDestination + dstOrigin))); 
    // The angle at current t 
    float angle = Mathf.Lerp(startAngle, endAngle, t); 

    // Rotate the object by the angle, then make sure it also faces destination 
    transform.rotation = Quaternion.LookRotation(dp - op) * Quaternion.Euler(angle, 0, 0); 

} 
+0

Отличный ответ. Но ваши сценарии, похоже, работают правильно на оси X и Z, но не на оси Y. Проверьте [this] (http://s17.postimg.org/70dgr072l/GIF.gif). –

+1

Посмотрев на это, я понял, что точка проецирования вычисляется неправильно, что делает поворот неточным, когда источник и место назначения не имеют одинаковой высоты. Обновлен ответ правильным способом. Я также обновил образец проекта, чтобы проиллюстрировать случай, когда происхождение или назначение перемещаются по оси Y. –

+0

С последним правлением куб не правильно вращается в определенных положениях. Проверьте [this] (http://s13.postimg.org/dj9h2c7x3/GIF2.gif). –

Смежные вопросы