안녕하세요? 글뻥입니다. Photon Cloud 2회차 강좌입니다.

* 링크와 소스가 깨진관계로 새로운 강좌와 예제파일은 http://www.wolfpack.pe.kr/939 에서 다운로드 받아주세요.

역시 퍼가는건 자유입니다. =)
하지만 출처 안밝히면 정말 정말 정말 싫어 할겁니다.
(자신이 쓴글도 아닌데 자신이 쓴 글처럼 자신의 블로그에 달아 놓는 행위는 도둑질에다가 글쓴이에 대한 모욕입니다.)

이번에는 Photon에 관련된 내용보다는 차회에 진행할 강좌에서 사용할 게임부터 만들어 보겠습니다.

이름하야~ 짝퉁 파리플라이트!

사용자 삽입 이미지

관련 소스는 [여기]에서 다운로드 가능합니다.

중요한 소스는 달랑 4개입니다.
먼저 MainGame은 적은 전체 게임을 관리하는 녀석입니다.
Player는 말그대로 아군 전투기에 대한 Script이구요,
Enemy는 적입니다.
그리고 나머지 하나가 Beam(총알)에 대한 스크립트입니다.

아마도 초보분들께는 퍼포먼스 튜닝이나 혹은 게임 구조를 만드실때 유용한 Tip 몇개가 포함되어 있을 것 같네요.

MainGame.cs

using UnityEngine;
using System.Collections;

public class MainGame : MonoBehaviour {
    
   //플레이어 Prefab 
    public GameObject Player1;
   //적 Prefab
    public GameObject enemy;
    
   //적이 생성되는 포지션입니다. 총 7개예요.
    private Vector3[] GenPoint = new Vector3[]{
        new Vector3(-4.5f, 10f, 0f), 
        new Vector3(-3f, 10f, 0f), 
        new Vector3(-1.5f, 10f, 0f),
        new Vector3(0f, 10f, 0f),
        new Vector3(1.5f, 10f, 0f),
        new Vector3(3f, 10f, 0f),
        new Vector3(4.5f, 10f, 0f)};

   //적생성된 시간을 기록할 변수입니다.
    private float GenStart = 0f;
   //적생성에 관한 Term 변수입니다.
    private float GenTerm = 3f;
   //적이 떨어지는 속도입니다.
    private float DropSpeed = 5f;

//시작하면 적 생성 시간을 Baseline으로 설정하고 아군전투기를 생성합니다.
        //마지막에  "Quaternion.Euler(new Vector3(0f,0f,180f)"를 사용한 이유는 전투기가 꺼꾸로 출현해서... 쿨럭..
void Start () {
        GenStart = Time.time;
        Instantiate(Player1, new Vector3(0f, 0f, 0f), Quaternion.Euler(new Vector3(0f,0f,180f)));
}

// 매 프레임마다 적 생성 Method를 호출합니다.
void Update () {
        EnemyGen();
}

    //적 생성 Method로 지정한 Term만큼의 시간이 지나면 작동됩니다. 점차 Drop속도가 빨라지도록 설정했습니다.
    void EnemyGen()
    {
        if (GenStart + GenTerm > Time.time) return;
        
        //GenTerm -= 0.01f;
        DropSpeed += 0.02f;
        GenStart = Time.time;
        StartCoroutine("EnemyDrop");
    }
 
    //유니티의 문제점이 C# Base다 보니 Init하거나 Destroy하는데 많은 시간을 소모합니다.
    //기본적으로 Class 즉, Reference Type이기에 어쩔수 없는... ㅡㅡ;;
    //그래서 별도의 Thread로 돌리기 위해 Coroutine을 사용합니다.
    IEnumerator EnemyDrop()
    {
        foreach (Vector3 genposition in GenPoint)
        {
            //생성한 GameObject에 값을 할당합니다.
            GameObject gobj = Instantiate(enemy, genposition, Quaternion.identity) as GameObject;
            gobj.GetComponent<Enemy>().Set_Speed(DropSpeed);
        }
        return null;
    }
}


