Знающий
Регистрация: 31.07.2008
Сообщений: 321
Написано 108 полезных сообщений (для 229 пользователей)
|
Ответ: Передача переменной в метод
камера наследует движение от цели как дочерний объект, пробовал вместо трансформа цели поставить трансформ камеры - то же самое.
Вот код целиком. Функция подобного движения активируется при долгом нажатии на левую кнопку мыши. Все действия в функциях с пометкой Slide

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class CameraNavigation : MonoBehaviour {
public Transform CameraTransform; //основа навигации камеры
public Transform CameraTarget, CameraRotate, CameraView; //цель камеры
public Transform Cursor;
public Camera RealCamera;
private float Speed, SpeedX, SpeedY, RealSpeedX, RealSpeedY, SpeedXFrom, SpeedYFrom; // эталонная скорость по координатам, реальная скорость, слепки для скорости
public int ScreenWidth, ScreenHeight; // размеры экрана
public bool inInertia; //инерция камеры
public List<float> Borders = new List<float>(); //список экранных маркеров
public enum GetBordersInfo {None,Left,Right,Up,Down,UpLeft,UpRight,DownLeft,DownRight}; // присвоение попавшей рамки
private GetBordersInfo BordersInfo, BordersInfoSave; //контейнер для хранения маркеров и слепка маркеров
public float InertiaTime, InertiaTimeScale, SlideTime, SlideTrigger; // время инерции и скорость инерции
public enum SlideStatus {Idle,Calc,Run}; // стадия слайда
public SlideStatus ActiveSlideStatus;
const float ScreenPercent = 0.01f; // размер рамки
public float MouseXCord, MouseYCord, MouseX, MouseY; // данные о мыши
public Vector3 MoveVector, SlideVector, SlideMem,SlideStart; //вектор перемещения, вектор скольжения,вектор слепка, вектор старта скольжения
public Vector2 StartSlidePos,SlidePos;
public float RotSpeed, ZoomDistance, Zooming, SlideSpeed; // скорость вращения
private float SlideSecond;
private Vector3 velocity = Vector3.zero;
public Ray Position_on_plane;
public RaycastHit RayInfo;
public Vector3 PointRay, CursorPosition;
void Start () {
Screen.showCursor = true;
ScreenWidth = Screen.width;
ScreenHeight = Screen.height; // размеры экрана
CameraTransform = transform; // трансформации камеры для перемещения
Speed = 0.1f; // скорость движения камеры
RotSpeed = 100f;
SlideSpeed = 10f;
InertiaTimeScale = 3f; // скорость движения во время инерции
SlideTrigger = SlideSecond = 0.2f; // время включения режима скольжения, частота съема слепка для слайда в секундах
inInertia = false;
ActiveSlideStatus = SlideStatus.Idle;
Borders.Add ((float)ScreenWidth*ScreenPercent); // 0 - слева
Borders.Add ((float)ScreenWidth*(1-ScreenPercent)); // 1 - справа
Borders.Add ((float)ScreenHeight*ScreenPercent); // 2 - сверху
Borders.Add ((float)ScreenHeight*(1-ScreenPercent)); // 3 - снизу
CameraTarget.position = new Vector3(0,0,0); // установка цели камеры
CameraView.position = new Vector3 (0,0,-5); // установка расстояния до цели
CameraRotate.position = CameraTarget.position; // выравнивание позиции цели и основы вращения
CameraRotate.rotation = CameraTarget.rotation; // выравнивание вращения цели и основы вращения
RotateCamera(); // запуск ограничителя высоты поворота
}
// Update is called once per frame
void Update () {
MouseX = Input.GetAxis("Mouse X"); // отклонение мыши Х
MouseY = Input.GetAxis("Mouse Y"); // отклонение мыши У
Zooming = Input.GetAxis("Mouse ScrollWheel");
Camera_Navigation();
}
public void CheckInBorders () { // проверка попадания в рамки
MouseXCord = Input.mousePosition.x;
MouseYCord = Input.mousePosition.y; // координаты мыши
if (!inInertia) { // если работает инерция то
BordersInfoSave = BordersInfo; // сделать слепок текущего квадрата экрана
if ((MouseXCord <= Borders[0])&&(BordersInfo != GetBordersInfo.Left)) BordersInfo = GetBordersInfo.Left; // мышь в левой части
if ((MouseXCord >= Borders[1])&&(BordersInfo != GetBordersInfo.Right)) BordersInfo = GetBordersInfo.Right; // мышь в правой части
if ((MouseYCord <= Borders[2])&&(BordersInfo != GetBordersInfo.Down)) BordersInfo = GetBordersInfo.Down; // мышь в нижней части
if ((MouseYCord >= Borders[3])&&(BordersInfo != GetBordersInfo.Up)) BordersInfo = GetBordersInfo.Up; // мышь в верхней части
if ((MouseXCord <= Borders[0])&&(MouseYCord >= Borders[3])&&(BordersInfo != GetBordersInfo.UpLeft)) BordersInfo = GetBordersInfo.UpLeft; // Лево-вверх
if ((MouseXCord >= Borders[1])&&(MouseYCord >= Borders[3])&&(BordersInfo != GetBordersInfo.UpRight)) BordersInfo = GetBordersInfo.UpRight; // Право-вверх
if ((MouseXCord <= Borders[0])&&(MouseYCord <= Borders[2])&&(BordersInfo != GetBordersInfo.DownLeft)) BordersInfo = GetBordersInfo.DownLeft; // Лево-Вниз
if ((MouseXCord >= Borders[1])&&(MouseYCord <= Borders[2])&&(BordersInfo != GetBordersInfo.DownRight)) BordersInfo = GetBordersInfo.DownRight; // Право-Вниз
if ((MouseXCord >= Borders[0])&&(MouseXCord <= Borders[1])&&(MouseYCord >= Borders[2])&&(MouseYCord <= Borders[3])&&(BordersInfo != GetBordersInfo.None)) BordersInfo = GetBordersInfo.None; // Курсор в центральной части
}
if (BordersInfoSave != BordersInfo) { // при смене квадрата
SpeedXFrom = SpeedX;
SpeedYFrom = SpeedY; // начальное значение скорости
inInertia = true; // включить инерцию
InertiaTime = 0f; // запустить таймер инерции
ChangeSpeed (); // расчитать конечную скорость
BordersInfoSave = BordersInfo; // сохранить текущий квадрат
}
if (inInertia)
{ // если инерция включена
InertiaTime += Time.deltaTime; // отчет времени
RealSpeedX = Mathf.Lerp(SpeedXFrom, SpeedX, InertiaTime*InertiaTimeScale); // плавное изменение скорости Х
RealSpeedY = Mathf.Lerp(SpeedYFrom, SpeedY, InertiaTime*InertiaTimeScale);// плавное изменение скорости У
if ((RealSpeedX == SpeedX)&&(RealSpeedY == SpeedY)) inInertia = false; // если скорость достигнута - отключить инерцию
}
}
public void ChangeSpeed () { // изменение скорости
switch (BordersInfo) { // куда перешел курсор мыши
case GetBordersInfo.Left:
SpeedX = -Speed;
SpeedY = 0f; // значения скорости
break;
case GetBordersInfo.Right:
SpeedX = Speed;
SpeedY = 0f; // значения скорости
break;
case GetBordersInfo.Up:
SpeedY = Speed;
SpeedX = 0f; // значения скорости
break;
case GetBordersInfo.Down:
SpeedY = -Speed;
SpeedX = 0f; // значения скорости
break;
case GetBordersInfo.UpLeft:
SpeedX = -Speed;
SpeedY = Speed; // значения скорости
break;
case GetBordersInfo.DownLeft:
SpeedX = SpeedY = -Speed; // значения скорости
break;
case GetBordersInfo.UpRight:
SpeedX = SpeedY = Speed; // значения скорости
break;
case GetBordersInfo.DownRight:
SpeedX = Speed;
SpeedY = -Speed; // значения скорости
break;
case GetBordersInfo.None:
SpeedX = SpeedY = 0f; // значения скорости
break;
}
}
public void CheckKeyBoardRule () { // управление с клавиатуры
if (BordersInfo == GetBordersInfo.None) {
if (Input.GetKey(KeyCode.LeftArrow)) BordersInfo = GetBordersInfo.Left;
if (Input.GetKey(KeyCode.RightArrow)) BordersInfo = GetBordersInfo.Right;
if (Input.GetKey(KeyCode.UpArrow)) BordersInfo = GetBordersInfo.Up;
if (Input.GetKey(KeyCode.DownArrow)) BordersInfo = GetBordersInfo.Down;
if (Input.GetKey(KeyCode.LeftArrow)&&Input.GetKey(KeyCode.UpArrow)) BordersInfo = GetBordersInfo.UpLeft;
if (Input.GetKey(KeyCode.LeftArrow)&&Input.GetKey(KeyCode.DownArrow)) BordersInfo = GetBordersInfo.DownLeft;
if (Input.GetKey(KeyCode.RightArrow)&&Input.GetKey(KeyCode.UpArrow)) BordersInfo = GetBordersInfo.UpRight;
if (Input.GetKey(KeyCode.RightArrow)&&Input.GetKey(KeyCode.DownArrow)) BordersInfo = GetBordersInfo.DownRight;
ChangeSpeed (); // изменить скорость
}
}
public void RotateCamera() {
if (Input.GetMouseButton(1))
{ // если нажата правая кнопка мыши
CameraRotate.Rotate (-MouseY*RotSpeed*Time.deltaTime,0f,0f); // вращать по Х
if (MouseYCord>ScreenHeight/2f) CameraTransform.Rotate (0f,-MouseX*RotSpeed*Time.deltaTime,0f); // вращать по У в верхней половине экрана
else CameraTransform.Rotate (0f,MouseX*RotSpeed*Time.deltaTime,0f); // вращать по У в нижней половине экрана
}
CameraRotate.eulerAngles = new Vector3 (Mathf.Clamp(CameraRotate.rotation.eulerAngles.x,30f,80f),CameraRotate.eulerAngles.y,CameraRotate.eulerAngles.z); // ограничители
}
public void ChangeMove (GetBordersInfo InBorders) {
switch (InBorders) {
case (GetBordersInfo.Left):
CameraTransform.Translate(0f,0f,MouseY*Time.deltaTime*2f);
break;
case (GetBordersInfo.Right):
CameraTransform.Translate(0f,0f,MouseY*Time.deltaTime*2f);
break;
case (GetBordersInfo.Up):
CameraTransform.Translate(MouseX*Time.deltaTime*2f,0f,0f);
break;
case (GetBordersInfo.Down):
CameraTransform.Translate(MouseX*Time.deltaTime*2f,0f,0f);
break;
}
}
public void Camera_zoom () {
ZoomDistance = Mathf.Clamp(Vector3.Distance(CameraView.transform.position,CameraRotate.transform.position),2f,10f);
if ((ZoomDistance<10f)&(ZoomDistance>2f)) CameraView.Translate (Vector3.forward*Zooming);
if ((Zooming<0f)&(ZoomDistance==2f)) CameraView.Translate (Vector3.forward*Zooming);
if ((Zooming>0f)&(ZoomDistance==10f)) CameraView.Translate (Vector3.forward*Zooming);
}
public void Camera_SlideCalc () {
//SlideVector = Vector3.zero;
CameraTransform.position = Vector3.SmoothDamp(CameraTransform.position,CameraTransform.position,ref velocity,2f);
if (Input.GetMouseButtonUp(0))
{
ActiveSlideStatus = SlideStatus.Run;
SlideTime = 0f;
SlideTrigger = SlideSecond;
}
}
public void Camera_Navigation() {
CheckInBorders(); // - проверка попадания в рамки
CheckKeyBoardRule (); // - управление c клавиатуры
if (BordersInfo == GetBordersInfo.None) RotateCamera(); // вращение только в центральной области игры
MoveVector = new Vector3(RealSpeedX,0,RealSpeedY); //вектор перемещения
CameraTransform.Translate (MoveVector); //перемещаем камеру в соответствии со скоростями
ChangeMove(BordersInfo); // расчет скоростей
Camera_zoom(); // Зум
Camera_SetPosition_on_plane ();
if (Input.GetMouseButton(0)&(ActiveSlideStatus==SlideStatus.Idle)) SlideTime += Time.deltaTime; // если слайда нет, то включить слайд через 0.2 сек
if (SlideTime > SlideTrigger) // готовимся сделать слайд
{
SlideStart = Cursor.position; // слепок текущего положения
SlideTime = 0f; // обнулить таймер
ActiveSlideStatus = SlideStatus.Calc; // начать расчет слайда
}
if (ActiveSlideStatus==SlideStatus.Calc) Camera_SlideCalc(); // расчет слайда
if (ActiveSlideStatus==SlideStatus.Run) Camera_SlideRun();
}
public void Camera_SlideRun() {
ActiveSlideStatus = SlideStatus.Idle;
}
public void Camera_SetPosition_on_plane () {
Position_on_plane = RealCamera.ScreenPointToRay(new Vector3(MouseXCord,MouseYCord,0f)); // пусить луч в координаты мыши
if (Physics.Raycast(Position_on_plane, out RayInfo, Mathf.Infinity)) // если пересечение то
{
PointRay = RayInfo.point; // получаем информацию о столкновении
CursorPosition = new Vector3(Mathf.Round(PointRay.x),0f,Mathf.Round(PointRay.z)); //позиция курсора на плоскости
}
Cursor.position = Vector3.SmoothDamp(Cursor.position,CursorPosition,ref velocity,0.1f); // плавно переместить курсор в точку назначения
}
}
|