- 1차전직 후, 머리 위 전구로 진행하는 스토리 퀘스트. 이것이 완료되어야 2차 전직이 가능
모험가 스토리의 스킵 조건은, 4차 전직을 한 모험가 직업이 있을 것. 즉 한 번은 스토리를 정직하게 밀거나 편법을 사용해야한다.
대표적인 편법으로는, 패스파인더 101레벨과 전직을 빠르게 한 후, 자유전직을 통해 보우마스터나 신궁으로 전직하는 방법이 있다. 자유전직은 '미나르 숲 : 산양의 골짜기1'로 텔레포트 후 전직관이 모여있는 '사제의 숲'으로 이동, 전직관에게 말을 걸어 진행이 가능하다.
만약 패스파인더로 궁성비를 사용해서 200레벨이 된 후 자유전직을 시도하면 4.6억메소를 지출해야 하므로, 101레벨까지 직접 육성할지와 저울질을 잘 해야 한다.
2. 듀얼블레이드
마찬가지로 2차전직을 필요로 하는데, 다른 모험가 직업들과 도중 스토리가 달라진다. 첫 슈가 퀘스트(모험가)는 동일하게 스킵이 가능하고, 직후 리스항구에서부터 독자 스토리를 시작한다.
- 튜토리얼 룸 3단계 클리어 - 넬라, 제이엠, 돈 지오바네 조사 - 탁한 유리구슬 깨뜨리기 : 1.5차 전직 - 머리 위 전구 퀘스트를 통해 헤네시스 이동 - 헤네시스에서 머리 위 전구를 통해 모험가 스토리 스킵 - 좌측 전구 : '[모험가] 비화원으로 돌아가는 법'+스킬 사용 또는 직접 이동을 통해 전직관에게 이동 - 2차 전직 완료 후 유니온 멤버 등록.
2차 전직 퀘스트가 어째서인지 좌측 전구에 뜨지 않아서 직접 설희(전직관)을 찾아가야 한다. 전체 과정 약 10분+ 소요
".env"파일을 ignore 되기 전에 미리 커밋 해 두는 방식도 생각할 수 있지만, 프로젝트의 진행에 따라 필요한 내용이 많아질 수 있어 아래와 같은 방식이 좋을 듯 하다.
WEB_SOCKET_URL=
CHANNEL_ID=
PAGE_IDX=
2. .gitignore에 내용 추가.
/Assets/.env
3. Unity에서 .env 파일 파싱 클래스 작성
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public static class EnvLoader
{
private static Dictionary<string, string> envValues = new Dictionary<string, string>();
public static void LoadEnv(string path)
{
envValues.Clear();
if (!File.Exists(path))
{
Debug.LogWarning($".env 파일이 존재하지 않습니다: {path}");
return;
}
var lines = File.ReadAllLines(path);
foreach (var line in lines)
{
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#")) continue;
var parts = line.Split('=');
if (parts.Length != 2) continue;
var key = parts[0].Trim();
var value = parts[1].Trim();
envValues[key] = value;
}
Debug.Log(".env 파일 로드 완료");
}
public static string Get(string key, string defaultValue = "")
{
return envValues.TryGetValue(key, out var value) ? value : defaultValue;
}
}
2. 이미지(기타 미디어에도 확장 예정)를 우클릭하면, '이미지를 특정 폴더에 저장' 메뉴가 뜨며, 프리셋으로 지정해놓았던 이름이 있어 해당 위치에 저장하게 된다.
개발 실패를 야기한 문제점
**크롬 정책 상 절대경로 참조를 통한 저장이 불가능하다.**
절대경로 저장을 위해서는, 저장 시점에 직접 폴더를 지정하거나 Native Messaging 외부 프로그램을 사용자가 함께 설치해야한다. - 직접 폴더지정의 경우는 애초에 설정한 프리셋이 무용지물이 되며 기존 기능인 '이미지를 다른 이름으로 저장...' 과 차이점이 없다. - Native Messaging 의 경우는 외부 프로그램의 힘을 빌려 연동하는 방식인데, 사용자가 직접 번거롭게 추가 세팅을 해야하는 게 제일 문제이다.
경로를 하드코딩하며 직접 실행 해 보았지만, 역시 기본 다운로드 폴더의 밖을 참조하려고 하면 오류가 발생한다.
즉 알려진 바로는 크롬의 기본 저장위치로부터의 상대경로(저장위치의 자식경로 한정)에만 저장이 가능하며, 이러한 제약사항때문에 확장프로그램의 효용성이 매우 떨어진다.
일단 GPT 자문을 통해, Unity 스타일과 C# 스타일에도 살짝 차이가 있다고 한다. 일단 차이를 확인 해 보면,
두 스타일이 크게 다르진 않은데, - private 멤버변수에 'm_'을 붙이느냐(Unity) 아니면 '_'을 붙이거나 아얘 생략하거나(C#) 할 수 있고 - C# 스타일에서는 public 멤버변수는 프로퍼티 사용을 하는 게 기본 스타일이라고 적혀있는데, 더 찾아보지는 않았다. 그리고 C#은 PascalCase를 사용하는 정도.
종종 변수명으로 private const string SERVER_ENDPOINT = "https://api.example.com"; 이렇게 ALL_CAPS의 경우도 보였는데, 이는 C++에서 주로 사용하는 스타일이고 C#에서는 ServerEndpoint 와 같이 PascalCase를 사용하는 게 권장된다고 한다. 또한 static readonly 변수의 경우에 특히 자주 보이는데 이 역시 PascalCase가 일반적으로 사용된다는 듯. 유니티와는 별개로 환경변수 파일에서는 ALL_CAPS 명명이 일반적이었던 것으로 기억한다.
게임개발 사이드라고 하더라도 유지보수에는 C# 스타일이 낫다고 하고, 개인적으로 m_ 명명법이 낯설어서 C# 스타일을 채택해야겠다.
새로운 서비스(앱, 게임 등) 생성 시, GameData, UserData, OtherData 폴더가 함께 생성되도록 하고, UserData 폴더에는 Info.json 파일을 생성하여 신규 유저의 UID 부여에 참고하도록 한다.
{"next_uid": "000000000"}
유저 정보 생성(회원가입)
회원가입을 위해 서비스 이름, 입력ID, 입력Password와 함께 서버에 요청한다.
서비스가 있는지 확인, 겹치는 유저 ID가 있는지 확인
(입력Password + 16자리의 salt) 를 해시 암호화 한 패스워드를 얻는다
UID의 폴더를 생성하고, Base.json을 작성한다.
uid, id, pass, salt 를 보관한다.
데이터 백업 압축파일 다운로드
백업했던 데이터 업로드하여 복원(덮어쓰기)
게임 데이터 업로드(기존 서버의 게임 데이터를 덮기)
게임 데이터 GET
로그인 기능
SERVICE 내 ID PASS 검증.(즉 이 세 요소를 서버에 같이 전송해야함)
토큰발행 후 유저에게 전송, 서버에 보관, (토큰-UID) 쌍이면 괜찮으려나
아까 UserData 폴더 내에 Info.json 파일로 UID 관리했듯이, Token.json 하나 미리 마련해두고 여기에서 동적으로 관리하면 될 것 같다.
로그아웃 기능
클라이언트 앱이 종료되거나, 로그아웃 버튼을 누르면 서버에서 로그아웃 기능 수행. Key값이 해당 계정의 토큰값인 아이템을 삭제하면 되나?
또는 토큰이 추가된 후 일정 시간(24시간?) 지난 게 확인되면 역시 보관된 아이템을 삭제하면 될듯. 만약 삭제된 뒤로 유저가 토큰으로 유저데이터에 접근을 시도할 경우, 클라이언트에 “님 지금 토큰이 보관되어있지 않은 것 같은데 로그인좀 다시 하셈” 이라고 메시지를 보내면 될 것 같다.