본문으로 바로가기

프로젝트 리뷰의 마지막 코드 분석입니다.

프로젝트를 진행하면서 인상깊었던 코드들을 정리해봅니다. (차 후 다른 게임에서도 쓸 일이 있겠죠.)



1. 배경이동


AIE 에서 보면 횡으로 플레이 할 경우 뒷 배경이 2D 플랜들로 여러장 구성되어있으며 움직입니다.

중간에 Freezia라는 중간보스를 만날때 서서히 속도가 느려지다가 멈추도록 설계되었는데요, 여러개의 플랜으로 이루어진 레이어가 서로 다른 속도로 조화롭게 움직이게 하는 부분입니다.

amtToMove += speed * Time.deltaTime;

renderer.material.mainTextureOffset = new Vector2 (amtToMove, 0); 
//transform.Translate (new Vector3 (0, 0, 1) * amtToMove);

2D배경의 경우 플랜이 통째로 움직이게 하지 않고 플랜위에 텍스쳐를 움직이는 랜더방식을 사용해서 움직이는듯한 느낌을 주도록 합니다.

if (Character.G_game_event_boss == 1 || Character.G_game_event_boss == 2) {
    if (speed > 0) {
       
        time += Time.deltaTime;

        time2 += Time.deltaTime / 60;
        * 배경의 감소속도를 정해주는 구간으로 플랜마다 60, 30, 20 등 프레임속도를 다르게 세팅하여 감소폭을 다르게 계산합니다.       


        if (time > 0.1) {
            speed = speed - time2;
            time = 0;
            time2 = 0;
        }
    }
           
    if (speed < 0) {

    * 간혹 속도가 음의 값으로 변해 정지하지 않는 불상사를 막기위한 예외처리
        speed = 0;
    }
}

if (Character.G_game_event_boss == 0) {
    speed = 0.1f;   
}



2. 필살기


필살기는 화면상에 있는 모든 적을 파괴해야합니다. AIE에서는 투명한 박스를 화면상에 스폰하도록 하여 그 박스와 충돌된 적들을 체크하여 파괴하는 방식으로 구현되었습니다.

bombtime += Time.deltaTime;
       
if(bombtime > 2 && bomb == true){
    vec = GameObject.Find("Main Camera").transform.position;

    * 현재 보여지는 카메라영역(화면)에 필살기가 소환될 수 있도록 합니다.
    vec.y -= 11;


    Instantiate(bombBox, vec, Quaternion.identity);

    * bombBox라는 투명한 박스를 생성시켜 적 오브젝트와 충돌체크를 하게 합니다.


    bombtime = 0;
    bomb = false;

    stopper = false;
    temp = 0;
    Camera_Event1_1.Stop();
}



3. 탄막


몬스터마다 고유의 탄막 패턴을 가지고 있습니다. 모든 탄은 AddForce를 이용하여 본체로 부터 발사되며, 이는 오브젝트의 생성을 통해 이뤄지게 됩니다. 


- 블랙스미스 (세개의 탄이 나란히 직선으로 발사되는 일직선 삼연발형 탄막)

if (Character.G_game_state == 0) {
    if (count % 120 == 0) {

    * 탄을 쏘는 주기 (계속해서 쏘지않고 텀을 두고 쏠 수 있도록)


        GameObject clone;


        clone = (GameObject)Instantiate (Bullet, point1.position, Quaternion.identity);
        clone.rigidbody.AddForce (point1.forward * 300);

        * 탄을 쏘는 방향과 생성구문
   
    } else if (count % 120 == 60) {
        GameObject clone;
        clone = (GameObject)Instantiate (Bullet, point2.position, Quaternion.identity);
        clone.rigidbody.AddForce (point2.forward * 300);
                   
    }
}
           
if (Character.G_game_state == 1) {
    if (count % 60 == 0) {
        GameObject clone;
        clone = (GameObject)Instantiate (Bullet, point1.position, Quaternion.Euler (0, 0, 90));
        clone.rigidbody.AddForce (point2.forward * 300);
               
    }
}



- 데빌메이지 (나선형 회전 탄막)

if (count % 10 == 0) {

* 탄을 쏘는 주기 (계속해서 쏘지않고 텀을 두고 쏠 수 있도록)


    Rigidbody clone;
    i++;


    clone = (Rigidbody)Instantiate (bullet, transform.position, Quaternion.identity);
    clone.velocity = new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * i * r)) * 5;

    * 탄을 쏘는 방향과 생성구문
                      
    clone = (Rigidbody)Instantiate (bullet, transform.position, Quaternion.identity);
    clone.velocity = new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 90) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 90) * r)) * 5;
                      
    clone = (Rigidbody)Instantiate (bullet, transform.position, Quaternion.identity);
    clone.velocity = new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 180) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 180) * r)) * 5;
                      
    clone = (Rigidbody)Instantiate (bullet, transform.position, Quaternion.identity);
    clone.velocity = new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 270) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 270) * r)) * 5;
  
}



