유니티 웹 서버 연동 - yuniti web seobeo yeondong

이번 차수에 진행하게 된 내용은 위와 같습니다. 주요한 내용은 유니티 에셋 스토어의 SImple fantasy ui 를 활용하여 UI 디자인을 한 후, 앞서 구축한 클래스와 DB를 활용하여 LOGIN과 NEW CREATE USER 기능을 입히는 것입니다.

 

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

그러기 위해서 로그인 및 아이디 생성시 안내 메세지가 나오도록 따로 만들어보았습니다. 안내 메세지는 위 php 스크립트에서 보듯이, 출력되는 text를 유니티의 WWWForm.downloadhandler.text 를 통해 받아왔습니다. 그래서 모든 성공/오류 메세지는 서버에서 관리되게 되는 것입니다. 

 

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

위와 같이 아이디를 생성할때, 패스워드가 동일하지 않다거나 아무것도 적지 않았을 때 php에 있는 내용이 유니티로 넘어오게됩니다.

 

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

그 다음으로 유저 인벤토리를 간단하게 데이터 베이스로 꾸며봅니다. 위와 같은 모양새입니다. 

 

유니티 웹 서버 연동 - yuniti web seobeo yeondong
유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

DB에는 users, items, usersitems가 있으며, 유저와 아이템 DB에는 각각에 맞는 데이터가 들어가며, usersitems는 유저가 어떤 아이템을 획득했는지 알 수 있습니다. 

유니티와 웹의 연동

. 어떨때 사용되는가

 보통 그냥 자료를 저장하는 공간을 넷(인터넷)같은곳에 두고 사용하는 것으로 서버라는것을 사용합니다.

 그리고 자신의 확인 타인의 확인등을 위해서 사용되기도 하고요 굳이 왜냐고 물으신다면은 서버는 해킹의 위험성을 막을수도 있습니다.

 즉

 1.해킹의 위험으로 어느정도 보호하는게 가능하다

 2.50mb의 작은 app데이터를 서버를 통해서 패치할수있다.(구글은 50메가이상은 않올라감)

 3.업데이트 관련을 패치할수잇다(에셋빌드라는 부분)

 4.아이디나 유료템등의 관리가능

 등등의 장점이 존재합니다.

 그러다 한다면은 어떻게 사용할수있을까?

 우선은 유니티를 통해서 간단한 강의를 드릴까합니다.

유니티는 www라는 클레스로 웹페이지와의 다운로드를 할수있으며 그리고 웹페이지의 여는시간은 어찌되었든 시간을 가늠할수없기에 코루틴으로 사용됩니다.

즉 저기 보이는 말은 우리가 매일치는 웹페이지 주소입니다.

간단하게 본다면은 이런말입니다. 즉 /?뒤에는 매개변수가 되는것입니다.

이런방식을 GET방식이라하며 이것은 빠르다라는 장점이 있으니 이것은 우선 노출의 위험이 있으며 (실제로 패킷(넷상의 테이터)을 해킹해서 볼수가 있어요) 용량또한 제한이 존재합니다.

그래서 사용하는 방식은 POST방식이 있습니다. 이것은 내부로 자바스크립트로 숨겨져있는방식인데요

이렇식으로 wwwFrom에 필드를 추가해서 그것과 함께 넘기는 방식입니다. 

이런식으로 출력되는 겁니다 :D

2. PHP

딱 보시면은 아시겠지만은 $_POST / $_GET 으로 해당하는 매개변수를 받아올수 있습니다 위에 매개변수의 인덱스를 넣으면은 해당것을 찾아서 변수에 넣는것이지요

 php에서는 변수를 선언할떄 $변수명 으로 정의합니다. 

 그리고 사용할때도 $변수명으로 사용합니다

 c++같은 경우에보면은 정의부 사용부가 있겠지만은 php는 그냥 사용가능합니다. 이건 독특한 부분이지요

 그리고 시작은 로 끝납니다.

 물론 php에서도 class / enum등등 그런것은 있습니다. 책이나 강좌를 한번 읽어보심도 괜찮을듯합니다.

