반응형
어느날 지인에게 메쉬를 생성하는법을 알려달라고 연락이 왔다.
해본적은 없지만(메쉬 개념도 없었다...) 재미있을거같아서 한번 시도해보았다.
1. 메쉬 생성(vertices, uv) : vertices만 알면 되는거같아서 uv 설정은 하지 않음.
2. Raycast를 이용해서 vertices 값이 유동적으로 바뀔수 있어야한다.
3. Circle 형태여야 함.
연락받았을 당시, 어몽어스에서 그림자가 표현되는 것을 상상했다.
그래서 코드를 2D로 만들었다가, 나중에 3D로 만들어야 된다고 뒤늦게 들어서.. 안타깝게도 코드가 2D와 3D가 섞인 코드가 됐다.
※※ 메쉬에 대한 개념은 구글링하면 바로나오니 패스한다.
- 코드
using UnityEngine;
using UnityEngine.Rendering;
public class MeshCreater : MonoBehaviour
{
public Material meshMaterial;
private Mesh mesh;
private MeshFilter meshFilter;
private MeshRenderer meshRender;
private void Start()
{
GameObject meshGameObject = new GameObject("Mesh", typeof(MeshFilter), typeof(MeshRenderer));
meshFilter = meshGameObject.GetComponent<MeshFilter>();
meshRender = meshGameObject.GetComponent<MeshRenderer>();
meshRender.material = meshMaterial;
mesh = new Mesh();
meshFilter.mesh = mesh;
}
private void Update()
{
CalculateMesh();
}
//Calculate vertex vector(circle)
private Vector3 ConvertAngleToVector(float _angle)
{
var rad = _angle * Mathf.Deg2Rad;
return new Vector3(Mathf.Cos(rad), Mathf.Sin(rad));
}
//*** Mesh vertices point : local position of gameObject
//recalculate vertices for vertices of mesh
private void CalculateMesh()
{
float targetAngle = 360f;
int rayCount = 360;
float angleIncrease = targetAngle / rayCount;
float angle = 0f;
float dist = 2f;
//Arr Length : ray counts + cneter point
Vector3[] vertices = new Vector3[rayCount + 1];
//Triangles : Multiple of 3
int[] triangles = new int[rayCount * 3];
//Center point is always Vector3.zero
Vector3 centerPoint = Vector3.zero;
//Set the center point to vertices[0] (triangle index 0)
vertices[0] = centerPoint;
int vertexIndex = 1;
int triangleIndex = 0;
for (int i = 0; i < vertices.Length; i++)
{
if (vertexIndex < vertices.Length)
{
Vector3 vertex = ConvertAngleToVector(angle);
RaycastHit hit;
//Get vertex points
if (Physics.Raycast(meshRender.transform.position, vertex, out hit, dist))
{
//Recalculate mesh point(local position)
//Set the local position(vertices), after Subtract the meshRender position from hit point.
vertices[vertexIndex] = hit.point - meshRender.transform.position;
}
else
{
vertices[vertexIndex] = vertex * dist;
}
}
//Set triangles
if (vertexIndex > 1)
{
triangles[triangleIndex] = 0;
triangles[triangleIndex + 1] = vertexIndex - 1;
triangles[triangleIndex + 2] = vertexIndex < vertices.Length ? vertexIndex : 1;
triangleIndex += 3;
}
vertexIndex++;
angle -= angleIncrease;
}
//Apply mesh info
mesh.vertices = vertices;
mesh.triangles = triangles;
}
}
※※ ConvertAngleToVector(float)는 삼각비를 이용해서 각도로 좌표를 구하는 함수다. (Raycast 함수의 direction 값이라 거리값은 필요가 없음.)
※※ 위 함수가 이해가 안간다면 다음글 참고
- 결과 보기
일단 개념을 잡는 쪽에 맞춰둔 코드라, 활용이나 최적화 작업은 목적에 따라 바뀔것 같다.
추가로 빛으로 활용하기 위한 참고 사이트 링크도 올려둠.
반응형
'Develoment > Unity' 카테고리의 다른 글
[유니티] UGUI 파티클을 사용하면서 배치를 줄여보자. (1) | 2021.07.26 |
---|---|
[유니티] 타일맵 팔레트 단축키 모음 (0) | 2021.06.23 |
[유니티] 게임 패드 Input - Xbox (0) | 2021.06.13 |
[유니티] dll(동적 링크 라이브러리) 빌드시 참고 (0) | 2021.05.11 |
[Unity iOS] 유니티 iOS 진동 구현 (0) | 2020.12.21 |