뭐 게임 끝나는 조건도 없습니다. 걍 끄십시오. ㅡㅡ;;

지금부터는 별게 없는 Enemy.cs를 보겠슴돠.

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {
    //MainGame에서 설정해주는 떨어지는 속도입니다.
    private float Dropspeed = 0f;

// Update is called once per frame
void Update () {
        //떨어지도록...
        Dropit();
        //어느정도 떨어지면 자동으로 없어지게...
        CheckAutoDie();
}

    //아래로 이동시키는 Method입니다.
    void Dropit()
    {
        transform.Translate(new Vector3(0f, -1f, 0f) * Dropspeed * Time.deltaTime);
    }
    //리소스가 자동으로 없어져야 겠죠? 역시 위에서 설명한대로 Coroutine으로 돌립니다.
    void CheckAutoDie()
    {
        if (transform.position.y > -5f) return;
        StartCoroutine("Die");
    }

    //MainGame에서 이녀석을 호출해서 떨어지는 값을 설정합니다. 그래서 public 선언자는 필수!
    public void Set_Speed(float x)
    {
        Dropspeed = x;
    }

    //총알과 부딪혔을때 죽는 처리해야 합니다.
    void OnTriggerEnter(Collider col)
    {
        if (col.tag != "beam") return;
        StartCoroutine("Die"); 
    }
    //자동으로 리소스에서 없애는 메소드입니다.
    IEnumerator Die()
    {
        Destroy(gameObject);
        return null;
    }
}

참으로 별게 없습니다. ㅡㅡ;; 초보라도 그냥 할 수 있는... (쿨럭..)

이제 주인공이 탈 뱅기인 player.cs파일입니다.

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {
    
    //총알 Prefab
    public GameObject beam;
    //MainGame에서 적을 생성할때와 같은 생성 주기에 대한 변수입니다.
    private float fire_last = 0f;
    private float fire_term = 0.3f;
    //이동속도입니다.
    private float Speed = 10f;

// 드라곤 플라이트와 같이 자동으로 마구마구 쏩니다.
        //대신 키보드의 좌우 키로 움직이도록 했습니다.
void Update () {
        Fire();
        if (Input.GetKey(KeyCode.RightArrow)) Move_Right();
        if (Input.GetKey(KeyCode.LeftArrow)) Move_Left();
}

    //오른쪽 움직임입니다. 현재 오브젝트가 꺼꾸로 뒤집혀 있다는 사실때문에 Vector3.left를 사용했습니다.
    void Move_Right()
    {
        transform.Translate(Vector3.left * Speed * Time.deltaTime);
        if (transform.position.x > 5f) transform.position = new Vector3(5f, 0f, 0f);
    }
   //왼쪽 움직임입니다.
    void Move_Left()
    {
        transform.Translate(Vector3.right * Speed * Time.deltaTime);
        if (transform.position.x < -5f) transform.position = new Vector3(-5f, 0f, 0f);
    }

    //자동으로 마구마구 쏩니다. 역시 Beam(총알)을 생성할때의 Performance 때문에 Coroutine사용!
    void Fire()
    {
        if (fire_last + fire_term > Time.time) return;
        StartCoroutine("Fire_Beam");
        fire_last = Time.time;
    }

    //이제 슬슬 주석다는게 지겨워 지려합니다. ㅡㅡ;; Coroutine땜시 있는겁니다.
    IEnumerator Fire_Beam()
    {
        Instantiate(beam, transform.position, Quaternion.identity);
        return null;
    }

   //적에게 부딪히면 사라지도록 설정. 역시 Coroutine
    void OnCollisionEnter(Collision col)
    {
        if (col.transform.tag != "enemy") return;
        StartCoroutine("Die");
    }

    //죽어야죠... ㅜㅜ
    IEnumerator Die()
    {
        Destroy(gameObject);
        return null;
    }
}

이 코드 역시 별게 없습니다.

마지막으로 총알인 Beam.cs파일입니다.


using UnityEngine;
using System.Collections;

public class Beam : MonoBehaviour {

