C# 通过Unity3D创建OPC UA客户端
实际上曾经问过我这个问题,但似乎没有人给我预期的答案:( 我试图在Unity3D中创建一个OPC UA客户端。更具体地说,它类似于:一个只有文本的简单场景。该文本显示从OPC UA服务器读取的变量值。 我添加了这段代码(在stackoverflow上找到),但它不起作用C# 通过Unity3D创建OPC UA客户端,c#,unity3d,opc-ua,C#,Unity3d,Opc Ua,实际上曾经问过我这个问题,但似乎没有人给我预期的答案:( 我试图在Unity3D中创建一个OPC UA客户端。更具体地说,它类似于:一个只有文本的简单场景。该文本显示从OPC UA服务器读取的变量值。 我添加了这段代码(在stackoverflow上找到),但它不起作用 using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using Opc.Ua; using
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Configuration;
public class main : MonoBehaviour
{
private async void Start()
{
Console.WriteLine("Step 1 - Create a config.");
var config = new ApplicationConfiguration()
{
ApplicationName = "test-opc",
ApplicationType = ApplicationType.Client,
SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier() },
TransportConfigurations = new TransportConfigurationCollection(),
TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 }
};
await config.Validate(ApplicationType.Client);
if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
{
config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted); };
}
Console.WriteLine("Step 2 - Create a session with your server.");
using (var session = await Session.Create(config, new ConfiguredEndpoint(null, new EndpointDescription("opc.tcp://localhost:4841")), true, "", 60000, null, null))
{
Console.WriteLine("Step 3 - Browse the server namespace.");
ReferenceDescriptionCollection refs;
byte[] cp;
session.Browse(null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out cp, out refs);
Console.WriteLine("DisplayName: BrowseName, NodeClass");
foreach (var rd in refs)
{
Console.WriteLine(rd.DisplayName + ": " + rd.BrowseName + ", " + rd.NodeClass);
ReferenceDescriptionCollection nextRefs;
byte[] nextCp;
session.Browse(null, null, ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out nextCp, out nextRefs);
foreach (var nextRd in nextRefs)
{
Console.WriteLine("+ " + nextRd.DisplayName + ": " + nextRd.BrowseName + ", " + nextRd.NodeClass);
}
}
Console.WriteLine("Step 4 - Create a subscription. Set a faster publishing interval if you wish.");
var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 };
Console.WriteLine("Step 5 - Add a list of items you wish to monitor to the subscription.");
var list = new List<MonitoredItem> {
new MonitoredItem(subscription.DefaultItem) { DisplayName = "aaatime", StartNodeId = "i=10004" } };
list.ForEach(i => i.Notification += OnNotification);
subscription.AddItems(list);
Console.WriteLine("Step 6 - Add the subscription to the session.");
session.AddSubscription(subscription);
subscription.Create();
Console.WriteLine("Finished client initialization");
}
}
private static void OnNotification(MonitoredItem item, MonitoredItemNotificationEventArgs e)
{
foreach (var value in item.DequeueValues())
{
Console.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode);
}
}
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用制度;
使用Opc.Ua;
使用Opc.Ua.Client;
使用Opc.Ua.Configuration;
公共课主要内容:单一行为
{
私有异步void Start()
{
WriteLine(“步骤1-创建配置”);
var config=新应用程序配置()
{
ApplicationName=“测试opc”,
ApplicationType=ApplicationType.Client,
SecurityConfiguration=new SecurityConfiguration{ApplicationCertificate=new CertificateIdentifier()},
TransportConfigurations=新的TransportConfigurationCollection(),
TransportQuotas=新的TransportQuotas{OperationTimeout=15000},
ClientConfiguration=new ClientConfiguration{DefaultSessionTimeout=60000}
};
等待config.Validate(ApplicationType.Client);
if(config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
{
config.CertificateValidator.CertificateValidation+=(s,e)=>{e.Accept=(e.Error.StatusCode==StatusCodes.BadCertificateUntrusted);};
}
WriteLine(“第2步-创建与服务器的会话”);
使用(var session=await session.Create(配置,新配置的数据点(null,新端点描述(“opc”)。tcp://localhost:4841“”),真“”,60000,空,空)
{
WriteLine(“步骤3-浏览服务器名称空间”);
参考描述集合参考;
字节[]cp;
session.Browse(null,null,objectId.ObjectsFolder,0u,browsedDirection.Forward,ReferenceTypeId.HierarchicalReferences,true,(uint)NodeClass.Variable |(uint)NodeClass.Object |(uint)NodeClass.Method,out cp,out refs);
Console.WriteLine(“显示名称:BrowseName,NodeClass”);
foreach(参考文献中的变量rd)
{
Console.WriteLine(rd.DisplayName+“:“+rd.BrowseName+”,“+rd.NodeClass);
参考描述集合的下一步;
字节[]nextCp;
session.Browse(null,null,ExpandedNodeId.ToNodeId(rd.NodeId,session.NamespaceUris),0u,browsedDirection.Forward,referenceTypeId.HierarchicalReferences,true,(uint)NodeClass.Variable |(uint)NodeClass.Object |(uint)NodeClass.Method,out-nextCp,out-nextRefs);
foreach(nextRefs中的var nextRd)
{
Console.WriteLine(“+”+nextRd.DisplayName+”:“+nextRd.BrowseName+”,“+nextRd.NodeClass”);
}
}
WriteLine(“第4步-创建订阅。如果愿意,请设置更快的发布间隔。”);
var subscription=新订阅(session.DefaultSubscription){PublishingInterval=1000};
WriteLine(“第5步-向订阅中添加要监视的项目列表”);
变量列表=新列表{
新的MonitoredItem(subscription.DefaultItem){DisplayName=“aaatime”,StartNodeId=“i=10004”};
list.ForEach(i=>i.Notification+=OnNotification);
订阅。附加项(列表);
WriteLine(“步骤6-将订阅添加到会话中”);
会话.添加订阅(订阅);
subscription.Create();
Console.WriteLine(“完成客户端初始化”);
}
}
私有静态void OnNotification(MonitoredItem项,MonitoredItemNotificationEventArgs e)
{
foreach(item.DequeueValues()中的var值)
{
WriteLine(“{0}:{1},{2},{3}”,item.DisplayName,value.value,value.SourceTimestamp,value.StatusCode);
}
}
}
按照我的预期,它会是这样的:当我按下Play时,Unity应用程序运行并连接到我的OPC UA服务器,然后,它从服务器读取变量的值,并以文本形式显示该值。所以我要做的是创建一个Unity项目->场景->画布->文本,一个C脚本(上面的代码)。但是,当我将脚本添加到画布时,会出现如下通知:无法添加脚本,请确保没有编译器错误,并且文件名和类名匹配。我想我已经检查了所有这些,但没有任何错误。你能为我的问题提出一些解决方案吗?
P/S:代码来自此线程:
一种解决方案是,如果您不熟悉opc ua,可以启动opc ua客户端并发出REST请求。这可以通过使用类似Konektilo()的opc ua到REST转换器和unity()的REST客户端来实现
我还体验到,一些opc ua客户端并不是在所有可以运行unity应用程序的平台上工作。我创建了一个适用于unity的opc ua客户端,示例来自 但我也喜欢@M.List和他的Rest OPC UA网关的想法,因为unity有自己的Rest通信库 但是,如果您需要使用opc ua,请在下面简要说明如何在我的项目中运行它 我首先在visual studio中的一个普通控制台应用程序中尝试了该示例。测试成功后,我将控制台应用程序的所有dll复制到unity中自己创建的插件文件夹中。如果在unity项目中创建一个名为plugins的文件夹,则可以将unity Autonomy包含的dll放入项目中以供使用。您需要所有这些dll 之后,我用示例中的代码创建了一个脚本“opcUaClient”。Unity的启动方法是示例的主要方法,更新方法是OnNotification方法 到目前为止,我只能在按下play按钮时在unity中运行这个客户端。我无法将它部署到android或hololens 但最简单的方法是从unity asset store中的games4automation下载OPC UA客户端。我试过了,效果很好 雷加