공부중
[Unity]동일한 구조(?)의 코드를 생성해야 하는 경우 본문
음 뭐라고 제목을 정할까 하다가 실제로 저런 문제를 해결하려고 구현한것이라서 일단 저렇게 써봤다.
문제의 상황은 아래와 같다.
Skill 이라는 클래스가 있고 Skill의 자식클래스로 각각의 스킬 구현을 할 예정이다.
// Skill.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PokemonDefine;
public abstract class Skill : MonoBehaviour
{
protected PokemonSkillInfoData skillInfo;
public void Init(string skillName)
{
this.skillInfo = PokemonDataManager.Instance.GetPokemonSkillData(skillName);
}
public virtual void DoSkill() { }
public PokemonSkillInfoData GetSkillInfo()
{
return skillInfo;
}
}
이런 스킬 클래스가 있고
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ########## : Skill
{
// protected PokemonSkillInfoData skillInfo;
// public void Init(string skillName);
public override void DoSkill()
{
base.DoSkill();
Debug.Log(this.skillInfo.name);
}
}
이런 모양의 자식 클래스들을 생성해줄것이다.
위의 코드에서 ##########에 클래스 이름을 스킬이름으로 넣어줄 생각이다.
스킬은 어떻게 구현할지 다르고 나머지 공통 부분은 Skill클래스에서 구현할 예정이므로 일단 저렇게 잡아놓았다.
문제는 만들어야할 파일이 한두개가 아니고 총 167개의 파일을 단순 노동으로 생성해야한다.
이것을 템플릿파일 한개를 만들어두고 이 탬플릿에서 변경할 내용을 정해서 파일을 생성해줄 예정이다.
구현한 코드는 아래와 같다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using PokemonDefine;
public class CreateSkillClass
{
// 스킬 클래스 관련 경로와 파일명
public static string skillClassFileDirectory = "Assets/Scripts/Game/Skill/Skills";
public static string skillClassTemplateFilePath = skillClassFileDirectory + "/Template.txt";
public static string T = "##########";
public static string templateString = "";
// 스킬파일에대한 경로와 파일명
public static string skillInfoFilePath = "Assets/Resources/Data/PokemonInfo/skillInfo_min.json";
public static PokemonSkillInfoData[] skillInfo;
[MenuItem("Assets/Create SkillClassFile")]
static void CreateSkillClassFiles()
{
Debug.Log("= 스킬 클래스 파일 생성 시작 =");
// 디렉토리가 존재하지 않는다면 생성한다.
if (false == Directory.Exists(skillClassFileDirectory))
{
Debug.Log("디렉토리가 존재하지 않으므로 생성합니다.");
Directory.CreateDirectory(skillClassFileDirectory);
Debug.Log("디렉토리가 생성 완료.");
}
// 스킬 정보 데이터 로드
if (true == File.Exists(skillInfoFilePath))
{
Debug.Log("스킬정보 데이터 파일 확인");
Debug.Log("스킬 정보 데이터 파일 읽기 시작");
string readSkillInfo = File.ReadAllText(skillInfoFilePath);
Debug.Log("스킬 정보 데이터 파일 읽기 완료");
Debug.Log("스킬 정보 데이터 Json 변환 시작");
PokemonSkillInfoDataList loadedData = JsonUtility.FromJson<PokemonSkillInfoDataList>(readSkillInfo);
if (null == loadedData.pokemonSkillInfoData)
{
Debug.LogError("Json 변환 실패");
return;
}
skillInfo = loadedData.pokemonSkillInfoData;
Debug.Log("스킬 정보 데이터 Json 변환 완료");
Debug.Log("스킬 갯수 : " + skillInfo.Length);
}
else
{
Debug.LogError("스킬정보 데이터 파일이 존재하지 않습니다. 경로를 확인해 주세요");
return;
}
// 템플릿 파일 로드
if (true == File.Exists(skillClassTemplateFilePath))
{
Debug.Log("클래스 템플릿 파일 확인");
Debug.Log("클래스 템플릿 파일 읽기 시작");
templateString = File.ReadAllText(skillClassTemplateFilePath);
if (0 == templateString.Length)
{
Debug.LogError("템플릿 파일 내용이 비어있습니다.");
return;
}
Debug.Log("클래스 템플릿 파일 읽기 완료");
Debug.Log("스킬 클래스 생성 시작!");
for (int i = 0; i < skillInfo.Length; i++)
{
string temp = templateString;
temp = temp.Replace(T, skillInfo[i].enName);
string newSkillFilePath = skillClassFileDirectory + "/" + skillInfo[i].enName + ".cs";
File.WriteAllText(newSkillFilePath, temp);
Debug.Log(newSkillFilePath + " 생성 성공");
}
Debug.Log("모든 스킬 클래스 생성 완료");
}
else
{
Debug.LogError("클래스 템플릿 파일이 존재하지 않습니다. 경로를 확인해 주세요");
return;
}
}
}
모든 코드는 위와 같으며 기능을 간단히 정리해보자면
- 먼저 skillInfo_min.json에 저장된 모든 스킬 정보들을 읽어와 스킬 정보를 수집한다.
- 클래스 템플릿 파일을 읽어온다.
- 읽어온 템플릿파일에서 변환할 부분만 변환작업을 거친뒤 저장해준다.
부분부분 코드를 보면 아래와 같다.
// 스킬 클래스 관련 경로와 파일명
public static string skillClassFileDirectory = "Assets/Scripts/Game/Skill/Skills";
public static string skillClassTemplateFilePath = skillClassFileDirectory + "/Template.txt";
public static string T = "##########";
public static string templateString = "";
// 스킬파일에대한 경로와 파일명
public static string skillInfoFilePath = "Assets/Resources/Data/PokemonInfo/skillInfo_min.json";
public static PokemonSkillInfoData[] skillInfo;
각각의 경로들과 템플릿에서 변환시킬 부분은 어떤것인지를 저장한것이다.
skillInfo_min.json에서 읽어온 스킬정보를 저장할 배열도 만들어놓았다.
[MenuItem("Assets/Create SkillClassFile")]
static void CreateSkillClassFiles()
{
Debug.Log("= 스킬 클래스 파일 생성 시작 =");
// 디렉토리가 존재하지 않는다면 생성한다.
if (false == Directory.Exists(skillClassFileDirectory))
{
Debug.Log("디렉토리가 존재하지 않으므로 생성합니다.");
Directory.CreateDirectory(skillClassFileDirectory);
Debug.Log("디렉토리가 생성 완료.");
}
......
[MenuItem( ... )]을 통해서 유니티 메뉴에 등록을 해주고
만일 지정한 경로가 없다면 폴더를 생성해주는 코드이다.
[MenuItem( ... )]을 사용하면 이렇게 지정한 메뉴경로에 생성이 된다.
....
// 스킬 정보 데이터 로드
if (true == File.Exists(skillInfoFilePath))
{
Debug.Log("스킬정보 데이터 파일 확인");
Debug.Log("스킬 정보 데이터 파일 읽기 시작");
string readSkillInfo = File.ReadAllText(skillInfoFilePath);
Debug.Log("스킬 정보 데이터 파일 읽기 완료");
Debug.Log("스킬 정보 데이터 Json 변환 시작");
PokemonSkillInfoDataList loadedData = JsonUtility.FromJson<PokemonSkillInfoDataList>(readSkillInfo);
if (null == loadedData.pokemonSkillInfoData)
{
Debug.LogError("Json 변환 실패");
return;
}
skillInfo = loadedData.pokemonSkillInfoData;
Debug.Log("스킬 정보 데이터 Json 변환 완료");
Debug.Log("스킬 갯수 : " + skillInfo.Length);
}
else
{
Debug.LogError("스킬정보 데이터 파일이 존재하지 않습니다. 경로를 확인해 주세요");
return;
}
....
스킬정보를 로드하는 부분인데 특별히 구현한것은 없고 JsonUtility를 통해서 읽어온 파일의 string을 json으로 적절히 변환해서 배열에 저장하는 내용이다.
....
// 템플릿 파일 로드
if (true == File.Exists(skillClassTemplateFilePath))
{
Debug.Log("클래스 템플릿 파일 확인");
Debug.Log("클래스 템플릿 파일 읽기 시작");
templateString = File.ReadAllText(skillClassTemplateFilePath);
if (0 == templateString.Length)
{
Debug.LogError("템플릿 파일 내용이 비어있습니다.");
return;
}
Debug.Log("클래스 템플릿 파일 읽기 완료");
Debug.Log("스킬 클래스 생성 시작!");
for (int i = 0; i < skillInfo.Length; i++)
{
string temp = templateString;
temp = temp.Replace(T, skillInfo[i].enName);
string newSkillFilePath = skillClassFileDirectory + "/" + skillInfo[i].enName + ".cs";
File.WriteAllText(newSkillFilePath, temp);
Debug.Log(newSkillFilePath + " 생성 성공");
}
Debug.Log("모든 스킬 클래스 생성 완료");
}
else
{
Debug.LogError("클래스 템플릿 파일이 존재하지 않습니다. 경로를 확인해 주세요");
return;
}
위에서 적어놓은 템플릿 파일 내용을 보면 ########## 이 부분이 변경할 내용이고 이 문자열은 string T에 저장되어있다.
File을 통해서 템플릿파일을 읽고 Replace를 통해서 #########을 위에서 읽어온 json파일의 내용중 스킬이름으로 변경하고 스킬명으로 .cs파일을 생성한다.
이제 컴파일후 메뉴에서 실행해보면
Console창에 이와같은 로그를 찍고 완료하게 된다.
실제로 .cs 파일을 생성한 모습이다.
'Programing > Unity3D' 카테고리의 다른 글
[Unity Shader]울렁울렁 거리는 굴절을 표현해 보자 (0) | 2020.05.20 |
---|---|
[Unity] string과 동일한 class 이름을 가진 타입을 인스턴스화 하기 (0) | 2020.04.08 |
[Unity]새로워진 스프라이트 아틀라스(Sprite Atlas) (0) | 2020.03.12 |
[Unity3D]프리팹 인스턴스 언패킹(Unpacking Prefab instances) (0) | 2020.02.25 |
3ds max에서 export한 fbx 모델이 유니티에서 회전되서 나오는 경우.. (0) | 2018.08.16 |