【Unity+Socket】实现聊天室

整体流程如下:

  1. 创建一个新的C#控制台应用程序项目用于编写服务器端代码
  2. 新建一个Unity项目,创建一个C#脚本来编写客户端代码
  3. 另外新建一个脚本用于在主线程中执行任务,以便更新UI
  4. UI搭建:InputField、Button、Scroll View、还有一个Text预制体用于显示文本内容
  5. 添加脚本并赋值

最终效果:

【unity+socket】实现聊天室

 开始制作

1.编写服务器端代码
// 聊天服务器类,包含启动服务器、处理客户端连接和消息广播的方法
private TcpListener listener;
private List<TcpClient> clients = new List<TcpClient>();

// 启动服务器方法,接受一个端口号作为参数
public void Start(int port)
{
    listener = new TcpListener(IPAddress.Any, port);
    listener.Start();
    Console.WriteLine("Server started on port " + port);

    while (true)
    {
        TcpClient client = listener.AcceptTcpClient();
        clients.Add(client);
        Console.WriteLine("Client connected!");

        Thread clientThread = new Thread(HandleClient);
        clientThread.Start(client);
    }
}

// 处理客户端连接的方法,接受一个对象作为参数
private void HandleClient(object obj)
{
    TcpClient client = (TcpClient)obj;
    NetworkStream stream = client.GetStream();

    while (true)
    {
        byte[] buffer = new byte[256];
        int bytesRead = stream.Read(buffer, 0, buffer.Length);
        if (bytesRead == 0)
        {
            clients.Remove(client);
            client.Close();
            Console.WriteLine("Client disconnected");
            break;
        }

        string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
        Console.WriteLine("Received: " + message);

        BroadcastMessage(message, client);
    }
}

// 广播消息方法,接受消息和发送者作为参数
private void BroadcastMessage(string message, TcpClient sender)
{
    foreach (TcpClient client in clients)
    {
        if (client != sender)
        {
            NetworkStream stream = client.GetStream();
            byte[] buffer = Encoding.UTF8.GetBytes(message);
            stream.Write(buffer, 0, buffer.Length);
        }
    }
}
}

// 程序主类,包含程序入口点
class Program
{
    static void Main(string[] args)
    {
        ChatServer server = new ChatServer();
        server.Start(5000);
    }

2.客户端代码
public InputField messageInput;
public Button sendButton;
public ScrollRect scrollView;
public GameObject textPrefab; // 预制体,包含Text组件

private TcpClient client;
private NetworkStream stream;
private Thread receiveThread;

void Start()
{
    sendButton.onClick.AddListener(SendMessage);
    ConnectToServer("127.0.0.1", 5000);
}

void ConnectToServer(string ip, int port)
{
    client = new TcpClient(ip, port);
    stream = client.GetStream();

    receiveThread = new Thread(ReceiveMessages);
    receiveThread.Start();
}

void ReceiveMessages()
{
    while (true)
    {
        byte[] buffer = new byte[256];
        int bytesRead = stream.Read(buffer, 0, buffer.Length);
        if (bytesRead == 0)
        {
            Debug.Log("Server disconnected");
            break;
        }

        string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
        AppendMessage(message);
    }
}

void AppendMessage(string message)
{
    UnityMainThreadDispatcher.Instance().Enqueue(() =>
    {
        GameObject newText = Instantiate(textPrefab, scrollView.content);
        newText.GetComponent<Text>().text = message;
        Canvas.ForceUpdateCanvases();
        scrollView.verticalNormalizedPosition = 0f;
        Canvas.ForceUpdateCanvases();
    });
}

public void SendMessage()
{
    string message = messageInput.text;
    byte[] buffer = Encoding.UTF8.GetBytes(message);
    stream.Write(buffer, 0, buffer.Length);
    messageInput.text = "";

    // 显示发送的消息
    AppendMessage(message);
}

void OnApplicationQuit()
{
    if (receiveThread != null && receiveThread.IsAlive)
    {
        receiveThread.Abort();
    }

    if (client != null && client.Connected)
    {
        client.Close();
    }
}

3.更新UI代码
private static readonly Queue<System.Action> _executionQueue = new Queue<System.Action>();

private static UnityMainThreadDispatcher _instance = null;

public static UnityMainThreadDispatcher Instance()
{
    if (_instance == null)
    {
        GameObject go = new GameObject("UnityMainThreadDispatcher");
        _instance = go.AddComponent<UnityMainThreadDispatcher>();
        DontDestroyOnLoad(go);
    }
    return _instance;
}

void Update()
{
    lock (_executionQueue)
    {
        while (_executionQueue.Count > 0)
        {
            _executionQueue.Dequeue().Invoke();
        }
    }
}

public void Enqueue(System.Action action)
{
    lock (_executionQueue)
    {
        _executionQueue.Enqueue(action);
    }
}
4.搭建UI框架

ps:这里我搭建的比较简洁,如有需要可以根据自己的审美进行搭建

大致如图

需要注意的是给Scroll View的Content添加两个组件用于多个文本更好的显示

 

同时也要给Text预制体添加上面的第二个组件用于文本全面地显示 。

5.添加脚本并赋值
  1. 在Hierarchy窗口中,创建一个空的GameObject,将客户端脚本添加上,并将Input Field、Button、Scroll View和Text预制体分别拖到客户端脚本的相应字段中。

  2. 在Hierarchy窗口中,创建一个空的GameObject,并将用于更新UI脚本附加到该GameObject上。

 最后
  1. 启动服务器端应用程序。

  2. 在Unity中运行项目,输入消息并点击发送按钮,消息将会显示在Scroll View中。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值