开始

Godot作为一款游戏引擎在MIT许可证下是完全免费和开源的,可以使用NuGet包来添加PLC通讯库实现在3D场景中的设备状态显示、动态变化。

1.新建项目

下载.NET版本的Godot引擎
新建项目后选择编辑器选项卡-编辑器设置-常规-.NET-编辑器External Editor属性选择脚本代码的编辑器(这里选择Visual Studio)
在这里插入图片描述
打开Visual Studio,在拓展-管理拓展中搜索“Force UTF-8”安装该拓展:
在这里插入图片描述

3.新建3D场景

添加新的3D场景,将设备部件的dae模型文件导入3D根节点下,dae模型文件会转化为Node3D节点:

在这里插入图片描述
在这里插入图片描述
之后分别加入Camera3D相机节点和DirectionalLight3D光照节点,勾选3D视图中的预览按钮,调整相机和光照的角度位置到合适:
在这里插入图片描述
在这里插入图片描述
调整完成后Ctrl+S保存场景:
在这里插入图片描述

2.新建2D场景

点击2D场景创建根节点:
在这里插入图片描述
在根节点中分别添加:SubViewportControlSprite2D子节点:
在这里插入图片描述
Sprite2D的属性Texture中,选择新建ViewportTexture:
在这里插入图片描述
选择刚才创建的SubViewport节点,并将Sprite2D移动到合适的位置:
在这里插入图片描述
调整SubViewport的Size大小、启用Transparent:

在这里插入图片描述
将之前保存的3D场景拖进SubViewport节点中:

在这里插入图片描述
可以看到Sprite2D节点显示出了3D场景:

在这里插入图片描述
接下来在Control节点下根据PLC程序的需要添加CheckButton Button Label LineEdit等按钮、开关、文本控件:

在这里插入图片描述

4.新建2D脚本

点击2D场景的根节点右键添加脚本:

在这里插入图片描述
脚本语言选择C#:

在这里插入图片描述
如果提前在编辑器选项卡里设置脚本编辑器为Visual Studio的话,创建脚本后会自动打开Visual Studio:

在这里插入图片描述
在Visual Studio可以直接通过 项目-管理NuGet程序包 下载对应PLC的通讯NuGet程序包:

在这里插入图片描述

5.编辑脚本

5.1添加脚本中要用到的节点变量

public partial class 2D场景名称 : Node2D
{
  private Vector3 velocity1, velocity2 = Vector3.Zero;//3D位置坐标
  private CheckButton ChBut;//CheckButton控件
  private Node3D But,Tray,Float;//3D场景中的Node3D节点
  private Button LeftBut,RightBut,UpBut,DownBut,SUpBut,SDownBut,Conbut;//按钮控件
  private Label MYLabel;//文本
  private LineEdit Text1, Text2;//编辑文本行
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{}
}

5.2在脚本的_Ready()动作中给节点变量赋值

public override void _Ready()
{
  ChBut = GetNode<CheckButton>("Control/CheckButton");
  But = GetNode<Node3D>("SubViewport/3DView/前护罩");
  Conbut = GetNode<Button>("Control/Button");
  LeftBut = GetNode<Button>("Control/GridContainer/Button");
  RightBut = GetNode<Button>("Control/GridContainer/Button2");
  UpBut = GetNode<Button>("Control/GridContainer/Button3");
  DownBut = GetNode<Button>("Control/GridContainer/Button4");
  SUpBut = GetNode<Button>("Control/GridContainer/Button5");
  SDownBut = GetNode<Button>("Control/GridContainer/Button6");
  Tray = GetNode<Node3D>("SubViewport/3DView/载板");
  Float = GetNode<Node3D>("SubViewport/3DView/升降台");
  MYLabel = GetNode<Label>("Control/Label");
  Text1 = GetNode<LineEdit>("Control/GridContainer/LineEdit");
  Text2 = GetNode<LineEdit>("Control/GridContainer/LineEdit2");
  acceptDialog = GetNode<AcceptDialog>("AcceptDialog");
  Conbut.Pressed += Connect;
}
private void Connect()
{
    ConPlc.ConnectPlc();
}

以3D场景中的载板模型为例,它的路径为:3DView/载板

在这里插入图片描述
而在2D场景中,载板所处3D场景的节点路径为:Node2D/SubViewport/3DView

在这里插入图片描述
综合两条路径,省略掉脚本本身所处的节点,可以在脚本中获取载板模型所处的Node3D节点:

