#unity3d #camera #uibutton #lerp
#unity3d #камера #uibutton #lerp
Вопрос:
Использование нескольких кнопок пользовательского интерфейса для попытки изменить положение основных камер на разные виды. Я не хочу менять сцену. Я смотрю на один объект, скажем, на автомобиль, и я хочу увидеть фары головного света, я хочу нажать кнопку, чтобы переместить основную камеру, чтобы увидеть фары головного света, и появится всплывающее окно с текстом «Фары». Затем я хочу перейти к режиму BrakeLights, я нажимаю кнопку break lights, и основная камера перемещается в область break light, где появляется еще один всплывающий текст с надписью «break lights». Для каждой детали автомобиля есть несколько кнопок, я застрял, новичок в Unity и ищу помощи.
Комментарии:
1. Попробуйте пакет cinemachine. Если вы ищете облегченный вариант, есть бесплатный ресурс под названием Fungus с простыми возможностями переключения положения камеры.
2. Я проверю это. Я импортировал ее, но мне придется поиграть с ней, чтобы увидеть, что происходит. Спасибо!
Ответ №1:
Если я вас правильно понимаю, у вас есть несколько кнопок, и нажатие каждой из них переместит вашу основную камеру в место, соответствующее этой кнопке. Что вы должны сделать, это:
-
Создайте скрипт, который сохраняет текст, который вы хотите отобразить, а также положение и поворот камеры. Прикрепите его к игровым объектам каждой из кнопок.
-
Затем создайте функцию в этом скрипте для установки текста и положения / поворота камеры. Сценарий должен выглядеть примерно так:
using UnityEngine;
using UnityEngine.UI;
public class CameraSwitch : MonoBehaviour
{
public Text UILabel;
public string text;
public Vector3 cameraPos;
public Vector3 cameraRot;
public void SwitchToHere()
{
Camera.main.transform.position = cameraPos;
Camera.main.transform.rotation = Quaternion.Euler(cameraRot);
UILabel.text = text;
}
}
-
Вернитесь к Unity. В каждом из событий OnClick кнопки подписывайтесь (добавляйте) на ту функцию, которую вы только что создали. (Обязательно добавьте функцию из скрипта, прикрепленного к этой кнопке)
-
Измените текст на любой, который вы хотите, и установите cameraPos и cameraRot так, как вы хотите, чтобы камера переключалась при нажатии этой кнопки.
Вот видео, на котором я делаю все это: https://youtu.be/L621IcEBAtU
Это определенно сработает, но переход между каждым пятном происходит мгновенно. Если вы хотите плавный переход, вы можете либо использовать пакет cinemachine, либо изменить сценарий.
Комментарии:
1. Спасибо за помощь. Я пробовал это, и оно отлично работает. Я собираюсь также попробовать другие упомянутые, чтобы посмотреть, что еще можно добавить или улучшить. Я не был очень конкретен в своем вопросе, и это моя ошибка, но ваш ответ действительно помог.
Ответ №2:
Если вы хотите, для каждой позиции вы могли бы создать две Vector3
‘ы, одну для позиции, в которой вы хотели бы, чтобы камера находилась, а другую, к которой вы хотели бы, чтобы камера была обращена.
public Vector3 cameraPos;
public Vector3 cameraLootAkPos;
public void ChangeCameraTransform()
{
Camera.main.transform.position = cameraPos;
Camera.main.transform.LookAt(cameraLootAkPos);
}
Я сделал свою собственную версию этого, если вы хотите ее использовать. Вышеупомянутая версия обеспечивает мгновенный переход, а та, что включена ниже, переходит более плавно во время выполнения. вы можете рассмотреть возможность дальнейшего использования таких вещей, как Mathf.Lerp
public class ChangeCamera : MonoBehaviour
{
// You can populate each list with the appropriate positions. Making sure they are in order from 0 upward
public List<Vector3> CameraPositions;
public List<Vector3> CameraLookAtPositions;
public Vector3 LookAtTarget;
// to see which camera configuration we should use.
public int CamConfig;
float moveSpeed = .5f;
float rotSpeed = .5f;
public Transform MainCamera;
void Update()
{
if (MainCamera.position != CameraPositions[CamConfig])
{
MainCamera.position = Vector3.MoveTowards(MainCamera.position, CameraPositions[CamConfig], moveSpeed);
}
LookAtTarget = Vector3.MoveTowards(LookAtTarget, CameraLookAtPositions[CamConfig], rotSpeed);
MainCamera.LookAt(LookAtTarget);
}
public void ChangeCameraConfig(int ConfigNo)
{
CamConfig = ConfigNo;
}
}
Комментарии:
1. Я попробовал это, и это помогло. Я ценю это и посмотрю, смогу ли я использовать это больше. Еще раз спасибо.
2. Привет, я включил обновление моей собственной рабочей реализации, возможно, это поможет вам добиться более плавного результата, который вы искали; D
Ответ №3:
В качестве упражнения я попытался написать простой скрипт на C #, чтобы сделать что-то вроде того, что вы описали выше. Я надеюсь, что это поможет в качестве отправной точки для вашего собственного:
using UnityEngine;
public class CamSwitcher : MonoBehaviour {
public CamSpotInfo[] spots;
[Range(0.1f, 3.0f)] public float anim_speed = 0.3f;
protected int idx = 0;
protected float t_accum = 0.0f;
void Update() {
Transform cam = Camera.main.transform;
cam.position = Vector3.Lerp(cam.position, spots[idx].transform.position, t_accum);
cam.LookAt(spots[idx].target); /* TODO: interpolate target positions */
t_accum = Time.deltaTime * anim_speed;
}
void OnGUI() {
if (GUI.Button(new Rect(10, 70, 200, 30), "next spot: " spots[idx].name)) {
if ( idx >= spots.Length)
idx = 0;
t_accum = 0.0f;
}
}
}
[System.Serializable]
public class CamSpotInfo {
public Transform transform;
public Transform target;
public string name;
}
Чтобы назначить массиву новые «точки камеры», сначала установите «Размер» вручную в инспекторе Unity, а затем перетащите новые игровые объекты / преобразования из окна иерархии сцен в отдельные элементы массива в инспекторе (это могут быть, например, просто пустые игровые объекты, указывающие положение камеры для каждой «точки камеры»). Затем назначьте цели камеры каждому элементу в массиве, вы хотите, чтобы основная камера смотрела на каждую «точку камеры» (например, колеса). И, наконец, введите имя для каждого элемента, который будет отображаться на кнопке графического интерфейса.
В этом примере в режиме воспроизведения будет отображаться только одна кнопка графического интерфейса, которая используется для переключения на следующую «точку» в массиве. Но вы можете легко изменить сценарий, чтобы камера переключалась на определенные элементы напрямую…
(Не уверен, что это действительно хороший вопрос для этого сайта, поскольку он довольно открытый, поскольку существует множество различных способов поиска возможных решений для такой функции (задействовано множество различных областей, таких как контроллер движения камеры, интерполяция пути, графический интерфейс и т.д.)).
РЕДАКТИРОВАТЬ: несколько кнопок графического интерфейса
Вот модифицированная версия сценария выше, которая использует несколько кнопок графического интерфейса, по одной для каждой точки камеры. Каждая из них может быть включена / отключена в инспекторе с помощью флажка «Показывать графический интерфейс»:
using UnityEngine;
public class CamSwitcher : MonoBehaviour {
public CamSpotInfo[] spots;
[Range(0.1f, 3.0f)] public float animSpeed = 0.3f;
protected uint idx = 0;
protected float t = 0.0f;
void Update() {
Transform cam = Camera.main.transform;
Vector3 dir_target = spots[idx].target.position - cam.position;
Quaternion roti = Quaternion.LookRotation(dir_target);
cam.position = Vector3.Lerp(cam.position, spots[idx].transform.position, t);
cam.rotation = Quaternion.Slerp(cam.rotation, roti, t);
t = Time.deltaTime * animSpeed;
}
void OnGUI() {
Rect rect = new Rect(10, 70, 200, 30);
for (uint i=0; i<spots.Length; i) {
if (spots[i].showGUI) {
if (GUI.Button(rect, "switch to " spots[i].name)) {
idx = i;
t = 0.0f;
}
rect.y = rect.height 5;
}
}
}
}
[System.Serializable]
public class CamSpotInfo {
public Transform transform;
public Transform target;
public string name;
public bool showGUI = true;
}
Комментарии:
1. Да, это была моя ошибка в неопределенном вопросе. У меня было что-то похожее на пустой объект, у которого было положение камеры, которое я хотел изначально, и использовал if, else if, else для индекса элементов, но, думая о большем масштабе, я пытался найти другие решения. По сути, идея заключается в том, чтобы создать игровой объект, представляющий собой сборку со многими дочерними элементами (отдельными частями, составляющими транспортное средство). Я подумал, может быть, об использовании боковой панели прокрутки, в которой есть кнопка сборки и автоматическое заполнение для каждого дочернего элемента. При нажатии кнопки основная камера поворачивается, чтобы увидеть деталь и отобразить информацию. спасибо за помощь.
2. Привет! Я добавил версию с несколькими кнопками (но без прокрутки или каких-либо других продвинутых элементов пользовательского интерфейса). Надеюсь, это поможет! — Если ваш объект car является сборным, вы все равно можете перетащить дочерние объекты в массив в качестве целей камеры. — Для автоматического заполнения «массива cam spot», возможно, вы могли бы использовать теги Unity, чтобы отметить важные части, которые должны быть добавлены в массив с помощью (другого) скрипта. Или вместо этого вы могли бы добавить специальные «сценарии маркеров» к важным частям модели, которые также содержат заголовок, ссылку на соответствующее преобразование камеры и т.д. (см.: Компонент. GetComponentsInChildren в документах).