20241105 / Unity_6차 9주차 화요일
건축 시스템을 만들고 있으나 에셋도 마땅한 게 없고 시간도 별로 없다.
아직은 건설 미리보기까지밖에 구현 안됐다.
public class BuildingSystem : MonoBehaviour
{
[SerializeField] private List<BuildObject> objects = new();
[SerializeField] private BuildObject currentObject;
[SerializeField] private Transform cam;
[SerializeField] private LayerMask buildPosTargetLayer;
private Transform currentPreview;
private Vector3 currentPos;
[SerializeField] private float offset = 1.0f;
[SerializeField] private float gridSize = 1.0f;
public bool isBuilding = true;
private void Start()
{
ChangeCurrentBuilding();
}
private void Update()
{
if (isBuilding)
{
StartPreview();
}
}
public void ChangeCurrentBuilding()
{
GameObject curPreview = Instantiate(currentObject.preview, currentPos, Quaternion.identity) as GameObject;
currentPreview = curPreview.transform;
}
public void StartPreview()
{
if (Physics.Raycast(cam.position, cam.forward, out RaycastHit hit, 10, buildPosTargetLayer))
{
if (hit.transform != transform)
{
NormalizePosition(hit);
}
}
}
private void NormalizePosition(RaycastHit hit)
{
currentPos = hit.point;
currentPos -= Vector3.one * offset;
currentPos /= gridSize;
currentPos = new Vector3(Mathf.Round(currentPos.x), Mathf.Round(currentPos.y), Mathf.Round(currentPos.z));
currentPos *= gridSize;
currentPos += Vector3.one * offset;
currentPreview.position = currentPos;
}
}
[System.Serializable]
public class BuildObject
{
public string name;
public GameObject preview;
public int gold;
}
건설 대상 위치는 Interact 와 마찬가지로 플레이어 카메라에서 Raycast하여 닿는 대상의 위치로 한다.
currentObject는 건설 미리보기 오브젝트인데, 건설 가능 여부를 판단하기 위해 collider를 가지고 있다.
그런데 이 collider 때문에 미리보기일 뿐인 본인이 Raycast에 맞는 경우가 생긴다.
이를 방지하기 위해 Raycast에 본인의 Layer를 제외한 LayerMask가 따로 필요하다.
또한 건설 위치를 맞추기 위해 포지션을 정규화 하는 함수를 만들었다.