Udonsharp이란


기존의 기하학적 아름다움을 추구하는 Udon Graph(우동그래프) 방식 대신,

간결하고 깔끔하게, 그리고 C#의 기능까지 추가한 개발 방식이 바로 Udonsharp임.

개인적으로 파이썬이라도 건들여본 적 있다면 우동샾을 강력 권장함.

물론 Type나 흐름제어(if, for, while), 은닉(public, private), 함수 개념들이 친숙하진 않겠지만, 조금이라도 고차원의 월드를 만들고 싶다면 필수적으로 익혀야 할 거임.




기본 구조

모든 유니티의 스크립트는 이벤트(Event)를 통해 실행됨.

UdonSharpBehaviour도 기존 유니티 이벤트에, Vrchat에서만 존재하는 특별한 이벤트가 추가로 붙음.


아래는 대표적인 이벤트들임.


Start - 처음 켜지면 작동됨. 초기 설정 해줄때 편함 

맵 만들때만 보이고, 실행하면 가리는 목적인 경우 이곳에 작성하면 원하는 대로 작동함.

Update - 매 프레임마다 작동됨.

사실 이걸 남발하면 매우 느려져서, 특별히 사용할 일은 없음. (본인은 아직 써본적 없음)


OnTriggerEnter - 콜라이더(collider)에 부딧히기 시작한 순간에 한번 작동함.

내가 몬스터에 부딧혔는지, 아니면 아이템에 부딧혔는지 처음 판단할때 사용함.

이게 있으려면 반드시 collider가 필요하고, Trigger 셋팅이 되어 있어야함. 아니면 collision 사용.
(트리거로 해야 플레이어가 통과할 수 있음)

주로 셋트로, OnTriggerEnter - OnTriggerStay - OnTriggerExit / 시작한번, 계속 반복, 탈출한번


Interact - VRCSDK 에서 추가한 이벤트. 플레이어가 *상호작용* 하면 작동함.
이게 붙으면 이제 물체에 상호작용 할 수 있는 기능이 생김. 만약 플레이어가 상호작용 하면 실행됨.
실제 사용시에는 public override void Interact() 라고 해야하는데, 미리 만들어둔 기능이라 우리가 덮어써서(override) 사용하는 의미임.


OnPickup - 플레이어가 뭔가를 들면 작동함.

당연히 VRC pickup 컴포넌트 추가 해줘야함.
이것도 VRCSDK 에서 추가한 이벤트여서 override 해줘야함.


문 (interact) 와 양털블럭 (OnPickup)의 차이.

것보기엔 똑같지만, 행동은 완전히 다름.



아무튼 종류는 수십가지. 이런 것들을 적당히 이용하면서 "시작점"을 설정 하는거임.



입력


컴포넌트에 값 넣는거.

이건 보통 코드 최 상단에 적음. (클래스 아래, start 위에)


입력은 아래의 경우로 생각해볼 수 있음.

> 나만 써야함! - private
> 누구나 쓸 수 있음! - public

> 나만 써야함! 근데 특별히 inspector(설정창) 에서만 쓸 수 있게 해줄께 - [SerializeField]


private는 보통 코드 내부적으로 쓰이는 값들임. 

생략이 가능함. 위에서 currentPage는 현재 내가 보는 만화책 페이지를 가르키는데, 굳이 외부에서 알 필요는 없기에 private로 설정함.

또는 내부적으로만 쓰이는 값들에도 적용.


public은 외부에서 수정해야 하면 사용함.

만화책 이미지를 할당해주는 images는 외부에서 스크립트로 자동으로 적용시킴. 따라서 외부에서 접근을 해야하니 public.


[SerializeField]가 udonsharp의 기본이라 생각할 수 있음.

저걸 붙여주면 내가 위에서처럼 컴포넌트에서 수정이 가능함. 중요한 설정에 넣어주는 형태.


이거 매우 중요함.


디버깅


코드는 그냥 짜면 됨. 코딩만큼 중요한게 디버깅.

기껏 월드 만들었는데 작동 안하면 매우 슬픔. 그래서 수정하는 기술이 중요한데, 이것도 나름 노하우가 있음.


1. 중요부분에서 Log 출력

아무리 코드를 잘 짜도, 실행하고 보면 왜 작동을 안하는지 알기 어려움.

그래서 중간중간 어디까지 작동했는지 적어주면 좋음.


예를들어서, 이제 책 페이지를 불러올 거임

Debug.Log($"[TabletUdon.udon] loading image [{currentCharacter}-{currentPage + i} and {currentPage + i + 1}]");
처럼 뭘 불러오는지 적어주면 유용함.

