Валка дерева в случайном направлении? - PullRequest
0 голосов
/ 28 апреля 2020

Я не могу понять, как заставить дерево со случайным вращением Y упасть после его вырубки. Я хочу, чтобы он падал, пока он не будет перпендикулярен земле (90 градусов), но я хочу, чтобы он был случайным, в каком направлении он падает.

Шарнир находится на нижней части дерева, поэтому, если я просто поверните ось Z на 90 градусов, после чего все выглядит так, как будто она падает, но я хочу случайным образом определить направление, я попробовал кое-что, но он не выполняет то, что я ожидаю:

public void Fall(float duration)
{
    int xOrZ = Random.Range(0, 1);
    float randomRot = Random.Range(0,90);

    Vector3 rotation = Vector3.zero;

    if (xOrZ == 0)
        rotation = new Vector3(90, 0, randomRot);
    else
        rotation = new Vector3(randomRot, 0, 90);

    mTransform.DORotate(rotation, duration);
}

Я подумал, что убедился в одном оси составляет 90, тогда она всегда будет падать на землю, но это не сработало вообще.

1 Ответ

1 голос
/ 28 апреля 2020

Поскольку шарнир вашего объекта находится внизу, Lerp вектор transform.up дерева GameObject проще, чем он начинает наклоняться. Вы можете выбрать точку внутри окружности, используя Unity's Random.InsideUnitCircle. Это вернет Vector2, тогда вы можете умножить каждый компонент на ваш правый и прямой векторы, чтобы найти, где будет вершина дерева, когда оно упадет. Теперь вектор между положением объекта дерева и точкой падения должен быть вашим новым вектором вверх для объекта дерева. Затем вы можете запустить простую сопрограмму, которая переводит вектор вверх объекта дерева в недавно вычисленный вектор роста. Lerp позволяет вам определить длительность, и вы можете отключить сопрограмму, как только расстояние между требуемым вектором повышения и текущим вектором роста станет ниже определенного порога. Если вы используете этот код и вызываете функцию «Падение» именно так, как вам хотелось бы, она будет работать:

    using System.Collections; // for IEnumerator

    public GameObject treeObject; // assuming this is your tree object

    public void Fall(float duration)
    {
        // pick a random point on the circle to match the up vector
        Vector2 pointOnCircle = UnityEngine.Random.insideUnitCircle * treeObject.transform.localScale.y;

        // find the fall point, assuming the pivot of the object is at the bottom
        Vector3 fallPoint = treeObject.transform.position + 
            pointOnCircle.x * treeObject.transform.right + 
            pointOnCircle.y * treeObject.transform.forward;

        // find the target up vector
        Vector3 updatedUpVector = Vector3.Normalize(fallPoint - treeObject.transform.position);

        // Start the coroutine to tilt the up vector to the desired target
        StartCoroutine(UpdateUpVector(treeObject, updatedUpVector, duration, 0.001f));
    }

    public IEnumerator UpdateUpVector(GameObject target, Vector3 upVector, float duration, float threshold = 0.001f)
    {
        // the target vector and up vector would get closer to each other until the threshold is hit
        while(Vector3.Distance(upVector, target.transform.up) > threshold)
        {
            target.transform.up = Vector3.Lerp(target.transform.up, upVector, duration * Time.deltaTime);
            yield return new WaitForEndOfFrame();
        }
    }

В результате приведенный выше код приводит к использованию цилиндра с шарниром внизу. Обратите внимание, что дерево падает в направлении случайной точки на единичном круге, которая находится вокруг transform.position объекта дерева .:

imagetransform.position of the tree object.">

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...