Visual Studio 2017 이후에서 C++ 빌드 빠르게 하기

코드 유지 보수의 목적으로 소스 파일이 나뉘게 되는데
빌드할 때 C++ 소스가 OBJ 파일로 변경되어 링크되는데
수가 많다보니 엄청 느립니다.
이를 개선하는 방법 중 하나로 여러 개의 소스 파일을 하나의 소스 파일에 include 해서
OBJ 파일 생성 수량을 조절하는 방법이 있습니다.
(언리얼 엔진 3에서 사용하던 그 방법… 언4는 BS가 사용을 안해봐서 모르겠네요)

https://devblogs.microsoft.com/cppblog/support-for-unity-jumbo-files-in-visual-studio-2017-15-8-experimental/

간단히 내용을 요약하면
최상위 폴더에 Directory.Build.props 파일을 만들어 아래 내용 입력

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <EnableUnitySupport>true</EnableUnitySupport>
  </PropertyGroup>
</Project>

VS IDE에서 C++ 빌드 옵션에 Unity Build 항목이 나타남
설정을 잘하고 빌드

Unity3D에서 쿠키로 전달된 세션 유지하는 방법

많이들 쓰기는 Unity입니다.


그리고 최근 모바일 게임에서 많이 쓰이는 게 웹 응용 서버이죠.


그리고 웹 응용 프로그램에서 많이 쓰이는 쿠키와 세션…


Unity의 WWW, WWWForm 으로 세션을 유지하는 방법을 소개합니다.


[원본 링크]


아래처럼 세션을 유지하기 위한 쿠키 정보를 저장할 해시 테이블을 만들고

// will be set to some session id after login
private Hashtable session_ident = new Hashtable();
 
// and some helper functions and properties
public void ClearSessionCookie(){
    session_ident["Cookie"] = null;
}
 
public void SetSessionCookie(string s){
    session_ident["Cookie"] = s;
}
 
public Hashtable SessionCookie{
    get { return session_ident; }
}
 
public string GetSessionCookie(){
    return session_ident["Cookie"] as string;
}
 
public bool SessionCookieIsSet{
    get { return session_ident["Cookie"] != null; }
}

그리고 로그인 응답으로부터 파싱해서 저장해 두었다가