Debug.Log($"[TabletUdon.udon] complete to load name [{currentCharacter}-{currentPage + i}]");

그리고 어떤 페이지를 불러오는데 성공 했는지,

Debug.Log($"[TabletUdon.udon] failed to load images");

아니면 싹다 실패했는지.

당연히 내가 알아보기 쉬워야 하니 한글로 적어도 무방함. 다만 코딩하는 사람들은 한/영 누르기가 귀찮아서 그냥 영어로 쓰는거임.


저렇게 적어두면 이제,

이런식으로 (4페이지 만화임)


3-4 페이지를 불러오려고 함 --> 3페이지 성공 --> 4페이지 성공

다음 페이지 불러오려고 함 --> 다음페이지로 --> 5-6 페이지를 불려오려고 함 --> 로딩 실패
(실제로 오류시엔 1-2 페이지로 이동함)

이전 페이지를 불러오려고 함 --> 이전 페이지로 --> -1-0 페이지를 불려오려고 함 --> 로딩 실패


무슨일이 일어나는지 자세히 알 수 있음

특히 코드가 길어질수록 로그는 매우 중요해짐


노란색 양털 잡음 --> 이벤트 받음 - 노란색임 
입력순서는 빨강 / 라임 / 노랑 // 이었음
첫번째 수(i=0) --> 비밀번호 1번째 확인함

두번째 수(i=1) --> 비밀번호 2번째 확인함

세번째 수(i=3) --> 비밀번호 3번째 확인함

비밀번호 테스트 통과함

리셋코드 테스트 실패함 (리셋코드는 검정 //// 임)

시크릿 모드 보여드림


이런식으로 내가 만든 코드의 추적이 가능해짐.



그리고 코드가 많아지거나, 코드끼리 소통하는 상황이라면, 저렇게 앞에 소속을 붙여두면 좋음.


[SendTabletPageInteractEvent] 라는 코드는, 만화책의 페이지를 상호작용 하면 그 이벤트를 주인인 TabletUdon에 보내주는 역할을 함. 그러면 타블렛이 받아서 이전페이지로 가는 기능임.

[SendPickupEvent] 라는 코드는, 블럭을 집었을때 어떤 블럭을 집었는지 알려줌. 그리고 그걸 PasswordMaster에서 받아서 작동하게 됨.

근데 파일끼리 소통을 어떻게 하냐고?



UdonBehaviour간 소통


최상단에 보면 저런식으로 클래스라는걸 만듬.

저걸 굳이 전문적으로 이야기 하자면 "우리는 UdonSharpBehaviour 라는 클래스를 상속받아서 SendBookCollisionEvent 라는 클래스를 만들거임" 인데, 그냥 UdonSharpBehaviour를 배낀 거라고 생각하면 됨.


그러면 우리는 어떨결에 SendBookCollisionEvent 라는걸 만들게 되었음.

그리고 이걸 어디서든 접근할 수 있음.


실제로는 tablet에 내가 집은걸 보내야 하니 TabletUdon을 설정해두었음. (아직 public이 아닌데도 작동하는진 모르겠음)

TabletUdon도 본인이 만든 우동샾 코드. 저런식으로 지정해서,

tabletUdon.FindCharacterName 이라는 걸 불러옴.

TabletUdon에서 만들어둔 public 함수.


당연히 만약 private 라면?

(보호 레벨 때문에 접근 못함 ㅅㄱ)

이런식으로 존재는 하지만, 접근할 수 없다고 = 사용할 수 없다고 말함.

(참고로 udonsharp은 어느파일 몇번째 줄, 몇번째 글자에서 오류났는지도 잘 알려줌)


그러면 나중에 설정만 잘 해두면

사용할 수 있게 되는 거임.



(기타)

플레이어에 관한건 VRCPlayerAPI 에서 관리함

그러나 서버 통신은 모두 Networking 에서 관리함.


그래서 클라이언트를 실행중인 플레이어는 Networking.LocalPlayer 으로 가져오지만, 저 localPlayer는 VRCPlayerAPI 에서 관리함.
근데 플레이어 텔레포트는 플레이어가 하는거니까 Networking.LocalPlayer.TeleportTo() 로 해주면 됨.
이제 처음에는 이상해 보일 수 있지만, 자료형을 알면 바로 이해가 갈거임.

Udon에서 국수가닥 않이어지는게 바로 저 자료형 때문임.



udonsharp 강좌는 주변에 널려서 뭔가 없는 내용만 적어봄.


우동 쉬우니까 님들도 같이 합시다 


:)