Windows 命名管道(Named Pipe),用于 Unity 与桌面程序之间的进程间通信(IPC)

Unity与桌面程序集成 – 使用说明

项目概述

这个解决方案演示了如何通过C#桌面程序启动Unity,并通过命名管道(Named Pipe)实现双向进程间通信,使桌面程序与Unity可以互相发送消息和调用方法。

快速开始

步骤1:准备Unity项目

打开Unity编辑器(2021.3.5f1c1或兼容版本)打开项目(当前目录)确保场景中有GameObject,并将脚本添加到该GameObject上
如果没有GameObject,在Hierarchy中右键 -> Create Empty,命名为”UnityMain”将
Assets/UnityMain.cs
脚本拖拽到该GameObject上将
Assets/PipeServer.cs
脚本拖拽到该GameObject上(用于接收桌面消息)
PipeClient
脚本会在UnityMain启动时自动添加(用于向桌面发送消息) 保存场景

UnityMain源码


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Unity主类,提供可被桌面程序通过管道调用的方法,并可以向桌面程序发送消息
/// </summary>
public class UnityMain : MonoBehaviour
{
    private string currentStatus = "Unity已启动";
    private PipeClient pipeClient;

    // Start is called before the first frame update
    void Start()
    {
        // 确保主线程调度器存在
        UnityMainThreadDispatcher.Instance();

        // 初始化管道客户端(用于向桌面程序发送消息)
        pipeClient = gameObject.AddComponent<PipeClient>();
        if (pipeClient == null)
        {
            pipeClient = FindObjectOfType<PipeClient>();
        }

        Debug.Log("UnityMain初始化完成 - 双向管道通信已就绪");
        currentStatus = "Unity已初始化";

        // 发送初始化消息到桌面程序
        SendMessageToDesktop("UnityInitialized|Unity应用程序已启动并初始化完成");
    }

    /// <summary>
    /// 按钮点击方法 - 可以被桌面程序通过管道调用
    /// </summary>
    public void OnClickBtn() 
    {
        Debug.Log("OnClickBtn被调用 - hahah");
        currentStatus = $"按钮已点击 - {System.DateTime.Now:HH:mm:ss}";
        
        // 可以在这里添加更多的Unity逻辑
        // 例如:播放音效、动画、改变场景等
        
        // 示例:改变对象的颜色(如果有Renderer组件)
        Renderer renderer = GetComponent<Renderer>();
        if (renderer != null)
        {
            renderer.material.color = new Color(Random.value, Random.value, Random.value);
        }

        // 向桌面程序发送通知消息
        SendMessageToDesktop($"ButtonClicked|OnClickBtn方法已被调用,时间: {System.DateTime.Now:HH:mm:ss}");
    }

    /// <summary>
    /// 带消息的按钮点击方法 - 可以被桌面程序通过管道调用
    /// </summary>
    public void OnClickBtnWithMessage(string message)
    {
        Debug.Log($"OnClickBtnWithMessage被调用,消息: {message}");
        currentStatus = $"收到消息: {message} - {System.DateTime.Now:HH:mm:ss}";
        
        // 可以在这里处理传入的消息
        
        // 向桌面程序发送响应消息
        SendMessageToDesktop($"MessageReceived|Unity收到消息: {message}");
    }

    /// <summary>
    /// 获取当前状态
    /// </summary>
    public string GetStatus()
    {
        return currentStatus;
    }

    /// <summary>
    /// 向桌面程序发送消息
    /// </summary>
    /// <param name="message">消息内容,格式:类型|内容</param>
    public void SendMessageToDesktop(string message)
    {
        if (pipeClient != null)
        {
            bool success = pipeClient.SendMessage(message);
            if (success)
            {
                Debug.Log($"已发送消息到桌面程序: {message}");
            }
            else
            {
                Debug.LogWarning($"发送消息到桌面程序失败: {message}");
            }
        }
        else
        {
            Debug.LogWarning("PipeClient未初始化,无法发送消息到桌面程序");
        }
    }

    /// <summary>
    /// 发送状态更新到桌面程序
    /// </summary>
    public void SendStatusUpdate()
    {
        SendMessageToDesktop($"StatusUpdate|{currentStatus}");
    }

