Как заставить объект вращаться вокруг цели со случайной высотой и с возможностью изменения радиуса вращения?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateAroundTarget : MonoBehaviour
{
    public Transform target;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.RotateAround(target.transform.position, new Vector3(0,1,0), 20 * Time.deltaTime);
        transform.position = new Vector3(0,Random.Range(0,5f),0);
    }
}

RotateAround работал нормально, но как только я добавил часть Random.Range, объект не просто прыгал очень быстро.

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

А как добавить возможность изменения поворота по радиусу вокруг цели?

Попробовал код выше, но он все еще далек от того, что я хотел.

Я попытался использовать InvokeRepeating, но преобразование больше не вращается.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateAroundTarget : MonoBehaviour
{
    public Transform target;

    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating("ChangePosition", 0, 2);
    }

    // Update is called once per frame
    void Update()
    {
        transform.RotateAround(target.transform.position, new Vector3(0,1,0), 20 * Time.deltaTime); 
    }

    private void ChangePosition()
    {
        transform.position = new Vector3(0, Random.Range(0, 5f), 0);
    }
}
Руководство для начинающих по веб-разработке на React.js
Руководство для начинающих по веб-разработке на React.js
Веб-разработка - это захватывающая и постоянно меняющаяся область, которая постоянно развивается благодаря новым технологиям и тенденциям. Одним из...
Разница между Angular и React
Разница между Angular и React
React и AngularJS - это два самых популярных фреймворка для веб-разработки. Оба фреймворка имеют свои уникальные особенности и преимущества, которые...
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
0
0
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Есть пара проблем с вашим кодом. Во-первых, установка позиции с помощью:

transform.position = new Vector3(0,Random.Range(0,5f),0);

Полностью перезапишет любое изменение X/Z, вызванное предыдущим RotateAround. Вот почему ваша ротация остановилась, как только вы ввели этот код. Чтобы установить положение без потери значений X/Z, вы можете использовать:

transform.position = new Vector3(
    transform.position.x,
    Random.Range(0,5f),
    transform.position.z);

Итак, теперь ротация снова работает. Но изменения высоты все еще неустойчивы, потому что ваш код устанавливает новую случайную высоту в каждом кадре. Что мы можем сделать вместо этого?

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

public class RotateAroundTarget : MonoBehaviour
{
    public Transform target;
    public float verticalSpeed = 20;
    public float radius = 10;

    private float targetHeight;

    // Start is called before the first frame update
    void Start()
    {
        // Initialize with a height to start moving toward
        targetHeight = GetNewTargetHeight();

        // If we start at a given distance away from the target, then this
        // will become our radius when we RotateAround it
        transform.position = new Vector3(0, 0, radius);
    }

    // Update is called once per frame
    void Update()
    {
        transform.RotateAround(target.transform.position,
            new Vector3(0,1,0), 20 * Time.deltaTime);

        // Just like your rotation rate, we scale this based on game time
        float maxHeightChange = verticalSpeed * Time.deltaTime;
        float targetHeightDelta = targetHeight - transform.position.y;

        if (maxHeightChange >= Mathf.Abs(targetHeightDelta)){
            // If the current height is close enough to the target, we can move it
            // there and then generate a new height to go towards
            transform.position = new Vector3(
                transform.position.x,
                targetHeight,
                transform.position.z);
            targetHeight = GetNewTargetHeight();
        }
        else{
            // Otherwise, limit the magnitude of the height change by the speed and
            // apply it to the current height
            float allowedHeightChange = Mathf.Clamp(
                targetHeightDelta,
                -maxHeightChange,
                maxHeightChange);
            transform.position = new Vector3(
                transform.position.x,
                transform.position.y + allowedHeightChange,
                transform.position.z);
        }
    }

    private float GetNewTargetHeight()
    {
        return Random.Range(0,5f);
    }
}

Как я могу заставить преобразование вращаться вокруг цели по вертикали? теперь он вращается по горизонтали. я пытался изменить ось внутри RotateAround нового Vector3 (0,1,0) на 1,0,0 или на 0,0,1, играл с ним, но он не вращался по вертикали.

daniel zedek 14.02.2023 20:32

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

daniel zedek 14.02.2023 20:47

@danielzedek Вы правы, это решение предназначено только для вращения вокруг вертикальной оси при изменении высоты. Но для адаптации к оси X или Z для горизонтального вращения не требуется больших изменений. Вам нужно будет изменить 3 вещи: начальное положение объекта, ось вращения и компонент преобразования, который вы устанавливаете случайным образом. Например, если вы хотите вращаться вокруг оси X, вы можете начать с начальной позиции (0, радиус, 0), оси вращения (1, 0, 0) и сосредоточиться на рандомизации преобразования. .position.x вместо y.

Serlite 15.02.2023 00:46

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

Serlite 15.02.2023 00:48

Другие вопросы по теме