일전 콘솔 프로젝트에서 개인 프로젝트를 진행하면서, Git으로 버전 관리하는 방법에 대해 배운 바가 있다. 하지만 Git으로 개인 작업만 하는 것이 아닌, 팀 프로젝트나 협업을 해야 할 때가 있을 것이다.
오늘은 Git으로 협업하는 방법과, 유니티 작업물을 Git으로 관리하는 방법에 대해 알아보고자 한다.
콘솔 프로젝트와 달리 관리방법이 아주 달라지는 것은 아니지만, 의외로 유니티를 깃으로 관리하는 방법은 기존 비주얼 스튜디오 관리보단 어려웠다. 하지만 내 나름대로의 유니티 깃 등록 방법을 정리하고자 한다.
깃을 먼저 만들고, 해당 이름으로 프로젝트 이름이 확정된다는 느낌으로 가면 된다.
우선은 원하는 경로에 깃을 생성한다. 여기서 Git Ignore을 Unity로 꼭 설정하도록 한다!
그러면 이와 같이 깃이 생성된 것을 확인할 수 있다.
이제 다음으로 유니티 허브로 들어가서 프로젝트 생성을 한다.
아까 깃을 생성한 폴더에 유니티 프로젝트를 생성한다.
유니티가 잘 생성된 것을 확인하면 종료한다.
이제 깃허브로 돌아가보자.
13791개의 요소가 추가된 것을 확인할 수 있다. 이건 지금 잘못된 상황이다(Unity ignore가 적용되지 않은 상황)
그래서 해당 내용을 바꾸기 위해서 해당 폴더 경로로 들어간다.
내용을 보면 깃 구성품 안에 유니티 프로젝트 폴더가 생긴 것을 확인할 수 있다. 여기서 UnityTest 폴더 내의 내용물을 전부 꺼내줘야 한다.
해당 내용물을 전부 Git과 같은 위치로 꺼내준다.
이와 같이 한 후 깃허브를 다시 확인해보자.
변동사항이 28개로 줄었다. 이게 정상적으로 Git Ignore가 적용된 상황이므로 이대로 커밋을 한다.
하지만 여기서 또 문제가 생길 수도 있다.
다시 해당 프로젝트를 유니티 허브로 열어보려고 하니, 파일을 열 수 없다고 뜬다.
여기서는 안 열리는 프로젝트를 삭제한다.
그 다음으론 Add를 통해 프로젝트를 다시 열어본다.
이제 처음 깃으로 만들었던 이름으로 프로젝트가 생성되며 프로젝트가 정상적으로 열리는 것을 확인할 수 있다.
유니티 프로젝트를 만들다 보면 에셋을 사용하는 경우가 많을 것이다. 하지만 에셋을 깃으로 다운 받으면 해당 내용 또한 깃으로 변동사항이 뜨는 것을 확인할 수 있다.
이런 에셋의 내용 또한 깃으로 커밋해버리는 건 위험성이 있다. 구매한 것이라고 하더라도 소스파일을 그대로 올리는 것이기 때문에, 저작권이라든지 불법 배포 문제가 발생할 수 있기 때문이다. 그러면 이런 것들은 어떻게 관리해야 할까?
관리를 위해 에셋은 전부 Imports 폴더 안으로 넣어 관리하기로 한다.
여기서 이제 Imports 폴더를 무시하기로 설정하면 해당 내용은 앞으로 깃으로 뜨지 않게 설정한다. 이와 같이 외부 자료 및 에셋 등의 요소는 앞으로 Imports 폴더로 따로 관리하여 사옹하는 방식으로 하도록 한다.
해당 내용을 깃에도 기록해 두면 좋다.
이와 같이 하면 에셋만 따로 깃에서 뺀 채로 작업할 수 있다.
다만 이와 같이 작업했을 경우 이런 문제가 발생할 수 있다.
이와 같은 경우 에셋을 팀원들과 공유하는 추가적인 작업이 필요하다. 이를 위한 방법으론 에셋을 개인적으로 공유하는 방법을 사용해야 한다.
이와 같이 에셋을 관리하는 방법에 관해 유의하며 협업을 할 수 있도록 하자.
협업으로 게임 개발을 할 경우, 회사나 팀에서 정해진 깃 커밋 메시지 규칙이 있을 것이다. 그것을 준수하는 것을 기본으로 하되, 아래와 같은 보편적인 규칙 또한 참고할 만하다.
키워드 | 내용 |
---|---|
feat | 새로운 기능 추가, 기존의 기능을 요구 사항에 맞추어 수정 |
fix | 기능에 대한 버그 수정 |
build | 빌드 관련 수정 |
chore | 그 외 기타 수정 |
ci | CI 관련 설정 수정 |
docs | 문서(주석) 수정 |
style | 코드 스타일, 포맷팅에 대한 수정 |
refactor | 기능의 변화가 아닌 코드 리팩터링 |
test | 테스트 코드 추가/수정 |
release | 버전 릴리즈 |
하나의 기능을 개발하기 위한 분기를 두어, 협력자들끼리 기능을 분담하여 개발하는 방식이다.
협업이 진행되는 방식은 다음과 같다.
해당 프로세스가 돌아가는 원리를 설명하자면 간단하게 아래와 같이 설명할 수 있다.
그러면 실제로 이런 Branch를 추가하고, 각각 작업하는 과정이 어떻게 이루어지는지 살펴 보자.
Branch를 생성해보자.
작업하는 사람이 한 명 더 왔다고 했을 때, Branch를 생성할 위치를 정해서 또 생성해 주면 된다.
이때, 각각의 작업자가 각자 1스테이지, 2스테이지를 만들고 있을 때, 그 둘 사이의 내용을 공유되지 않는다.
따라서 택의 시점에서는 Level1 씬만 있고, 훈의 시점에서는 Level2 씬만 있다.
이 둘의 작업상황을 살펴보기 위해 Open in Visual Studio Code를 눌러보자.
Git 그래프 확장을 깔아놓은 상태면 해당 커밋 상황을 살펴볼 수 있다.
만약 어떤 기능을 구현하였고 해당 기능을 메인에 병합하려 할 때, 아래와 같은 방식으로 병합할 수 있다.
메인을 먼저 활성화시킨다. 여기서 붙이고 싶은 Branch를 선택한다.
Merge Commit을 진행한다.
(아래 두 가지의 경우도 유용한 방식이나, 리스크가 있어 지금 단계에선 가장 리스크가 적은 Merge Commit을 사용한다.)
이와 같이 각 작업자가 Branch를 만들면 해당 사항을 Visual Studio Code로도 현황을 확인할 수 있다.
가령, 이런 상황이 발생할 수도 있다.
플레이어 스크립트를 만드는 사람이 두 사람이 있다고 하자 (다만, 이런 방식이 권장 방식은 아니다)
프로그래머 A는 플레이어의 체력을 30으로 설정하였고, 프로그래머 B는 플레이어의 체력을 5로 설정하였다.
프로그래머 A가 먼저 메인과 파일 병합을 했고 프로그래머 B가 뒤늦게 병합을 시도하였을 때 무슨 일이 벌어질까?
이와 같은 상황에서 충돌이 발생한다. 깃허브는 이런 상황에서 플레이어의 체력을 30으로 설정할 지, 5로 설정할 지 결정내릴 수 없기 때문이다.
위와 같은 상황이 실제에서 어떻게 벌어지는 지 확인해 보자.
프로그래머 택은 체력 30으로 merge를 진행하면 정상적으로 merge가 진행된다. 하지만 프로그래머 훈이 merge를 진행할 때, 아래와 같이 경고가 뜨게 된다.
해당 경고를 인지하고 merge를 진행하려 하면 아래와 같이 어떤 내용에서 충돌이 발생하는지 알려준다.
해당 내용을 해결할 때까지는 merge가 불가능하며, 비주얼 스튜디오 코드로 열어보라는 알림이 뜬다. (비주얼 스튜디오로도 켤 수 있음)
내용을 확인하기 위해 비주얼 스튜디오를 켜 보자.
이러한 충돌이 발생했을 때에는, 명심해야 할 내용이 있다.
충돌이 발생했을 경우, 임의로 변경하지 말고
꼭 팀원 전체가 모여서 회의를 진행한 후 변경하도록 한다.
이것을 원칙으로 하며, 위와 같은 상황에서 문제 해결을 위해 아래와 같이 토의하여 선택하고, 진행해 주면 된다.
이런 식으로도 진행할 수도 있다.
위에서 충돌에 대해 배워보았다면, 충돌이 발생하지 않게 하도록 유의해야 하는 것을 알 수 있을 것이다.
그러면 충돌이 일어나지 않도록 하기 위해서 어떻게 해야 할 지에 대한 고민이 필요하다.
아래에서 해당 문제의 발생을 미연에 방지하기 위한 조언과 규칙을 정리했다.
충돌이라는 것이 발생하는 전제 조건 자체가, 하나의 파일을 두 사람 이상이 같이 작업하면서 발생한다.
따라서 충돌 방지를 위해서, 협업을 하는 상황에서는 Branch로 각자의 파일을 만들고 각자의 공간에서 작업하는 것이 좋다. 상대방의 파일을 왠만하면 건들지 않는 상황을 만들도록 하자.
씬 또한 위의 상황처럼 충돌이 발생할 수 있다. 하지만 코드 상에서의 충돌이 일어나는 것보다 훨씬 복구가 어렵다.(사실상 복구가 불가능하다고 봐야함)
씬에서 충돌이 나는 상황을 일부러 발생시켜 보고, 어떻게 해결하라고 뜨는지 살펴보자.
(훈이 아이템 하나를 배치했고, 따로 작업한 택이 몬스터 하나를 배치했다는 설정)
분명 아이템의 유무와 몬스터의 유무 정도의 두 개의 충돌밖에 없어야 하지만, 10개의 충돌이 발생한 것을 확인할 수 있다. 해당 문제를 해결하기 위해서 코드를 열어보자.
씬 파일은 이와 같이 C# 코드처럼 한 눈에 파악하기가 힘들다. 해당 코드 전문만 해도 558줄의 코드가 나왔고, 코드 내용을 해석할 수 있다고 해도 사실상 원하는 대로 복구하기가 매우 어려울 것이다.
사실상 해당 문제를 해결하지 못하면 이렇게 씬이 아예 날아가버리는 사태가 발생할 수도 있다.
씬을 제작하기 위해 많은 작업을 했을 수도 있는데 한순간에 날아가버릴 수도 있는 것이다.
따라서 씬을 작업할 때에는 이와 같이 작업해야 한다.
왠만하면 씬을 담당하는 담당자 한 명 만이 씬을 건들 수 있도록 한다. 씬을 관리하는 담당자는, 자신이 씬 작업을 하고 있을 경우 필히 협업자들에게 알린다.
캐릭터 담당자나 몬스터 담당자 등이 씬에 작업물을 배치해야 하는 경우, 씬 담당자에게 자신의 작업 파일을 복사해서 가져가 달라는 식으로 부탁한다. 씬 담당자는 서로 합의가 된 상태에서 해당 파일로 들어가 직접 작업물을 복사해서 붙여넣는 방식으로 한다.
씬 담당자가 아닌 작업자들이 테스트가 필요할 경우, 씬을 직접 복사해서 자신의 파일에서 테스트를 진행하거나, 테스트용 씬을 따로 만들어서 진행 후 작업물을 올린다.
게임사들이 이런 식으로 테스트용 맵에서 테스트를 진행하는 것도 위와 같은 상황의 방지를 위한 일환이다.
유니티 프로젝트에서 작업을 할 때, 게임오브젝트, 프리팹, 스크립트 등 모든 작업물은 meta 파일이 같이 생성된다.
메타 파일의 역할은 해당 작업물의 아이디(GUID)를 담는 정보로, 유니티 상에서 인식하는 파일 양식이다.
따라서 메타파일을 실수로 소실 시키거나, 메타파일의 버전 관리를 하지 않았을 경우 해당 작업물은 사용할 수 없게 된다.
메타파일이 사라진 오브젝트는 이런 식으로 붉은 색으로 바뀌며, 프로젝트에서 사라지게 된다.
위와 같이 큐브가 사라진 모습이다.
따라서 메타 파일 또한 관리에 유의해야 하며, 모든 파일은 파일 원본과 meta 파일을 쌍으로 들고 다녀야 한다고 생각하면 된다.
충돌이 발생했을 경우 모든 팀원이 모여서 회의를 진행해야 한다고 말한 바 있다.
하지만 늘 상시적으로 모여서 토론할 수도 없고, 해당 문제가 발생하기 이전에 방지하는 편이 효율에 좋을 것이다.
따라서, 무작정 Main에 Merge 하는 것이 아니라, Merge를 하기 이전 모두의 동의를 받고서 진행하는 시스템이 있다.
커밋으로 기능을 구현하였을 경우 깃허브 사이트에서 이와 같이 pull request를 권하는 것을 확인할 수 있다.
풀 리퀘스트는 같이 작업하는 팀원에게 자신의 작업물을 merge해도 되는지 확인시키게 하는 작업이다.
그러면 풀 리퀘스트를 해 보자.
이와 같이 설명으로 무엇을 어떤 의도로 구현했는지 작성하고, Create Pull Request를 누르면 풀 리퀘스트가 올라간다.
그러면 이렇게 풀 리퀘스트가 업로드되며, 예를 들어 팀장의 경우 세팅했을 경우 알람도 온다.
해당 상황을 확인하기 위해 풀 리퀘스트를 들어가 다른 팀원들이 코드 검증을 한다.
이와 같이 어떤 파일이 추가되었고 어떤 내용이 들어가 있는지 확인할 수 있다.
해당 내용을 확인하고 이런 식으로 댓글을 달 수도 있고
혹은 아래의 버튼과 같이 승인과 거절을 할 수 있다.
또한 성공적으로 merge가 완료되어 해당 풀 리퀘스트가 종료되었을 경우, 해당 branch를 지워주는 것이 깔끔하다.
해당 내용이 성공적으로 반영된 것을 확인할 수 있다.
이와 같이 협업하는 상황에서는 독단적으로 Merge를 진행하지 말고, 팀원들과 상의를 하여 풀 리퀘스트롤 통해 작업할 수 있도록 한다.
이와 같은 풀 리퀘스트에 대한 것 또한 Setting으로 룰 관리를 할 수 있으니 참고하도록 하자.