- 머쉬룸보이 (일반 탄)

if (count == 20) {

* 탄을 쏘는 주기 (계속해서 쏘지않고 텀을 두고 쏠 수 있도록)


    GameObject clone;


    if (Character.G_game_state == 0) {


        clone = (GameObject)Instantiate (Bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (point.forward * 300);

        * 탄을 쏘는 방향과 생성구문


    } else if (Character.G_game_state == 1) {
        clone = (GameObject)Instantiate (Bullet, point.position, Quaternion.Euler (0, 0, 90));
        clone.rigidbody.AddForce (point.forward * 300);
    }
}



- 프리지아 (HP의 양에 따른 2가지 패턴탄막)

if (time > 2.0) {
    GameObject clone;

    for (float i = -0.3f; i <= 0.3f; i+=0.3f) {
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (1.0f * i, 0.0f, dir * 1.0f) * 500);
           
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (1.0f * i, 0.0f, dir * 1.0f) * 550);
           
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (1.0f * i, 0.0f, dir * 1.0f) * 600);
           
    }
    time = 0;   
}


if (g_freezia_hp > 0 && g_freezia_hp < 900) {


    if (count % 5 == 0) {

    * 탄을 쏘는 주기 (계속해서 쏘지않고 텀을 두고 쏠 수 있도록)


        GameObject clone;
        i++;
                     
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * i * r)) * 500);

        * 탄을 쏘는 방향과 생성구문                           
                           
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 90) * r)) * 500);
                           
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 180) * r)) * 500);          
                           
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 270) * r)) * 500);            
                           
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 270) * r), 0, Mathf.Sin ((Mathf.PI / 180) * i * -r)) * 500);        
                   
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 270) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 90) * -r)) * 500);
                           
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 270) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 180) * -r)) * 500); 
                           
        clone = (GameObject)Instantiate (bullet, point.transform.position, Quaternion.Euler (0, 0, 0));
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 270) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 270) * -r)) * 500);
                           
    }
}



- 파이어베어 (HP의 양에 따른 2가지 패턴탄막 + 일반탄막2)

if (g_firebear_hp > 1800) {


    if (count % 10 == 0) {

    * 탄을 쏘는 주기 (계속해서 쏘지않고 텀을 두고 쏠 수 있도록)


        i++;
        if (i > 38) {
            i = 17;
        }
        if (i % 2 == 0) {
            GameObject clone;


            clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
            clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * i * 10)) * 400);

            * 탄을 쏘는 방향과 생성구문


                       
            clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
            clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * i * 10)) * 500);
                           
            clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
            clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * i * 10)) * 600);
                           
        }
    }
} else if (g_firebear_hp > 900) {
    if (count % 5 == 0) {
        GameObject clone;
        i++;
                       
                       
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * i * r)) * 500);
                       
                       
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 90) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 90) * r)) * 500);
                       
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 180) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 180) * r)) * 500);
                       
                       
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 270) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 270) * r)) * 500);
                       
    }
                   
    if (count % 3 == 0) {
        GameObject clone;
        i -= 0.5f;
        i++;
                       
                       
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * i * r)) * 500);
                       
                       
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 90) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 90) * r)) * 500);
                       
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 180) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 180) * r)) * 500);
                       
                       
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 270) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 270) * r)) * 500);
                       
    }

} else {
    GameObject clone;
                   
    if (count % 5 == 0) {
        i++;
                       
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, Mathf.Sin ((Mathf.PI / 180) * i * r)) * 300);
                   
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (-Mathf.Cos ((Mathf.PI / 180) * i * (r + 3)), 0, Mathf.Sin ((Mathf.PI / 180) * i * r)) * 300);
                   
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * i * r), 0, -Mathf.Sin ((Mathf.PI / 180) * i * r)) * 300);
                   
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (-Mathf.Cos ((Mathf.PI / 180) * i * (r + 3)), 0, -Mathf.Sin ((Mathf.PI / 180) * i * r)) * 300);
                   
                   
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 45) * r), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 45) * r)) * 300);
                   
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (-Mathf.Cos ((Mathf.PI / 180) * (i + 45) * (r + 3)), 0, Mathf.Sin ((Mathf.PI / 180) * (i + 45) * r)) * 300);
                   
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (Mathf.Cos ((Mathf.PI / 180) * (i + 45) * r), 0, -Mathf.Sin ((Mathf.PI / 180) * (i + 45) * r)) * 300);
                   
        clone = (GameObject)Instantiate (bullet, point.position, Quaternion.identity);
        clone.rigidbody.AddForce (new Vector3 (-Mathf.Cos ((Mathf.PI / 180) * (i + 45) * (r + 3)), 0, -Mathf.Sin ((Mathf.PI / 180) * (i + 45) * r)) * 300);

    }
}



