분류 전체보기 10

모델링 표현 - 2 (언리얼이 그래픽이 더 좋은 이유)

왜 언리얼로 만든 게임이 평균적으로 유니티로 만든 게임보다 그래픽이 더 좋아보일까? 이것을 한번 분석해보자. 사실 유니티로도 좋은 그래픽의 게임을 만들 수 있다. 대표적인 예시가 타르코프이다. 타르코프는 유니티로 만들었지만 뛰어난 그래픽을 보여준다. 또한 유니티의 HDRP를 이용한다면 언리얼 못지않은 그래픽을 보여줄 수 있다. 하지만 이런 뛰어난 그래픽을 유니티에서 보여주려면 셰이더, HDRP, 랜더링 등 유니티를 깊게 공부해야한다. 유니티는 게임개발을 처음 입문하는 사람들이 쉽게 게임을 만들 수 있도록 이러한 것들을 깊게 공부하지 않아도 만들 수 있게 해두었다. 그래서 언리얼보다 비교적 쉽게 게임을 만들 수 있지만 그만큼 퀄리티가 떨어진다. 반면에 언리얼은 비교적 입문하기 어렵지만 기본값으로 높은 수준..

Shader 2023.01.12

모델링 표현 - 1 (게임 그래픽을 향상 시키는 방법)

게임을 하려면 여러 요소가 필요하다. 맵, 오브젝트, 플레이어 등등. 이러한 요소들을 게임엔진에서 구현하려면 3D 모델링 툴에서 모델링을 하여 가져와야 한다. 그런데 이런 모델링 하나만 가지고는 좋은 그래픽을 지원하는 게임을 만들기 힘들다. 그렇다면 좋은 그래픽을 지원하려면 어떠한 것들이 필요할까? 크게 네가지로 나누어 보았다. Texture, Shader, Material, Mesh 1. Texture 텍스쳐도 여러 종류의 텍스쳐가 있다. 물체의 색, 질감, 투명도 등을 텍스쳐에 담아 표현할 수 있다. 아래 사진은 한 에셋 사이트에서 돌 에셋을 받아왔을 때 그 돌에 들어있는 텍스쳐들이다. (해당 에셋 링크는 글 마지막에 첨부) 순서대로 Albedo, Emission, Metallic, Normal 텍스..

Shader 2023.01.11

유니티 Shader Graph 입문

우선 Shader Graph가 무엇일까? Shader는 컴퓨터 그래픽에서 물체를 최종적으로 화면에 그릴 때 사용하는 함수이다. 라고 많이들 하는데 잘 감이 안온다면 구글에 "마인크래프트 셰이더" 라고 검색해 보고 이미지들을 봐보자. 아마 셰이더를 적용하기 전에 보았던 마인크래프트보다 훨씬 예쁜 장면들이 나올 것이다. 내가 알던 마인크래프트는 네모네모난 세상이였는데 이런 사진들을 보면 전혀 다른 세상이 나온다. 셰이더가 뭐길레 이렇게 보이는 것일까? 컴퓨터에서 마인크래프트 세상을 우리 화면에 보이게 하기 위해서는 여러 과정들을 거친다. 그 과정들은 아래 링크에서 자세하게 설명해 준다. 마인크래프트에 셰이더를 적용하면 화면에 마인크래프트 세상을 보여주기 전에 한번 더 작업을 거쳐 아름다운 모습으로 보여준다...

Shader 2023.01.09

MonoBehaviour

유니티에서 C#스크립트를 하나 만들어보자. 그럼 아래 사진처럼 기본 내용이 만들어질 것이다. 그런데 항상 기본적으로 MonoBehaviour를 상속한다. MonoBehaviour이 도대체 무엇이길레 상속하는 것일까? 이 MonoBehaviour를 지워보면 어떤일이 일어날까? 아래 사진을 보면 지우기 전에는 "Start는 Update 메서드가 처음으로 호출되기 바로 전에 호출됩니다." 라고 뜨지만 지우고 나면 "프라이빗 맴버 "NewBehaviourScript.Start()"를 사용하지 않습니다." 라는 경고문이 뜬다. MonoBehaviour를 상속하는 동안에는 Start를 Update를 호출하기 전에 처음 한번 호출되는 유니티의 메서드로 인식하지만 상속을 하지 않을때는 하나의 프라이빗 맴버 함수로 본다..

Unity 분석 2023.01.08

Enum의 활용

