2015年4月16日 星期四

Unity 網路遊戲 功能: 聊天室、看到對方行為

※ 此文章所使用的Unity 版本 Unity 5.0.1,若版本太低請自行改Network語法。

ServerMain (Unity js):

#pragma strict

var Message : String;
var scrollPosistion : Vector2;

function OnGUI ()
{
  if (Network.peerType == NetworkPeerType.Disconnected) {
        GUILayout.Label("Network server is not running.");
        if (GUILayout.Button ("Start Server"))
{
startServer();
}
    }
    else {
    if (Network.peerType == NetworkPeerType.Connecting)
        GUILayout.Label("Network server is starting up...");
    else { 
        GUILayout.Label("Network server is running.");        
        showServerInformation();
        showClientInformation();
        }
        if (GUILayout.Button ("Stop Server"))
{
stopServer();
Message = "";
}
    }
    GUILayout.Box(Message);
}

@RPC
function ReqstMessage(name:String, talkword:String){
Message += "\n" + name + " from :" + talkword;
}

public var listenPort : int;
public var maxClients : int;

function startServer() {
Network.InitializeServer(maxClients, listenPort, false);
}

function stopServer() {
Network.Disconnect();
}

function OnServerInitialized() {
  Debug.Log("Network server initialized and ready");
}

function OnDisconnectedFromServer(info : NetworkDisconnection) {
Debug.Log("Network server disconnected");
}

@script RequireComponent(ServerPlayerManager)
private var spm : ServerPlayerManager;
function Awake() {
spm = gameObject.GetComponent(ServerPlayerManager);
}

function OnPlayerConnected(player: NetworkPlayer) {
Debug.Log("Player " + player + "  connected from ip/port: " + player.ipAddress + "/" + player.port);
spm.spawnPlayer(player);
}

function OnPlayerDisconnected(player : NetworkPlayer) {
Debug.Log("Player disconnected");
spm.deletePlayer(player);
}

function showClientInformation() {
GUILayout.Label("Clients: " + Network.connections.Length + "/" + maxClients);
    for(var p: NetworkPlayer in Network.connections) {
GUILayout.Label(" Player " + p + " from ip/port: " + p.ipAddress + "/" + p.port);
}
}

function showServerInformation() {
GUILayout.Label("IP: " + Network.player.ipAddress + " Port: " + Network.player.port);  
}

ServerPlayerManager (Unity js):

#pragma strict

var players = new Hashtable();

function spawnPlayer(player : NetworkPlayer) {
Debug.Log("Spawning player game object for player " + player);
var ply : PlayerInfo = GameObject.FindObjectOfType(PlayerInfo);
var go : GameObject = Network.Instantiate(ply.playerPrefab, Vector3.up*3, Quaternion.identity, 0);
players[player] = go;
}

function deletePlayer(player : NetworkPlayer) {
Debug.Log("Deleting player game object for player " + player);
  var go : GameObject = players[player];
  Network.RemoveRPCs(go.GetComponent.<NetworkView>().viewID); // remove buffered Instantiate calls
Network.Destroy(go); // destroy the game object on all clienst
players.Remove(player); // remove player from server list
}

@RPC
function handlePlayerInput(player: NetworkPlayer, vertical: float, horizontal: float) {
Debug.Log("Received move from player " + player);
  var go : GameObject = players[player];
  go.transform.position = go.transform.position + Vector3.right*horizontal;
  go.transform.position = go.transform.position + Vector3.forward*vertical;
}


------------------------------------------------------

Client Main(Unity js):

var scrollPosistion : Vector2;

var MyName:String = "";
var Inputword:String = "";
var Outputword:String = "";

function Update() {
if(Input.anyKey) {
sendInputToServer();
}
}

function sendInputToServer() {
var vertical: float = Input.GetAxis("Vertical");
var horizontal: float = Input.GetAxis("Horizontal");
if((vertical!=0)||(horizontal!=0)) {
GetComponent.<NetworkView>().RPC("handlePlayerInput",RPCMode.All,Network.player,vertical, horizontal);
}
}