    //총알 속도입니다.
    private float speed = 10f;

// 생성되면 위로 올라가면서 어느정도 갔을때 자동으로 없어지는게 애가 하는 일 전부입니다.
void Update () {
        Moving();
        AutoDie();
}

    //가자 위로!
    void Moving()
    {
        transform.Translate(Vector3.up * speed * Time.deltaTime);
    }

    //자동으로 없어지게.. 역시 Coroutine!
    void AutoDie()
    {
        if (transform.position.y < 6f) return;
        StartCoroutine("Die");
    }

    //죽어랏!!!
    IEnumerator Die()
    {
        Destroy(gameObject);
        return null;
    }
}


아~ 귀차니즘이 묻어나오는 주석이군요!
결과는 이러합니다.


사용자 삽입 이미지


2~3시간정도 걸린듯 싶네요. 소스작성부터 포스팅하는데 까지...
(가장 많은 시간은 파리 이미지 찾느라... 쿨럭..)

다음에는 Photon Cloud 붙여서 멀티플레이 만들어 보겠습니다. =)

2012/11/28 16:10 2012/11/28 16:10
음... 이글을 써야 할지, 공개하는게 맞는지 잘 모르겠습니다.
왜냐하면, 1월에 OO대 특강이 있어서 그 때 사용할 예정이었거든요.
쩝... 그래도 걍 쓸렵니다. ㅡㅡ;; 학생들이 항의하면 "배째라"할 거니까요. ㅋㅋㅋ

이번에는 첫회로 채팅서버 한번 만들어 보겠습니다. =)
한가지더, 요즘 제가 글을 안쓰는 이유는 일부 블로거들이 자신의 글인양 출처도 안밝히시고 마구 퍼가서 입니다. 의욕이 많이 다운 됐어요. 퍼가시는건 자유지만, 반드시 출처를 밝혀주세요.
발견시 "Lingo Games"의 지적재산권을 해친것으로 간주하고 법적인 절차를 밟겠습니다.

정말입니다.


1. Exit Games에 가입부터 하셔야 합니다.
https://cloud.exitgames.com 으로 접속하세요! 이메일만 넣으시면 자동가입완료!
사용자 삽입 이미지
2. 로그인하신후에 MyApplication에서 New App을 클릭합니다.
App의 이름과 Create만 눌러 주시면 완료!
사용자 삽입 이미지


3. 생성된 App의 ID를 기록해 둡니다.
저기 빨간색 부분입니다.
사용자 삽입 이미지


4. 이제 유니티의 Asset Store에서 Photon Plugin을 다운 받아 Import합니다.
검색어는 "Photon"입니다.
사용자 삽입 이미지


5. 유니티 윈도우에서 Photon Unity Networking 을 클릭하시면 Cloud 관련 메뉴가 뜹니다.
Setup 누르시고 붉은색으로 표현된 부분에 App ID를 입력하면 기본 설정완료!
사용자 삽입 이미지


사용자 삽입 이미지
사용자 삽입 이미지


6. 하지만 애석하게도 Photon의 경우 기본 네델란드로 연결됩니다. 따라서, 가장 가까운 서버로 바꿔줄 필요가 있죠.
사용자 삽입 이미지
위의 "ServerSettings.cs"파일을 찾고
public static string DefaultCloudServerUrl= "app.exitgamescloud.com";

부분을 찾아서 다음과 같이URL을 변경해줍니다.


* 유럽 : app.exitgamescloud.com
* 미국동부 : app-us.exitgamescloud.com
* 아시아(싱가폴) : app-asia.exitgamescloud.com
* 일본 : app-jp.exitgamescloud.com
* 한국 : app-kr.exitgamescloud.com

쉽죠? ^^?

7. 새로운 씬을 하나 만들고 네트워크에 접속할 Script를 넣을 빈 오브젝트를 하나 만듭니다.

사용자 삽입 이미지

8. "Network_Connect.cs"파일을 하나 만들어서 다음과 같이 붉은 색으로 표시된 부분만 고쳐줍니다.
물론 다 고쳐진 소스는 방금 만들었던 GameMaster에 Attach 시켜야 겠죠?