내가 Enum을 처음 배웠을 때 든 생각은 "저걸 어따쓰지" 이였다. 상수에 이름을 붙여서 어떠한 이득을 주는지 알지 못했고 그것이 필요한 상황을 만나지 못했기 때문이다. 하지만 프로젝트를 같이하던 한 프로그래머 분이 이것을 활용하는 것을 보았고 그때부터 Enum의 활용과 필요성에 대해 느끼게 되었다. enum Item { axe, //0 meat, //1 rope = 5 //5 stone = 10 //10 } enum은 쉽게 말하면 상수에 이름을 붙이는 것이다. 위처럼 Item을 선언하면 Item.axe는 0, Item.meat는 1이 된다. 이러한 Enum을 이용하면 아이템처럼 특정 이름에 인덱스를 필요로 하는 경우에 활용될 수 있다. enum Item { axe, //0 meat, //1 rope ..

Unity 분석 2023.01.07

코루틴의 작동방식

코루틴은 작업을 다수의 프레임에 분산시켜서 실행할 수 있는 문법이다. 여기에서 작업을 다수에 프레임에 분산 시킨다는 것은 한 함수를 해당 프레임에서 호출했을 때 일반적으로는 그 프레임에서 모두 실행을 한다. 하지만 코루틴은 이러한 작업을 그 함수를 실행한 프레임에서 한번에 실행시키는 것이 아니라 여러 프레임에 나누어서 실행시킬 수 있다. https://docs.unity3d.com/kr/2021.3/Manual/Coroutines.html 코루틴 - Unity 매뉴얼 코루틴을 사용하면 작업을 다수의 프레임에 분산할 수 있습니다. Unity에서 코루틴은 실행을 일시 정지하고 제어를 Unity에 반환하지만 중단한 부분에서 다음 프레임을 계속할 수 있는 메서드입니 docs.unity3d.com using Sy..

Unity 분석 2023.01.06

메모리 구조와 유니티 - GC에 대한 심층적 이해

개발을 하다보면 "메모리가 낭비된다", "메모리 누수" 등 메모리를 효율적으로 사용해야 한다는 내용들이 많이 나온다. 그렇다면 어떻게 하면 우리가 게임을 만들 때 메모리를 아낄 수 있을까? 내가 쓴 코드에서 어느 부분이 저장될까? 유니티에서 C# 스크립트를 할 때 메모리가 어떻게 할당되고 사용되는지 알아보자. 위 사진은 컴퓨터 메모리 구조이다. 프로그래밍에 대해 배우다 보면 한두번쯤은 봤을 것이다. 메모리는 크게 코드, 데이터, 힙, 스택 영역으로 나뉘어 저장된다. 아래 예제를 통해 어느 부분이 어디에 저장되는지 알아보자. using System.Collections; using System.Collections.Generic; using UnityEngine; [System.Serializable] p..

Unity 분석 2023.01.05

GameObject.Find()

GameObject.Find(string name) 함수는 찾고자 하는 오브젝트의 이름을 안에 넣으면 해당 이름을 가진 오브젝트를 찾아준다. ex) using UnityEngine; public class Find : MonoBehaviour { private GameObject player; private void Start() { player = GameObject.Find("Player"); } } 하지만 나는 이 GameObject.Find() 함수를 최대한 지양한다. 그 이유는 다음과 같다. 1. 오브젝트의 이름이 바뀌거나 중복되는 경우 이 함수를 여러 스크립트에 남용을 했다가 개발도중에 해당 오브젝트의 이름이 바뀌는 경우가 생길 수 있다. 이런 경우 해당 함수를 썼던 스크립트를 모두 수정해야 ..

Unity 분석 2023.01.04

물체가 이동하면서 얇은 벽을 통과하는 경우

위 사진은 벽과 공에 모두 콜라이더와 Rigidbody를 넣었으나 서로 영향을 미치지 못한 상황이다. 이러한 현상이 왜 발생할까? 원인은 아래 코드에 있다. using UnityEngine; public class Move : MonoBehaviour { void Update() { if(Input.GetKey(KeyCode.A)) { transform.position += Time.deltaTime * new Vector3(-20, 0, 0); } } } 이 코드는 A 버튼이 눌렸을 때 1초에 -20만큼 좌측으로 공을 이동시키는 코드이다. 이때 벽이 너무 얇아 이동하는 도중에 벽을 지나쳐 버린 것이다. 이러한 문제를 해결하기 위해서는 여러가지 방법들이 있다. 그중 하나는 Raycast를 사용해서 앞에 ..

Unity 분석 2023.01.04

FixedUpdate

FixedUpdate는 유니티에서 물리연산을 하는데 최적화된 함수이다. 그렇다면 이 FixedUpdate가 무슨 이점을 주길레 물리연산을 할때 써야할까? 아래는 같은 코드를 FixedUpdate문과 Update문에 넣고 실행한 결과이다. 위에 있는 동그라미가 FixedUpdate, 아래에 있는 동그라미는 Update로 실행한 것이다. using UnityEngine; public class Move : MonoBehaviour { void Update() { if(Input.GetKey(KeyCode.A)) { transform.position += Time.deltaTime * new Vector3(-10, 0, 0); } } } using UnityEngine; public class MoveFixe..

Unity 분석 2023.01.04