실전 Unity3D Engine Programing 과정 8일차 (2013.07.31 (수))



복습

터랫

어탯, 충돌, 테크 지정

몬스터 쫒아다니기

카메라 3인칭


카메라 3인칭은 카메라가 공유하고 높이도 알아서 캐릭터를 바라보게 했다.

댐핑을 써서 카메라를 늦게 동작하게 된다...



네트워크 관련된 것 이전에 설명했다.


이제 두개의 스크립트 만든다.

- 네트워크 화면 스크립트

- 출력용 로그 스크립트



@@Tip

앗셋에 폴더 두개 만든다.

- Scripts

   - ScriptsAttribute

     - 클래스의 속성을 정해 줄 수 있다. C#에만 있는 기능이다. 이것을 유니티에서 가능하다.

- Skins

   마우스에서 create > GUI Skin 만든다.



클래스에 속성 주기 스크립트에 기록한다.

using UnityEngine;

using System.Collections;


[ExecuteInEditMode]

public class ScriptsAttribute : MonoBehaviour {

public Rect myRect;

void OnGUI()

{

GUI.Button(myRect,"BUTTON");

}

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

}

}


빈오브젝트 Test만들고 스크립트를 붙인다.
인스팩트의 MyRect를 클릭해서 좌표를 지정하면
OnGUI
Update는 play하지도 않고 Game화면에서 볼 수 잇다.







[RequireComponent(typeof(Rigidbody))] 속성을 붙여주여주면

리지디바디가 없으면 자동으로 붙여 준다.


using UnityEngine;

using System.Collections;


[RequireComponent(typeof(Rigidbody))]

[ExecuteInEditMode]

public class ScriptsAttribute : MonoBehaviour {

public Rect myRect;

void OnGUI()

{

GUI.Button(myRect,"BUTTON");

}

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

}

}



##새로 하자.

1. 로그 출력 스크립트를 만든다.

    - 스크롤과 버튼 등 만든다.

    - RPC로 로그를 받는다.

[RPC]  //함수의 속성을 지정하며 이렇게 RPC로 하면 네트워크모듈이 특별관리한다.

public void ScreenLog(string text)

{

}

using UnityEngine;
using System.Collections;

