Вращение камеры вокруг объекта

Сделать так, чтобы объект вращался вокруг своей оси очень просто, для этого есть функция Rotate. Кроме обычного вращения, еще можно сделать орбиту, по которой будет задано вращение относительно другого объекта, здесь поможет функция RotateAround, достаточно указать цель, ось и скорость. Но что если, нужно чтобы вращение управлялось с помощью мышки? Например, есть некая планета и надо, чтоб камера крутилась вокруг нее. Именно это мы попробуем реализовать в сегодняшнем скрипте. Дополнительно, сделаем небольшую модификацию, чтобы вращение какого-нибудь объекта тоже управлялось мышкой.

C# скрипт CameraRotateAround:

using UnityEngine;
using System.Collections;

public class CameraRotateAround : MonoBehaviour {

	public Transform target;
	public Vector3 offset;
	public float sensitivity = 3; // чувствительность мышки
	public float limit = 80; // ограничение вращения по Y
	public float zoom = 0.25f; // чувствительность при увеличении, колесиком мышки
	public float zoomMax = 10; // макс. увеличение
	public float zoomMin = 3; // мин. увеличение
	private float X, Y;

	void Start () 
	{
		limit = Mathf.Abs(limit);
		if(limit > 90) limit = 90;
		offset = new Vector3(offset.x, offset.y, -Mathf.Abs(zoomMax)/2);
		transform.position = target.position + offset;
	}

	void Update ()
	{
		if(Input.GetAxis("Mouse ScrollWheel") > 0) offset.z += zoom;
		else if(Input.GetAxis("Mouse ScrollWheel") < 0) offset.z -= zoom;
		offset.z = Mathf.Clamp(offset.z, -Mathf.Abs(zoomMax), -Mathf.Abs(zoomMin));

		X = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivity;
		Y += Input.GetAxis("Mouse Y") * sensitivity;
		Y = Mathf.Clamp (Y, -limit, limit);
		transform.localEulerAngles = new Vector3(-Y, X, 0);
		transform.position = transform.localRotation * offset + target.position;
	}
}

Итак, у нас тут есть цель target, вокруг которой будем крутить камеру. Чувствительность мышки, регулируется переменной - sensitivity. И конечно же, предусмотрено смещение offset, на старте, нужно установить позицию таргета и добавить смещение. По поводу, limit, это ограничение по оси Y, если значение будет больше 90, то картинка начнет глючить, поэтому присутствует страховка. Вешаем скрипт на камеру, указываем объект + смещение и собственно смотрим, что получилось.



Если нам нужно вращать объект мышкой, то сделаем упрощенный вариант этого скрипта.

Назовем его ObjectRotate:

using UnityEngine;
using System.Collections;

public class ObjectRotate : MonoBehaviour {

	public float sensitivity = 3; // чувствительность мышки
	private float X, Y;

	void Update ()
	{
		X = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivity;
		Y += Input.GetAxis("Mouse Y") * sensitivity;
		Y = Mathf.Clamp (Y, -90, 90);
		transform.localEulerAngles = new Vector3(-Y, X, 0);
	}
}

Этот скрипт вешаем на тот объект, который хотим вращать.

Комментариев 12

Офлайн
Arik 2 июля 2016
Подскажите как сделать в этом скрипте приближение мышкой
Офлайн
Light 3 июля 2016
Arik, скрипт обновлен, теперь там есть эта возможность.
Офлайн
StrangerNemo 19 июля 2016
Здравствуйте. Допустим у меня есть планета по которой идет персонаж, соответственно нужно чтобы планета крутилась в сторону персонажа, но с меньшей скоростью, так как она больше (проект в 3d). Подскажите пожалуйста как реализовать такой скрипт или может есть ссылка на что-то подобное. Спасибо.
Офлайн
Light 19 июля 2016
StrangerNemo, вращение объекта: transform.Rotate(ось * скорость)
Офлайн
StrangerNemo 19 июля 2016
Это обычное вращение, а мне нужно чтобы в сторону персонажа. Представьте шестерёнки, если одна крутится вправо, то другая будет крутиться влево. Допустим персонаж пошел "вниз" планеты, тогда планета должна крутиться "вверх". По сути "визуально" персонаж всегда должен находиться в центре планеты. Вот как здесь https://youtu.be/TicipSVT-T8 только камера не от первого лица, а вид сверху. Либо тогда должна крутиться не планета, а камера, чтобы "огибала" планету. Извиняюсь за такой объем текста :)
Офлайн
Light 19 июля 2016
StrangerNemo, то есть вращение планеты в противоположную сторону вектора движения?
Офлайн
StrangerNemo 19 июля 2016
Цитата: Light
StrangerNemo, то есть вращение планеты в противоположную сторону вектора движения?