@RPC
function handlePlayerInput(player: NetworkPlayer, vertical: float, horizontal: float) {          
}

@RPC
function ReqstMessage(sayWord:String,name:String){
Outputword += "\n" + sayWord + " from :" + name;
}
      
function OnGUI ()
{
if (Network.peerType == NetworkPeerType.Disconnected)
{
GUILayout.Label("Not connected to server.");
if (GUILayout.Button ("Connect to server"))
connectToServer();
}
else
{
if(Network.peerType == NetworkPeerType.Connecting)
GUILayout.Label("Connecting to server..."); //unity bug: this never happens
else {
GUILayout.Label("Connected to server.");
GUILayout.Label("IP/port: " + Network.player.ipAddress + "/" + Network.player.port);
}
if(Network.isClient){
scrollPosistion = GUILayout.BeginScrollView(scrollPosistion, GUILayout.Width(200), GUILayout.Height(500));
MyName=GUILayout.TextArea(MyName); 
Inputword=GUILayout.TextArea(Inputword);
GUILayout.Box(Outputword);
if(GUILayout.Button("Enter")){
GetComponent.<NetworkView>().RPC("ReqstMessage", RPCMode.All, Inputword, MyName);
}
}
if (GUILayout.Button ("Disconnect")){
disconnectFromServer();
MyName = "";
Inputword = "";
}
GUILayout.EndScrollView ();
}
}

var remoteIP : String;
var remotePort : int;

function connectToServer() {
Debug.Log("Tyring to connect to Server...");
Network.Connect(remoteIP, remotePort);
}

function disconnectFromServer() {
Debug.Log("Tyring to disconnect from the Server...");
Network.Disconnect();
}

function OnConnectedToServer() {
Debug.Log("Successfully connected to server as player " + Network.player);
}

function OnDisconnectedFromServer (info : NetworkDisconnection) {
  if (info == NetworkDisconnection.LostConnection)
    Debug.Log("Lost connection to the server");
else
Debug.Log("Disconnected from the server");
var gos : GameObject[] = GameObject.FindGameObjectsWithTag("Player");
for(var go : GameObject in gos) {
Destroy(go);
}
}

function OnFailedToConnect (error : NetworkConnectionError)  {
Debug.Log("Failed to connect to Server: " + error);
}

------------------------------------------------------


共用腳本 PlayerInfo(Unity js):

#pragma strict

var playerPrefab : GameObject;

------------------------------------------------------


執行結果:

Server: 

Client  01

Client 02



專案下載: http://pan.baidu.com/s/1mg3Otny


2015年4月12日 星期日

Unity Server / Client 基本聊天室

※ Unity 5.0 版本以上,network 參數被捨棄,請改寫成 GetComponent<Network>().RPC(......) 或者 gameObjcet.AddComponent<Network>().RPC(......)。

C#  Server(Network Unity C# ) :

using UnityEngine;
using System.Collections;

public class TestServer : MonoBehaviour {

public int port;

string Message="";
 Vector2 scrollPostition;

void OnGUI(){
switch(Network.peerType){
case NetworkPeerType.Disconnected:
StartServer();
break;
case NetworkPeerType.Server:
OnServer();
break;
case NetworkPeerType.Client:
Debug.Log("Client Line");
break;
case NetworkPeerType.Connecting:
Debug.Log("Test Line");
break;
}
}

void StartServer(){
if(GUILayout.Button("Start Server")){
//Create Server, but Client ten Clinet line;
NetworkConnectionError error = Network.InitializeServer(10, port, false);
//line Error Message;
Debug.Log("Error" + error);
}
}

void OnServer(){
GUILayout.Label ("Create server, Wait client line......");

int lenght = Network.connections.Length;

//Client quantity;
for(int i=0; i < lenght; i++){
GUILayout.Label("Lineing client ID: "+i);
GUILayout.Label("Lineing client IP: "+Network.connections[i].ipAddress);
GUILayout.Label("Lineing client Port: "+Network.connections[i].port);
}

if(GUILayout.Button("Over server")){
Network.Disconnect();
//Return Message;
Message = "";
}

//Create scroll view, Message;
scrollPostition = GUILayout.BeginScrollView (scrollPostition, GUILayout.Width(200), GUILayout.Height(Screen.height));
//Message view
GUILayout.Box (Message);

//Client Posistion Message;
GUILayout.EndScrollView ();
}
[RPC]
// Client talk message;
void RequestMessage(string message, NetworkMessageInfo info){
Message += "\n" + "Clinet: " + info.sender + " message: " +message;
}
}