// Failed=Bad server error, Error=server did reply with an error, OK=all fine
public enum ReturnCode : int { Failed=-1, Error=0, OK=1 }
public delegate void OnNetResult(ReturnCode code, string result);
public IEnumerator Login(OnNetResult callback, string nm, string pw)
{
    // create params to send
    WWWForm form = new WWWForm();
    form.AddField("nm", nm);
    form.AddField("pw", pw);
 
    // let www do its thing
    WWW www = new WWW("http://path_to/login/", form);
    yield return www;
 
    // the following code can be used to see what the SET-COOKIE contains
    // Have a look at http://en.wikipedia.org/wiki/HTTP_cookie to see what Set-Cookie is all about
    // It is bascially how the server will tell you what it expects you to be doing with the cookie
    // The name you are looking for will be the first characters followed be "=", after that follows
    // the value of the cookie. There could also be other entries on the same line like 'Expires'
    // but they will all be seperated by ';'
    //if (www.responseHeaders.ContainsKey("SET-COOKIE")){
    //  Debug.Log(www.responseHeaders["SET-COOKIE"]);
    //}
 
    // handle the data from www, but first check if there where errors
    if (!string.IsNullOrEmpty(www.error) || string.IsNullOrEmpty(www.text))
    {
        errmsg = "Network communication error.";
        if (callback != null) callback(ReturnCode.Failed, errmsg);
    }
    else
    {
        errmsg = "Network communication error.";
 
        // like I mentioned in description, this code
        // expects "1player_name" on success, else "0"
        if (www.text[0] == '1')
        {
            try
            {
                // extract the public name of player
                Game.Instance.name = www.text.Substring(1);
                Game.Instance.ClearSessionCookie();
 
                // check if session cookie was send, if not, well, no use to continue then
                if (www.responseHeaders.ContainsKey("SET-COOKIE"))
                {
                    // extract the session identifier cookie and save it
                    // the cookie will be named, "auth" (this could be something else in your case)
                    char[] splitter = { ';' };
                    string[] v = www.responseHeaders["SET-COOKIE"].Split(splitter);
                    foreach (string s in v)
                    {
                        if (string.IsNullOrEmpty(s)) continue;
                        if (s.Substring(0, 4).ToLower().Equals("auth"))
                        {   // found it
                            Game.Instance.SetSessionCookie(s);
                            break;
                        }
                    }
                }
            }
            catch {
                // this should only possibly happen during development
                if (callback != null) callback(ReturnCode.Failed, "Network communication error.");
            }
        }
 
        // let whomever is interrested know that the login succeeded or failed
        if (callback != null)
        {
            if (www.text[0] == '1' && Game.Instance.SessionCookieIsSet)
            {
                callback(ReturnCode.OK, "Login ok");
            }
            else if (www.text[0] == '0' || !Game.Instance.SessionCookieIsSet)
            {
                errmsg = "Invalid login name or password.";
                // my server sometimes sends "0some_explenation", therefore this next line
                if (www.text.Length > 1) errmsg = www.text.Substring(1);
                callback(ReturnCode.Error, errmsg);
            }
            else
            {
                // this should only happen during development since there was an unexpected
                // value at [0], not 0 or 1 as expected, so probably some script error
                errmsg = "Network communication error.";
                callback(ReturnCode.Failed, errmsg);
            }
        }
    }
}

다른 요청에서 헤더에 넣으면 됩니다

public IEnumerator NormalRequest(string url, OnNetResult callback, Dictionary p)
{
    // p: is a set of keys and values where the key is the name and value the value for the post field
    // create form to send with request
    WWWForm form = new WWWForm();
    if (p != null) {
        foreach (KeyValuePair kv in p) form.AddField(kv.Key, kv.Value);
    }
 
    // let www do its thing, note that you send the SessionCookie along
    WWW www = new WWW(url, form.data, Game.Instance.SessionCookie);
    yield return www;
    // ...
}


Unity의 .NET Framework와의 호환

Unity 라는 녀석이 있습니다.


삼성에서 회사를 통째로 사고 싶어한다는 루머가 있지요.


이 녀석은 Mono 라는 녀석을 기반으로 삼고 있습니다.


Mono는 오픈 소스 .NET Framework 입니다.


그리고 그 Mono를 가지고 Unity 라는 녀석이 나왔습니다.


그런데 궁금하군요… Unity에서 호환 가능한 .NET Framework 버전은 얼마일까?



  • [Programmer J님의 포스트]에 따르면 Unity 4 버전은 Mono 2.6을 사용하고
    그래서 .NET Framework 3.5와 호환이 된다고 합니다.

  • 그런데 [Unity 질답 게시판 글]에 따라 코드를 만들어 테스트 하면 2.0으로 나옵니다.
    2.0 (Visual Studio built mono)

    Type type = Type.GetType("Mono.Runtime");
    if (type != null) {
    	MethodInfo mi = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
    	if (mi != null) {
    		print(mi.Invoke(null, null));
    	}
    }
    


  • 유니티 설치 후 MonoDevelop을 통해 Assembly-CSharp의 속성을 보면 3.5를 타겟으로 하고 있습니다.
    그리고 System, System.Core, System.Xml 이렇게 3개의 어셈블리를 참조한다고 되어 있군요.

  • [구글에서만 검색되고 Unity 사이트에서는 정상적으로 접근 할 수 없는 자료]에 따르면 2.0이라고 나옵니다.
    여기에서는 System, System.Core 만 보입니다.

결론은… 서버 프로그래밍이나 잘 하자 입니다. 하하하….