씬 만들 때
Basic(URP): 카메라와 디렉셔널 라이트 1개가 있는 상태로 시작
Standard(URP): 카메라와 디렉셔널 라이트에 포스트 프로세스가 적용되어 있고, 포스트 프로세스에는 톤 매핑(Tone mapping)과 블룸(Bloom)이 적용된 HDR 씬 구조로 시작
오브젝트 확대 : 단축키 F 혹은 더블 클릭
셰이더 만들기 : Project 창 > Create > Shader Graph > URP > Unlit Shader Graph
셰이더 적용 방법
셰이더의 '폴더'를 바꾸려면 셰이더 그래프에서 '폴더명과 경로'를 적어주어야 한다.

셰이더 선택할 때 기본 경로는 'Shader Graphs'로 돼있는데, 여러 개 만들다보면 한 폴더에 전부 몰려서 정리가 안됨.
Shader Graph 창 좌측 상단에서 셰이더 그래프 이름 아래에 있는 작은 글씨를 더블 클릭해서 경로를 바꿔주면 됨.
아예 지워버리면 루트에 노출됨. '/'를 사용해서 여러 디렉토리로 나눌 수도 있음.
셰이더 그래프 수정 후 Save Asset 또는 Ctrl+S로 저장하는거 잊지 말기
Properties : 셰이더의 UI를 담당. 오브젝트 선택했을 때 머테리얼에 나오는 셰이더 옵션 제어하는 부분.
(Blackboard나 Graph Inspector가 안 보이면 우측 상단 버튼 눌러서 표시)
좌측 상단의 +를 눌러서 프로퍼티 만들 수 있다.
Name : 이름. 한글도 가능. (버전 따라 실수로 한글 지원 안될수도)
Refernece : 입력 받은 값에 접근할 때의 변수명.
_ 를 붙여서 외부에서 들어온 값이라는 걸 알기 쉽게 하면 좋다.Color Property를 만들고 Graph Inspector > Mode를 확인하면 HDR 옵션이 있다.
Color는 float4 (Vector4)와 기본적으로 같지만,
Color는 float4와 다르게 Linear가 아니라 sRGB로 취급된다는 차이가 있다
하지만 유니티 2D를 사용하면 완전히 똑같다. 이유는 나중에.
평범한 2D 텍스쳐를 받을 수 있다. 매우 많이 사용한다.
Mode : 이 프로퍼티에 텍스쳐 없을 때 기본 색깔. 일반적으로 White나 Black. 노말맵 텍스쳐 받는 Property는 NormalMap 사용.
텍스쳐 Tiling, Offset 조절 기능 : Node Settings > Use Tling and Offset
Cubemap : 스카이박스나 반사용 텍스쳐처럼, 주변을 360도로 감싸는 좌표를 가진 텍스쳐.
Graph Inspector
Node 생성 : 스페이스바, 또는 우클릭 > Create Node

'Color를 만들어 Fragment의 Base Color로 출력한다'는 명령.
노드 만들고 색상 바꿀 때 Property와 연결해놓으면 머테리얼 Inspector에서 색상 선택 가능. 방법은 2가지.
한 자리 숫자(Float)를 어딘가에 연결하면 그 곳의 비어있는 모든 자리에 들어간다.
근데 두 자리 필요하면 두 자리를, 세 자리 필요하면 세 자리 넣는게 자연스럽고 안전하다.

XYZ에 들어간 값은, RGBA에 차례대로 배정. A에는 아무런 값도 안 들어갈 것.
R에는 1, G,B에는 0 들어갈 거고 A는 자동으로 0될 것.
값을 다시 합쳐줄 수 있다

Ctrl+G 누르거나 우클릭 > Group Selection.Ctrl+U 누르거나 우클릭 > Ungroups Selection 더하기 : Add 노드
곱하기 : Multiply 노드
빼기 : Substract 노드
나누기 : Divide 노드
반전 : One Minus 노드
블랜드 : Blend 노드
숫자가 1을 넘어가면? : 1 이상일 때 Bloom 효과 발생하도록 Post Process 상태가 되어있다면 (처음 프로젝트 만들 때 Standard로 만들었다면) 빛나는 것처럼 보인다.
RGB(0.5,0.5,0.5)인 Vector3 노드 2개를 Add 노드로 합치면 흰색이 되지만,
RGB(0.5,0.5,0.5)인 Color 노드 2개를 합치면 약간 밝은 회색이 된다.
(0이나 1이면 상관 없음)
굳이 안 더해도 Color 회색이 숫자 0.5로 만든 회색보다 어둡다.
Color에는 sRGB 처리가 돼있어서 숫자 회색의 Linear와는 다르기 때문.
이를 사람의 색 감각에 맞추기 위한 색상보정인 '감마 코렉션'이라 한다.
감마 코렉션?
인간 눈은 어두운 부분의 변화에 민감하기 때문에, 모니터는 인간의 감각에 맞추기 위해 중간 부분을 어둡게 끌어내림. 이것을 감마(Gamma)라 부름.하지만 그렇게 되면 원래 이미지보다 어두워지기 때문에, color는 sRGB 공간이라는 밝은 영역으로 저장됨. 셰이더로 불러올 때 감마가 연산되어 다시 원래 색으로 돌아옴.
Color를 제대로 연산하려면 Color 노드를 Linear 공간으로 만들어야 함.
Colorspace Conversion 노드를 만들고, Linear > RGB로 컬로 공간 변환을 하면 컬러가 정상적으로 돌아온다.