    /// <summary>
    /// 示例:Unity主动发送消息到桌面程序
    /// 可以在Unity的Update、协程或其他事件中调用
    /// </summary>
    void Update()
    {
        // 示例:按空格键发送消息到桌面程序
        if (Input.GetKeyDown(KeyCode.Space))
        {
            SendMessageToDesktop($"KeyPressed|Unity中按下了空格键");
        }
    }

    void OnDestroy()
    {
        // 清理资源(如果需要)
    }

    void OnApplicationQuit()
    {
        // 清理资源(如果需要)
    }
}

PipeServer 源码


using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Threading;
using UnityEngine;

/// <summary>
/// Unity中的命名管道服务器,用于接收来自桌面程序的消息
/// </summary>
public class PipeServer : MonoBehaviour
{
    private const string PipeName = "UnityDesktopPipe";
    private NamedPipeServerStream pipeServer;
    private Thread pipeThread;
    private bool isRunning = false;
    private UnityMain unityMain;

    void Start()
    {
        unityMain = FindObjectOfType<UnityMain>();
        if (unityMain == null)
        {
            Debug.LogError("未找到UnityMain组件!");
            return;
        }

        StartPipeServer();
    }

    void StartPipeServer()
    {
        try
        {
            isRunning = true;
            pipeThread = new Thread(ServerThread);
            pipeThread.IsBackground = true;
            pipeThread.Start();
            Debug.Log("管道服务器已启动,等待客户端连接...");
        }
        catch (Exception ex)
        {
            Debug.LogError($"启动管道服务器失败: {ex.Message}");
        }
    }