참고로 에티드 프로그램은(비쥬얼스튜디오등)에서 작업하셔도 되는데 오류나 그런것은 못잡아요 한마디로 그냥 메모장이나 같은것이니 오타에 주의 하세요

1. 비밀번호 암호화

node.js route의 member.js에서 

crypto 모듈을 사용해서 비밀번호를 암호화 해줌

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

비밀번호를 암호화하는 function을 만들어준다.

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

post부분에 추가해준다

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

암호화된 비밀번호가 길어져서 안 들어올 수 도 있으므로 비밀번호 문자열데이터 길이를 늘려준다.

DB에서 테이블을 수정해주고

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

자바스크립트에서 member.js에서 password type을 수정해줌

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

유니티 웹 서버 연동 - yuniti web seobeo yeondong

DB에 비밀번호가 암호화 되어서 들어옴

 

 

 

2. 등록

 

등록 UI를 만들어준다.

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

SignUp 클래스를 만들어주고

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UISignUp : MonoBehaviour
{
    public InputField inputMemberName;
    public InputField inputPassword;
    public Button btnSubmit;

    public void Init()
    {

    }

 
}

 

test 클래스 start 부분에 init( )하고 작성해줌

this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });

 

public void SignUp(Protocols.req_member_post req)
    {
        //로딩바 켜줌
        this.loading.SetActive(true);
        StartCoroutine(this.Post1("/member", req, (responseCode) =>
        {
            //로딩바 꺼줌
            this.loading.SetActive(false);
            if (responseCode == 200)
            {
                Debug.Log("가입 완료");
            }
        }));
    }

 

//form으로 보내기 
    //body로 보내는 방법도 있음
    private IEnumerator Post1(string uri, Protocols.req_member_post req, System.Action<long> onComplete)
    {
        //List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
        var form = new WWWForm();
        form.AddField("username", req.username);
        form.AddField("password", req.password);
        var url = string.Format("{0}:{1}{2}", host, port, uri);
        var www = UnityWebRequest.Post(url, form);
        yield return www.SendWebRequest();

        if (www.isNetworkError || www.isHttpError)
        {
            Debug.Log(www.error);
        }
        else
        {
            Debug.Log(www.responseCode);
            onComplete(www.responseCode);
        }
    }

 

 

3. 수정

 

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

팝업 창을 보여줄 prompt 오브젝트를 만들고 스크립트도 만듦

비활성화 해놨다가 멤버 리스트의 수정 버튼을 누르면 나타나고

변경한 이름 적고 등록 버튼을 누르거나 취소 버튼을 누르면 사라지게 함

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class UIPopUpPrompt : MonoBehaviour
{
    public InputField inputNewMemberIndexName;
    public Button btnOkay;
    public Button btnCancel;
    public UnityAction<int, string> OnClickOk;


    private int id;

    public void Init()
    {
        this.btnOkay.onClick.AddListener(() =>
        {
            this.OnClickOk(this.id, this.inputNewMemberIndexName.text);
        });
    }

    public void Close()
    {
        this.gameObject.SetActive(false);
    }

    public void Open(int id)
    {
        this.id = id;
        this.gameObject.SetActive(true);
    }
}

 

멤버 리스트의 수정 버튼을 눌렀을 때 대리자를 호출함

UIMembers 의 Refresh 메서드의 멤버들을 생성하는 foreach문에 써준다.

    	listItem.btnUpdata.onClick.AddListener(() =>
            {
                this.OnUpdateClick(member.id, member.username);
            });

 

test 의 start 부분에 대리자 정의를 써줌

팝업이 열림

 	//수정
        this.uiMembers.OnUpdateClick = (id, username) =>
        {
            Debug.LogFormat("{0},{1}", id, username);
            this.uiPopUpPrompt.Open(id);
        };

        

 

UIPopUpPrompt 를 start 에서 init 해주고

나타난 팝업에서 변경한 이름을 적고 등록버튼(btnOkay)를 누르면 호출되는 대리자를 정의해줌

	this.uiPopUpPrompt.Init();
        this.uiPopUpPrompt.OnClickOk = (id, newMemberName) =>
        {
            //test 에서 id를 전역변수로 갖고 값을 저장해서 보내는 것보다
            //이 방법이 낫다!
            //id와 membername을 서버에 보냄
            Debug.LogFormat("{0},{1}", id, newMemberName);
            var req = new Protocols.req_member_put();
            req.username = newMemberName;
            this.UpdateMemberName(id, req);
        };

 

