미니 과제 프로젝트에서 유일하게 구현에서 유일하게 못한 부분이 Firebase를 활용한 서버 연결이다.
- 횡스크롤 방식의 간단한 전투 구현 프로젝트 수행
- 플레이어 고정되어 있고 1초마다 몬스터에게 100의 대미지 피해를 줍니다.
- 몬스터의 체력이 0이 되면 다음 몬스터가 등장합니다. (플레이어 체력은 없고, 공격만 합니다.)
- Physics.Overlap 사용 적 감지 및 공격
- OnTriggerEnter 및 Collider를 통한 몬스터 대미지 인식
- 몬스터 CSV 데이터 파싱 (Name, Grade, Speed, Health)
- 몬스터 Healthbar 구현 및 이동속도 반영
- 데이터 순서대로 반복해서 몬스터 등장
- 몬스터 선택 시 팝업창을 띄워 정보를 보여줌
선택사항
firebase를 활용한 서버 연결참고
아래의 SampleCSV를 바탕으로 몬스터의 정보를 설정합니다.
- 이외 오브젝트는 기본으로 제공하는 UI 활용합니다.
- 요구사항에 기재되지 않은 항목들은 자유롭게 설정하여 구현합니다.
Firebase에 대해선 아무것도 아는 것이 없었지만, 모바일 게임을 만들기 위해 대부분의 현업 현장에서 쓰일 것이라 하여 추가로 공부하면서 기록한다.
게임을 만들다 보면 로그인이나 랭킹 등 서버를 이용해야하는 것들이 있다. 서버를 직접 만들어도 되지만, 이미 만들어져있는 서버를 제공받아 이용할 수 도 있다. 이런 것을 Backend as a Service라 부른다고 한다.
Firebase는 구글이 제공하는 서비스고, 간단하게 이용 가능하며 초기엔 무료고 사용량에 따라 청구되기 때문에 개인 뿐만 아니라 많은 기업에서도 사용한다고 한다.
기본 베이스가 하나도 없기 때문에 동영상을 보면서 필요한 부분을 적용하고 있다.
오늘코딩 - [유니티] 파이어베이스로 회원가입과 로그인 구현하기
https://www.youtube.com/watch?v=harSUx-aIzo
파이어베이스 Storage에 CSV파일을 올렸고, 패키지를 설치했다.
FirebaseStorage.unitypackage
저장소 주소
예시 : storageRef = storage.GetReferenceFromUrl("gs://주소/SampleMonster.csv");
그리고 코루틴을 이용해 파일을 받는다.
private IEnumerator LoadCSV()
{
var task = storageRef.GetDownloadUrlAsync();
yield return new WaitUntil(() => task.IsCompleted);
// 에러 처리
if (task.Exception != null)
{
Debug.LogError("URL 오류");
yield break;
}
// URL 이용해서 유니티 웹 리퀘스트
string url = task.Result.ToString();
UnityWebRequest www = UnityWebRequest.Get(url);
yield return www.SendWebRequest();
// 에러 처리
if (www.result != UnityWebRequest.Result.Success)
{
Debug.LogError("CSV 파일 다운 실패");
yield break;
}
string csvData = www.downloadHandler.text;
ProcessCSV(csvData);
}
private List<EnemyData> ProcessCSV(string csvData)
{
StringReader reader = new StringReader(csvData);
List<EnemyData> enemyDataList = new List<EnemyData>();
bool isFirstLine = true;
while (reader.Peek() > -1)
{
string line = reader.ReadLine();
if (isFirstLine)
{
isFirstLine = false;
continue; // 첫 라인 건너뜀
}
string[] values = line.Split(',');
EnemyData data = new EnemyData
{
Sprite = dataManager.EnemySprite[int.Parse(values[0])],
Name = values[1],
Grade = values[2],
Speed = float.Parse(values[3]),
Health = float.Parse(values[4])
};
enemyDataList.Add(data);
}
return enemyDataList;
}
작동이 안되고 위와 같은 에러 메세지가 출력되었다. 파이어베이스 초기화가 안 된 것 같다.
해당 오류는 파이어베이스 설정 파일인 google-services.json 또는 google-service-desktop.json이 누락되었거나 잘못된 형식일 때 발생한다고 한다.
이 파일들은 Firebase 프로젝트와 Unity 프로젝트를 연결하는 데 필요하다.
이 파일은 Unity 프로젝트의
Assets/StreamingAssets
폴더에 추가해야한다.
또한 기본적으로 파이어베이스는 모바일을 지원하므로, 데스크톱에서 사용하려면 google-services.json을 복사하여 google-service-desktop.json으로 변경해줘야 한다고 한다.
이 파일도 스트리밍 애셋 폴더에 똑같이 넣으면 된다.
void Start()
{
StartCoroutine(Init());
}
private IEnumerator Init()
{
// CSVLoader가 enemyDataList를 설정할 때까지 기다림
while (enemyDataList == null || enemyDataList.Count == 0)
{
yield return null;
}
CreateEnemy();
}
// 에러 처리
if (task.Exception != null)
{
Debug.LogError($"URL 오류: {task.Exception}");
yield break;
}
프로젝트 초기화와 패키지를 다시 한 번 확인했는데도 안되서 위와 같은 코드로 찾아보려한다.
URL 오류: System.AggregateException: One or more errors occurred. (User does not have permission to access this object.) ---> Firebase.Storage.StorageException: User does not have permission to access this object.
--- End of inner exception stack trace ---
---> (Inner Exception #0) Firebase.Storage.StorageException: User does not have permission to access this object.<---
UnityEngine.Debug:LogError (object)
CSVLoader/<LoadCSV>d__4:MoveNext () (at Assets/01_Scripts/Utility/CSVLoader.cs:43)
UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr)
스토리지 접근 권한이 없기 때문이라고 한다. 이를 고치기 위해 파이어 베이스 보안 규칙을 수정해야한다.
Firebase Console에서 보안 규칙 수정:
• Firebase Console에서 프로젝트를 선택
• Storage 섹션으로 이동
• 규칙 탭을 선택
• 보안 규칙을 수정하여 읽기 권한을 부여
기존 인증 규칙
rules_version = '2';
// Craft rules based on data in your Firestore database
// allow write: if firestore.get(
// /databases/(default)/documents/users/$(request.auth.uid)).data.isAdmin;
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if false;
}
}
}
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
// 모든 사용자에게 읽기 권한 부여
allow read: if true;
// 쓰기 권한은 필요에 따라 설정
allow write: if request.auth != null;
}
}
}
모든 사용자에게 읽기 권한을 부여하고, 인증된 사용자에게만 쓰기 권한을 부여한다.
이는 개발 중에는 모든 사용자에게 부여하지만, 보안에 취약해지므로 배포 전에 적절한 인증 및 권한 설정을 필요로 한다.
올라간 CSV파일로 적용 완료!