두번째 붉은 박스의 소스에는 "버전"을 넣어서 Client 버전별로 문제가 발생하지 않도록 설정했습니다.
사용자 삽입 이미지


9. 플레이 버튼을 눌러서 에러가 없다면 추가로 소스를 더 수정해보도록 하겠습니다.

OnJoinedLobby는 최초 서버에 접속되었을때 호출되는 메소드입니다.
OnPhotonRandomJoinFailed는 Random Join이 실패했을때 호출되는 메소드입니다.
OnJoinedRoom은 Room에 입장했을때 호출되는 메소드입니다.

사용자 삽입 이미지


정리하자면, 서버접속 -> Lobby에 접속후 Random혹은 지정된 방으로 이동 -> 이동 실패시 방을 새로 만듬
-> 성공시 방에 접속 OK! Log를 찍습니다.

이상이  "Network_Connect.cs" 파일의 내용입니다.

9. 이제 "Network_Chat.cs"파일을 하나 더 만들어서 다음과 같이 개노가다 합니다.

사용자 삽입 이미지

Awake까지 수정하신후에 OnGUI 메소드를 다음과 같이 (쿨럭..) 입력합니다.
GUI에 관련된 소스이지만, 중요한건 RPC를 어떻게 호출하는가를 잘 봐주세요.
사용자 삽입 이미지


마지막으로 AddMessage, SendChat 및 [RPC] 메소드를 노가다 합니다. T_T
중요한건 붉은 박스의 [RPC] 메소드와 이를 호출하는 photonView.RPC 입니다.
사용자 삽입 이미지

[RPC]란 리모트 프로시져로 외부에서 호출될 수 있는 메소드라는 표시이며,
이를 호출하기 위해서는 photonView.RPC("메소드명", 대상, Arg[])의 형태로 호출됩니다.
대상의 Target은
ALL, ALLBUF, OTHER, OTHERBUF, MASTER 이며 BUF가 붙은 넘은 버퍼에 넣어둔다로 이해하시면 됩니다.

이녀석도 앞에서 만들어둔 "GameMaster"에 Attach하시면 이제 1단계만 남습니다.

10. Component에서 PhotonView를 찾아 GameMaster에 Attach합니다.
GameMaster에 Attach된 Script 3종을 확인해 주세요!
사용자 삽입 이미지


이제 실행
사용자 삽입 이미지
하나의 클라이언트는 Build&Run을 했고 하나는 Editor상에서 실행한 겁니다. =)

복잡한 네트워크 지식 없어도 참 편하죠?

차회에는 조금 더 복잡하게 가보겠습니다. 꾸뻑~




2012/11/26 21:53 2012/11/26 21:53

아마도 최초가 아닐까 싶어요. 실시간 멀티플레이 AOS 게임인 GOH 입니다.
금번 Gstar 2012에 출품됩니다.
박용재 작가님의 팬싸인회도 있어요 ㅋ

2012/10/23 15:38 2012/10/23 15:38
설마 이런 게임을 제가 만들 줄은 꿈에도 몰랐어욤 ㅋㅋㅋ

저희 디자이너가 슴가 매니아 인데, 어느 날 밤에 슴가를 열심히 보고 있길레... 뭐하냐? 했더니...
3D로 얼마나 슴가를 자연스럽게 구현할까? 고민중이었다고 했습니다.
그래서, "그럼~ 한번 해봐!" 하고 1달간 개발팀 붙여 주고해서 만든 게임입니다. ㅡㅡ;;

게임의 수위상 안드로이드 구글플레이전용이구욤...

https://play.google.com/store/apps/details?id=com.lingo.LovingRuving&feature=search_result#?t=W251bGwsMSwyLDEsImNvbS5saW5nby5Mb3ZpbmdSdXZpbmciXQ..


에서 다운로드 가능합니다.

담부터는 ios도 지원하기위해 슴가가 움직이는 FPS나 스포츠게임하라고 했습니다. ㅋㅋㅋ

리듬스테이지 깨면 겔러리에서 체험하는 모드로 넘어갑니다. =)