----------------------------------------

C#  Client(Network Unity C# ) :

using UnityEngine;
using System.Collections;

public class TestClient : MonoBehaviour {

public string IP;
public float speed = 10f, rosistionSpeed = 10f;

int port = 10000;
string InputMessage = "Talk View", Message="";
Vector2 scrollPosistion;

GameObject mainPlay, clientPlay;

void Start(){
mainPlay = GameObject.Find ("Cube");
clientPlay = GameObject.Find ("Cube1");
}

void OnGUI(){
switch (Network.peerType) {
case NetworkPeerType.Disconnected:
StartConnect ();
break;

case NetworkPeerType.Server:
Debug.Log ("Client to server line");
break;

case NetworkPeerType.Client:
OnClient ();
break;

case NetworkPeerType.Connecting:
Debug.Log ("Test connecting");
break;
}
}

void StartConnect(){

if(GUILayout.Button("Start Game")){
NetworkConnectionError error = Network.Connect(IP,port);
Debug.Log("Line Message: "+error);
}
}
void OnClient(){

scrollPosistion = GUILayout.BeginScrollView (scrollPosistion, GUILayout.Width (200), GUILayout.Height (Screen.height));
GUILayout.Box (Message);
GUILayout.BeginHorizontal ();
InputMessage = GUILayout.TextArea (InputMessage);

if (GUILayout.Button ("Input Talk")) {
networkView.RPC("RequestMessage", RPCMode.AllBuffered, InputMessage);
}

GUILayout.EndHorizontal ();

if (GUILayout.Button ("Exit Game")) {
Network.Disconnect ();
Message = "";
}

GUILayout.EndScrollView ();

}
[RPC]
void RequestMessage(string message, NetworkMessageInfo info){
Message += "\n" + "Client: " + info.sender + ":" + message;
}
}

結果圖:



2015年4月6日 星期一

Unity Server / Client