4. 터치영역


AIE에서는 많은 슈팅게임의 예제에서 나오는 것처럼 뒷 배경텍스쳐가 움직여서 속도감이 느껴지는 방식이 아닌, 풀맵으로 제작되었습니다. 따라서 캐릭터와 일정 카메라 영역이 같이 맵의 동선을 따라 움직이도록 되어있습니다.

if(StopAllObjects.g_playerstop == false) {
   
    //세로.
    if (Character.G_game_state == 0 || Character.G_game_state == 3) {
        if (Input.GetTouch (0).phase == TouchPhase.Began) {

        * 화면에 터치를 했을때
            if (Mathf.Pow (Input.touches [0].position.x, 2) + Mathf.Pow (Input.touches [0].position.y, 2) < Mathf.Pow (Screen.width * (5.0f / 12.0f), 2)) {
                ChangeProperties.g_property = 4;
                inputPosition = Input.touches [0].position;
            } else {
                inputPosition.x = Screen.width;
                inputPosition.y = Screen.height;


                oldPos = Camera.main.ScreenToWorldPoint (new Vector2 (Input.touches [0].position.x, Input.touches [0].position.y));

                * 처음 터치한 위치의 좌표를 월드좌표로 변환하여 기억


                Pos = new Vector3 (transform.position.x, transform.position.y, transform.position.z);

                * 카메라영역이 맵을따라 계속 움직이므로 좌표값이 계속 변하게 됨. 그 값을 계속해서 갱신한다.(Update 함수 안에 위치하므로)


            }
        }
       
       
        if (Input.GetTouch (0).phase == TouchPhase.Moved) {

        * 터치를 한 상태에서 움직였을때(드래그)
            if (Mathf.Pow (inputPosition.x, 2) + Mathf.Pow (inputPosition.y, 2) < Mathf.Pow (Screen.width * (5.0f / 12.0f), 2)) {
            } else {


                movePos = Camera.main.ScreenToWorldPoint (new Vector2 (Input.touches [0].position.x, Input.touches [0].position.y));
                targetPos = (movePos - oldPos) + Pos;
                transform.position = new Vector3 (targetPos.x, targetPos.y, targetPos.z);

                * 드래그한 포지션과 처음 터치한 포지션의 차이를 계산하여 플레이어위치를 옮김. + Pos를 더해서 조작이 있던 사이동안의 카메라 이동영역을 보정한다.
       
            }
        }
               
        if (Input.GetTouch (0).phase == TouchPhase.Ended) {
            ChangeProperties.g_property = 3;
        }
               
    }
           
           
    // 가로.
    if (Character.G_game_state == 1) {
        if (Input.GetTouch (0).phase == TouchPhase.Began) {
            if (Mathf.Pow (Input.touches [0].position.x - Screen.width, 2) + Mathf.Pow (Input.touches [0].position.y, 2) < Mathf.Pow (Screen.width * (5.0f / 12.0f), 2)) {
                ChangeProperties.g_property = 4;
                inputPosition = Input.touches [0].position;
            } else {
                inputPosition.x = Screen.width;
                inputPosition.y = Screen.height;
                oldPos = Camera.main.ScreenToWorldPoint (new Vector2 (Input.touches [0].position.x, Input.touches [0].position.y));
                Pos = new Vector3 (transform.position.x, transform.position.y, transform.position.z);

            }
        }
       
       
        if (Input.GetTouch (0).phase == TouchPhase.Moved) {
            if (Mathf.Pow (inputPosition.x - Screen.width, 2) + Mathf.Pow (inputPosition.y, 2) < Mathf.Pow (Screen.width * (5.0f / 12.0f), 2)) {
            } else {
                movePos = Camera.main.ScreenToWorldPoint (new Vector2 (Input.touches [0].position.x, Input.touches [0].position.y));
                targetPos = (movePos - oldPos) + Pos;
                transform.position = new Vector3 (targetPos.x, targetPos.y, targetPos.z);

       
            }
        }
               
        if (Input.GetTouch (0).phase == TouchPhase.Ended) {
            ChangeProperties.g_property = 3;
        }
               
    }
       
}



5. 에너지바 (NGUI로 만드는 프로그래스 바)


프로그래스바를 만드는 예제는 서적에도 있습니다. 다만, NGUI를 이용해서 프로그래스 바를 만드는 것은 서적에는 없었습니다. NGUI를 통해서 프로그래스바를 만드는 법은 인터넷을 찾아보면 있습니다. 다만 외형적으로 만드는 부분만 있고 스크립트에 대한 내용은 없습니다. 구현은 localScale을 통해 가능합니다.

