Одна из первых проблем, вставших передо мной — показать игроку мир вокруг него.
Собственно, в Unity3D уже есть необходимые компоненты, которые просто можно «навесить» на объект, настроить параметры и всё будет работать…. К примеру, можно взять обычный Standart Assets -> MouseOrbit, или, например, скрипт Камера от третьего лица.
Но мы не ищем лёгких путей
Обращаю внимание, что в этой статье я «изобретаю велосипед» с целью познакомиться с элементарными операциями в Unity3D, изучения классов и операций с объектами. Поэтому, если Вы гуру программирования, то можете проходить мимо =)
Подготовка объектов.
Итак, начнём с того, что создадим какой-нибудь объект (например куб) и привяжем на него камеру (она у нас сейчас только одна — главная камера).
После этого создадим скрипт C#, и назовём его MoveMouse
Написание скрипта.
Изначально нужно было определить позицию мышки.
Это оказалось довольно просто — через класс Input и его параметр mousePosition, который содержит три координаты для каждой из осей — x, y и z.
Итак, заведём внутреннюю переменную MousePos, и будем сохранять в неё координаты текущей позиции мышки. Делать это лучше всего перед отрисовкой экрана в событии Update().
using UnityEngine; using System.Collections; public class MoveMouse : MonoBehaviour { private Vector3 MousePos; void Update () { MousePos = Input.mousePosition; } }
Для удобства, сохраним ссылку на камеру и ссылку на объект, к которому она привязана во внутренних переменных, чтоб всегда можно было к ним обратиться.
При этом мы считаем, что камера привязана именно к тому объекту, вокруг которого будет вращаться. Поэтому ищем этот объект через связь «Родитель-потомок».
Незачем это делать каждый раз, а достаточно будет сделать при создании самой камеры на сцене:
public GameObject go; private Camera goCamera; void Start(){ // Инициализируем кординаты мышки и ищем главную камеру goCamera = camera; go = goCamera.transform.parent.gameObject; }
Итак, у нас уже есть ссылка на камеру, которую будем крутить, ссылка на объект, вокруг которого будем крутить, и координаты мышки.
Добавим условие, что крутить камеру будем только тогда, когда нажата правая клавиша мышки.
Узнать состояние клавиш мышки можно через всё тот-же класс Input. Специально для этого у него есть метод GetMouseButton.
Само перемещение камеры будем располагать в событии FixedUpdate():
void FixedUpdate () { if(Input.GetMouseButton(1)) { // } }
И наконец, мы подошли к самому интересному — определить угол поворота в зависимости от позиции мышки и повернуть камеру.
Коэффициент поворота определить довольно просто: определяем позицию мышки, отнимаем от неё координату середины экрана, и делим получившееся число на размер экрана (отдельно для оси Х и отдельно для Y).
К примеру, мышка находится на координате 852 по оси Х, а размер экрана по ширине равен 1024. Тогда, согласно формуле:
(852-1024)/1024=-0,16796875
Коэффициент -0,16796875 как раз и будет отвечать за угол поворота по оси Х.
private float MyAngle = 0F; void FixedUpdate () { if(Input.GetMouseButton(1)) { MyAngle = 0; MyAngle = ((MousePos.x-(Screen.width/2))/Screen.width); } }
Угол мы рассчитали, теперь осталось только повернуть камеру.
Сделать это можно, используя метод RotateAround класса transform.
goCamera.transform.RotateAround(go.transform.position, goCamera.transform.up, MyAngle);
Примечание.
Внимательные читатели могли заметить, что ось, указанная для поворота по горизонтали указана goCamera.transform.up. Честно говоря, я не знаю почему так, но именно так оно работает.
И теперь то-же самое для поворота по вертикали:
MyAngle = ((MousePos.y-(Screen.height/2))/Screen.height); goCamera.transform.RotateAround(go.transform.position, goCamera.transform.right, -MyAngle);
Вроде-бы можно и закругляться, но есть ещё один момент, который нужно учесть.
Пользователи всегда хотят настраиваемые параметры. И чувствительность мышки обычно стоит на одном из первых мест при настройке игры «под себя».
Давайте учтём это желание в нашем скрипте. Для этого введём параметр чувствительности sensitivity, и будем его использовать как коэффициент, влияющий на угол поворота:
MyAngle = sensitivity*((MousePos.x-(Screen.width/2))/Screen.width); goCamera.transform.RotateAround(go.transform.position, Vector3.up, MyAngle); MyAngle = sensitivity*((MousePos.y-(Screen.height/2))/Screen.height); goCamera.transform.RotateAround(go.transform.position, Vector3.left, MyAngle);
Скрипт целиком.
Вот теперь точно всё, и осталось только показать весь скрипт целиком, с моими комментариями =)
using UnityEngine; using System.Collections; public class MoveMouse : MonoBehaviour { /// <summary> /// Скрипт управления камерой через мышку /// GameObject - объект, к которому привязана камера (вращаемся вокруг этого объекта) /// sensitivity - чувствительность мышки /// </summary> public GameObject go; public float sensitivity = 1F; private Camera goCamera; private Vector3 MousePos; private float MyAngle = 0F; void Start(){ // Инициализируем кординаты мышки и ищем главную камеру goCamera = camera; go = goCamera.transform.parent.gameObject; } void Update () { MousePos = Input.mousePosition; } void FixedUpdate () { if(Input.GetMouseButton(1)) { MyAngle = 0; // расчитываем угол, как: // разница между позицией мышки и центром экрана, делённая на размер экрана // (чем дальше от центра экрана тем сильнее поворот) // и умножаем угол на чуствительность из параметров MyAngle = sensitivity*((MousePos.x-(Screen.width/2))/Screen.width); goCamera.transform.RotateAround(go.transform.position, goCamera.transform.up, MyAngle); MyAngle = sensitivity*((MousePos.y-(Screen.height/2))/Screen.height); goCamera.transform.RotateAround(go.transform.position, goCamera.transform.right, -MyAngle); } } }