파일 이름 추출하기

Tom·2025년 1월 13일
0

카드게임 만들기

목록 보기
12/13

자유롭게 아이템을 장착할 수 있는 캐릭터가 필요했는데, 꼭 알맞은 에셋을 찾았다.
https://assetstore.unity.com/packages/2d/characters/pixel-hero-maker-250116 자유롭게 부위를 바꿔 끼울 수 있는 2D 픽셀 캐릭터임. 사용하기 위해 뜯어봤다. 원하는 디자인을 만들고, PNG로 스프라이트 아틀라스를 추출해줘 사용할 수 있게 만든 에셋인 듯? 근데 이러면 내가 원하는 캐릭터를 만드려면 매번 스프라이트를 추출해줘야 했다. 이럼 몇번을 노가다를 해야하는 것이오? 런타임에 사용할 수 있는 방법이 없을까 생각해봤다.

구매한 에셋도 내 요구에 맞게 커스터마이즈해서 쓸 수 있음

에셋스토어에서 구매한 에셋은 사용자에게 보통 Single Entity 라이선스가 부여된다. 사용 권한엔 개인이 수정이 포함되는데, 내가 필요한 기능이 없다면 추가해서 써도 된다는 이야기. 그래서 에셋 코드를 뜯어봤다. 스프라이트들을 ScriptableObject로 관리해서 이름에 따라 캐릭터의 외형에 적용시켜주는 모양이었음. 그럼 런타임에 이 코드를 실행만 시켜줄 수 있으면 먼저 만들어놓지 않아도 캐릭터 외형을 재구성 해줄 수 있겠다. 근데 문제는 스프라이트의 이름을 문자열로 받아서 적용중이라는거였음.

문자열 사용을 조심해

문자열은 아주 간편하다. 그냥 내가 쓰는대로 사용이 가능함. 근데 대신 매우 불안정하다. 왜냐? 내가 쓰는대로 적용되니까.

public class Character 
{
	public string Armor;
}

public class Equipment
{
	private Character _char;
    
    private void Start()
    {
    	_char.Armor = "갑옷";
        _char.Armor = "갑욧";
    }
}

내가 착용한 방어구를 문자열로 관리하면, 외부에서 이 장비에 수정이 필요할 때 어떤 문자던 적용이 가능하다. 그리고 사용된 문자열이 유효한지 유효하지 않은지도 확인이 불가능하지롱. 그리고 이건 오류가 아니기 때문에 컴파일러도 오류 확인을 못함. 내가 착용하고 싶은게 갑옷인데 실수로 갑욧을 친건 컴파일러의 알빠가 아니니까. 매우 불편한 부분이 아닐 수 없다. 단순한 문자열로 끝나는 게 아니라 저걸 매개로 다른 시스템에서 사용된다면 사소한 오타 하나가 굉장히 큰 나비효과를 불러 일으킬 수도 있다. 그럼 어떡하느뇨? 사용 가능한 문자들을 미리 정의해두면 된다. 일단 아는건 enum 밖에 없으니 이걸로 하면 될 듯.

에셋 제작자가 옵션을 고봉밥처럼 꽉꽉 눌러담아줘서, 가슴 방어구에만 스프라이트가 53개가 있었다. 이걸 다 손으로 일일히 옮겨 enum으로 변경하는 미련한 짓은 사실 내가 시도했었음. 한 4개쯤 치고 있을 때 현타와 함께 다른 방법을 쓰기로 했다.
이걸 손으로 언제 다 옮겨적냐고요. 안해~!

using System;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        string folderPath = @"경로"; 
        string outputPath = @"경로";

        string[] files = Directory.GetFiles(folderPath, "*.png", SearchOption.TopDirectoryOnly); 

        using (StreamWriter writer = new StreamWriter(outputPath))
        {
            writer.WriteLine("public enum SpriteEnum");
            writer.WriteLine("{");

            foreach (string file in files)
            {
                string fileName = Path.GetFileNameWithoutExtension(file);
                Console.WriteLine(fileName);

                string validName = fileName.Replace(" ", "_").Replace("-", "_");
                writer.WriteLine($"    {validName},");
            }

            writer.WriteLine("}");
        }
    }
}

간단한 콘솔 앱으로 png파일의 이름만 추출해서 enum으로 변환작업을 해줬다. 경로만 넣으면 알아서 .cs파일을 배설하게 되는데, 저 Armor폴더를 돌려 본 결과

    public enum SpriteEnum
    {
        Angel,
        Apache,
        ArcherTunic,
        BanditTunic,
        BlueKnight,
        BlueWizardTunic,
        Box,
        CaptainArmor,
        Chief,
        ClericRobe,
        DeathRobe,
        DeerCostume,
        DemigodArmour,
        Dracula,
        DruidRobe,
        ElfTunic,
        Executioner,
        FarmerClothes,
        FemaleOutfit,
        FemaleSwimmingSuit,
        FireWizardRobe,
        Gladiator,
        GuardianTunic,
        HeavyKnightArmor,
        Hellsing,
        HolowKnight,
        HornsKnight,
        IronKnight,
        LegionaryArmor,
        Link,
        Maid,
        MilitiamanArmor,
        MinerArmour,
        MonkRobe,
        MusketeerTunic,
        NecromancerRobe,
        NinjaTunic,
        Overalls,
        Panda,
        Pharaon,
        PilotArmor,
        PirateCostume,
        PirateRobe,
        PlagueDoctor,
        Priest,
        PumpkinOveralls,
        Samurai,
        SantaHelperTunic,
        SantaTunic,
        Spartan,
        Squaw,
        ThiefTunic,
        TravelerTunic,
    }

이런 파일을 배설해냈다. 아주 성공적. 일단 필요할 것 같은 부위들만 추출해줬다. 그리고 이 값들을 전달했을 때 잘 적용되는지 테스트만 해보면 됨.

using UnityEngine;
using PlayerItems;
using System;
using System.Collections;
public class CharaTest : MonoBehaviour
{
   [SerializeField] public PlayerBuildHandler handler;


    private void Start()
    {
        StartCoroutine(routine());
    }

    private IEnumerator routine()
    {
        while (true)
        {
            Helmet randomHelmet = Random<Helmet>();
            Armor randomArmor = Random<Armor>();
            Weapon randomWeapon = Random<Weapon>();
            Shield randomShield = Random<Shield>();

            handler.Helmet = randomHelmet.ToString();
            handler.Armor = randomArmor.ToString();
            handler.Weapon = randomWeapon.ToString();
            handler.Shield = randomShield.ToString();

            Debug.Log($"Helmet: {randomHelmet}, Armor: {randomArmor}, Weapon: {randomWeapon}, Shield: {randomShield}");

            handler.Rebuild();

            yield return new WaitForSeconds(0.2f);
        }
    }

    private T Random<T>() where T : Enum
    {
        Array values = Enum.GetValues(typeof(T));
        return (T)values.GetValue(UnityEngine.Random.Range(0, values.Length));
    }
}

0.5초마다 외형을 변경해봤음. 제발 오류야 뜨지마라아주 잘 되었다. 이제 저 enum을 한번 거쳐가면 오타 걱정 없는 안전한 장비 제작이 가능할듯.짱빠르게 바꾸기

profile
여기 글은 보통 틀린 경우가 많음

0개의 댓글

관련 채용 정보