    void ServerThread()
    {
        while (isRunning)
        {
            try
            {
                pipeServer = new NamedPipeServerStream(
                    PipeName,
                    PipeDirection.In,
                    1,
                    PipeTransmissionMode.Byte,
                    PipeOptions.Asynchronous);

                Debug.Log("等待客户端连接...");
                pipeServer.WaitForConnection();
                Debug.Log("客户端已连接!");

                byte[] buffer = new byte[4096];
                StringBuilder messageBuilder = new StringBuilder();
                
                while (pipeServer.IsConnected && isRunning)
                {
                    try
                    {
                        if (!pipeServer.IsConnected)
                            break;
                            
                        int bytesRead = pipeServer.Read(buffer, 0, buffer.Length);
                        if (bytesRead > 0)
                        {
                            string received = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                            messageBuilder.Append(received);
                            
                            // 处理所有完整的消息(以换行符分隔)
                            string allData = messageBuilder.ToString();
                            
                            // 查找所有完整的消息(以换行符结尾的)
                            int lastNewline = -1;
                            for (int i = 0; i < allData.Length; i++)
                            {
                                if (allData[i] == '
' || allData[i] == '
')
                                {
                                    // 找到完整的消息
                                    if (lastNewline + 1 < i)
                                    {
                                        string completeMsg = allData.Substring(lastNewline + 1, i - lastNewline - 1).Trim();
                                        if (!string.IsNullOrEmpty(completeMsg))
                                        {
                                            Debug.Log($"收到消息: {completeMsg}");
                                            UnityMainThreadDispatcher.Instance().Enqueue(() => ProcessMessage(completeMsg));
                                        }
                                    }
                                    lastNewline = i;
                                }
                            }
                            
                            // 保留未完成的部分(最后没有换行符的内容)
                            if (lastNewline >= 0)
                            {
                                messageBuilder.Clear();
                                if (lastNewline + 1 < allData.Length)
                                {
                                    messageBuilder.Append(allData.Substring(lastNewline + 1));
                                }
                            }
                        }
                        else
                        {
                            // 没有数据,检查连接是否断开
                            Thread.Sleep(50);
                        }
                    }
                    catch (Exception readEx)
                    {
                        Debug.LogWarning($"读取管道数据时出错: {readEx.Message}");
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"管道服务器错误: {ex.Message}");
            }
            finally
            {
                if (pipeServer != null)
                {
                    pipeServer.Close();
                    pipeServer.Dispose();
                    pipeServer = null;
                }
            }

            // 等待一段时间后重新监听
            if (isRunning)
            {
                Thread.Sleep(1000);
            }
        }
    }

    void ProcessMessage(string message)
    {
        if (string.IsNullOrEmpty(message) || unityMain == null)
        {
            return;
        }

        string[] parts = message.Split('|');
        string methodName = parts[0];
        string parameter = parts.Length > 1 ? parts[1] : "";

        Debug.Log($"处理方法: {methodName}, 参数: {parameter}");

        switch (methodName)
        {
            case "OnClickBtn":
                unityMain.OnClickBtn();
                break;
            case "OnClickBtnWithMessage":
                unityMain.OnClickBtnWithMessage(parameter);
                break;
            default:
                Debug.LogWarning($"未知的方法: {methodName}");
                break;
        }
    }

    void OnDestroy()
    {
        isRunning = false;
        
        if (pipeServer != null && pipeServer.IsConnected)
        {
            pipeServer.Close();
            pipeServer.Dispose();
        }

        if (pipeThread != null && pipeThread.IsAlive)
        {
            pipeThread.Join(1000);
        }
    }

    void OnApplicationQuit()
    {
        isRunning = false;
        
        if (pipeServer != null)
        {
            pipeServer.Close();
            pipeServer.Dispose();
        }
    }
}


PipeClient 源码


using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Threading;
using UnityEngine;

/// <summary>
/// Unity中的命名管道客户端,用于向桌面程序发送消息
/// </summary>
public class PipeClient : MonoBehaviour
{
    private const string PipeName = "DesktopUnityPipe";
    private NamedPipeClientStream pipeClient;
    private bool isConnected = false;
    private object sendLock = new object();
    private Thread reconnectThread;
    private bool isRunning = false;

    void Start()
    {
        isRunning = true;
        StartReconnectThread();
    }

    void StartReconnectThread()
    {
        reconnectThread = new Thread(ReconnectLoop)
        {
            IsBackground = true
        };
        reconnectThread.Start();
    }

    void ReconnectLoop()
    {
        while (isRunning)
        {
            if (!isConnected || pipeClient == null || !pipeClient.IsConnected)
            {
                TryConnect();
            }
            Thread.Sleep(2000); // 每2秒检查一次连接
        }
    }

    bool TryConnect()
    {
        lock (sendLock)
        {
            if (isConnected && pipeClient != null && pipeClient.IsConnected)
            {
                return true;
            }

            try
            {
                if (pipeClient != null)
                {
                    try
                    {
                        pipeClient.Close();
                        pipeClient.Dispose();
                    }
                    catch { }
                    pipeClient = null;
                }

                pipeClient = new NamedPipeClientStream(
                    ".",
                    PipeName,
                    PipeDirection.Out,
                    PipeOptions.None);

                pipeClient.Connect(1000); // 1秒超时

                if (pipeClient.IsConnected)
                {
                    isConnected = true;
                    Debug.Log("已连接到桌面程序管道!");
                    return true;
                }
            }
            catch (TimeoutException)
            {
                // 桌面程序可能还没启动,继续重试
                isConnected = false;
            }
            catch (Exception ex)
            {
                Debug.LogWarning($"连接桌面程序管道失败: {ex.Message}");
                isConnected = false;
            }

            return false;
        }
    }

    /// <summary>
    /// 向桌面程序发送消息
    /// </summary>
    public bool SendMessage(string message)
    {
        lock (sendLock)
        {
            if (!isConnected || pipeClient == null || !pipeClient.IsConnected)
            {
                // 尝试连接
                if (!TryConnect())
                {
                    Debug.LogWarning("无法连接到桌面程序管道,消息发送失败");
                    return false;
                }
            }

            try
            {
                byte[] messageBytes = Encoding.UTF8.GetBytes(message + "
");
                pipeClient.Write(messageBytes, 0, messageBytes.Length);
                pipeClient.Flush();
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogWarning($"发送消息到桌面程序失败: {ex.Message}");
                isConnected = false;
                try
                {
                    pipeClient?.Close();
                    pipeClient?.Dispose();
                    pipeClient = null;
                }
                catch { }
                return false;
            }
        }
    }

    /// <summary>
    /// 检查是否已连接
    /// </summary>
    public bool IsConnected
    {
        get
        {
            lock (sendLock)
            {
                return isConnected && pipeClient != null && pipeClient.IsConnected;
            }
        }
    }

    void OnDestroy()
    {
        isRunning = false;
        Disconnect();
    }

    void OnApplicationQuit()
    {
        isRunning = false;
        Disconnect();
    }

    void Disconnect()
    {
        lock (sendLock)
        {
            isConnected = false;
            if (pipeClient != null)
            {
                try
                {
                    if (pipeClient.IsConnected)
                    {
                        pipeClient.Close();
                    }
                    pipeClient.Dispose();
                }
                catch { }
                pipeClient = null;
            }
        }

        if (reconnectThread != null && reconnectThread.IsAlive)
        {
            reconnectThread.Join(1000);
        }
    }
}


UnityMainThreadDispatcher 源码


using System;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Unity主线程调度器,用于在其他线程中执行Unity主线程的操作
/// </summary>
public class UnityMainThreadDispatcher : MonoBehaviour
{
    private static UnityMainThreadDispatcher _instance;
    private Queue<Action> actions = new Queue<Action>();

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

    void Update()
    {
        lock (actions)
        {
            while (actions.Count > 0)
            {
                Action action = actions.Dequeue();
                try
                {
                    action?.Invoke();
                }
                catch (Exception ex)
                {
                    Debug.LogError($"执行主线程操作失败: {ex.Message}");
                }
            }
        }
    }

    public void Enqueue(Action action)
    {
        lock (actions)
        {
            actions.Enqueue(action);
        }
    }
}


以上便是Unity工程的主要代码

步骤2:编译Unity应用程序

在Unity编辑器中,File -> Build Settings选择平台(Windows)点击”Build”按钮,选择输出目录等待编译完成

步骤3:编译并运行桌面程序

使用Visual Studio或命令行编译:


cd DesktopApp
msbuild DesktopApp.csproj /p:Configuration=Release

运行生成的
DesktopApp.exe
(位于
DesktopApp/bin/Release/
目录)。

步骤5:使用流程

启动桌面程序

运行
DesktopApp.exe

配置Unity应用程序路径(首次使用)

点击”启动Unity应用程序”按钮如果找不到Unity应用程序,会弹出文件选择对话框选择你编译后的Unity应用程序exe文件(例如:
D:MyGamesMyUnityGame.exe
)选择的路径会自动保存,下次启动时会自动使用

启动Unity应用程序

Unity应用程序会自动启动等待3-5秒,让Unity应用程序初始化和管道服务器启动

从桌面程序调用Unity方法

桌面程序会自动连接到Unity的管道服务器在桌面程序中,点击”调用OnClickBtn”按钮查看Unity应用程序的输出或日志,应该能看到”OnClickBtn被调用 – hahah”的日志点击”调用带消息方法”按钮,传入消息文本在Unity中按空格键,桌面程序会收到Unity发送的消息查看桌面程序的输出窗口,可以看到来自Unity的消息

工作原理

架构图(双向通信)


桌面程序 (DesktopApp)
    ├─ PipeClient ──→ UnityDesktopPipe ──→ PipeServer (Unity端)
    │                                                  ↓
    │                                            UnityMain类方法
    │                                                  ↓
    └─ PipeServer ←── DesktopUnityPipe ←── PipeClient (Unity端)
                                                      ↑
                                              Unity发送消息

通信方向:

桌面→Unity: 通过
UnityDesktopPipe
管道,桌面程序调用Unity方法Unity→桌面: 通过
DesktopUnityPipe
管道,Unity主动发送消息到桌面程序

关键组件

Unity端脚本


PipeServer.cs
: 命名管道服务器,在后台线程中监听来自桌面程序的消息(接收桌面→Unity)
PipeClient.cs
: 命名管道客户端,向桌面程序发送消息(发送Unity→桌面)
UnityMain.cs
: 主类,提供可调用的方法(OnClickBtn、OnClickBtnWithMessage等),并提供
SendMessageToDesktop()
方法向桌面发送消息
UnityMainThreadDispatcher.cs
: 确保Unity API在主线程中调用PipeServer收到消息后,通过
UnityMainThreadDispatcher
在主线程中调用Unity方法

桌面程序


MainForm.cs
: 主窗体,包含启动Unity和调用方法的按钮,并接收Unity消息
PipeClient.cs
: 命名管道客户端,连接到Unity的管道服务器(发送桌面→Unity)
PipeServer.cs
: 命名管道服务器,接收来自Unity的消息(接收Unity→桌面)通过管道发送消息(格式:
方法名|参数
)来调用Unity方法通过事件处理接收Unity主动发送的消息

通信机制

双向命名管道: 使用两个独立的Windows命名管道实现双向通信

UnityDesktopPipe
: 桌面程序→Unity通信
DesktopUnityPipe
: Unity→桌面程序通信 消息格式: 消息格式为
类型|内容

方法名|参数
,简单明了主线程执行: 所有Unity方法调用都在主线程中执行自动重连: 管道连接断开后可以自动重连实时通信: Unity和桌面程序可以随时互相发送消息

自定义扩展

添加新的可调用方法

1. 在Unity中实现方法


Assets/UnityMain.cs
中添加新方法:


public void MyNewMethod(string param1, int param2)
{
    Debug.Log($"MyNewMethod被调用: {param1}, {param2}");
    // 你的逻辑...
}
2. 在PipeServer中添加消息处理


Assets/PipeServer.cs

ProcessMessage
方法中添加对应的case分支:


case "MyNewMethod":
    string[] methodParams = parameter.Split(',');
    if (methodParams.Length == 2)
    {
        unityMain.MyNewMethod(methodParams[0], int.Parse(methodParams[1]));
    }
    break;
3. 在桌面程序中调用


DesktopApp/MainForm.cs
中添加按钮,在按钮事件中调用:


private void BtnMyNewMethod_Click(object sender, EventArgs e)
{
    if (pipeClient != null && pipeClient.IsConnected)
    {
        try
        {
            pipeClient.CallMethod("MyNewMethod", "Hello,123");
            AppendOutput("已调用 MyNewMethod");
        }
        catch (Exception ex)
        {
            AppendOutput($"调用失败: {ex.Message}");
        }
    }
}

就是这么简单! 只需要在Unity中添加方法,在PipeServer中添加case分支,然后在桌面程序中通过管道发送消息。

Unity主动发送消息到桌面程序

1. 在Unity中发送消息


Assets/UnityMain.cs
中,使用
SendMessageToDesktop()
方法向桌面程序发送消息:


// 发送简单消息
SendMessageToDesktop("StatusUpdate|Unity状态已更新");

// 发送带类型和内容的消息
SendMessageToDesktop("GameEvent|玩家得分: 100");

// 在Unity的方法中自动发送消息(已在OnClickBtn和OnClickBtnWithMessage中实现)
public void OnClickBtn()
{
    // Unity逻辑...
    
    // 自动发送通知到桌面程序
    SendMessageToDesktop($"ButtonClicked|OnClickBtn方法已被调用,时间: {System.DateTime.Now:HH:mm:ss}");
}
2. 桌面程序自动接收消息

桌面程序的
PipeServer
会自动接收Unity发送的消息,并在输出窗口中显示。消息格式为:
类型|内容

示例输出:


[Unity消息] 类型: UnityInitialized, 内容: Unity应用程序已启动并初始化完成
[Unity消息] 类型: ButtonClicked, 内容: OnClickBtn方法已被调用,时间: 14:30:25
[Unity消息] 类型: MessageReceived, 内容: Unity收到消息: Hello from Desktop App!
3. 自定义消息处理

如果需要自定义处理Unity发送的消息,可以在
DesktopApp/MainForm.cs

OnUnityMessageReceived
方法中添加处理逻辑:


private void OnUnityMessageReceived(string message)
{
    string[] parts = message.Split('|');
    string messageType = parts.Length > 0 ? parts[0] : "Unknown";
    string messageContent = parts.Length > 1 ? parts[1] : message;

    // 根据消息类型进行不同的处理
    switch (messageType)
    {
        case "StatusUpdate":
            // 处理状态更新
            break;
        case "GameEvent":
            // 处理游戏事件
            break;
        default:
            // 默认处理:显示在输出窗口
            AppendOutput($"[Unity消息] 类型: {messageType}, 内容: {messageContent}");
            break;
    }
}

修改Unity路径

桌面程序会自动保存Unity应用程序路径到
UnityDLLAppPath.txt
配置文件中。如果需要修改:

方式1:使用界面按钮清除(推荐)✅

在桌面程序界面中,点击”清除保存的路径”按钮确认清除操作下次启动时会重新弹出文件选择对话框,可以重新选择路径

方式2:手动删除配置文件

找到
DesktopApp/bin/Release/
目录(或Debug目录,取决于你的编译配置)删除
UnityDLLAppPath.txt
文件下次启动时会重新弹出文件选择对话框

方式3:直接编辑配置文件

找到
DesktopApp/bin/Release/UnityDLLAppPath.txt
文件直接编辑文件内容,修改为新的Unity应用程序路径保存文件,下次启动时会使用新路径

故障排除

问题1:管道连接失败

症状:桌面程序显示”无法连接到Unity管道”

解决方案

确保Unity应用程序已启动等待更长时间(5-10秒)让Unity完全初始化和管道服务器启动检查Unity应用程序是否正常运行(没有崩溃)查看Unity控制台是否有管道服务器启动的日志确保Unity场景中的GameObject包含
UnityMain

PipeServer
组件

问题2:Unity应用程序未启动

症状:点击”启动Unity应用程序”按钮后没有反应

解决方案

检查Unity应用程序exe路径是否正确确认Unity应用程序exe文件存在且没有被删除手动启动Unity应用程序exe,确认可以正常运行检查是否有权限运行该exe文件查看桌面程序的输出窗口,获取详细的错误信息

问题3:方法调用没有效果

症状:点击调用按钮后,Unity控制台没有输出

解决方案

检查Unity场景中是否有GameObject包含
UnityMain

PipeServer
组件检查Unity控制台是否有收到消息的日志确认管道连接已成功(查看桌面程序状态显示”已连接到Unity管道”)检查PipeServer的ProcessMessage方法中是否有对应的方法处理重新编译Unity应用程序

技术细节

管道名称

项目使用两个独立的命名管道:

桌面→Unity管道:
UnityDesktopPipe

Unity端:
Assets/PipeServer.cs

PipeName
常量桌面端:
DesktopApp/PipeClient.cs

PipeName
常量(必须与PipeServer一致)

Unity→桌面管道:
DesktopUnityPipe

Unity端:
Assets/PipeClient.cs

PipeName
常量桌面端:
DesktopApp/PipeServer.cs

PipeName
常量(必须与PipeClient一致)

可以在各自的文件中修改管道名称,但必须确保两端的名称一致。

消息格式

消息格式为:
方法名|参数

示例:


OnClickBtn
– 无参数方法
OnClickBtnWithMessage|Hello World
– 带一个字符串参数的方法
MyNewMethod|param1,param2,param3
– 多个参数用逗号分隔

线程安全

Unity的所有API必须在主线程中调用。本项目使用以下机制确保线程安全:


PipeServer
在后台线程接收消息使用
UnityMainThreadDispatcher
将方法调用调度到主线程所有Unity方法都在主线程中执行

数据传递

方法参数通过管道以字符串形式传递:

基本类型(string, int, float, bool等)通过字符串传递多个参数用逗号分隔在PipeServer的ProcessMessage中解析参数

常见问题

Q: 现在默认就是启动编译后的Unity应用程序(.exe),如何修改路径?

A: 首次运行时会弹出文件选择对话框,选择Unity应用程序exe文件后,路径会自动保存到
UnityDLLAppPath.txt
配置文件中。如果需要修改路径,有以下几种方式:

使用界面按钮清除(推荐):点击桌面程序界面中的”清除保存的路径”按钮,下次启动时会重新弹出文件选择对话框手动删除配置文件:删除
DesktopApp/bin/Release/UnityDLLAppPath.txt
文件,下次启动时会重新弹出文件选择对话框直接编辑配置文件:直接编辑
UnityDLLAppPath.txt
文件,修改其中的路径即可

Q: 如何清除保存的Unity路径?

A: 最简单的方式是点击桌面程序界面中的”清除保存的路径”按钮。也可以手动删除
DesktopApp/bin/Release/UnityDLLAppPath.txt
文件。清除后,下次启动时会重新弹出文件选择对话框。

Q: 能否同时连接多个Unity实例?

A: 当前实现使用固定的管道名称,不支持多个实例。要实现多实例支持,需要修改
PipeServer

PipeClient
,为每个实例使用不同的管道名称。

Q: 支持双向通信吗?

A: 当前实现是单向的(桌面程序 -> Unity)。要实现双向通信(Unity -> 桌面程序),可以:

在桌面程序中创建另一个管道服务器Unity端创建管道客户端连接到桌面程序Unity端通过管道发送消息给桌面程序

Q: 为什么使用命名管道而不是内存映射文件?

A: 命名管道实现更简单,无需编译DLL,所有代码都在项目中。管道通信稳定可靠,对于这种消息传递场景非常合适。

Q: 可以在Unity编辑器中使用吗?

A: 可以!在Unity编辑器中Play场景时,桌面程序也可以连接到Unity编辑器中的场景。这对于开发和调试非常有用。

许可证

本项目仅供学习和参考使用。完整示例视频如下

20251202_155633

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
_sumnnrising的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容