提交 bf3c5411 编写于 作者: C chenyun

Initial commit

上级
fileFormatVersion: 2
guid: ace687235282a99418de2ad9fb080dd5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 0c0b2726b4fdde94691d974a98847a5e
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: f7b95038beb1cb44db151aaba05c82fb
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: c353a751003986f49ad334432c689ef5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
此差异已折叠。
fileFormatVersion: 2
guid: b39e5fb6a93beb34a96ef57e7407d91f
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: a4c229f88efc8d84aab128321045d651
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System;
using Assets.Scripts.ModBus;
using Assets.Scripts.Serial;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.Scripts
{
public class AppStart : MonoBehaviour
{
private void Awake()
{
}
private void Start()
{
var uiRoot = GameObject.Find("UIRoot").transform;
var uiCamera = GameObject.Find("UICamera").GetComponent<Camera>();
var motionControl = uiRoot.Find("MotionControl");
var mainUi = uiRoot.Find("MainUi");
var mainGrid = mainUi.Find("MainGrid");
var grid = mainGrid.Find("Grid");
var btnOpenSerial = grid.Find("Btn1").GetComponent<Button>();
btnOpenSerial.onClick.AddListener(OnBtnOpenSerial);
var btnCloseSerial = grid.Find("Btn2").GetComponent<Button>();
btnCloseSerial.onClick.AddListener(OnBtnCloseSerialClick);
var btnSendData = grid.Find("Btn3").GetComponent<Button>();
btnSendData.onClick.AddListener(OnBtnSendDataClick);
var grid2 = mainGrid.Find("Grid2");
var btnHoldingRegister = grid2.Find("Btn1").GetComponent<Button>();
btnHoldingRegister.onClick.AddListener(OnBtnHoldingRegisterClick);
var btnInputRegister = grid2.Find("Btn2").GetComponent<Button>();
btnInputRegister.onClick.AddListener(OnBtnInputRegisterClick);
var btnMultipleRegister = grid2.Find("Btn3").GetComponent<Button>();
btnMultipleRegister.onClick.AddListener(OnBtnMultipleRegisterClick);
var grid3 = mainGrid.Find("Grid3");
var btnSetRtuSlave = grid3.Find("Btn1").GetComponent<Button>();
btnSetRtuSlave.onClick.AddListener(OnBtnSetRtuSlaveClick);
SerialModel.Instance.SetSerialPort();
ModBusRtu.Instance.Init();
}
private void OnBtnOpenSerial()
{
try
{
SerialModel.Instance.Open();
}
catch (Exception e)
{
Debug.LogError("无法打开此串口,请检查是否被占用");
throw;
}
}
private void OnBtnCloseSerialClick()
{
SerialModel.Instance.Close();
}
private void OnBtnSendDataClick()
{
SerialModel.Instance.SendData("hello!");
}
private void OnBtnHoldingRegisterClick()
{
var registers = ModBusRtu.Instance.ModbusSerialRtuMasterReadHoldingRegisters();
for (int i = 0; i < registers.Length; i++)
{
Debug.Log($"index:{i},value:{registers[i]}");
}
}
private void OnBtnInputRegisterClick()
{
var registers = ModBusRtu.Instance.ModbusSerialRtuMasterReadInputRegisters();
for (int i = 0; i < registers.Length; i++)
{
Debug.Log($"index:{i},value:{registers[i]}");
}
}
private void OnBtnMultipleRegisterClick()
{
ModBusRtu.Instance.ModbusSerialRtuMasterWriteMultipleRegisters();
}
private void OnBtnSetRtuSlaveClick()
{
ModBusRtu.Instance.StartModbusSerialRtuSlave();
}
void OnApplicationQuit()
{
ModBusRtu.Instance.Dispose();
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 043b7256106a3114abbfbc25cdca0174
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: b6ca7f1b864488a4b937bfa7540cda4c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.Scripts.ModBus
{
public static class ModBusHelper
{
public static byte[] Crc16(byte[] data)
{
var len = data.Length;
if (len <= 0) return new byte[] { 0, 0 };
ushort crc = 0xFFFF;
for (int i = 0; i < len; i++)
{
crc = (ushort)(crc ^ (data[i]));
for (int j = 0; j < 8; j++)
{
crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);
}
}
byte hi = (byte)((crc & 0xFF00) >> 8); //λ
byte lo = (byte)(crc & 0x00FF); //λ
return BitConverter.IsLittleEndian ? new byte[] { lo, hi } : new byte[] { hi, lo };
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: c3276d51e8dc04b46bb55b838286739b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
using NModbus;
using NModbus.Serial;
using UnityEngine;
namespace Assets.Scripts.ModBus
{
public class ModBusRtu
{
private static ModBusRtu m_Instance;
public static ModBusRtu Instance
{
get
{
if (m_Instance == null)
m_Instance = new ModBusRtu();
return m_Instance;
}
}
private string masterPortName = "COM2";
private string slavePortName = "COM3";
private byte slaveAddress = 0x01;
private ushort startAddress = 0;
private ushort numberOfPoints = 10;
private CancellationToken token;
private CancellationTokenSource cts;
public void Init()
{
if (cts != null)
{
cts.Cancel();
cts = null;
}
cts = new CancellationTokenSource();
token = cts.Token;
}
public void Dispose()
{
cts.Cancel();
}
public ushort[] ModbusSerialRtuMasterReadHoldingRegisters()
{
// configure serial port
using SerialPort masterPort = new SerialPort(masterPortName);
masterPort.BaudRate = 9600;
masterPort.DataBits = 8;
masterPort.Parity = Parity.None;
masterPort.StopBits = StopBits.One;
masterPort.Open();
var factory = new ModbusFactory();
IModbusSerialMaster master = factory.CreateRtuMaster(masterPort);
// read register
ushort[] registers = master.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);
return registers;
}
public ushort[] ModbusSerialRtuMasterReadInputRegisters()
{
// configure serial port
using SerialPort masterPort = new SerialPort(masterPortName);
masterPort.BaudRate = 9600;
masterPort.DataBits = 8;
masterPort.Parity = Parity.None;
masterPort.StopBits = StopBits.One;
masterPort.Open();
var factory = new ModbusFactory();
IModbusSerialMaster master = factory.CreateRtuMaster(masterPort);
// read register
ushort[] registers = master.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints);
return registers;
}
public void ModbusSerialRtuMasterWriteMultipleRegisters()
{
// configure serial port
using SerialPort port = new SerialPort(masterPortName);
port.BaudRate = 9600;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.Open();
var factory = new ModbusFactory();
IModbusMaster master = factory.CreateRtuMaster(port);
ushort[] data = new ushort[] { 10, 20, 30, 0, 0 };
// write register
master.WriteMultipleRegisters(slaveAddress, startAddress, data);
}
public void StartModbusSerialRtuSlave()
{
StartModbusSerialRtuSlaveWithCustomStoreAsync(token);
}
public async void StartModbusSerialRtuSlaveWithCustomStoreAsync(CancellationToken ct)
{
if (ct.IsCancellationRequested) return;
// configure serial port
using SerialPort slavePort = new SerialPort(slavePortName);
slavePort.BaudRate = 9600;
slavePort.DataBits = 8;
slavePort.Parity = Parity.None;
slavePort.StopBits = StopBits.One;
slavePort.Open();
var factory = new ModbusFactory();
var slaveNetwork = factory.CreateRtuSlaveNetwork(slavePort);
slavePort.ReadTimeout = 50;
slavePort.WriteTimeout = 1000;
var dataStore = new SlaveStorage();
dataStore.CoilDiscretes.StorageOperationOccurred += (sender, args) =>
{
Debug.Log(GetSlaveMsg("CoilDiscretes", args));
};
dataStore.CoilInputs.StorageOperationOccurred += (sender, args) =>
{
Debug.Log(GetSlaveMsg("CoilInputs", args));
};
dataStore.InputRegisters.StorageOperationOccurred += (sender, args) =>
{
Debug.Log(GetSlaveMsg("InputRegisters", args));
};
dataStore.HoldingRegisters.StorageOperationOccurred += (sender, args) =>
{
Debug.Log(GetSlaveMsg("HoldingRegisters", args));
};
IModbusSlave slave = factory.CreateSlave(slaveAddress, dataStore);
slaveNetwork.AddSlave(slave);
// listen async
await Task.Run(() => { slaveNetwork.ListenAsync(ct); }, ct);
}
private string GetSlaveMsg(string type, StorageEventArgs<bool> args)
{
string value = type + $":{args.Operation} StartingAddress:{args.StartingAddress} ";
for (int i = 0; i < args.Points.Length; i++)
{
value += $"Point{i + args.StartingAddress}:{args.Points[i]} ";
}
return value;
}
private string GetSlaveMsg(string type, StorageEventArgs<ushort> args)
{
string value = type + $":{args.Operation} StartingAddress:{args.StartingAddress} ";
for (int i = 0; i < args.Points.Length; i++)
{
value += $"Point{i + args.StartingAddress}:{args.Points[i]} ";
}
return value;
}
public void StartModbusBand()
{
// configure serial port
using SerialPort port = new SerialPort(masterPortName);
port.BaudRate = 9600;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.Open();
var factory = new ModbusFactory();
IModbusMaster master = factory.CreateRtuMaster(port);
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: f004e6d95111deb41a9e140638b311c9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections.Generic;
using NModbus;
namespace Assets.Scripts.ModBus
{
public class SlaveStorage : ISlaveDataStore
{
private readonly SparsePointSource<bool> m_CoilDiscretes;
private readonly SparsePointSource<bool> m_CoilInputs;
private readonly SparsePointSource<ushort> m_HoldingRegisters;
private readonly SparsePointSource<ushort> m_InputRegisters;
public SlaveStorage()
{
m_CoilDiscretes = new SparsePointSource<bool>();
m_CoilInputs = new SparsePointSource<bool>();
m_HoldingRegisters = new SparsePointSource<ushort>();
m_InputRegisters = new SparsePointSource<ushort>();
}
public SparsePointSource<bool> CoilDiscretes => m_CoilDiscretes;
public SparsePointSource<bool> CoilInputs => m_CoilInputs;
public SparsePointSource<ushort> HoldingRegisters => m_HoldingRegisters;
public SparsePointSource<ushort> InputRegisters => m_InputRegisters;
IPointSource<bool> ISlaveDataStore.CoilDiscretes => m_CoilDiscretes;
IPointSource<bool> ISlaveDataStore.CoilInputs => m_CoilInputs;
IPointSource<ushort> ISlaveDataStore.HoldingRegisters => m_HoldingRegisters;
IPointSource<ushort> ISlaveDataStore.InputRegisters => m_InputRegisters;
}
/// <summary>
/// Sparse storage for points.
/// </summary>
public class SparsePointSource<TPoint> : IPointSource<TPoint>
{
private readonly Dictionary<ushort, TPoint> _values = new Dictionary<ushort, TPoint>();
public event EventHandler<StorageEventArgs<TPoint>> StorageOperationOccurred;
/// <summary>
/// Gets or sets the value of an individual point wih tout
/// </summary>
/// <param name="registerIndex"></param>
/// <returns></returns>
public TPoint this[ushort registerIndex]
{
get
{
if (_values.TryGetValue(registerIndex, out var value))
return value;
return default(TPoint);
}
set { _values[registerIndex] = value; }
}
public TPoint[] ReadPoints(ushort startAddress, ushort numberOfPoints)
{
var points = new TPoint[numberOfPoints];
for (ushort index = 0; index < numberOfPoints; index++)
{
points[index] = this[(ushort) (index + startAddress)];
}
StorageOperationOccurred?.Invoke(this,
new StorageEventArgs<TPoint>(PointOperation.Read, startAddress, points));
return points;
}
public void WritePoints(ushort startAddress, TPoint[] points)
{
for (ushort index = 0; index < points.Length; index++)
{
this[(ushort) (index + startAddress)] = points[index];
}
StorageOperationOccurred?.Invoke(this,
new StorageEventArgs<TPoint>(PointOperation.Write, startAddress, points));
}
}
public class StorageEventArgs<TPoint> : EventArgs
{
public StorageEventArgs(PointOperation pointOperation, ushort startingAddress, TPoint[] points)
{
Operation = pointOperation;
StartingAddress = startingAddress;
Points = points;
}
public ushort StartingAddress { get; }
public TPoint[] Points { get; }
public PointOperation Operation { get; }
}
public enum PointOperation
{
Read,
Write
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 026474e33d11f9249b001d921264115a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 8d970d8a2d102e24bb3395a0e786b57f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System.IO.Ports;
using UnityEngine;
namespace Assets.Scripts.Serial
{
public class SerialModel
{
private static SerialModel m_Instance;
public static SerialModel Instance
{
get
{
if (m_Instance == null)
m_Instance = new SerialModel();
return m_Instance;
}
}
private SerialPort m_SerialPort;
public void SetSerialPort()
{
string[] serialPortArray = SerialPort.GetPortNames();
foreach (string serialPort in serialPortArray)
{
Debug.Log($"Serial Port Name:{serialPort}");
}
m_SerialPort = new SerialPort();
//端口名
m_SerialPort.PortName = "COM2";
//波特率
m_SerialPort.BaudRate = 9600;
//奇偶校验
m_SerialPort.Parity = Parity.None;
//数据位
m_SerialPort.DataBits = 8;
//停止位
m_SerialPort.StopBits = StopBits.One;
//串口接收数据事件
m_SerialPort.DataReceived += ReceiveData;
}
public void Open()
{
m_SerialPort.Open();
}
public void Close()
{
m_SerialPort.Close();
}
public void SendData(byte[] data)
{
var isOpen = m_SerialPort.IsOpen;
if (!isOpen)
{
Open();
}
//发送字节数组
//参数1:包含要写入端口的数据的字节数组。
//参数2:参数中从零开始的字节偏移量,从此处开始将字节复制到端口。
//参数3:要写入的字节数。
m_SerialPort.Write(data, 0, data.Length);
}
public void SendData(string data)
{
var isOpen = m_SerialPort.IsOpen;
if (!isOpen)
{
Open();
}
//直接发送字符串
m_SerialPort.Write(data);
}
private void ReceiveData(object obj, SerialDataReceivedEventArgs e)
{
//读取串口缓冲区的字节数据
byte[] result = new byte[m_SerialPort.BytesToRead];
m_SerialPort.Read(result, 0, m_SerialPort.BytesToRead);
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: b0f27fa87c7a3e540b5ebfa351e53a07
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
{
"dependencies": {
"com.unity.collab-proxy": "1.13.5",
"com.unity.ide.rider": "2.0.7",
"com.unity.ide.visualstudio": "2.0.15",
"com.unity.ide.vscode": "1.2.5",
"com.unity.test-framework": "1.1.31",
"com.unity.textmeshpro": "3.0.6",
"com.unity.timeline": "1.4.8",
"com.unity.ugui": "1.0.0",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
}
{
"dependencies": {
"com.unity.collab-proxy": {
"version": "1.13.5",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.nuget.newtonsoft-json": "2.0.0",
"com.unity.services.core": "1.0.1"
},
"url": "https://packages.unity.com"
},
"com.unity.ext.nunit": {
"version": "1.0.6",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ide.rider": {
"version": "2.0.7",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.1"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.15",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.9"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.vscode": {
"version": "1.2.5",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.nuget.newtonsoft-json": {
"version": "2.0.0",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.services.core": {
"version": "1.0.1",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.31",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.textmeshpro": {
"version": "3.0.6",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.4.8",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.director": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.ugui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.androidjni": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.animation": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.assetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.audio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.cloth": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.director": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0"
}
},
"com.unity.modules.imageconversion": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.imgui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.jsonserialize": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.particlesystem": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics2d": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.screencapture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.subsystems": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.terrain": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.terrainphysics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0"
}
},
"com.unity.modules.tilemap": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics2d": "1.0.0"
}
},
"com.unity.modules.ui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.uielements": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.uielementsnative": "1.0.0"
}
},
"com.unity.modules.uielementsnative": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.umbra": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unityanalytics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.unitywebrequest": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unitywebrequestassetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.unitywebrequestaudio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.audio": "1.0.0"
}
},
"com.unity.modules.unitywebrequesttexture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.unitywebrequestwww": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.vehicles": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.video": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.vr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
},
"com.unity.modules.wind": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.xr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.subsystems": "1.0.0"
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册