Unity Server Script (c#) :

using UnityEngine;
using System.Collections;

public class Server : MonoBehaviour {

public string IP = "Server IP";
public int Port = Server Port;

void OnGUI(){
if(Network.peerType == NetworkPeerType.Disconnected){
if(GUI.Button(new Rect(Screen.width/Screen.width, Screen.height/Screen.height+120f,100, 50), "Start Server")){
Network.InitializeServer(10, Port);
}
}else{
if(Network.peerType == NetworkPeerType.Server){

GUI.Label(new Rect(Screen.width/Screen.width,Screen.height/Screen.height, 100, 50), "Server");
GUI.Label(new Rect(Screen.width/Screen.width, Screen.height/Screen.height+50f, 100, 50), "Connection Clinet Number: "+ Network.connections.Length);

if(GUI.Button(new Rect(Screen.width/Screen.width, Screen.height/Screen.height+100f,100, 50), "Logout")){
Network.Disconnect(250);
}
}
}
}
}

---------------------------

Unity Client Script (c#) :

using UnityEngine;
using System.Collections;

public class Client : MonoBehaviour {

public string IP = "Server IP";
public int Port = Server Port;
void OnGUI(){
if(Network.peerType == NetworkPeerType.Disconnected){
if(GUI.Button(new Rect(Screen.width/Screen.width, Screen.height/Screen.height,100, 50), "Start Clinet")){
Network.Connect(IP, Port);
}
}else{
if(Network.peerType == NetworkPeerType.Client){
GUI.Label(new Rect(Screen.width/Screen.width,Screen.height/Screen.height, 100, 50), "Clinet");
if(GUI.Button(new Rect(Screen.width/Screen.width, Screen.height/Screen.height + 50f,100, 50), "Logout")){
Network.Disconnect(250);
}
}
}
}
}

---------------------

結果圖 :

    Server Start:


Client Login :







2015年3月31日 星期二

TCP: Server / Client

Java (Server):

package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket; 
import java.util.Date;
  

public class Server  implements Runnable {
      private Socket clientSocket;
      Server (){
          ServerSocket ss = null;
          try {
            ss = new ServerSocket(1800);
            System.out.println("[▶] 伺服器已啟動,等待連線中...");
          } catch (IOException e) {
        }

     while (true) {
            try {
                Socket s = ss.accept();
                new Thread(this).start();
            } catch (IOException e) {
            }
       }
    }

    @Override
    public void run() {
        
        InputStreamReader isr = null;
        BufferedReader br = null;
        OutputStreamWriter osw = null;
        PrintWriter wr = null;
        String ip = null;
        
               try {
                System.out.println("------------------------------------------");
                ip = clientSocket.getInetAddress().toString();
                System.out.println("連線IP : " + ip + ":" + clientSocket.getPort());
                System.out.println("連線時間 : " + new Date());
                isr = new InputStreamReader(clientSocket.getInputStream());
                br = new BufferedReader(isr);
                String msg = br.readLine();
                osw = new OutputStreamWriter(clientSocket.getOutputStream());
                wr = new PrintWriter(osw, true);
                System.out.println("傳來的值:" + msg);
               // 遊戲邏輯,對接收到的值之後進行分類,再依需求做處理。
            } catch (IOException e) {
            }
    }
    
        public static void main(String [] args) {
         new Server ();
   }
}

--------------------------------------------------

Client (Unity C#):

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

public class TcpClientScript : MonoBehaviour{

Socket socket;
StreamReader sr;

byte[] bate, aaa;

TcpClient tcpClient;
NetworkStream ns;

public void setClinetStart(string ip, int port){

try {

tcpClient = new TcpClient (ip, port);
NetworkStream ns = tcpClient.GetStream (); 
StreamWriter sw = new StreamWriter (ns); 
sw.WriteLine ("Unity C# 傳來的訊息");           
sw.Flush (); 
StreamReader sr = new StreamReader (ns); 
print ("從 Java服務器接收到的訊息:" + sr.ReadLine ());
} catch (Exception e) {
print (e); 
Application.Quit();
}
}
}


2015年3月16日 星期一

Unity5.0 Animator 建立粒子系統.....

操作方法:  

1. Gameobjcet 新建一個Animation,Unity5.0 會自動建立Animator。
2. Animator視窗進去後,會看到橘色的Animation(設計者建立)。
3. Inspector 視窗底下會看到Add Behaviour 按鈕點下去,會讓設計者尋找腳本。
4. 若沒有腳本選擇New Script後打上Script name 後 點擊Create and add 按鈕建立腳本。
5. 以下程式函式Unity本身就會建立,只是要注意下函式不同的用法即可。

-------------------------------------------------------------------

程式碼部分:

using UnityEngine;
using System.Collections;

public class SpecialAttackParticlesSmb : StateMachineBehaviour {

public GameObject particles;   
public AvatarIKGoal attackLimb; 

private Transform particlesTransform; 
private ParticleSystem particleSystem; 

override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {

if(particlesTransform != null)
return;

GameObject particleInstance = Instantiate (particles);
particlesTransform = particleInstance.transform;
particleSystem = particleInstance.GetComponent<ParticleSystem> ();
}

override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
particleSystem.Stop ();
}

override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {

if(particleSystem == null || particlesTransform == null)
return;

Vector3 limnPosistion = animator.GetIKPosition (attackLimb);
Quaternion limbRotation = animator.GetIKRotation (attackLimb);

particlesTransform.position = limnPosistion;
particlesTransform.rotation = limbRotation;

if(!particleSystem.isPlaying)
particleSystem.Play();

}
}

-------------------------------------------------------------------

結果圖:



2015年1月26日 星期一

Unity GUI 擴充


Unity  GUI 擴充在這裡適用Unity 本身的GUI來進行自己的擴充工具的類別。

這邊擴充了ImageButton及Windws與HorizontalSlider三個比較常用的工具,還可以繼續在擴充。


GUIComponents(自訂) class:

using UnityEngine;
using System.Collections;

public class GUIComponents{

//ImageButton OnClick View
bool imageButtonOnClick;

// windwosTitleName and WindwosIdNumber
public string windowsTitle;
public int windowsId;

/**
* ImageButton
* TODO ImageButton function(wordPosistionSize, image, style) 
*/
public bool getImageButton(Rect rectScreenRect, Texture image, GUIStyle style){

imageButtonOnClick = GUI.Button (rectScreenRect, image, style);

return imageButtonOnClick;
}

/**
* setAlertDialog
* TODO setAlertDialog Message
* @param {string}Title
* @param {string}Message
*/
public void setAlertDialog(string Title){
this.windowsTitle = Title;
windowsId++;
}

/**
* Windows
* TODO Windows function(wordPosistionSize, windwfunctuin, title)
*/
public void getWindwos (int id, Rect screenRect, GUI.WindowFunction windowFunctuin, string title){

title = this.windowsTitle;
id = this.windowsId;
GUI.Window (id, screenRect, windowFunctuin, title);
}

/**
* HorizontalSlider
* TODO HorizontalSlider function(wordPosistionSize, SliderValue, MaxValue, SliderStyle, ThumbStyle)
*/
public float getHorizontalSlider (Rect screenRect, float sliderValue, float sliderMaxValue, GUIStyle slider, GUIStyle thumb){

screenRect.x += screenRect.width; 
sliderValue = GUI.HorizontalSlider (screenRect, sliderValue, 0.0f, sliderMaxValue, slider, thumb);

return sliderValue;
}
}

--------------------------------------------------------------------------------

套用腳本:

using UnityEngine;
using System.Collections;

public class SystemSetting : MonoBehaviour{

//ImageButton in a Image and buttonStyle
public Texture image;
public GUIStyle buttonstyle;

/**
* WindowSetting
* OnGUI Windows Setting
* WindowsfunctionSetting can in another class use unction
*/
public void OnGUI(){

DpiResolution dpiResolution = new DpiResolution ();
GUIComponents guiCompoents = new GUIComponents ();
Rect wordPosition = new Rect (dpiResolution.getScreenWidth()/dpiResolution.getScreenWidth(),dpiResolution.getScreenHeight()/dpiResolution.getScreenWidth(), 
                             dpiResolution.getScreenWidth(), dpiResolution.getScreenHeight()/1.2f);

guiCompoents.setAlertDialog ("123");
guiCompoents.getWindwos (guiCompoents.windowsId, wordPosition, WindwosMessage, guiCompoents.windowsTitle);

}


void WindwosMessage(int id){

GUIComponents guiCompents = new GUIComponents ();
DpiResolution dpiResolution = new DpiResolution ();
Rect wordPosition = new Rect (dpiResolution.getScreenWidth()/dpiResolution.getScreenWidth(),dpiResolution.getScreenHeight()/dpiResolution.getScreenWidth(), 
                             image.width/5, image.height/2);
if(guiCompents.getImageButton (wordPosition,image, buttonstyle)){
Debug.Log("ok");
}
}
}

--------------------------------------------------------------------------------

執行結果: