using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using S7.Net;

public class MainProgRobertControl : MonoBehaviour
{
    private Plc plc;
    [Header("Настройки вращения")]
    public RotateObject VerticalRotate;
    public RotateObject HorizontalRotate;
    public DetailsStand FlanSetter;
    public BasketSystem BasketSystem;
    public ConveyorController StartedConveyer;
    public ConveyorController FinalConveyer;
    public RelativeRotator Stan;
    public RotateObject Shield;
    public MoveHandBasePosition MovementHandBase;
    public ClawController LongClaw;
    public ClawController ShortClaw;

    [Header("Датчики")]
    public Boolean Start_Pos;
    public Boolean FL1_Ready;
    public Boolean FL2_Ready;
    public Boolean Shield_Opened;
    public Boolean Shield_Closed;
    public Boolean P1_Opened;
    public Boolean P1_Closed;
    public Boolean P2_Opened;
    public Boolean P2_Closed;
    public Boolean P3_Opened;
    public Boolean P3_Closed;
    public Boolean P4_Opened;
    public Boolean P4_Closed;
    public Boolean P5_Opened;
    public Boolean P5_Closed;
    public Boolean P6_Opened;
    public Boolean P6_Closed;
    public Boolean P7_Opened;
    public Boolean P7_Closed;
    public Boolean Work_End_Stan;
    public Boolean Alert_Stan;
    public float VerticalRotateCurrentAngle;
    public float HorizontalRotateCurrentAngle;

    [Header("Сигналы управления")]
    public Boolean Shield_Open;
    public Boolean Shield_Close;
    public Boolean P1_Open;
    public Boolean P1_Close;
    public Boolean P2_Open;
    public Boolean P2_Close;
    public Boolean P3_Open;
    public Boolean P3_Close;
    public Boolean P4_Open;
    public Boolean P4_Close;
    public Boolean P5_Open;
    public Boolean P5_Close;
    public Boolean P6_Open;
    public Boolean P6_Close;
    public Boolean P7_Open;
    public Boolean P7_Close;
    public Boolean Start_Stan;
    public Boolean Stop_Stan;

    void Start()
    {
        plc = new Plc(CpuType.S7300, "192.168.0.165", 0, 2); // IP-адрес и параметры PLC
        plc.Open();

        if (plc.IsConnected)
        {
            Debug.Log("Connected to PLC");
        }
        else
        {
            Debug.Log("Failed to connect to PLC");
        }
    }

    public void WriteMultiple(Dictionary<string, object> data)
    {
        foreach (var item in data)
        {
            plc.Write(item.Key, item.Value);
        }
    }