여기까지 잘 이해 안되면, '컬러는 무조건 Colorspace Conversion으로 Linear > RGB로 해주는게 옳은 계산'이라고 외워도 된다.
(유니티 3D URP의 기본 컬러 공간이 Linear라서 생기는 문제다. 2D URP로 프로젝트를 만들면 컬러 공간이 Gamma가 되면서 이런 문제가 발생하지 않는다.)
카메라를 Scene 뷰에서 보이는 시점으로 옮기기 : GameObject > Align With View
AI Navagarion 설치 > Terrain에 Navmesh Surface > Bake > Player에 Navmesh Agent 컴포넌트 추가

(Troubleshooting) Navmesh 구웠는데 안 보임. 모든 걸 확인했는데 bake가 안됨. 우측 하단 AI Navigation > Surfaces > Show Navmesh 토글 켰더니 보이기 시작.
public class Mover : MonoBehaviour
{
[SerializeField] Transform target;
[SerializeField] NavMeshAgent navMeshAgent;
void Update()
{
navMeshAgent.destination = target.position;
}
}
이러면 Navmesh agent를 붙인 오브젝트가 Navmesh surface를 따라 간다.
Generated Links
강의에선 오브젝트 우측 Static이 설정돼있지 않으면 Navmesh Bake할 때 인식하지 못한다고 했지만, 버전이 올라가서 그런가 알아서 잘 인식해줬음.
동적으로 움직이는 물체를 피해가도록 설정 : (강의에서 말하기론 Static을 풀고) Navmesh Obstacle 컴포넌트 추가. Carve를 설정하면 접근 금지 범위가 넓어진다.
Advanced
if (Input.GetMouseButtonDown(0))
{
lastRay = Camera.main.ScreenPointToRay(Input.mousePosition);
}
Debug.DrawRay(lastRay.origin, lastRay.direction * 100);
void Update()
{
if (Input.GetMouseButtonDown(0))
{
MoveToCursor();
}
}
private void MoveToCursor()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
bool hasHit = Physics.Raycast(ray, out hit);
if (hasHit) navMeshAgent.destination = hit.point;
}
파라미터 확인 : 파라미터 괄호에 커서 두고 Ctrl+Shift+Space
VS Code 키보드 단축키 모음 보기 : Help > Keyboard Shorcuts References
void Update()
{
transform.position = target.position;
}
시네머신 없이 follow camera 구현하기 위해 follow camera라는 빈 게임 오브젝트 생성하고 main camera를 자식으로 두기
원래 있던 Player 게임 오브젝트에서 Mesh Filter, Collider 지우고 애셋 프리팹 추가해준 후에
Navmesh Agent에서 Base Offset을 0으로 바꿔주고 Radius를 조정함.
Animator 컴포넌트 : Animator Controller를 통해 게임 오브젝트에 애니메이션 할당
Animator Controller : 애니메이션과 애니메이션 전환 모음 (state machine)
Blend Tree : 여러 개의 애니메이션 자연스럽게 섞기
Character를 위한 Animator Controller 생성 > Animator 창 우클릭 > Create State > From New Blend Tree > 생성된 노드 더블 클릭 > Inspector에서 Motion의 + 버튼, Add Motion Field > (애셋에 있던 motion들 사용) > 우측 하단 Blend Tree에서 재생하고 슬라이더를 조절하여 테스트
만들었던 Controller 적용하고, 애셋에 있던 Avatar 적용하고, Apply Root Motion 체크 해제 확인
해야 하는 것
Animation Clip > Inspector > 하단 Average Velocity를 보면 애니메이션의 이동 속력이 있다.
Blend Tree의 Inspector > Automate Threshholds > Compute Thresholds > Velocity Z : Average Velocity에 맞게 조정된다.
Navmesh Agent 컴포넌트 > Speed를 최고 Threshhold로 변경한다.
InverseTransformDirection : 글로벌을 로컬로 변환
월드 좌표계 기준인 Navmesh Agent의 속도를 현재 게임 오브젝트 기준의 로컬 방향으로 변환한다.
private void UpdateAnimator()
{
Vector3 velocity = navMeshAgent.velocity;
Vector3 localVelocity = transform.InverseTransformDirection(velocity);
float speed = localVelocity.z;
GetComponent<Animator>().SetFloat("forwardSpeed", speed);
}
Navmesh Agent의 Angular Speed와 Acceleration을 조절하여 움직임 자연스럽게 조정
void Update()
{
if (Input.GetMouseButton(0))
{
MoveToCursor();
}
UpdateAnimator();
}
GetKey : 해당 키 누르는 동안 true 반복적 반환
GetKeyDown : 해당 키 누르면 단 한 번 true 반환
GetKeyUp : 해당 키 누름 해제되면 true 한 번 반환
void LateUpdate()
{
transform.position = target.position;
}
플레이어가 이동한 후에 카메라를 움직여야 하니까 카메라 이동 로직은 LateUpdate()

t:material 이런 식으로 검색하면 머테리얼만 검색 가능. 물론 검색창 오른쪽에서 태그 설정도 가능.