Tray = GetNode<Node3D>("SubViewport/3DView/载板");

5.3在脚本的_Process()动作中进行画面更新

public override void _Process(double delta)
{
    DataValueRead dataValueRead = new DataValueRead();
    dataValueRead.CacheData(dataValueRead.ReadValue);//读取PLC中的变量参数
    But.Visible = !ChBut.ButtonPressed;//控制节点是否显示
    velocity1.X = (float)(dataValueRead.ReadValue.D1 / 100);
    velocity1.Y = (float)(dataValueRead.ReadValue.D3 / 100);
    Tray.Position = velocity1;//更新载板模型位置
    velocity2.Y = (float)(dataValueRead.ReadValue.D3 / 100);
    Float.Position = velocity2;//更新平台模型位置

    string Text = "当前横移位置:" + dataValueRead.ReadValue.D1.ToString("F2") + "\r\n";
    Text += "当前横移速度:" + dataValueRead.ReadValue.D2.ToString("F2") + "\r\n";
    Text += "当前升降位置:" + dataValueRead.ReadValue.D3.ToString("F2") + "\r\n";
    Text += "当前升降速度:" + dataValueRead.ReadValue.D4.ToString("F2") + "\r\n";
    MYLabel.Text = Text;//更新显示文本

    dataValueRead.WriteValue = dataValueRead.ReadValue;
    dataValueRead.WriteValue.B4 = LeftBut.ButtonPressed;
    dataValueRead.WriteValue.B5 = RightBut.ButtonPressed;
    dataValueRead.WriteValue.B10 = UpBut.ButtonPressed;
    dataValueRead.WriteValue.B11 = DownBut.ButtonPressed;
    dataValueRead.WriteValue.B12 = SUpBut.ButtonPressed;
    dataValueRead.WriteValue.B13 = SDownBut.ButtonPressed;
    if(Text1.Text != null)
    {
      dataValueRead.WriteValue.F1 = float.Parse(Text1.Text);
    }
    if(Text2.Text != null)
    {
      dataValueRead.WriteValue.F2 = float.Parse(Text2.Text);
    }
    dataValueRead.WriteData(dataValueRead.WriteValue);//向PLC中写入当前参数
}

6.读写PLC变量

PLC重连:

using S7.Net;
internal class ConPlc
{
    internal static Plc plc = new Plc(CpuType.S71500, "192.168.0.1", 0, 1);

    internal static bool ReConPlc = false;

    internal static void ConnectPlc()
    {
        try
        {
            plc.Open();
        }
        catch 
        {
            MainView.acceptDialog.Visible = true;
            ReConPlc = true;
        }
    }
}

读写PLC变量:

internal class DataValueRead
{
    internal DataStatic WriteValue = new DataStatic();
    internal DataStatic ReadValue = new DataStatic();
    public void CacheData(DataStatic DR)
    {
        try
        {
            if (ConPlc.plc.IsConnected)
            {
                ConPlc.plc.ReadClass(DR, 3, 0);
            }
        }
        catch ()
        {
        }
    }

    public void WriteData(DataStatic DR)
    {
        try
        {
            if (ConPlc.plc.IsConnected)
            {
                ConPlc.plc.WriteClass(DR, 3, 0);
            }
        }
        catch ()
        {
        }
    }
}

定义结构体:

internal class DataStatic
{
    public bool B1 { get; set; }
    public bool B2 { get; set; }
    public bool B3 { get; set; }
    public bool B4 { get; set; }//点动前进
    public bool B5 { get; set; }//点动后退
    public float F1 { get; set; }//横移点动速度
    public double D1 { get; set; }//横移当前位置
    public double D2 { get; set; }//横移当前速度
    public bool B6 { get; set; }
    public bool B7 { get; set; }
    public bool B8 { get; set; }
    public bool B9 { get; set; }
    public bool B10 { get; set; }//点动上升
    public bool B11 { get; set; }//点动下降
    public float F2 { get; set; }//升降速度
    public double D3 { get; set; }//升降当前位置
    public double D4 { get; set; }//升降当前速度
    public bool B12 { get; set; }//步进上升
    public bool B13 { get; set; }//步进下降
    public float F3 { get; set; }
    public float F4 { get; set; }
}

7.运行效果

F5运行项目DEBUG:

250528演示

Logo

一站式虚拟内容创作平台,激发创意,赋能创作,进入R空间,遇见同道,让优质作品闪耀发光。​

更多推荐