Точно. У вас получилось в двух словах это объяснить ;D
Офлайн
Light 19 июля 2016
StrangerNemo, можно попробовать тот скрипт из видео, убрать вращение камерой, сделать вектор движения всегда transform.forward, перса заставить смотреть на курсор, чтоб он шел в его сторону. А камеру закрепить над ним... как-то так.. Может на эту тему сделаю что-нибудь, посмотрим.
Офлайн
StrangerNemo 19 июля 2016
Цитата: Light
StrangerNemo, можно попробовать тот скрипт из видео, убрать вращение камерой, сделать вектор движения всегда transform.forward, перса заставить смотреть на курсор, чтоб он шел в его сторону. А камеру закрепить над ним... как-то так.. Может на эту тему сделаю что-нибудь, посмотрим.

Спасибо.
Офлайн
SUGAN 27 июля 2017
А что если мне нужно вращать камеру по одной оси вокруг объекта без всяких овсетов?
Офлайн
Falkonio 27 января 2018
Скрипт великолепен, но не могу придумать как исправить вращение после поворота по оси Z. Так как вращение скриптом продолжается в глобальных X и Y, а локальные оси уже не соответствуют.

rotationAngle += Input.GetAxis("Horizontal");
Camera.main.transform.Rotate(Vector3.forward, rotationAngle);

После такого поворота всё начинает вращаться уже неправильно. Думал решить проблему, вложив камеру в пустой объект и вращая по Z только родителя, но не помогло.
Офлайн
Falkonio 27 января 2018
Цитата: SUGAN
А что если мне нужно вращать камеру по одной оси вокруг объекта без всяких овсетов?

Я такой делал скрипт

private float screenYdistance = 15; // отступ от края экрана

mouseX = Input.GetAxis("Mouse X");
mouseY = Input.GetAxis("Mouse Y");

float rotationY = Camera.main.transform.localEulerAngles.y;
float height = Camera.main.transform.position.z;

//Управление зумом
if (scrollWheel != 0) cameraZoom += scrollWheel * zoomSpeed;
cameraZoom = Mathf.Clamp(cameraZoom, zoomMin, zoomMax);

//Управление наклоном
float playerY = Camera.main.WorldToScreenPoint(transform.position).y; //Кэшируем положение в стек
if ((playerY <= Camera.main.pixelHeight - screenYdistance && mouseY < 0) || (playerY >= screenYdistance && mouseY > 0)) //Наклоняем камеру, если игрок в кадре
rotationX -= mouseY * sensitivity;

//Поддержание дистанции
Vector3 position = transform.position - ((transform.position -
Camera.main.transform.position).normalized * cameraZoom);
position = new Vector3(position.x, transform.position.y + cameraZoom / 2, position.z); // корректировка высоты

//Управление вращением и наклоном
Camera.main.transform.RotateAround(transform.position, Vector3.up, mouseX);
Quaternion lookRotation = Quaternion.LookRotation((transform.position + Vector3.up * cameraZoom) - Camera.main.transform.position); //Поворот в точку над игроком
Camera.main.transform.position = (transform.position+Vector3.up*cameraZoom)+lookRotation * Vector3.back * cameraZoom;
Camera.main.transform.localEulerAngles = new Vector3(rotationX, lookRotation.eulerAngles.y, 0);
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика