Back-End/UnityScript(C#)

Unity Script(유니티 스크립트), API Server HTTP 통신 및 JsonData 처리(JsonArray, Unity Script, SendWebRequest, UnityWebRequest, Coroutine, C#)

개발자 DalBy 2024. 7. 18. 18:06
반응형

Unity Script(유니티 스크립트), HTTP 통신 및 JsonData 처리 (JsonArray, Unity Script, SendWebRequest, UnityWebRequest, Coroutine, C#)

이번에는 Unity Game 개발중, HTTP 통신 및 JsonArray Data처리에 대해 간단하게 데이터 통신 처리관련 포스팅하겠습니다.

 

 

필자가 테스트한 규격은 다음과 같습니다.

API Server - SpringBoot 3.x

Client - Unity 2022.x

 

 

 

먼저 API Server(SpringBoot)의  API 코드를 추가 해 줍니다.

 

 

DTO

@Data
public class GameParamDTO {
    private String licenseKey;
    private String loginId;
    private List<Map<String, Object>> data;

}

 

 

 Service

public GameParamDTO lifeGameLicense(GameParamDTO gameParamDTO) throws Exception{
    GameParamDTO dto = new GameParamDTO();
    if("admin".equals(gameParamDTO.getLoginId())){
        dto.setLicenseKey("TEST001");
        dto.setLoginId(gameParamDTO.getLoginId());

        // 테스트 데이터
        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
        String testData[] = {"실패자", "평범한 회사원", "평범한 사장님", "프리랜서", "결혼 생활", "Flex, I am God Life"};
        
        for(int i = 0; i < 6; i++){
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("endingId", "ST1"+i+"00");
            map.put("endingName", testData[i]);
            Random r = new Random();
            map.put("endingOpen", r.nextInt(2));
            data.add(map);
        }
        
            dto.setData(data);
    }
    return dto;
}

간단하게 List와 Map으로 임시 JsonArray 데이터를 만들어, Unity에서 request시 위 코드의 해당 데이터로 response합니다. (Json + JsonArray)

 

 

 

Controller

@RequestMapping(value="/lifeGameLicense")
@ResponseBody
public GameParamDTO lifeGameLicense(Model model, @RequestBody GameParamDTO gameParamDTO) throws Exception{
    LOG.info("lifeGameLicense -> " + gameParamDTO);
    return solutionService.lifeGameLicense(gameParamDTO);
}

 

 

 

 

Unity C# Script는 다음과 같습니다.

직렬화 할 Class

[Serializable]
public class LicenseCheck
{
    public string licenseKey;
    public string loginId;
    public string endingId;
    public string endingName;
    public string endingOpen;
}

 

 

JsonArray 데이터를 처리하기 위해 추가로 JsonHelper를 구현 해 줍니다.

public static class JsonHelper
{
    public static T[] FromJson<T>(string json)
    {
        Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
        return wrapper.data;
    }

    [Serializable]
    private class Wrapper<T>
    {
        public T[] data;
    }
}

 

 

간단하게 저장된 데이터를 체크한다고 가정할 때, 해당 로직은 게임이 시작되고 딱 한번 호출합니다.

void Awake()
{
    StartCoroutine(Access());
}

 

 

HTTP 통신하여 Json 데이터를 처리하는 소스는 다음과 같습니다.

    IEnumerator Access()
    {
        string url = "https://dalbyutility.com/api/api-req/lifeGameLicense";
        string jsonData = "{ \"loginId\" : \"admin\"}";

        using (UnityWebRequest www = UnityWebRequest.Post(url, jsonData, "application/json"))
        {
            yield return www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError(www.error);
            }
            else
            {
                string json = www.downloadHandler.text;

                LicenseCheck[] licenseCheck = JsonHelper.FromJson<LicenseCheck>(json);

                for(int i = 0; i < licenseCheck.Length; i++)
                {
                    string endingId = licenseCheck[i].endingId;
                    string endingName = licenseCheck[i].endingName;
                    int endingOpen = Int32.Parse(licenseCheck[i].endingOpen);

                    Debug.Log("처리될 데이터 ==>> endingId " + endingId + " endingName " + endingName + " endingOpen " + endingOpen);

                    int AllrecordIndex = contentPanel.transform.childCount; // 6

                    for(int j = 0; j < contentPanel.transform.GetChild(i).childCount; j++)
                    {
                        string name = contentPanel.transform.GetChild(i).transform.GetChild(j).name;

                        if ("EndingText".Equals(name))
                        {
                            if (endingOpen > 0)
                            {
                                endingText[i].text = endingName;
                            } else
                            {
                                endingText[i].text = "알려지지 않음";
                            }
                        }

                        if ("EndingImage".Equals(name))
                        {
                            Image img = contentPanel.transform.GetChild(i).transform.GetChild(j).GetComponent<Image>();

                            if (endingOpen > 0)
                            {
                                img.sprite = endingImageList[i+1];
                            }
                            else
                            {
                                img.sprite = endingImageList[0];
                            }
                        }
                    }
                }
            }
        }
    }

 

 

 

간단하게 통신된 response JsonData를 바로 확인 할 수 있게, 패널에 데이터 처리관련 여러기능을 추가하여 처리하였습니다. (해당 소스는 통신 데이터 처리와 무관합니다.)

public List<GameObject> popupPanels;
public List<Sprite> endingImageList;
public List<TMP_Text> endingText;
public GameObject contentPanel;

public void PopupPanelsControl()
{
    string btnTagName = EventSystem.current.currentSelectedGameObject.tag;

    for (int i = 0; i < popupPanels.Count; i++)
    {
        string panelTagName = popupPanels[i].gameObject.tag;

        if (panelTagName.Equals(btnTagName))
        {
            popupPanels[i].SetActive(!popupPanels[i].activeSelf);

        } else
        {
            popupPanels[i].SetActive(false);
        }
    }
}

 

 

테스트 결과는 다음과 같습니다.

API Log

 

Unity Log

 

Log에서 endingOpen 값이 0일 때 엔딩 포인트는 알 수 없음으로 표시됩니다.

테스트 확인
테스트 확인

 

감사합니다.

감사합니다
감사합니다

 

반응형