public class Log : MonoBehaviour {
public GUISkin skin;
public int ScrollSize; // 스크롤에차일드 갯수 꼬리에붙여준다.
private int index = 0;
private Vector2 scrollPosition = Vector2.zero;
private string[] logtext;
public static Log logInstance; //싱글톤으로하자.
public bool IsOn = true;  //로그출력On/Off.
void Awake()
{
//신이호출되자마자불린다.
logInstance = this;
//신이바뀌이도로그화면은 계속나와야한다. 
// 아래 것을지정하면신이바뀌어도계속존재한다.
DontDestroyOnLoad(gameObject);
}
// Use this for initialization
void Start () {
//초기화.
if(ScrollSize == 0)
{
ScrollSize = 1000;
}
logtext = new string[ScrollSize];
for(int i =0;i<ScrollSize;i++)
{
logtext[i] = " ";
}
}
void OnGUI()
{
//초기화버튼.
if(GUI.Button(new Rect(0, 0, 48,16), "X"))
{
index =0;
for(int i =0;i<ScrollSize;i++)
{
logtext[i] = " ";
}
scrollPosition = Vector2.zero;
}
IsOn = GUI.Toggle(new Rect(100,0,100,24), IsOn, "On/Off");
if(IsOn.Equals(true))
{
GUI.skin = skin;
//스크롤영역을잡고그안에스크롤바를넣게한다 BeginScrollView와EndScrollView를지정하면그안에영역을잡는다는것이다
scrollPosition = GUI.BeginScrollView(new Rect(10,50,Screen.width - 10, Screen.height -100),scrollPosition, new Rect(0,0,1000,ScrollSize *24));
GUI.color = Color.white;
for(int i=0;i<ScrollSize;i++)
{
GUI.Label(new Rect(0,i*28, 700,28), logtext[i]);
}
GUI.EndScrollView();
}
}
public void SetOnOff(bool onoff)
{
IsOn = onoff;
}
[RPC]
public void ScreenLog(string text)
{
if(logtext == null)
{
return;
logtext[index] = text;
index++;
if(index > ScrollSize -1)
{
for(int i=0;i<ScrollSize;i++)
{
logtext[i] = logtext[i+1];
}
index = ScrollSize + 1;
}
}
}


빈오브제트 만들어 Chat으로 하고 여기에 상기 스크립트를 붙이다. 

NetChat 스크립트를 만든다.

using UnityEngine;

using System.Collections;


public class NetChat : MonoBehaviour {

public string ConnectToIP = "127,0,0,1";

public int connectPort = 12345;

public ArrayList clientScripts = new ArrayList();

private string chatMessage = "";

void Awake() {

DontDestroyOnLoad(gameObject);

Application.runInBackground = true; //포커스를일어도백그라운드에서도는것 정의. 

}

void OnServerInitialized(){

//소켓준비가완료되면호출된다.

Debug.Log("Server Start ~ ");

}

void OnPlayerConnected(NetworkPlayer newPlayer)

{

Debug.Log("A Client connected to me(server) " + newPlayer.ipAddress.ToString());

}

void OnPlayerDisconnected(NetworkPlayer player)

{

Debug.Log("Player Quit~ " + player.ipAddress.ToString());

}

void OnDisconnectedFromServer(NetworkDisconnection info)

{

Debug.Log("Connecting Failed~ "+info.ToString());

}

void OnConnectedToServer()

{

Debug.Log("Connecting Success ~");

}

void OnGUI()

{

if(Network.peerType == NetworkPeerType.Disconnected)

{

//disconnected

GUILayout.BeginArea(new Rect(Screen.width/2-100, Screen.height/2-129, 200, 256));

GUILayout.Label("Connection Sttus: Disconnected");

ConnectToIP = GUILayout.TextField(ConnectToIP, GUILayout.MinWidth(100));

connectPort = int.Parse(GUILayout.TextField(connectPort.ToString()));

//button 2개만들자.

//서버에접속하는클라이언트.

if(GUILayout.Button("Connect as Client", GUILayout.MinHeight(40)))

{

Debug.Log("Click Connect as Client~");

Network.Connect(ConnectToIP, connectPort);

}

//서버로동작하는버튼.

if(GUILayout.Button("Start as Server", GUILayout.MinHeight(40)))

{

Debug.Log("Click Start as Server~");

//32 user수

Network.InitializeServer(32, connectPort, false);

}

GUILayout.EndArea();

} else

{

   //connected

GUILayout.BeginArea(new Rect(Screen.width-150, 20, 150, 200));

if(Network.peerType == NetworkPeerType.Connecting)

{

GUILayout.Label("Connection Status: Connecting");

}else if(Network.peerType == NetworkPeerType.Client)

{

GUILayout.Label("Connection Status: Client!");

GUILayout.Label("Ping to Server "+Network.GetAveragePing(Network.connections[0]));

}else if(Network.peerType == NetworkPeerType.Server)

{

GUILayout.Label("Connection Status: Server!");

GUILayout.Label("Connections: "+Network.connections.Length.ToString());

if(Network.connections.Length > 0)

{

GUILayout.Label("Ping : "+Network.GetAveragePing(Network.connections[0]));

}

}

if(GUILayout.Button("Disconnect"))

{

Debug.Log("Click Disconnect");

Network.Disconnect(200);

}

GUILayout.EndArea();

//채팅.

chatMessage = GUI.TextField(new Rect(Screen.width / 2 -200, Screen.height -30, 400,30),chatMessage);

if(GUI.Button(new Rect(Screen.width/2+220, Screen.height -30,100,30),"SEND"))

{

if(chatMessage != " ")

{

//SendMsg함수가호출되고서버만전달된다.

networkView.RPC("SendMsg ",RPCMode.Server, Network.player.ipAddress + ":" +chatMessage);

chatMessage = " "; // 초기화.

}

}

}

}

[RPC]

public void SendMsg(string msg)

{

Debug.Log("Called SendMsg");

networkView.RPC("ScreenLog", RPCMode.All, msg);

}

}



UI만들때 자동으로 영역을 채우는 방법도 있다. 거의 쓸일은 없다.

GUILayout.BeginArea(new Rect(Screen.width/2-100, Screen.height/2-129, 200, 256));

GUILayout.EndArea();

Rect가 필요없다.



메인카메라 백그라운칼라를 바꿔준다.


Chat 오브젝트 선택하고 menu > componet > miscellonuse > Network View  그리고 syncronization 은 off한다.

NetChat 스크립트 붙인다.

- IP주소 확인한다. 자신의 컴퓨터 것

실행해 본다.



menu > File > Buld Setting 을 누르고 만든 Scene을 넣어 주다.

빌드후 파일명을 넣어 준다. Build.exe

빌드버튼을 누른다.


탐색기에서 해당 파일을 실행한다. 해상도 지정해 준다.

이것은 클라이언트로 실행한다. 


유니티는 다시 플레이해서 서버로 실행한다.

이제 상호 통신해 본다.



실행 순서는

서버를 킨후 클라이언트를 연결 요청한다.