3D 관련

Unity 로우폴리곤 3D 행성 테스트

by 소서리스25 2024. 9. 24.
반응형

Unity 로우폴리곤 3D 행성 테스트

 

오래간만에 3D 모델링을 진행했다. 꽤 오래전부터 구상했던 것이 있었는데, 아직까지도 구체적인 기획 결과에 도달하지 못했다. 다만, 기본적인 구성은 그때나 지금이나 동일한 것이어서 시각적인 테스트 몇 가지라도 해보면 좀 더 좋을 것 같아서 진행하게 되었다. 뭐 만들고 싶다는 욕구 때문인지도 모르겠다.

 

클리커, 방치형, 힐링 등의 요소로서 적합한지 검토하는 중이다.

 

이것 이전에 했던 테스트들은 shader 들을 주로 다뤘는데 만족할만한 결과물에는 도달하지 못했다.

 

아무튼 오래간만에 3D 툴을 붙잡고 모델링을 진행했다.

 

 

아래와 같이 3종의 나무들도 로우폴리곤 진행했다. 당연하지만 행성에서 육지의 숲에 해당하는 영역에 들어갈 것이다.

나무 3종 세트
나무 3종 세트

 

 

다음은 구름이다. 다양한 구름을 랜덤으로 생성하기 위해 모양을 잡고 있다.

메인 구름이 생성되면 서브로 주위에 작은 구름이 뭉쳐서 생성하면 어떨까 하는 생각으로 아래와 같이 모델링하였다.

구름의 여러 모양
구름의 여러 모양

 

 

일단 나무를 행성에 고정하기 위해서 Unity에서 테스트를 진행해 봤다.

또 간만에 그나마도 잘 모르는 코딩을 해서 아래와 같은 결과물을 얻었다. 현재는 나무지만 구름, 산, 극지방, 등등 여러 요소를 추가하면 재미있을 것 같다.

Unity에서 나무 배치
Unity에서 나무 배치

 

 

일단 육지에 나무를 랜덤 하게 심는 것은 단번에 되지는 않았고, 여러 참고자료를 찾았지만 내 수준으로 이해하기 어려워서 내가 알기 쉽도록 코드를 아래와 같이 구성해 봤다.

나중에는 seed 값을 넣어서 랜덤이되 고정되는 값을 적용하고자 한다. 찾아보니 Random.Value 로 되는 것 같은데 좌표의 생성 지점이 평면이 아닌 구체 표면이여서 문제가 좀 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class TreePosition : MonoBehaviour
{
 
    public GameObject _landSurface;
    public GameObject[] _tree;
 
    Vector3 _centerPos = new Vector3(000);
 
    void Start()
    {
        TreeGen();
    }
 
    void TreeGen()
    {
        RaycastHit hit;
        Ray _ray;
 
        for (int i = 0; i < 1000; i++)
        {
            while (true)
            {
                Vector3 _randomDir = Random.onUnitSphere * 10f;
 
                transform.position = _randomDir;
 
                Vector3 _targetDir = (transform.position - _centerPos).normalized;
                Vector3 _thisUp = transform.forward;
                transform.rotation = Quaternion.FromToRotation(-_thisUp, _targetDir) * transform.rotation;
 
                _ray = new Ray(transform.position, transform.forward);
                if (Physics.Raycast(_ray, out hit))
                {
                    GameObject _treeIntance = Instantiate(_tree[Random.Range(03)]);
                    _treeIntance.transform.position = hit.point;
 
                    Vector3 _treetDir = (_treeIntance.transform.position - _landSurface.transform.position).normalized;
                    Vector3 _treeUp = _treeIntance.transform.forward;
 
                    _treeIntance.transform.rotation = Quaternion.FromToRotation(_treeUp, _treetDir) * _treeIntance.transform.rotation;
                    _treeIntance.transform.name = "tree_" + i;
 
                    _treeIntance.transform.parent = _landSurface.transform;
 
                    break;
                }
            }
        }
    }
 
}
 
cs

 

 

구성된 코드를 간단하게 설명하면 구체 밖에서 중심으로 ray를 쏴서 충돌하는 지점에 나무를 심는 것이다.

원래는 구체 밖이 아닌 안쪽 중심에서 밖으로 ray를 쐈는데 문제는 object의 backside를 인식하지 못해 object를 생성하지 못했다. 혹시나 RaycastAll을 써볼까 했는데 문제는 hit.point가 필요해서 위와 같은 방식으로 진행했다.

while문을 통해 for문에서 정해진 수량까지 생성될때까지 반복하여 배치한다.

 

아직은 완전 초기단계라 shader나 mapping 등은 진행해 봐야 한다.

 

행성 모델링도 대충대충 한 거라 게임상에 진행한다면 mesh를 생성하거나 그게 문제가 된다면 여러 타입의 행성을 미리 만들어 놓는 것도 생각해 볼 예정이다. 

 

생각보다 긴 시간에 들어갈 것 같다. 

반응형

댓글