요즘 보면 젊다는게 좋은것 같아요!

2012/10/23 03:47 2012/10/23 03:47

뻐하하하. T_T

공개형 게임 개발툴을 공개하다뉘 T_T 넘 기뽀..
http://www.microsoft.com/xna/
http://msdn.microsoft.com/directx/xna/gamestudio/

2006/08/16 21:05 2006/08/16 21:05

게임하나 맹글어 보겠다고 결심한게 15년이 다되어가는데.. 쩝..
쉬운 3D 모델링 툴찾다가 찾은것이 스케치업이다. 간단히 2시간 두닥거린것에 나온 첫작품 ㅡㅡ;;
설정은 장갑차다.. ㅋㅋ

2006/04/21 00:44 2006/04/21 00:44
결국 고민고민하다가 이걸로 가기로 했습니다. T_T 쩝..
AXIOM의 속도에 반했는데.. 하려고 하는것이 그리 큰 사이즈가 아니라서.. (초보에게 멀바라는거얏!)

일단 Lua를 지원하는데 합격점. XML파서기능 지원에도 합격점. zip파일 지원, 64bit지원(이거 필요한거야?),
꼼수로 이지스 PHYX 물리엔진 지원... 등등등
단, 네트워크 지원안한다는 OTL...
결국 만들어야 겠네요 ㅋㅋㅋ
아직 버전 0.14니까 만들다 보면 나올지도.. ㅡㅡ;;
(아우~ 그냥 C++배워서 OGRE로 만드는게 속편한가? ㅡㅡ;;)

Official :http://irrlicht.sourceforge.net/
2006/04/07 17:15 2006/04/07 17:15

이걸로 코딩한것은 없지만 슈팅게임하나 개발해보려고 찾던도중 찾은 2D엔진입니다.
요즘 2D라면 차라리 플래쉬로 개발하지 어렵게 왜 랭귀지 써서 개발하겠습니까만은..
기본 스팩이 너무 좋아 포기하기 아깝네요.
오픈 소스의 한계랄까? 진짜로 탐나는건 AXIOM인데 아직 1.0도 릴안된상태고 T_T 갈길이 멉니다.

스팩은 다음과 같습니다.
클라이언트/서버 네트워킹
풀오브젝트 관리됨
기타 등등 무지하게 좋고 쉽게 개발가능하며 특히 크로스 플랫폼 지원함.
DirectX기반임


관련사이트
official : http://ovorp.bryanlivingston.com/defau ··· orp.html
Demo : http://vrs-net.sourceforge.net/

2006/04/07 16:55 2006/04/07 16:55
아주 흥미로운 결과가 넷상에 있어서 공개해드립니다.
테스트 환경은 다음과 같습니다.
  • Direct 9.0c October
  • .NET Framework: 1.1.4322.573
  • 1600MGz Pentium M
  • 512 RAM
  • ATI Mobility Radeon 9000 32MB
  • 1400x1050 @ 32bpp Fullscreen
  • Operating System: Microsoft Windows NT 5.1.2600.0 (Windows XP)
  • Axiom Version: Build from CVS 10-16-04
  • OGRE Version: 0.14.0 Prebuilt Release

    사용한 닷넷 프레임워크는 1.1로 현재 2.0보다 느린 버전입니다.

    Name Camera Track Cel
    Shading
    Cube
    Mapping
    Dot3
    Bump
    Fresnel (Pond) Particle
    FX
    Skeletal
    Animation
    Smoke Water Average
    Axiom (C#) 99.94 172.43 130.05 124.79 28.34 33.28 135.84 57.67 101.35 98.19
    OGRE (C++) 89.55 172.98 124.79 81.21 24.26 36.37 153.12 82.72 108.64 97.07


    초당 프레임이 1프레임밖에 안나는 황당한 결과.. -_-;; 저에게는 희망이군요..
    출처 : http://realmforgewiki.castlegobs.nl/in ··· parision
    관련사이트 : http://axiomengine.sourceforge.net/wik ··· ain_page

  • 2006/03/29 11:25 2006/03/29 11:25