V_PlayerSlider.foreground.localScale = new Vector3(playerHP, V_PlayerSlider.foreground.localScale.y, V_PlayerSlider.foreground.localScale.z);

* foreground의 localScale 비율을 조절하여 구현합니다.



6. 랭킹시스템


랭킹시스템은 유니티의 www클래스를 이용해서 구현합니다. 랭킹 결과만 주고받는식이므로 웹페이지형식으로 생각하면 됩니다. (유니티 <-> PHP <-> DB 를 통한 데이터 전송흐름) AIE 구현에는 MySQL을 DB로 사용했습니다. DB테이블은 플레이어이름 / 점수 / 킬 수 정보만 입력됩니다.


- 랭킹보드 (보여지는 부분. 새로운 데이터의 입력이 이루어지진 않음. 업데이트만 가능)

using UnityEngine;
using System.Collections;

[System.Serializable]
public class Score
{   
    public UILabel nameLabel;
    public UILabel pointLabel;

    * NGUI의 텍스트 라벨을 통해 표현될 항목입니다.
}

public class ScoreBoard : MonoBehaviour {
   
    public Score[] score = new Score[10];
    * 랭킹은 10위까지만 표시하려했기때문에 10개의 배열로 선언했습니다.
   
    public string url = "";
   
    public WWW www;
   
    public bool checkStart = false;
   
    public void Start()
    {
        SetURL();
        DownloadData();
    }
   

    public void SetURL()
    {
        url = "웹상의php파일 경로";
    }
   
    IEnumerator WaitWWW(WWW www)
    {
        yield return www;
    }
  

    
    public void DownloadData()
    {   
        checkStart = true;
        WWWForm form = new WWWForm();
        form.AddField("select","show");
        www = new WWW(url,form);
        WaitWWW(www);              
    }

 
   
    public void SettingDownloadData()
    {
        string[] data = www.text.Split('&');
        string[][] row = new string[data.Length][];
        * php의 문법에 맞게 규칙을 정합니다.
       
        for(int i=0;i<data.Length;i++)
        {
            row[i] = data[i].Split('?');
        }

           
        for(int i =0; i< row.Length-1; i++)
        {
            if(checkStart)
            {
            score[i].nameLabel.text = row[i][0];
            score[i].pointLabel.text = row[i][2];

            * 랭킹보드화면에서는 킬 수를 표시하지 않기때문에 row[i][1]을 제외하였습니다. 
            }
        }


        checkStart = false;
    }
   

    void Update () {
       
        if(checkStart)
        {
            if(www.isDone)
            {
                SettingDownloadData();
                checkStart = false;

                * checkStart 플래그를 두어 자동적으로 업데이트가 이루어지게 할지 아니면 수동업데이트가 가능하게 할 지는 선택사항 :)
       
            }
        }
   
    }

}



- 랭킹등록 (점수를 DB에 등록하는 부분)

[System.Serializable]
public class SubmitScore : MonoBehaviour {
   
    public int score;
    public int hit;
    public string playername;
   
    // DB 연결 설정에 관한 부분.
    public string url = "";
    public WWW www;
   
   
    // Use this for initialization
    void Start () {
        score = GameManager.g_score;
        hit = GameManager.g_kill;
        playername = YesButtonAction.g_playername;
       
        SetURL();
        UpLoadData();
       
    }
   
    // DB 서버 연결설정.
    public void SetURL()
    {
        url = "웹상의php파일 경로";
    }
   
    // WWW 클래스 사용.
    IEnumerator WaitWWW(WWW www)
    {
        yield return www;
    }
   
    // 데이터를 DB에 업로드.
    public void UpLoadData()
    {
       
   
        WWWForm form = new WWWForm();
        form.AddField("select","submit");


        form.AddField("id",SystemInfo.deviceUniqueIdentifier.ToString());

        * 구체적으로 활용되지는 않았지만, 기기 아이디도 수집합니다. (차후 중복랭킹 방지여부로..)


        form.AddField("name", playername);
        form.AddField("point", score);
        form.AddField("hit", hit);
           
        www = new WWW(url,form);
   
        WaitWWW(www);
       
    }
   
    // Update is called once per frame
    void Update () {
   
    }
}



이렇게 코드 분석까지 마쳤습니다. 이로서 Angel In Earth의 프로젝트리뷰는 마칩니다. (차후 생각나는게 있으면 더 추가할지도?!)

프로젝트 리뷰하고나니 고칠 부분들이 많이 보이네요. 차후 Angel In Earth의 프로젝트를 이어나가게 된다면 계속해서 진화하는 프로젝트의 모습을 글로 담아 보여드리도록 하겠습니다. :-)