Unity實(shí)現(xiàn)局域網(wǎng)聊天室功能
基于Unity實(shí)現(xiàn)一個(gè)簡(jiǎn)單的局域網(wǎng)聊天室,供大家參考,具體內(nèi)容如下
學(xué)習(xí)Unity有一點(diǎn)時(shí)間了,之前學(xué)的都是做客戶端的一些內(nèi)容,現(xiàn)在開始學(xué)習(xí)聯(lián)網(wǎng)。我的這個(gè)是在觀看了 Siki 的教學(xué)內(nèi)容來(lái)做的,也有自己的一點(diǎn)點(diǎn)小小的改動(dòng)在里面。純粹用于練手了。
因?yàn)楸救艘彩切“滓幻?,所以,有錯(cuò)誤的地方或者更好的實(shí)現(xiàn)方法,也希望有大神能幫忙指正,多謝!
整體過(guò)程分為兩部分:構(gòu)建服務(wù)端、構(gòu)建客戶端。
服務(wù)端:
大概思路:
1. 聲明Socket連接以及綁定IP和端口,這里面使用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using System.Net; namespace ServerApplication { class Program { public static string IP; public static int Port; static List<Client> clientList = new List<Client>(); static Socket serverSocket; static void Main(string[] args) { //綁定IP和端口 BindIPAndPort(); // while (true) { Socket clientSocket = serverSocket.Accept(); Client client = new Client(clientSocket); clientList.Add(client); Console.WriteLine("一臺(tái)主機(jī)進(jìn)入連接"); } } /// <summary> /// 廣播數(shù)據(jù) /// </summary> public static void BroadcostMSG(string s) { List<Client> NotConnectedList = new List<Client>(); foreach (var item in clientList) { if(item.IsConnected) { item.SendMSG(s); } else { NotConnectedList.Add(item); } } foreach (var item in NotConnectedList) { clientList.Remove(item); } } /// <summary> /// 綁定IP和端口 /// </summary> public static void BindIPAndPort() { //創(chuàng)建一個(gè)serverSocket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //聲明IP和端口 Console.WriteLine("輸入IP地址:"); IP = Console.ReadLine(); string ipStr = IP; Console.WriteLine("請(qǐng)輸入端口:"); Port = int.Parse(Console.ReadLine()); int port = Port; IPAddress serverIp = IPAddress.Parse(ipStr); EndPoint serverPoint = new IPEndPoint(serverIp, port); //socket和ip進(jìn)行綁定 serverSocket.Bind(serverPoint); //監(jiān)聽最大數(shù)為100 serverSocket.Listen(100); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using System.Threading; namespace ServerApplication { class Client { public Socket clientSocket; //聲明一個(gè)線程用于接收信息 Thread t; //接收信息所用容器 byte[] data = new byte[1024]; //構(gòu)造函數(shù) public Client(Socket s) { clientSocket = s; t = new Thread(ReceiveMSG); t.Start(); } /// <summary> /// 接收數(shù)據(jù) /// </summary> void ReceiveMSG() { while(true) { if (clientSocket.Poll(10,SelectMode.SelectRead)) { break; } data = new byte[1024]; int length = clientSocket.Receive(data); string message = Encoding.UTF8.GetString(data, 0, length); Program.BroadcostMSG(message); Console.WriteLine("收到消息:" + message); } } /// <summary> /// 發(fā)送數(shù)據(jù) /// </summary> /// <param name="s"></param> public void SendMSG(string message) { byte[] data = Encoding.UTF8.GetBytes(message); clientSocket.Send(data); } //判斷此Client對(duì)象是否在連接狀態(tài) public bool IsConnected { get { return clientSocket.Connected; } } } }
客戶端:
a.UI界面
UI界面是使用UGUI實(shí)現(xiàn)的
登錄用戶可以自己取名進(jìn)行登錄(發(fā)言時(shí)用于顯示),使用時(shí)需要輸入服務(wù)端的IP地址和端口號(hào)
下面是聊天室的頁(yè)面,在輸入框內(nèi)輸入要發(fā)送的消息,點(diǎn)擊Send,將信息發(fā)送出去
這是服務(wù)端的信息
b.關(guān)于客戶端的腳本
(1)這是ClientManager,負(fù)責(zé)與服務(wù)端進(jìn)行連接,通信
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net.Sockets; using System.Net; using System.Text; using UnityEngine.UI; using System.Threading; public class ClientManager : MonoBehaviour { //ip:192.168.1.7 public string ipAddressstr; public int port; public Text ipTextToShow; //Socket private Socket ClientServer; //文本輸入框 public InputField inputTxt; public string inputMSGStr; //接收 Thread t; public Text receiveTextCom; public string message; // Use this for initialization void Start() { ipTextToShow.text = ipAddressstr; // ConnectedToServer(); } // Update is called once per frame void Update() { if (message != null && message != "") { receiveTextCom.text = receiveTextCom.text + "\n" + message; message = ""; } } /// <summary> /// 連接服務(wù)器 /// </summary> public void ConnectedToServer() { ClientServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //聲明IP地址和端口 IPAddress ServerAddress = IPAddress.Parse(ipAddressstr); EndPoint ServerPoint = new IPEndPoint(ServerAddress, port); ipAddressstr = IpInfo.ipStr; port = IpInfo.portStr; //開始連接 ClientServer.Connect(ServerPoint); t = new Thread(ReceiveMSG); t.Start(); } /// <summary> /// 接收消息 /// </summary> /// <returns>“string”</returns> void ReceiveMSG() { while (true) { if (ClientServer.Connected == false) { break; } byte[] data = new byte[1024]; int length = ClientServer.Receive(data); message = Encoding.UTF8.GetString(data, 0, length); //Debug.Log("有消息進(jìn)來(lái)"); } } /// <summary> /// 發(fā)送string類型數(shù)據(jù) /// </summary> /// <param name="input"></param> public void SendMSG() { Debug.Log("button Clicked"); //message = "我:" + inputTxt.text; inputMSGStr = inputTxt.text; byte[] data = Encoding.UTF8.GetBytes(IpInfo.name+":"+inputMSGStr); ClientServer.Send(data); } private void OnDestroy() { ClientServer.Shutdown(SocketShutdown.Both); ClientServer.Close(); } private void OnApplicationQuit() { OnDestroy(); } }
(2)SceneManager,用于場(chǎng)景切換,這里只是利用GameObject進(jìn)行SetActive()來(lái)實(shí)現(xiàn),并不是創(chuàng)建了單獨(dú)的Scene進(jìn)行管理。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SceneManager : MonoBehaviour { public GameObject loginPanel; public GameObject communicatingPanel; // Use this for initialization public void OnSwitch() { loginPanel.SetActive(false); communicatingPanel.SetActive(true); } }
(3)LogInPanel和IPInfo,一個(gè)掛載在登錄界面上,一個(gè)是數(shù)據(jù)模型,用于存儲(chǔ)數(shù)據(jù)。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LogInPanel : MonoBehaviour { public Text nameInputTxt; public Text ipInputTxt; public Text portInputTxt; //private string name; //private string ipStr; //private string portStr; public void OnLogInClick() { IpInfo.name = nameInputTxt.text; IpInfo.ipStr = ipInputTxt.text; IpInfo.portStr = int.Parse(portInputTxt.text); } }
public static class IpInfo { public static string name; public static string ipStr; public static int portStr; }
總結(jié):第一次寫學(xué)習(xí)博,還有很多地方要學(xué)習(xí)啊。
留待解決的問(wèn)題:此聊天室只能用于局域網(wǎng)以內(nèi),廣域網(wǎng)就無(wú)法實(shí)現(xiàn)通信了,還要看看怎么實(shí)現(xiàn)遠(yuǎn)程的一個(gè)通信,不然這個(gè)就沒(méi)有存在的意義了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C# InitializeComponent()方法案例詳解
這篇文章主要介紹了C# InitializeComponent()方法案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08關(guān)于C#版Nebula客戶端編譯的問(wèn)題
這篇文章主要介紹了C#版Nebula客戶端編譯的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07c# 閉包的相關(guān)知識(shí)以及需要注意的地方
這篇文章主要介紹了c# 閉包的相關(guān)知識(shí)以及需要注意的地方,文中講解非常細(xì)致,代碼幫助大家理解和學(xué)習(xí),感興趣的朋友可以參考下2020-06-06c#反射機(jī)制學(xué)習(xí)和利用反射獲取類型信息
反射(Reflection)是.NET中的重要機(jī)制,通過(guò)放射,可以在運(yùn)行時(shí)獲得.NET中每一個(gè)類型(包括類、結(jié)構(gòu)、委托、接口和枚舉等)的成員,包括方法、屬性、事件,以及構(gòu)造函數(shù)等。還可以獲得每個(gè)成員的名稱、限定符和參數(shù)等。有了反射,即可對(duì)每一個(gè)類型了如指掌。如果獲得了構(gòu)造函數(shù)的信息,即可直接創(chuàng)建對(duì)象,即使這個(gè)對(duì)象的類型在編譯時(shí)還不知道2014-01-01C#實(shí)現(xiàn)將HTML轉(zhuǎn)換成純文本的方法
這篇文章主要介紹了C#實(shí)現(xiàn)將HTML轉(zhuǎn)換成純文本的方法,基于自定義類實(shí)現(xiàn)文本轉(zhuǎn)換功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07