본문 바로가기
IT/유니티

유니티 게임 프로그래밍 10장 예제 구현

by nutrient 2021. 5. 30.
728x90
728x170

 

BulletSprite

using UnityEngine;
using System.Collections;

public class BulletSprite : SpriteBase {
	
	public float Speed = 10.0f;
	
	// Use this for initialization
	void Start () {
		gameObject.AddComponent<Rigidbody>();
		gameObject.rigidbody.useGravity = false;
		gameObject.AddComponent<BoxCollider>();
		gameObject.collider.isTrigger = true;
	}
	
	// Update is called once per frame
	void Update () {
		float moveAmount = Speed * Time.deltaTime;
		transform.Translate(Vector3.up * moveAmount);
		if(transform.position.y > 10.0f)
			Destroy(gameObject);
	}
}

 

CameraRotate

using UnityEngine;
using System.Collections;

public class CameraRotate : MonoBehaviour {
	
	public float Speed = 0.5f;
	
	// Update is called once per frame
	void Update () {
		transform.RotateAround(Vector3.up,Time.deltaTime * Speed);
	}
}

 

EnemySprite

using UnityEngine;
using System.Collections;

public class EnemySprite : SpriteBase {
	
	public float Speed = 10.0f;
	public GameObject explosion;
	void Start () {
		gameObject.AddComponent<BoxCollider>();
	}
	void Update () {
		//add new code
		if(GameObject.FindWithTag("Player") == null)
			return;
		
		float moveAmount = Speed * Time.deltaTime;
		transform.Translate(Vector3.down * moveAmount);
		if(transform.position.y < -3.0f)
		{
			ResetPosition();
		}
	}
	void ResetPosition()
	{
		transform.position = new Vector3(Random.Range(-5.0f,5.0f),
			5.0f,0.0f);
	}
	void OnTriggerEnter(Collider other)
	{
		if(other.tag == "bullet")
		{
			Instantiate(explosion,transform.position,transform.rotation);
			ResetPosition();
		}
	}
}

 

MainHandler

using UnityEngine;
using System.Collections;

public class MainHandler : MonoBehaviour {
	
	public int Lives = 3;
	public int Score = 0;
	private float MovingSpeed = 50.0f;
	
	public GameObject DistanceLabel;
	public GameObject LifeLabel;
	public GameObject ScoreLabel;

	// Update is called once per frame
	void Update () {
		//add new code
		if(GameObject.FindWithTag("Player") == null)
			return;
		
		DistanceLabel.SendMessage("SetText",
			(Time.time*MovingSpeed).ToString("N1")+" m");
		LifeLabel.SendMessage("SetText","X "+Lives.ToString());
		ScoreLabel.SendMessage("SetText","Score:"+Score.ToString());
	}
	void Bomb(){
		Debug.Log("Bomb Button Click");
	}
}

 

PlayerSprite

using UnityEngine;
using System.Collections;

public class PlayerSprite : SpriteBase {
	
	public GameObject Bullet;
	public float Speed = 5.0f;
	
	float LastShootTime;
	public float ShootDelayTime = 0.2f;
	
	//new Code
	public NetworkPlayer Owner;
	public TextMesh NameMesh;
	[RPC]
	void SetPlayer(NetworkPlayer player){
		this.Owner = player;
		gameObject.AddComponent("PlayerRemote");
		string[] ip = this.Owner.ipAddress.Split('.');
		NameMesh.text = ip[ip.Length-1];
		NameMesh.renderer.material.color = Color.red;
		
	}
	void Start () {
		LastShootTime = Time.time;
	}
	void Update () {
		//new code
		if(Network.peerType != NetworkPeerType.Disconnected &&
			Network.player == Owner)
		{
			float moveAmount = Input.GetAxis("Horizontal")*Speed*Time.deltaTime;
			transform.Translate(Vector3.right * moveAmount);
			if(Time.time > LastShootTime + ShootDelayTime)
			{
				LastShootTime = Time.time;
				Network.Instantiate(Bullet,transform.position,transform.rotation,0);
			}
		}
	}
}

 

SpriteBase

using UnityEngine;
using System.Collections;

public class SpriteBase : MonoBehaviour {
	
	public Material mat;
	
	void Awake () {
		gameObject.AddComponent<MeshFilter>();
		gameObject.AddComponent<MeshRenderer>();
		Mesh mesh = GetComponent<MeshFilter>().mesh;
		mesh.Clear();
		mesh.vertices = new Vector3[]{new Vector3(0.0f,0.0f,0.0f),new Vector3(0.0f,1.0f,0.0f),
			new Vector3(1.0f,1.0f,0.0f),new Vector3(1.0f,0.0f,0.0f)};
		mesh.uv = new Vector2[]{new Vector2(0.0f,0.0f),new Vector2(0.0f,1.0f),
			new Vector2(1.0f,1.0f),new Vector2(1.0f,0.0f)};
		mesh.triangles = new int[] {0,1,2,0,2,3};
		mesh.RecalculateNormals();
		mesh.RecalculateBounds();
		if(mat != null)
			gameObject.renderer.material = mat;
		MakeResizeByImageSize();
		
	}
	void MakeResizeByImageSize()
	{
		float one_unit = 2.0f/ Screen.height;
		float x = one_unit * mat.mainTexture.width;
		float y = one_unit * mat.mainTexture.height;
		Vector3 newScale = new Vector3(x,y,one_unit);
		transform.localScale = newScale;
	}
}

 

PlayerRemote

using UnityEngine;
using System.Collections;

public class PlayerRemote : MonoBehaviour {
	
	public class State:System.Object{
		public Vector3 p;
		public Quaternion r;
		public float t;
		
		public State(Vector3 p , Quaternion r, float t)
		{
			this.p = p;
		 	this.r = r;
			this.t = t;
		}
	}
	
	public bool simulatePhysics = true;
	public bool updatePosition = true;
	public float physInterp = 0.1f;
	public float netInterp = 0.2f;
	public float ping;
	public float jitter;
	
	public bool isResponding = false;
	public string netCode = "(No Connections)";
	private int m;
	private Vector3 p;
	private Quaternion r;
	private State[] states = new State[15];
	private int stateCount = 0;
	private Vector3 velocity;
	
	private State nullstate;

	// Use this for initialization
	void Start () {
		networkView.observed = this;
		nullstate = new State(Vector3.zero,Quaternion.identity,0.0f);
		for(int i = 0 ; i < states.Length;i++)
		{
			states[i] = new State(nullstate.p,nullstate.r,nullstate.t);
		}
		velocity = new Vector3(0.0f,0.0f,0.0f);
		
	}
	
	
	void FixedUpdate(){
		if(!updatePosition || states[10].Equals(nullstate))
		{
			return;
		}
		
		float difftime = (float)Network.time - states[0].t;
		jitter = Mathf.Lerp(jitter, Mathf.Abs(ping - difftime),Time.deltaTime * 0.3f);
		ping = Mathf.Lerp(ping,(float)Network.time - states[0].t,Time.deltaTime * 0.3f);
		
		float interpolationTime = (float)Network.time - netInterp;
		if(states[0].t > interpolationTime)
		{
			int i;
			for(i = 0 ; i <stateCount;i++)
			{
				if(states[i] != null && (states[i].t <= interpolationTime || 
					i == stateCount - 1))
				{
					State rhs = states[Mathf.Max(i-1,0)];
					State lhs = states[i];
					float l = rhs.t - lhs.t;
					float t = 0.0f;
					if(l > 0.0001f)
						t = ((interpolationTime - lhs.t)/l);
					if(simulatePhysics){
						gameObject.transform.position = Vector3.Lerp(
							gameObject.transform.position,
							Vector3.Lerp(lhs.p,rhs.p,t),physInterp);
						gameObject.transform.rotation = Quaternion.Slerp(
							gameObject.transform.rotation, 
							Quaternion.Slerp(lhs.r,rhs.r,t),physInterp);						
						velocity = ((rhs.p - states[i+1].p)/(rhs.t - states[i+1].t));
						
					}else {
						gameObject.transform.position = Vector3.Lerp(lhs.p, rhs.p,t);
						gameObject.transform.rotation = Quaternion.Slerp(lhs.r,rhs.r,t);
					}
					isResponding = true;
					netCode = "";
					return;
				}
			}
		}else{
			float extrapolationLength = (interpolationTime - states[0].t);
			if(extrapolationLength < 1 && states[0].Equals(nullstate) == false 
				&& states[1].Equals(nullstate) == false){
				if(!simulatePhysics){
					gameObject.transform.position = states[0].p + 
						(((states[0].p - states[1].p) /(states[0].t - states[1].t)) * 
							extrapolationLength);
					gameObject.transform.rotation = states[0].r;
				}
				isResponding = true;
				if(extrapolationLength < 0.5f) netCode = ">";
				else netCode = "(Delayed)";
			}else{
				netCode = "(NotResponding)";
				isResponding = false;
			}
			
		}
		if(simulatePhysics && states[0].t > states[2].t)
		{
			velocity = ((states[0].p - states[2].p) /(states[0].t - states[2].t));
		}
		if(transform.localScale == Vector3.zero)
		{
			gameObject.SendMessage("MakeResizeByImageSize");
		}
	}
	void OnSerializeNetworkView(BitStream stream,NetworkMessageInfo info){
		if(stream.isWriting){
			p = gameObject.transform.position;
			r = gameObject.transform.rotation;
			m = stateCount == 0 ? 0 :(int)(((float)Network.time-states[0].t)*1000);
			stream.Serialize(ref p);
			stream.Serialize(ref r);
			stream.Serialize(ref m);
		}else{
			stream.Serialize(ref p);
			stream.Serialize(ref r);
			stream.Serialize(ref m);
			State state = new State(p,r,(float)(info.timestamp - (m > 0?(m/1000):0.0f)));
			if(stateCount == 0)
			{
				states[0] = new State(state.p,state.r,state.t);
			}else if(state.t > states[0].t)
			{
				for(int k = states.Length-1; k > 0;k--)
				{
					states[k] = states[k-1];
				}
				states[0] = new State(state.p,state.r,state.t);
				
			}else
			{
				Debug.Log(gameObject.name+"Out-of-order state received and ignored ("+
					((states[0].t-state.t)*1000)+")"+states[0].t+"---"+state.t+"---"+m+
					"---"+states[0].p.x+"---"+state.p.x);
			}
			stateCount = Mathf.Min(stateCount + 1, states.Length);
			
		}
	}
	
	public Vector3 GetVelocity()
	{
		return this.velocity;
	}
	
}

 

UnityNetworkCS

using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;

public class UnityNetworkCS : MonoBehaviour {
	
	public IPAddress ipaddress;
	public string connectToIP = "127.0.0.1";
	public int connectPort = 12345;
	public Transform PlayerPrefab;
	public ArrayList playerScripts = new ArrayList();
	public Vector3 spawnPosition;
	
	void Awake()
	{
		DontDestroyOnLoad(gameObject);
		Application.runInBackground = true;
	}
	
	// Use this for initialization
	void Start () {
		string name =  Dns.GetHostName();
		IPAddress[] ips = Dns.GetHostAddresses(name);
		foreach(IPAddress ip in ips)
		{
			Debug.Log(string.Format("{0}={1}({2})",name,ip,ip.AddressFamily));
			ipaddress = ip;
		}
	}
	
	void OnGUI(){
		if(Network.peerType == NetworkPeerType.Disconnected)
		{
			GUILayout.BeginArea( new Rect(Screen.width/2 - 100,
				Screen.height/2 - 128,200,256));
			
			GUILayout.Label("Connection Status:Disconnected");
			
			connectToIP = GUILayout.TextField(connectToIP,GUILayout.MinWidth(100));
			connectPort = int.Parse(GUILayout.TextField(connectPort.ToString()));
			
			if(GUILayout.Button("Connect as Client",GUILayout.MinHeight(40)))
			{
				Debug.Log("Click connect as client");
				Network.Connect(connectToIP,connectPort);
			}
			if(GUILayout.Button("Start Server",GUILayout.MinHeight(40)))
			{
				Debug.Log("Click Start Server");
				Network.InitializeServer(32,connectPort,false);
			}
			
			GUILayout.EndArea();
		}else{
			GUILayout.BeginArea( new Rect(Screen.width - 150, 20.0f,150.0f,200));
			GUILayout.Label("IP: "+this.ipaddress.ToString());
			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 : Sevrer~!");
				GUILayout.Label("Connections : "+Network.connections.Length);
				if(Network.connections.Length >=1)
				{
					GUILayout.Label("Ping fp: "+
						Network.GetAveragePing(Network.connections[0]));
				}
			}
			if(GUILayout.Button("Disconnect"))
			{
				Debug.Log("Click Disconnect");
				Network.Disconnect(200);
			}
			GUILayout.EndArea();
		}
	}
	
	void SpawnPlayer( NetworkPlayer newPlayer)
	{
		int playerNumber = int.Parse(newPlayer.ToString());
		Transform myNewTrans = null;
		Debug.Log("SpawnPlayer Called");
		
		if(Network.player == newPlayer)
		{
			myNewTrans = Network.Instantiate(PlayerPrefab,
				spawnPosition,transform.rotation,playerNumber) as Transform;
		}
		if(myNewTrans != null)
		{
			NetworkView newObjectsNetworkView = myNewTrans.networkView;
			playerScripts.Add(myNewTrans.GetComponent<PlayerSprite>());
			Debug.Log("Player Spawn :" + playerNumber);
			newObjectsNetworkView.RPC("SetPlayer",RPCMode.AllBuffered,newPlayer);
		}else
		{
			Debug.LogError("Cant Instantiated the Player Prefab");
		}
	}
	
	void OnServerInitialized(){
		Debug.Log("Server Initialze finish");
		SpawnPlayer(Network.player);
	}
	void OnConnectedToServer(){
		Debug.Log("Connected to Server");
		SpawnPlayer(Network.player);
	}
	void OnPlayerConnected(NetworkPlayer newPlayer){
		Debug.Log("A player connected to me(the server)");
	}
	void OnPlayerDisconnected( NetworkPlayer player)
	{
		
		int playerNumber = int.Parse(player.ToString());
		Network.RemoveRPCs(Network.player,playerNumber);
		Network.RemoveRPCs(player);
		Network.DestroyPlayerObjects(player);
		
	}
	void OnDisconnectedFromServer( NetworkDisconnection infor)
	{
		Application.LoadLevel(Application.loadedLevel);
	}
}
728x90
그리드형

댓글