#c# #unity3d #math #linear-algebra #isometric
#c# #unity3d #математика #линейная алгебра #изометрический
Вопрос:
Я разрабатываю 2D-изометрическую игру, такую же, как Age of Empires 2, TTD, Into the Breach и так далее. Я использую Unity и C#
Важный факт: я использую изометрическую карту листов
Я хочу, чтобы границы камеры оставались выровненными с границами карты, как в играх, упомянутых выше, но у меня возникают трудности, и я потратил на это так много времени, что я начинаю задаваться вопросом, стоит ли использовать изометрическую Tilemap или использовать обычный подход и просто создать обычную 2D-игрус повернутой камерой.
И это мой первый вопрос: действительно ли стоит использовать изометрическую Tilemap или обычный подход лучше (неизометрическая 2D-игра с повернутой камерой)? Если да, то как это сделать в Unity?
Несмотря на это, код, который я реализовал, приведен ниже, но в нем есть две ошибки:
- Камера застревает
firstBase
, иthirdBase
если пользователь нажимает клавишу вправо / влево и клавиши вверх / вниз - Если камера движется по границе, она может ее избежать
void Start(){
CameraMovement_Limits();
}
void CameraMovement_Limits(){
Vector3 gridOrigin = tilemapFloor.GetCellCenterWorld(tilemapFloor.origin);
float gridHypotenuse = ((tilemapFloor.size.x - 1) * tilemapFloor.cellSize.y);
homePlate = gridOrigin new Vector3(0, 0, -10);
firstBase = gridOrigin new Vector3(gridHypotenuse, gridHypotenuse/2, -10);
secondBase = gridOrigin new Vector3(0, gridHypotenuse, -10);
thirdBase = gridOrigin new Vector3(-gridHypotenuse, gridHypotenuse/2, -10);
}
void Update(){
CameraDiagonalMovement();
}
bool CheckCameraPosition(Vector2 p1, Vector2 p2, Vector2 pos){
//This is what this function do:
//find the linear equation for the line formed by 'p1' and 'p2' coordinates
//insert 'pos' coordinate on the equation and stores the result in 'ind'
//if 'ind' is positive, it means that 'pos' is above the line
//if its negative, its above
//if its zero, its on the line
//resuming, this funtion tells if 'pos' is above or below a line formet by 'p1' and 'p2'
float a = (p1.y - p2.y) / (p1.x - p2.x);
float ind = pos.y - p2.y - (a * (pos.x - p2.x));
return ind >= 0;
}
void CameraDiagonalMovement(){
Vector3 vecZero = Vector2.zero;
camPos = (Vector2)transform.position;
//Going to the left
if(Input.GetAxis("Vertical") < 0){
if(CheckCameraPosition(homePlate, thirdBase, camPos) amp;amp; CheckCameraPosition(homePlate, firstBase, camPos)){
vecZero.y = Input.GetAxis("Vertical");
}else if(!CheckCameraPosition(homePlate, thirdBase, camPos) amp;amp; CheckCameraPosition(homePlate, firstBase, camPos)){
vecZero.x = Input.GetAxis("Vertical") * .66f * -1;
vecZero.y = Input.GetAxis("Vertical") * .33f;
}else if(CheckCameraPosition(homePlate, thirdBase, camPos) amp;amp; !CheckCameraPosition(homePlate, firstBase, camPos)){
vecZero.x = Input.GetAxis("Vertical") * .66f;
vecZero.y = Input.GetAxis("Vertical") * .33f;
}
}
//Going to the right
if(Input.GetAxis("Vertical") > 0){
if(!CheckCameraPosition(secondBase, thirdBase, camPos) amp;amp; !CheckCameraPosition(firstBase, secondBase, camPos)){
vecZero.y = Input.GetAxis("Vertical");
}else if(CheckCameraPosition(secondBase, thirdBase, camPos) amp;amp; !CheckCameraPosition(firstBase, secondBase, camPos)){
vecZero.x = Input.GetAxis("Vertical") * .66f;
vecZero.y = Input.GetAxis("Vertical") * .33f;
}else if(!CheckCameraPosition(secondBase, thirdBase, camPos) amp;amp; CheckCameraPosition(firstBase, secondBase, camPos)){
vecZero.x = Input.GetAxis("Vertical") * .66f * -1;
vecZero.y = Input.GetAxis("Vertical") * .33f;
}
}
//Going down
if(Input.GetAxis("Horizontal") < 0){
if(CheckCameraPosition(homePlate, thirdBase, camPos) amp;amp; !CheckCameraPosition(secondBase, thirdBase, camPos)){
vecZero.x = Input.GetAxis("Horizontal");
}else if(!CheckCameraPosition(homePlate, thirdBase, camPos) amp;amp; !CheckCameraPosition(secondBase, thirdBase, camPos)){
vecZero.x = Input.GetAxis("Horizontal") * .66f;
vecZero.y = Input.GetAxis("Horizontal") * .33f * -1;
}else if(CheckCameraPosition(homePlate, thirdBase, camPos) amp;amp; CheckCameraPosition(secondBase, thirdBase, camPos)){
vecZero.x = Input.GetAxis("Horizontal") * .66f;
vecZero.y = Input.GetAxis("Horizontal") * .33f;
}
}
//Going up
if(Input.GetAxis("Horizontal") > 0){
if(CheckCameraPosition(homePlate, firstBase, camPos) amp;amp; !CheckCameraPosition(firstBase, secondBase, camPos)){
vecZero.x = Input.GetAxis("Horizontal");
}else if(CheckCameraPosition(homePlate, firstBase, camPos) amp;amp; CheckCameraPosition(firstBase, secondBase, camPos)){
vecZero.x = Input.GetAxis("Horizontal") * .66f;
vecZero.y = Input.GetAxis("Horizontal") * .33f * -1;
}else if(!CheckCameraPosition(homePlate, firstBase, camPos) amp;amp; !CheckCameraPosition(firstBase, secondBase, camPos)){
vecZero.x = Input.GetAxis("Horizontal") * .66f;
vecZero.y = Input.GetAxis("Horizontal") * .33f;
}
}
Vector3 newPos = new Vector3(vecZero.x, vecZero.y, 0);
transform.position = newPos * velocity * Time.deltaTime;
}
Комментарии:
1. Что происходит, когда вы достигаете ровно нуля? Движение влево меньше нуля, а движение вправо больше нуля. Если вы находитесь на нуле, камера не перемещается.
2.В общем, для повышения производительности вы должны использовать один
GetAxis("XY")
раз в началеUpdate
, а затем повторно использовать результат