Back-End/UnityScript(C#)

UnityScript UI 캐릭터 스킬 List Prefab 자동 생성 Script(Unity 오브젝트, UI 구현, Prefab)

개발자 DalBy 2024. 5. 14. 15:40
반응형

UnityScript UI 캐릭터 스킬 List Prefab 자동 생성 Script(Unity 오브젝트, UI 구현, Prefab)

UnityScript UI 캐릭터 스킬 List를 Prefab으로 만들어 특정 이벤트 호출 시 자동 생성되는 Script만들어 보았습니다.

Json 데이터를 기준으로 해당 Prefab의 내용들이 동적으로 입력 됩니다.

 

Json data 예시

{
	"data": [
		{
			"skill_id": 4,
			"skill_img": "cheer_up_0",
			"skill_text_title": "힘내세요!!",
			"skill_text_content": "동료를 응원한다."
		},
        생략 ...

	]
}

 

 

하이라키창에서 Json데이터와 같은 오브젝트를 mapping 시켜 처리하였습니다.

 

prefab의 예시는 다음과 같습니다.

스킬 패널의 구조
스킬 패널 UI

 

캔버스 오브젝트 mapping

캔버스 스크립트, object mapping 정보

 

스크립트에 mapping된 오브젝트는 다음과 같습니다.

    // 캔버스
    public Canvas canvas;

    // 스킬 패널
    public GameObject skillPanel;

    // 스킬 목록 패널
    public GameObject skillDetailPanel;

    // 스킬 Slot 패널
    public GameObject skillSlotPrefab;

    // 스킬 컷씬 패널
    public GameObject skillCutPanel;

    // 스킬 스프라이트
    public List<Sprite> gameSpriteResource;

    // 스킬 전용 스크립트
    public GameObject skillScript;

    public SkillData skillData;

    // 컷씬 노출 시간
    public float skillCutTime;

    // Json data
    public string jsonPath = "Assets/BattleStage/KangAri/kangAry_skill.json";

 

 

해당 스킬 패널을 오픈 할 때 이벤트 호출

public void SkillPanelOpenBtn()
{
    skillPanel.SetActive(true);
    SkillSlotCreateList();
}

 

오브젝트 구조

오브젝트 프리팹 구조

 

먼저 하위 자식 오브젝트를 삭제 후, prefab 오브젝트 부모 자식 위치를 찾고 Json 데이터 기준으로 동적 처리하여

스킬 슬롯을 만들고, 해당 스킬의 이벤트 함수 셋팅을 처리합니다.

public void SkillSlotCreateList() 
{

    // 하위 자식 삭제
    Transform[] target = skillDetailPanel.transform.GetComponentsInChildren<Transform>();
    // 0은 부모 1부터 자식 (자식 오브젝트만 삭제한다.)
    for (int i = 1; i < target.Length; i++)
    {
        Destroy(target[i].gameObject);
    }

    try{
        // Json data를 읽어 자식 오브젝트 생성 (skill-slot)
        string jsonData = File.ReadAllText(jsonPath);
        skillData = JsonUtility.FromJson<SkillData>(jsonData);

        // 스킬 slot 패널의 안에 오브젝트 생성 
        Transform point = skillDetailPanel.transform.GetComponent<Transform>();

        for (int i = 0; i < skillData.data.Count; i++)
        {
            // 새로운 프리팹을 생성할 때, JSON 데이터 내용으로 수정한다.
            GameObject createObj = preFabsInstance(skillData.data[i]);
            GameObject instance = Instantiate(createObj, point.position, Quaternion.identity);
            instance.transform.SetParent(point);

            // 동적으로 생성된 버튼 이벤트 처리
            string skill_img = skillData.data[i].skill_img;
            instance.transform.Find("skill_start").gameObject.GetComponent<Button>().onClick.AddListener(() => Skill(skill_img));

        }

    } catch(Exception e)
    {
        Debug.Log(e.Message);
    }
}


public GameObject preFabsInstance(SkillData skillData)
{
    GameObject obj = skillSlotPrefab;
    //string path = "Assets/BattleStage/KangAri/prayer/" + skillData.skill_img;

    for (int i = 0; i < gameSpriteResource.Count; i++)
    {
        if (skillData.skill_img == gameSpriteResource[i].name)
        {
            obj.transform.Find("skill_img").gameObject.GetComponent<Image>().sprite = gameSpriteResource[i];
            obj.transform.Find("skill_text_title").gameObject.GetComponent<TMP_Text>().text = skillData.skill_text_title;
            obj.transform.Find("skill_text_content").gameObject.GetComponent<TMP_Text>().text = skillData.skill_text_content;
        }
    }
    return obj;
}

 

 

현재 제작중인, 게임 BGM이 들릴 수 있습니다. (참고 부탁드립니다.)

테스트 결과

프리팹이 자동 생성되어 스킬 목록을 보여줌

 

 

추가 이미지 컷씬 만들기 

스킬 사용 시 3초간 스킬 컷씬을 노출하고, 컷씬을 종료합니다.

패널의 이미지를 변경하여 노출시킨 후 패널 setActive(false);

// 컷씬 노출 시간
public float skillCutTime;

// 스킬 사용
public void Skill(string skill_img)
{
    skillCutTime = 3.0f;
    //Debug.Log(gameSpriteResource.Count);
    skillCutPanel.SetActive(true);

    for (int i = 0; i < gameSpriteResource.Count; i++)
    {
        if (skill_img == gameSpriteResource[i].name)
        {
           // Debug.Log("실행 할 이미지 " + gameSpriteResource[i].name);
            skillCutPanel.transform.Find("skillCut").gameObject.GetComponent<Image>().sprite = gameSpriteResource[i];
            
        }
    }
}


void Update()
{

    // 3초가 흐르면 컷씬 닫기 임시
    skillCutTime -= Time.deltaTime;
    if (skillCutTime <= 0f)
    {
        skillCutPanel.SetActive(false);
    }

}

 

 

결과 예시

 

 

 

 

반응형