UpdateMemberName 메서드에서 변경할 id를 담은 uri를 만들고 put 코루틴 시작

  public void UpdateMemberName(int id, Protocols.req_member_put req)
    {
        var uri = string.Format("/member/{0}", id);
        StartCoroutine(this.Put(uri, req, (responseCode) =>
         {
             Debug.Log(responseCode);
         }));
        this.uiPopUpPrompt.Close();
    }

 

서버로 url과 req를 보냄

직렬화하고 01010001로 인코딩해서 보냄

유니티에서는 patch의 기능을 put이 하는데

www.method ="PATCH"; 

하면 member.js의 patch로 보낼 수 있음

//Unity에서는 Patch의 기능을 Put이 함
    private IEnumerator Put(string uri, Protocols.req_member_put req, System.Action<long> onComplete)
    {
        var url = string.Format("{0}:{1}{2}", host, port, uri);
        var json = JsonConvert.SerializeObject(req);
        var data = Encoding.UTF8.GetBytes(json);
        var www = UnityWebRequest.Put(url, data);
        www.SetRequestHeader("Content-Type", "application/json");
        //www.method = "PATCH"; //=> node.js에 patch로 들어간다.
        yield return www.SendWebRequest();


        if (www.isNetworkError || www.isHttpError)
        {
            Debug.Log(www.error);
        }
        else
        {
            Debug.Log(www.responseCode);
            onComplete(www.responseCode);
        }
    }

 

route 의 member.js에서 put 기능을 추가해줌

유니티 웹 서버 연동 - yuniti web seobeo yeondong

 

취소 버튼 누르면 닫기

this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });
0

 

 

4. 삭제

 

멤버리스트에서 삭제버튼을 누르면 멤버를 삭제시킬 거임

UIMember 클래스의 Refresh메서드 멤버들 접근하는 foreach부분에

삭제버튼을 누르면 id를 넘겨주는 대리자를 호출하게 함

this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });
1

 

test의 start부분에서 정의해줌

this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });
2

 

멤버 uri만들고 코루틴으로 넘겨줌

this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });
3
this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });
4

 

결과

 

 

 

 

전체 코드

 

Test

this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });
5

 

Protocols

this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });
6

 

UIMembers

this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });
7

 

UIlistItem

this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });
8

 

UISignUp

this.uISignUp.btnSubmit.onClick.AddListener(() =>
        {
            var memberName = this.uISignUp.inputMemberName.text;
            var password = this.uISignUp.inputPassword.text;
            Debug.LogFormat("{0},{1}", memberName, password);

            var req = new Protocols.req_member_post();
            req.username = memberName;
            req.password = password;
            this.SignUp(req);

        });
9

 

UIPopUpPrompt

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class UIPopUpPrompt : MonoBehaviour
{
    public InputField inputNewMemberIndexName;
    public Button btnOkay;
    public Button btnCancel;
    public UnityAction<int, string> OnClickOk;


    private int id;

    public void Init()
    {
        this.btnOkay.onClick.AddListener(() =>
        {
            this.OnClickOk(this.id, this.inputNewMemberIndexName.text);
        });
    }

    public void Close()
    {
        this.gameObject.SetActive(false);
    }

    public void Open(int id)
    {
        this.id = id;
        this.gameObject.SetActive(true);
    }
}

 

 

 

공유하기

게시글 관리

구독하기STUDY

'C# > 수업내용' 카테고리의 다른 글

2020.08.04. 수업내용 - NGUI(1)  (0)2020.08.042020.07.31. 수업내용 - WebView  (2)2020.07.312020.07.28. 수업내용 - DB 서버와 유니티 연동 ( MySQL, Nodejs, Unity)(1)  (0)2020.07.282020.07.08. 수업내용 - 인공지능 강화학습2 ( 펭귄 MLAgent)  (0)2020.07.082020.07.07. 수업내용 - 인공지능 강화학습 1  (0)2020.07.07