    void Update()
    {
        Start_Pos = VerticalRotate.currentAngle < 4 && HorizontalRotate.currentAngle < 94 && HorizontalRotate.currentAngle > 85;
        FL1_Ready = LongClaw.HasGrabbedObject;
        FL2_Ready = ShortClaw.HasGrabbedObject;

        Shield_Opened = Shield.currentAngle < 5;
        Shield_Closed = Shield.currentAngle > 84;

        P1_Opened = BasketSystem.pusherState == BasketSystem.PusherState.Extended;
        P1_Closed = BasketSystem.pusherState == BasketSystem.PusherState.Retracted;

        P2_Opened = FlanSetter.XState == DetailsStand.AxisState.AtEnd;
        P2_Closed = FlanSetter.XState == DetailsStand.AxisState.AtStart;
        P3_Opened = FlanSetter.YState == DetailsStand.AxisState.AtEnd;
        P3_Closed = FlanSetter.YState == DetailsStand.AxisState.AtStart;

        P4_Opened = LongClaw.IsClawFullyOpen;
        P4_Closed = LongClaw.IsClawFullyClosed;
        P5_Opened = ShortClaw.IsClawFullyOpen;
        P5_Closed = ShortClaw.IsClawFullyClosed;

        P6_Opened = MovementHandBase.YState == MoveHandBasePosition.AxisState.AtEnd;
        P6_Closed = MovementHandBase.YState == MoveHandBasePosition.AxisState.AtStart;
        P7_Opened = MovementHandBase.XState == MoveHandBasePosition.AxisState.AtEnd;
        P7_Closed = MovementHandBase.XState == MoveHandBasePosition.AxisState.AtStart;

        Work_End_Stan = !Stan.IsRotating();

        VerticalRotateCurrentAngle = VerticalRotate.currentAngle;
        HorizontalRotateCurrentAngle = HorizontalRotate.currentAngle;

        // Команды управления
        if (P1_Open) BasketSystem.StartFullExtendPusher();
        if (P1_Close) BasketSystem.StartFullRetractPusher();

        if (P2_Open) FlanSetter.MoveLeftStartContinuous();
        if (P2_Close) FlanSetter.MoveRightStartContinuous();
        if (P3_Open) FlanSetter.MoveUpStartContinuous();
        if (P3_Close) FlanSetter.MoveDownStartContinuous();
        if (!P2_Open && !P2_Close && !P3_Open && !P3_Close) FlanSetter.StopContinuousMovement();

        if (P6_Open) MovementHandBase.StartMoveForwardContinuous();
        if (P6_Close) MovementHandBase.StartMoveBackwardContinuous();
        if (P7_Open) MovementHandBase.StartMoveLeftContinuous();
        if (P7_Close) MovementHandBase.StartMoveRightContinuous();
        if (!P6_Open && !P6_Close && !P7_Open && !P7_Close) MovementHandBase.StopContinuousMovement();

        if (Shield_Open) Shield.StartNegativeRotation();
        if (Shield_Close) Shield.StartPositiveRotation();
        if (!Shield_Open && !Shield_Close) Shield.StopContinuousRotation();
        if (Start_Stan) Stan.RotateByAngle(120);

        if (plc.IsConnected) {
            try
            {
                // Пакетная запись всех значений за один вызов (если поддерживается)
                var writeData = new Dictionary<string, object>
                {
                    {"I0.0", Start_Pos},
                    {"I0.1", FL1_Ready},
                    {"I0.2", FL2_Ready},
                    {"I0.3", Shield_Opened},
                    {"I0.4", Shield_Closed},
                    {"I0.5", P1_Opened},
                    {"I0.6", P1_Closed},
                    {"I0.7", P2_Opened},
                    {"I1.0", P2_Closed},
                    {"I1.1", P3_Opened},
                    {"I1.2", P3_Closed},
                    {"I1.3", P4_Opened},
                    {"I1.4", P4_Closed},
                    {"I1.5", P5_Opened},
                    {"I1.6", P5_Closed},
                    {"I1.7", P6_Opened},
                    {"I2.0", P6_Closed},
                    {"I2.1", P7_Opened},
                    {"I2.2", P7_Closed},
                    {"I2.3", Work_End_Stan}
                };

                WriteMultiple(writeData); // Метод расширения для пакетной записи

                // Отдельно записываем аналоговые значения (если нужно)
                plc.Write("MD108", Convert.ToUInt32(VerticalRotateCurrentAngle));
                plc.Write("MD112", Convert.ToUInt32(HorizontalRotateCurrentAngle));
            }
            catch (Exception ex)
            {
                Debug.LogError($"PLC Write Error: {ex.Message}");
                plc.Close();
                // Здесь можно добавить переподключение
            }

            try 
            {
                // 2. Присваивание считанных значений
                P1_Open = (bool)plc.Read("Q0.0");
                P1_Close = (bool)plc.Read("Q0.0");
                P2_Open = (bool)plc.Read("Q0.2");
                P2_Close = (bool)plc.Read("Q0.3");
                P3_Open = (bool)plc.Read("Q0.4");
                P3_Close = (bool)plc.Read("Q0.5");
                P6_Open = (bool)plc.Read("Q0.6");
                P6_Close = (bool)plc.Read("Q0.7");
                P7_Open = (bool)plc.Read("Q1.0");
                P7_Close = (bool)plc.Read("Q1.1");
                Shield_Open = (bool)plc.Read("Q1.2");
                Shield_Close = (bool)plc.Read("Q1.3");
                Start_Stan = (bool)plc.Read("Q1.4");
            }
            catch (Exception ex)
            {
                Debug.LogError($"PLC Communication Error: {ex.Message}");
                // Аварийная остановка всех движений
                FlanSetter.StopContinuousMovement();
                MovementHandBase.StopContinuousMovement();
                Shield.StopContinuousRotation();
            }
        }

    }

    public void VerticalRotationVal(string value) {
        VerticalRotate.RotateToAngle(Convert.ToInt16(value).ConvertToUshort());
    }

    void OnDestroy()
    {
        if (plc.IsConnected)
        {
            plc.Close();
        }
    }
}
Давай отправлять и получать данные через WriteAsync и ReadAsync.
Также все данные отправляются и получаются через дата блок
DB1 - Блок данных для отправления в ПЛК
DB2 - Блок данных для получения из ПЛК

В плк обработка сигналов идет по скрипту
// Запись данных из DB в переменные
"Start_Pos" := "InputDB".Start_Pos;
"Fl1_Ready" := "InputDB".Fl1_Ready;
"FL2_Ready" := "InputDB".FL2_Ready;
"Shield_Opened" := "InputDB".Shield_Opened;
"Shield_Closed" := "InputDB".Shield_Closed;
"P1_Opened" := "InputDB".P1_Opened;
"P1_Closed" := "InputDB".P1_Closed;
"P2_Opened" := "InputDB".P2_Opened;
"P2_Closed" := "InputDB".P2_Closed;
"P3_Opened" := "InputDB".P3_Opened;
"P3_Closed" := "InputDB".P3_Closed;
"P4_Opened" := "InputDB".P4_Opened;
"P4_Closed" := "InputDB".P4_Closed;
"P5_Opened" := "InputDB".P5_Opened;
"P5_Closed" := "InputDB".P5_Closed;
"P6_Opened" := "InputDB".P6_Opened;
"P6_Closed" := "InputDB".P6_Closed;
"P7_Opened" := "InputDB".P7_Opened;
"P7_Closed" := "InputDB".P7_Closed;
"Work_End_Stan" := "InputDB".Work_End_Stan;
"Pos_Vert_Input" := "InputDB".Pos_Vert_Input;
"Pos_Horizontal_Input" := "InputDB".Pos_Horizontal_Input;

