표시 문제가 해결되었지만, 그 자리에 생성이 되지 않는다
또한, 회전이 반영되지 않은 원래 자리에 생성되었다
다음 사진들을 보자
1. 이건 처음 위치이다. 마우스 커서는 현재 초록색으로 표시된 4개의 격자 중 왼쪽 아래의 위치에 고정되어있다
2. 이 상태로 R키를 누르면 시계방향 90도 회전한다
회전중심은 초록색 부분의 왼쪽 아래 점이다
3. 이 상태로 클릭하면, 초록색 위치에 생성되는 것이 아니라 회전이 반영되기 전의 위치에 생성된다
4. 비어있는 격자에 건물이 있는 것처럼 계산되어 건물을 지을 수 없다
5. 또한, 건물이 있는 곳은 건물이 없는 것처럼 표시가 된다
6. 그래서 클릭해보면, 위에 생성된다
이 문제는
회전을 preview에 보여줄 때 반영하고 실제 오브젝트를 생성할 때 반영하지 않았기 떄문이다
하지만 이것을 해결하는 과정은 매우 복잡할 수 있다
왜냐하면 오브젝트가 있는 격자의 위치를 마우스 커서의 위치를 기반으로 표시하기 때문이다
여기서 회전을 하면 마우스 커서가 없는 곳에 격자가 이동한다
격자의 실제 위치를 기반으로 오브젝트를 생성하게 바꾸어야한다
그 전에 먼저 오브젝트를 생성하는 과정을 살펴보자
1. TempInputManager의 Update에서는 마우스 왼쪽 클릭하면 delegate OnClicked에 메서드가 있으면 호출하는데, UI에서 아이콘을 클릭하면 PlaceStructure를 구독한다
(ESC 누르면 OnExit에 메서드가 있으면 호출하는데, 마찬가지로 UI에서 아이콘 클릭하면 StopPlacement를 구독한다)
public class TempInputManager : MonoBehaviour
{
[SerializeField] private Camera sceneCamera; // 3인칭 시점의 메인카메라가 있는데 굳이 필요할까?
public Vector3 lastPos;
[SerializeField] private LayerMask placementLayerMask; // 내려놓을 지점의 layer가 Grid일 때만 내려놓을 수 있다
// 클릭하면 다른 클래스에 알리는 용도
public event Action OnClicked, OnExit;
private void Update()
{
if (Input.GetMouseButtonDown(0))
OnClicked?.Invoke(); // 있으면 호출(안전하게 이벤트 호출)
if (Input.GetKeyDown(KeyCode.Escape))
OnExit?.Invoke();
}
...
2. 이 상태에서 씬의 grid를 클릭하면 구독되어있는 PlacementSystem의 PlaceStructure가 호출된다
private void PlaceStructure()
{
if (inputManager.IsPointerOverUi())
{
return;
}
Vector3 mousePos = inputManager.GetSelectedMapPos(); // 마우스로 선택한 위치 가져온다
Vector3Int gridPosition = grid.WorldToCell(mousePos); // 마우스가 있는 위치를 3d로 변환하여 그리드의 어느 격자 내에 있는지 알아낸다
// 물체가 회전했다면 회전된 오브젝트의 중심 좌표를 계산하여 위치 보정
Vector3Int adjustedGridPosition = AdjustPositionForRotation(gridPosition);
/// 오브젝트 생성
/// preview의 회전상태를 반영해야한다
buildingState.OnAction(adjustedGridPosition);
}
3. PlacementState의 OnAction을 호출
/// <summary>
/// 마우스 누를 때 발생, 맵에 개체를 배치
/// 오브젝트를 내려놓는 위치를 mousePosition에서, preview의 position으로 수정
/// 또한, preview의 회전상태를 반영하여야한다
/// </summary>
/// <param name="gridPosition"></param>
public void OnAction(Vector3Int gridPosition)
{
// PlaceStructure
/// 영역검사할때도 격자의 회전을 반영해야한다
bool placementValidity = CheckPlacementValidity(gridPosition, selectedObjIndex);
if (placementValidity == false)
{
soundFeedback.PlaySound(SoundType.wrongPlacement);
return;
}
soundFeedback.PlaySound(SoundType.Place);
/// 오브젝트 생성(오브젝트 정보는 previewSystem.previewObject가 가지고 있다)
int index = objectPlacer.PlaceObject(database.objectsData[selectedObjIndex].Prefab, grid.CellToWorld(gridPosition));
// 이 객체의 인덱스를 데이터에 추가
GridData selectedData = database.objectsData[selectedObjIndex].ID == 0 ? tree : buildingData; // 나무와 건물을 구분한다
selectedData.AddObjectAt(gridPosition,
database.objectsData[selectedObjIndex].Size,
database.objectsData[selectedObjIndex].ID,
index);
previewSystem.UpdatePosition(grid.CellToWorld(gridPosition), false);
}
4. ObjectPlacer의 PlaceObject를 호출하여 오브젝트를 생성한다
/// <summary>
/// 건물 오브젝트를 맵에 추가
/// </summary>
public class ObjectPlacer : MonoBehaviour
{
[SerializeField]
private List<GameObject> placedGameObjects = new List<GameObject>(); // 생성된 게임오브젝트 저장
public int PlaceObject(GameObject prefab, Vector3 position)
{
GameObject newObject = Instantiate(prefab);
newObject.transform.position = position; // 격자 오브젝트를 그 좌표로 이동
placedGameObjects.Add(newObject); // 생성한 게임오브젝트 저장
return placedGameObjects.Count - 1;
}
}
PlaceObject를 수정하여 오브젝트의 생성 위치와 회전 상태를 바로잡아야 할 것 같다
5. 이어서 PreviewSystem의 UpdatePosition를 호출하여 ApplyFeedbackToCursor에 false를 전달하여 호출
public void UpdatePosition(Vector3 position, bool validity)
{
if (previewObject != null)
{
MovePreview(position);
ApplyFeedbackToPreview(validity);
}
// cursor는 null이 아니므로
MoveCursor(position);
ApplyFeedbackToCursor(validity);
}
6. 이 위치에는 오브젝트가 생성되었으므로 preview의 색깔을 빨간색으로 바꾼다
private void ApplyFeedbackToCursor(bool validity)
{
Color c = validity ? Color.green : Color.red;
c.a = 0.5f;
cellIndicatorRenderer.material.color = c;
}
7. 재귀를 빠져나온 다음 PlacementSystem의 Update를 실행
private void Update()
{
//if (selectedObjIndex < 0)
if (buildingState == null)
return;
Vector3 mousePos = inputManager.GetSelectedMapPos(); // 마우스로 선택한 위치 가져온다
Vector3Int gridPosition = grid.WorldToCell(mousePos); // 마우스가 있는 위치를 3d로 변환하여 그리드의 어느 격자 내에 있는지 알아낸다
// 회전된 오브젝트의 위치 보정
Vector3Int adjustedGridPosition = AdjustPositionForRotation(gridPosition);
// grid 내에서 커서가 이동하면 연산하지 않는다
//if (lastDetectedPosition != gridPosition)
//{
// buildingState.UpdateState(gridPosition);
// lastDetectedPosition = gridPosition;
//}
if (lastDetectedPosition != adjustedGridPosition)
{
buildingState.UpdateState(adjustedGridPosition);
lastDetectedPosition = adjustedGridPosition;
}
// R키를 누르면 시계방향으로 회전
if (Input.GetKeyDown(KeyCode.R))
{
preview.RotatePreview(90); // 초당 90도 회전
}
}
여기까지가 생성 로직의 끝이다
grid위에 클릭하면, PlacementSystem의 StopPlacement가 호출되는줄 알았는데... 하지 않는다
이건
※참고
TempInputManager의 Update가 매 프레임 호출되면서 esc가 입력되면
OnExit에 있는 StopPlacement가 호출된다
/// <summary>
/// 선택한 건물을 Grid에 내려놓을때 호출된다
/// 회전을 고려한 위치에 내려놓아야한다(현재는 그렇지 않은 문제가 있다)
/// </summary>
private void StopPlacement()
{
soundFeedback.PlaySound(SoundType.Click);
if (buildingState == null)
return;
//selectedObjIndex = -1;
gridVisualization.SetActive(false);
//cellIndicator.SetActive(false);
//preview.StopShowingPreview();
buildingState.EndState();
inputManager.OnClicked -= PlaceStructure;
inputManager.OnExit -= StopPlacement;
lastDetectedPosition = Vector3Int.zero;
buildingState = null;
}
따라서 오브젝트의 생성과는 관계없다
문제가 되는 이유는
회전할 때 preview의 position이 바뀌지 않기 때문이다
R을 눌러서 회전했는데
회전을 했을 뿐, position이 같다는 문제
position에 변화를 주어야한다
아니면 처음부터 격자를 바꾸지 말고 preview 오브젝트만 회전을하면 된다
오래 생각했다
RotatePreview에 문제가 있었다
현재 RotatePreview는
현재 코드에서는 previewObject.transform.Rotate(Vector3.up, angle);를 사용하여 단순 회전만 수행한다
이 방식은 "로컬 회전"을 적용하므로 transform이 변하지 않는다 ★
transform.Rotate는 로컬 회전을 하므로 position이 안바뀐다 ★
/// <summary>
/// R키 누르면 y축 기준으로 시계방향 회전
/// 격자, 프리팹 모두 회전한다
/// </summary>
/// <param name="angle"></param>
public void RotatePreview(float angle)
{
previewObject.transform.Rotate(Vector3.up, angle);
/// 격자 다시 표시해야함
/// cellIndicator 또한 angle만큼 회전한다
cellIndicator.transform.Rotate(Vector3.up, angle);
}
이 방식을 바꾸어서
격자의 중심을 기준으로 회전을 적용해야한다
여러 방법을 시도했으나 다 실패했다
position이 바뀌지 않고, rotation만 바뀌기 때문에 좌표로 해결할 수 없다
preview가 회전하는 양상을 보고 생각하자
1. preview가 회전하는 위치, 회전상태를 저장하고 이를 매개변수로 넘겨서
생성되는 위치를 갱신해야한다
2. cellIndicator의 위치를 기억해서 원래 cell의 좌표 또한 바꿔야한다
오브젝트 생성의 경우 다음 순서로 호출하니 적당한 곳에서 position과 rotation을 대입한다
TempInputManager.Update → PlacementSystem.PlaceStructure → PlacementState.OnAction → ObjectPlacer.PlaceObject
PlacementSystem.PlaceStructure에서는 마우스 커서가 있는 grid를 gridPosition에 저장하고
회전을 하면 adjustGridPosition에 저장하는데, 문제는 회전 gridPosition 중심으로 회전하니까 값이 바뀌지 않는다
PlacementState.OnAction에 들어가는 매개변수 또한 회전의 중심인 원래 grid의 중심이므로 원래 position이 그대로 들어간다
PreviewSystem.Rotate에서 회전각을 저장한다. TempInputManager에 저장하는 것이 가장 좋다
내부에 계속해서 전달할 수 있기 때문이다
실제 오브젝트를 만드는건 ObjectPlacer.PlaceObject 함수
grid를 표시하는건 PlacementState.UpdateState 함수
둘 다 TempInputManager에 있는 변수를 가져와서 쓰면 된다
TempInputManager에 의존도가 높아지긴 하지만, TempInputManager는 매니저다
의존다가 높아져야 한다면 차라리 매니저에 의존하게 하는 것이 낫다
1. 오브젝트 회전 생성
PreviewSystem에서 angle을 저장했다
참조로 저장되므로 tempInputManager가 싱글턴이 아니더라도 가져가서 사용할 수 있다
using UnityEngine;
/// <summary>
/// 미리 보여주는 격자, 오브젝트
/// 격자의 회전 처리는 여기서 해야된다
/// </summary>
public class PreviewSystem : MonoBehaviour
{
[SerializeField] private float previewYOffset = 0.06f; // 오브젝트는 그리드보다 약간 위에 있다
[SerializeField] private GameObject cellIndicator; // 생성 전에 오브젝트가 걸치고 있는 격자
public GameObject previewObject; // 생성 전 미리 보여줄 오브젝트
[SerializeField] private Material previewMaterialPrefab; // 투명상태를 나타내는 material
private Material previewMaterialInstance; // 생성한 오브젝트의 원래 material
private Renderer cellIndicatorRenderer;
private float currentRotationAngle = 0f; // 현재 회전 상태 저장
public TempInputManager tempInputManager; // 회전각을 저장
...
/// <summary>
/// R키 누르면 y축 기준으로 시계방향 회전
/// 격자, 프리팹 모두 회전한다
/// </summary>
/// <param name="angle"></param>
public void RotatePreview(float angle)
{
// 현재 프리뷰 크기 가져오기
Vector2Int size = GetCurrentSize();
// 중심점을 기준으로 회전하도록 변경
Vector3 pivot = previewObject.transform.position + new Vector3(size.x / 2f, 0, size.y / 2f);
// 1️ 회전 중심으로 이동
previewObject.transform.position -= pivot;
cellIndicator.transform.position -= pivot;
// 2️ 회전 수행
previewObject.transform.Rotate(Vector3.up, angle);
cellIndicator.transform.Rotate(Vector3.up, angle);
/// 회전각을 저장
tempInputManager.angle = angle;
// 3️ 다시 원래 위치로 이동
previewObject.transform.position += pivot;
cellIndicator.transform.position += pivot;
}
// 현재 회전 각도를 가져오는 메서드 추가
public int GetRotationAngle()
{
return Mathf.RoundToInt(currentRotationAngle);
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 건물 오브젝트를 맵에 추가
/// </summary>
public class ObjectPlacer : MonoBehaviour
{
[SerializeField]
private List<GameObject> placedGameObjects = new List<GameObject>(); // 생성된 게임오브젝트 저장
public TempInputManager tempInputManager; // angle을 가져온다
public int PlaceObject(GameObject prefab, Vector3 position)
{
/// tempInputManager에서 회전각을 가져온다
float angle = tempInputManager.angle;
GameObject newObject = Instantiate(prefab);
newObject.transform.position = position; // 격자 오브젝트를 그 좌표로 이동
newObject.transform.rotation = Quaternion.Euler(0, angle, 0); // Y축 기준으로 회전
placedGameObjects.Add(newObject); // 생성한 게임오브젝트 저장
return placedGameObjects.Count - 1;
}
}
오브젝트가 회전을 반영하여 생성된다
2. Grid 회전 생성
격자는 회전을 하면 안된다.
좌표계가 돌아간 상태에서 진행이 되기 때문에 또 회전하게되면 영역인식을 못하게 된다...
이렇게 된다
따라서 Grid는 회전하지 않고, x와 y의 길이를 바꾸는 식으로 회전을 구현한 것처럼 보이게 해야한다
화면에 보이는 격자는 뭘까?
CoursorindicatorParent 의 scale이 계속 변하고 있다
이걸 누가 참조하고 있는지 알면 되겠다
Grid를 그릴 때 호출되는 순서에 대해 알아보자
PlacementSystem.Update → TempInputManager.GetSelectedMapPos→ PlacementSystem.Update → PreviewSystem.RotatePreview
과정을 거쳐 Grid가 이동한다
PlacementSystem.Update 에서 raycast 한다
private void Update()
{
//if (selectedObjIndex < 0)
if (buildingState == null)
return;
Vector3 mousePos = inputManager.GetSelectedMapPos(); // 마우스로 선택한 위치 가져온다
Vector3Int gridPosition = grid.WorldToCell(mousePos); // 마우스가 있는 위치를 3d로 변환하여 그리드의 어느 격자 내에 있는지 알아낸다
// 회전된 오브젝트의 위치 보정
Vector3Int adjustedGridPosition = AdjustPositionForRotation(gridPosition);
// grid 내에서 커서가 이동하면 연산하지 않는다
if (lastDetectedPosition != adjustedGridPosition)
{
buildingState.UpdateState(adjustedGridPosition);
lastDetectedPosition = adjustedGridPosition;
}
// R키를 누르면 시계방향으로 회전
if (Input.GetKeyDown(KeyCode.R))
{
preview.RotatePreview(90); // 초당 90도 회전
}
}
TempInputManager.GetSelectedMapPos 에서 raycast한 layer가 Placement인지 확인한다
GridVisualization의 layer이다. ray가 마우스 위치로 조사한 ray가 GridVisualization에 충돌하여 좌표를 가져온다
public Vector3 GetSelectedMapPos()
{
Vector3 mousePos = Input.mousePosition;
mousePos.z = sceneCamera.nearClipPlane; // 카메라에서 렌더링 되지 않은 물체를 선택할 수 없게 만듦
Ray ray = sceneCamera.ScreenPointToRay(mousePos);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100, placementLayerMask))
{
lastPos = hit.point;
}
return lastPos;
}
이렇게 raycast가 끝마녀
PlacementSystem.Update에서 grid.WorldToCell이라는 grid 내장 함수를 호출하여 가져온 좌표가 몇 번째 Grid에 있는지 구한다
그 뒤에
PreviewSystem.RotatePreview 에서 Grid의 위치와 회전상태가 결정된다
public void RotatePreview(float angle)
{
// 현재 프리뷰 크기 가져오기
Vector2Int size = GetCurrentSize();
// 중심점을 기준으로 회전하도록 변경
Vector3 pivot = previewObject.transform.position + new Vector3(size.x / 2f, 0, size.y / 2f);
// 1️ 회전 중심으로 이동
previewObject.transform.position -= pivot;
cellIndicator.transform.position -= pivot;
// 2️ 회전 수행
previewObject.transform.Rotate(Vector3.up, angle);
cellIndicator.transform.Rotate(Vector3.up, angle);
/// 회전각을 저장
tempInputManager.angle = angle;
// 3️ 다시 원래 위치로 이동
previewObject.transform.position += pivot;
cellIndicator.transform.position += pivot;
}
여기를 수정해야한다. cellIndicator는 회전하면 안된다
회전하는 것처럼 보여야 한다
이를 위해서 previewObject의 크기를 가져와야한다
90도씩 회전하면서 어느방향으로 x, y를 바꾸어 그리면 마치 Grid가 회전하는 것처럼 보인다
/// <summary>
/// R키 누르면 y축 기준으로 시계방향 회전
/// 격자, 프리팹 모두 회전한다
/// </summary>
/// <param name="angle"></param>
public void RotatePreview(float angle)
{
// 현재 프리뷰 크기 가져오기
Vector2Int size = GetCurrentSize();
// 중심점을 기준으로 회전하도록 변경
Vector3 pivot = previewObject.transform.position + new Vector3(size.x / 2f, 0, size.y / 2f);
// 1️ 회전 중심으로 이동
previewObject.transform.position -= pivot;
// 2️ 회전 수행
previewObject.transform.Rotate(Vector3.up, angle);
/// 회전각을 "누적하여" 저장(왜냐하면 누를때마다 angle에는 90만 들어올 수 있으므로)
currentRotationAngle = (currentRotationAngle + angle) % 360;
tempInputManager.angle = currentRotationAngle;
// 3️ 다시 원래 위치로 이동
previewObject.transform.position += pivot;
/// cellIndicator는 실제로 회전하지 않지만, 크기를 조정해야 한다
/// 회전하면 회전한 것의 기준으로 size.x, size.y가 갱신된다
/// 처음에 size.x == 1, size.y == 2 였다면
/// 90도 회전한 뒤에는 size.x == 2, size.y ==1 이 되는 것이다
/// x = 1 y = 2
/// x = 2 y = -1 (90도 회전)
/// x = -1 y = -2 (180도 회전)
/// x = -2 y = -1 (270도 회전)
/// x에는 y가 들어가며 y는 -x가 들어간다
int newX = size.y; // 기존 y값이 새로운 x 크기가 된다.
int newY = -size.x; // 기존 x값이 새로운 y 크기가 되는데, 부호가 반대가 된다.
cellIndicator.transform.localScale = new Vector3(newX, 1, newY);
}
가운데 줄이 생긴건 조금 이상하지만...
x, z는 맞게 들어간 것 같다 (x == 2, y == -1 )
한번 더 회전
좌표가 안맞다
아...
scale은 양수로 바꾸고
position을 바꿔야 하는거구나
/// <summary>
/// R키 누르면 y축 기준으로 시계방향 회전
/// 격자, 프리팹 모두 회전한다
/// </summary>
/// <param name="angle"></param>
public void RotatePreview(float angle)
{
// 현재 프리뷰 크기 가져오기
Vector2Int size = GetCurrentSize();
// 중심점을 기준으로 회전하도록 변경
Vector3 pivot = previewObject.transform.position + new Vector3(size.x / 2f, 0, size.y / 2f);
// 1️ 회전 중심으로 이동
previewObject.transform.position -= pivot;
// 2️ 회전 수행
previewObject.transform.Rotate(Vector3.up, angle);
/// 회전각을 "누적하여" 저장(왜냐하면 누를때마다 angle에는 90만 들어올 수 있으므로)
currentRotationAngle = (currentRotationAngle + angle) % 360;
tempInputManager.angle = currentRotationAngle;
// 3️ 다시 원래 위치로 이동
previewObject.transform.position += pivot;
/// cellIndicator는 실제로 회전하지 않지만, 크기를 조정해야 한다
/// 회전하면 회전한 것의 기준으로 size.x, size.y가 갱신된다
/// scale은 양수여야 한다
/// 처음에 size.x == 1, size.y == 2 였다면
/// 90도 회전한 뒤에는 size.x == 2, size.y ==1 이 되는 것이다
///
/// position을 부호 고려해서 바꾸면 된다
/// x = 1 y = 2
/// x = 2 y = -1 (90도 회전)
/// x = -1 y = -2 (180도 회전)
/// x = -2 y = -1 (270도 회전)
/// x에는 y가 들어가며 y는 -x가 들어간다
/// scale은 양수
/// size는 처음부터 양수니까 절댓값 필요없다
int newX = size.y;
int newY = size.x;
cellIndicator.transform.localScale = new Vector3(newX, 1, newY);
/// position은 부호 반영
Vector3 newPosition = cellIndicator.transform.position;
newPosition.x += (Mathf.Sign(size.y) - 1) * 0.5f * newX;
newPosition.z += (Mathf.Sign(size.x) - 1) * 0.5f * newY;
cellIndicator.transform.position = newPosition;
}
4가지 상태의 position과 scale을 비교하자
0도, 360도
90도
180도
270도
좌표가 조금씩 안맞는다
position을 바꾸면 안된다
우선 저 격자는 PreviewSystem의 cellIndicator 이다
그러니 PreviewSystem에서 오브젝트 회전상태가 정해지면, 그 크기를 기반으로 cellIndicator의 크기를 정하는 것이 바람직하다
/// <summary>
/// 오브젝트의 크기를 보여준다
/// 여기에서 커서가 나온다
/// 여기를 수정해야한다
/// </summary>
/// <param name="size"></param>
private void PrepareCursor(Vector2Int size)
{
if (size.x > 0 || size.y > 0)
{
cellIndicator.transform.localScale = new Vector3(size.x, 1, size.y);
cellIndicatorRenderer.material.mainTextureScale = size;
}
}
여기를 호출해서 모양을 바꿔야한다
오버로딩해서 private void PrepareCursor(Vector2Int size, float rotationAngle)를 만들었고
90도 회전할 때마다 바르게 나오는 조건을 수동으로 찾아낸다
(회전축이 변하지 않는 전제다)
넷 다 pos은 변하지 않는다(pos는 회전축의 위치이므로 x=0, z=0 고정이다)
scale만 바꾼다
x와 z의 값은
0도
x = 1, z = 2
90도
x = 2, z = -1
180도
x = -1, z = -2
270도
x = -2, z = 1
이렇게 된다
PrepareCursor를 오버로딩하여 격자가 preview를 따라서 회전하게 만들었다
/// <summary>
/// 격자의 크기를 조정 (회전 고려)
/// </summary>
/// <param name="size"></param>
/// <param name="rotationAngle"></param>
private void PrepareCursor(Vector2Int size, float rotationAngle)
{
Vector2Int rotatedSize = size;
// 90도 단위로만 회전한다고 가정
int angle = Mathf.RoundToInt(rotationAngle) % 360;
rotatedSize = new Vector2Int(size.y, size.x);
switch (angle)
{
case 90: /// x = 2, z = -1
case -270:
cellIndicator.transform.localScale = new Vector3(rotatedSize.x, 1, -rotatedSize.y);
break;
case 180: /// x = -1, z = -2
case -180:
cellIndicator.transform.localScale = new Vector3(-rotatedSize.x, 1, -rotatedSize.y);
break;
case 270: /// x = -2, z = 1
case -90:
cellIndicator.transform.localScale = new Vector3(-rotatedSize.x, 1, rotatedSize.y);
break;
case 0: /// x = 1, z = 2
case 360:
default:
cellIndicator.transform.localScale = new Vector3(rotatedSize.x, 1, rotatedSize.y);
break;
}
}
하지만
90도, 270도를 회전할 때 날 일자 모양이 안나오고 H자가 나온다
또한 90도, 270도 회전할떄는 바르지 않은 방식으로 인식하더라
겹쳤는데도 놓을 수 있다
오른쪽도...
그럼 놓을 수 없는 구역이 어디??
물체를 놓은 지점과 겹치는 지점은 당연히 안된다
그것보다 1칸 위에 평행하게
그것보다 1칸 아래 평행하게
다음 세 지점에는 놓을 수 없다
어째서 다음 영역들이 놓을 수 없는 구간이 된 것일까?
이 부분은 이어서 작성한다
'유니티 부트캠프 8기 > Ch05. Unity 게임 개발 숙련' 카테고리의 다른 글
Grid 기반의 건축 시스템 4. pivot을 잡고 원래대로 되돌리기, 회전연산 (0) | 2025.03.19 |
---|---|
Grid 기반의 건축 시스템 3. scale이 -값이 되었을 때 발생하는 문제 (0) | 2025.03.18 |
Grid 기반의 건축 시스템 1. 회전하여 격자 표시하기까지 (0) | 2025.03.16 |
Grid 기반의 건축 시스템 prototype (0) | 2025.03.13 |
벽 타기, 매달리기 (0) | 2025.03.11 |