반응형
반응형
저번 글에서는 터레인 지형편집을 알아보았는데요
하지만 지형이 한 곳만 튀어나오는 문제점이 있었습니다
이번 글에서는 그 문제를 해결하기 위하여 브러쉬를 만들고 적용시켜 보겠습니다
먼저 브러쉬에 사용할 이미지를 만들어주어야 합니다
저는 GIMP로 간단하게 하나 만들어 주었습니다
그다음 텍스쳐 설정에서 Read/Write를 활성화시켜 주세요
이러면 텍스쳐 설정은 끝났습니다 이제 코드를 작성할 시간입니다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TerrainEditor : MonoBehaviour
{
[SerializeField] private Terrain terrain;
[SerializeField] private LayerMask terrainMask;
[SerializeField] private float power = 3f;
[SerializeField] private Texture2D brashTex;
private Color32[] curBrashArr;
private TerrainData data => terrain.terrainData;
private float[,] heightMap;
private void Awake()
{
heightMap = data.GetHeights(0, 0, data.heightmapResolution, data.heightmapResolution);
//브러쉬 텍스쳐의 정보를 가져와주기
curBrashArr = brashTex.GetPixels32(0);
}
private void Update()
{
//시프트를 누르고 클릭하면 내려가게
if (Input.GetKey(KeyCode.LeftShift) && Input.GetMouseButton(0))
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hit, 1000, terrainMask))
{
DrawTerrain(hit.point, false);
}
}
else if (Input.GetMouseButton(0))
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hit, 1000, terrainMask))
{
DrawTerrain(hit.point, true);
}
}
}
private void DrawTerrain(Vector3 point, bool up)
{
int mousePosToTerrainX = (int)((point.x / data.size.x) * data.heightmapResolution);
int mousePosToTerrainZ = (int)((point.z / data.size.z) * data.heightmapResolution);
int size = (int)Mathf.Sqrt(curBrashArr.Length);
int cnt = 0;
//브러쉬 텍스쳐 데이터를 탐색하며 더해주기
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
//인덱스를 범위를 넘어섰을때 continue
if (mousePosToTerrainZ + (x - size / 2) < 0 ||
mousePosToTerrainZ + (x - size / 2) > data.heightmapResolution - 1 ||
mousePosToTerrainX + (y - size / 2) < 0 ||
mousePosToTerrainX + (y - size / 2) > data.heightmapResolution - 1)
{
cnt++;
continue;
}
//지형을 높여야 하는지 낮추어야 하는지 비교
if (up)
{
heightMap
[
mousePosToTerrainZ + (x - size / 2),
mousePosToTerrainX + (y - size / 2)
] +=
//역보간으로 현제 브러시 데이터의 값을 0 ~ 1 로 변환
Mathf.InverseLerp(0, 255, curBrashArr[cnt].r) * Time.deltaTime / power;
}
else
{
heightMap
[
mousePosToTerrainZ + (x - size / 2),
mousePosToTerrainX + (y - size / 2)
] -=
Mathf.InverseLerp(0, 255, curBrashArr[cnt].r) * Time.deltaTime / power;
}
cnt++;
}
}
data.SetHeights(0, 0, heightMap);
}
}
브러쉬 텍스쳐의 색 값을 읽어온 다음
역보간을 이용하여 0 ~ 1로 고정해 주고 그 값을 기반으로 지형을 변경시키는 식으로 작성하였습니다
이제 코드에 텍스쳐를 할당해 주고
실행해 주시면?
지형편집이 잘 되는 것을 확인하실 수 있습니다
이뿐만이 아니라 흑백으로 이루어진 이미지라면 브러쉬로 사용할 수 있습니다
이런 네모모양 브러쉬를 사용해도 잘 동작하는 것을 확인할 수 있습니다
이렇게 이번 글에서는 브러쉬를 구현해 보았는데요
다음 글에서는 지형색칠에 관하여 알아보도록 하겠습니다
반응형
'유니티 > 3D 맵 에디터' 카테고리의 다른 글
[Unity] 3D 맵 에디터 - 3. 지형 색칠 (0) | 2024.02.29 |
---|---|
[Unity] 3D 맵 에디터 - 1. 지형 편집 (0) | 2024.02.28 |