// Запись данных из переменных в DB
"OutputDB".Open_Shield := "Shield_Opened";
"OutputDB".Close_Shield := "Shield_Closed";
"OutputDB".P1_Open := "P1_Opened";
"OutputDB".P1_Close := "P1_Closed";
"OutputDB".P2_Open := "P2_Opened";
"OutputDB".P2_Close := "P2_Closed";
"OutputDB".P3_Open := "P3_Opened";
"OutputDB".P3_Close := "P3_Closed";
"OutputDB".P4_Open := "P4_Opened";
"OutputDB".P4_Close := "P4_Closed";
"OutputDB".P5_Open := "P5_Opened";
"OutputDB".P5_Close := "P5_Closed";
"OutputDB".P6_Open := "P6_Opened";
"OutputDB".P6_Close := "P6_Closed";
"OutputDB".P7_Open := "P7_Opened";
"OutputDB".P7_Close := "P7_Closed";
"OutputDB".Start_Stan := "Start_Stan";
"OutputDB".Pos_Vert := "Pos_Vert";
"OutputDB".Pos_Horizontal := "Pos_Horizontal";

Вот InputDB (DB1)
	Static							
	Start_Pos	Bool	0.0	false	True	True	False	Default tag table
	Fl1_Ready	Bool	0.1	false	True	True	False	Default tag table
	FL2_Ready	Bool	0.2	false	True	True	False	Default tag table
	Shield_Opened	Bool	0.3	false	True	True	False	Default tag table
	Shield_Closed	Bool	0.4	false	True	True	False	Default tag table
	P1_Opened	Bool	0.5	false	True	True	False	Default tag table
	P1_Closed	Bool	0.6	false	True	True	False	Default tag table
	P2_Opened	Bool	0.7	false	True	True	False	Default tag table
	P2_Closed	Bool	1.0	false	True	True	False	Default tag table
	P3_Opened	Bool	1.1	false	True	True	False	Default tag table
	P3_Closed	Bool	1.2	false	True	True	False	Default tag table
	P4_Opened	Bool	1.3	false	True	True	False	Default tag table
	P4_Closed	Bool	1.4	false	True	True	False	Default tag table
	P5_Opened	Bool	1.5	false	True	True	False	Default tag table
	P5_Closed	Bool	1.6	false	True	True	False	Default tag table
	P6_Opened	Bool	1.7	false	True	True	False	Default tag table
	P6_Closed	Bool	2.0	false	True	True	False	Default tag table
	P7_Opened	Bool	2.1	false	True	True	False	Default tag table
	P7_Closed	Bool	2.2	false	True	True	False	Default tag table
	Work_End_Stan	Bool	2.3	false	True	True	False	Default tag table
	Alert_Stan	Bool	2.4	false	True	True	False	Default tag table
	Pos_Horizontal_Input	DInt	4.0	0	True	True	False	
	Pos_Vert_Input	DInt	8.0	0	True	True	False	

Вот OutputDB (DB2)
	P1_Open	Bool	0.0	false	True	True	False	
	P1_Close	Bool	0.1	false	True	True	False	
	P2_Open	Bool	0.2	false	True	True	False	
	P2_Close	Bool	0.3	false	True	True	False	
	P3_Open	Bool	0.4	false	True	True	False	
	P3_Close	Bool	0.5	false	True	True	False	
	P4_Open	Bool	0.6	false	True	True	False	
	P4_Close	Bool	0.7	false	True	True	False	
	P5_Open	Bool	1.0	false	True	True	False	
	P5_Close	Bool	1.1	false	True	True	False	
	P6_Open	Bool	1.2	false	True	True	False	
	P6_Close	Bool	1.3	false	True	True	False	
	P7_Open	Bool	1.4	false	True	True	False	
	P7_Close	Bool	1.5	false	True	True	False	
	Open_Shield	Bool	1.6	false	True	True	False	
	Close_Shield	Bool	1.7	false	True	True	False	
	Start_Stan	Bool	2.0	false	True	True	False	
	Stop_Stan	Bool	2.1	false	True	True	False	
	Pos_Vert	DInt	4.0	0	True	True	False	
	Pos_Horizontal	DInt	8.0	0	True	True	False