基于Unity的C/S架构数据交互

2 篇文章 0 订阅

最近在做一个项目,主体是Unity。项目涉及到一些大规模数值计算,需要借助服务器来完成。所以我们需要设计一个通信系统,包含以下过程。

1.Unity客户端向服务器发送计算命令
2.服务器调用后台进程进行数值计算
3.服务器通知Unity客户端计算完成
4.Unity客户端从服务器读取计算结果

为了实现该系统,我们需要这些东西

1.一台终端Windows计算机,安装了Unity,作为客户端。
2.一台Linux计算机,搭建了服务器环境,作为后台计算。

将Linux计算机搭建为服务器的方法请参考:
搭建基于阿里云服务器的网站

搭建好环境后,接下来开始系统实现。

(一)Unity客户端

这部分主要使用了UnityWebRequest功能,该模块可以很好地实现上传文件到服务器以及从服务器下载数据的需求,下面给出了测试代码。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using System.Text;

public class CS_communication_test : MonoBehaviour
{
    public string url_PHP = "http://x.x.x.x/CS_test/CS.php";
    public string url_download = "http://x.x.x.x/CS_test/result.txt";
    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(CS_work(100));
    }

    IEnumerator CS_work(int num)
    {
        //测试功能:使用服务器将一个整数×100,打印计算结果
        
        //第一部分:上传数据到服务器,等待服务器处理完成
        byte[] bytes = Encoding.Default.GetBytes(num.ToString());
        WWWForm form = new WWWForm();//创建提交数据表单
        form.AddField("folder", "UploadData/");//定义表单字段用来定义文件夹
        form.AddBinaryData("file", bytes, "uploadData.txt", "text/plain");//字段名,文件数据,文件名,文件类型
        UnityWebRequest uploadRequest = UnityWebRequest.Post(url_PHP, form);
        yield return uploadRequest.SendWebRequest();

        if (uploadRequest.isDone)
        {
            Debug.Log("服务器已完成计算");
        }

        //第二部分:从服务器获取计算结果
        UnityWebRequest downloadRequest = UnityWebRequest.Get(url_download);
        yield return downloadRequest.SendWebRequest();

        if (downloadRequest.isDone)
        {
            Debug.Log(downloadRequest.downloadHandler.text);
        }
    }
}

(二)服务器

我们使用Python来编写计算进程,用PHP作为Web中间交互,用Linux的命名管道实现PHP与Python的进程通信。

1.实验环境设置

我们来到网站的根目录下

如果按照上述博客搭建服务器的话,地址是/var/www/html

创建实验文件夹,并设置权限

mkdir CS_test
chmod 777 CS_test

进入文件夹,创建命名管道文件

cd CS_test
mkfifo -m 777 php2py # 保存php进程向python进程传递的数据
mkfifo -m 777 py2php # 保存python进程向php进程传递的数据

创建文件夹,用来保存上传的数据,记得设置权限

mkdir UploadData
chmod 777 UploadData

分别创建一个python文件和一个php文件

touch CS.py
touch CS.php

目前实验文件夹下有这些东西

[root@iZwz9a8g2mt6x5kq9jp6abZ CS_test]# ls
CS.php  CS.py  php2py  py2php  UploadData

2.python文件编写

这部分的功能是数值计算,将php2py管道中的原始数据读出,计算后将结果写入py2php管道。

def work(rawData):
    print("input number: " + rawData)
    resultData = str(int(rawData) * 100)
    print("output number: " + resultData)
    return resultData

while True:
    fread = open("php2py", "r")
    fwrite = open("py2php", "w")
    rawData = fread.read(1024)
    resultData = work(rawData)
    fwrite.write(resultData)
    fwrite.close()
    fread.close()

3.php文件编写

这部分的功能是

1.接收Unity客户端的调用,将其上传的数据写入文件
2.数据写入php2py管道
3.从py2php管道读出计算结果
4.将结果写进文件

<?php
 
    $folder=$_POST["folder"];//根据表单字段接收文件夹的字符串信息
    $fileName =$_FILES["file"]["name"];//根据表单字段接收需要保存的文件名字
    $tmp=$_FILES["file"]["tmp_name"];
    $fil=$folder.$fileName;
 
    // 判断当期目录下的 upload 目录是否存在该文件
    if (!file_exists($fil))
    {
        // 如果 upload 目录不存在该文件则将文件上传到相应目录下
        move_uploaded_file($_FILES["file"]["tmp_name"], $fil);
    }
    
    //将数据写入管道
    function write($content)
    {
     $fwrite = fopen("php2py", "w");
     fwrite($fwrite, $content);
     fclose($fwrite);
    }
    
    //将数据从管道读出
    function read()
    {
     $fread = fopen("py2php", "r");
     $content = fread($fread, 1024);
     fclose($fread);
     return $content;
    }
    
    //读出上传的数据,并写入管道
    $dataStr = file_get_contents("UploadData/uploadData.txt");
    $data = number_format($dataStr);
    write($data);
    
    //从管道读出计算结果
    $resultData = read();
    
    //将计算结果写入结果文件
    $writeFile = fopen("result.txt","w");
    fwrite($writeFile,$resultData);
    fclose($writeFile)

?>

(三)系统测试

完成上述任务后,我们开始实验测试。

1.在服务器中启动python进程

python CS.py

2.在Unity中将脚本挂在一个场景物体上,并运行测试

服务器端结果

input number: 100
output number: 10000

Unity客户端结果
在这里插入图片描述
实验成功!

最后记得将Python进程中断。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Winform中打开Unity游戏并进行数据交互,可以使用Unity提供的DLL插件功能。具体步骤如下: 1.在Unity中创建一个DLL插件,该插件可以处理数据交互。 2.将DLL插件导出到Winform项目中。 3.在Winform中编写代码,以启动Unity游戏并与该DLL插件进行交互。 以下是一个简单示例: 在Unity中创建一个DLL插件: ``` using UnityEngine; using System.Runtime.InteropServices; public class UnityPlugin : MonoBehaviour { [DllImport("UnityPlugin")] private static extern void SetData(string data); [DllImport("UnityPlugin")] private static extern string GetData(); public void SendDataToWinform(string data) { SetData(data); } public string GetDataFromWinform() { return GetData(); } } ``` 在Winform中编写代码,以启动Unity游戏并与该DLL插件进行交互: ``` using System; using System.Windows.Forms; using System.Diagnostics; using System.Runtime.InteropServices; namespace WinformUnity { public partial class Form1 : Form { [DllImport("UnityPlugin")] private static extern void StartUnity(); [DllImport("UnityPlugin")] private static extern void SendDataToUnity(string data); [DllImport("UnityPlugin")] private static extern string GetDataFromUnity(); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // 启动Unity游戏 StartUnity(); } private void button1_Click(object sender, EventArgs e) { // 向Unity发送数据 SendDataToUnity(textBox1.Text); // 从Unity获取数据 string data = GetDataFromUnity(); // 在Winform中显示数据 textBox2.Text = data; } } } ``` 在Unity游戏中使用UnityPlugin脚本进行数据交互: ``` using UnityEngine; public class UnityPlugin : MonoBehaviour { void Start () { // ... } void Update () { // ... } // 接收来自Winform的数据 public void SetData(string data) { // 处理数据 } // 向Winform发送数据 public string GetData() { // 准备数据 return "Hello Winform!"; } } ``` 注意:为了使Unity能够正常运行,需要将Unity游戏的发布平台设置为Windows,并将生成的DLL插件拷贝到Winform项目的输出目录中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值