当前位置:网站首页>[unity] upgraded version · Excel data analysis, automatically create corresponding C classes, automatically create scriptableobject generation classes, and automatically serialize asset files

[unity] upgraded version · Excel data analysis, automatically create corresponding C classes, automatically create scriptableobject generation classes, and automatically serialize asset files

2022-07-07 02:18:00 51CTO


  Realization function :

  • Automatically create inheritance ScriptableObject Of C# Data class , Every one of them Excel The data of , Have corresponding fields Get function ;
  • 【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _excel【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _ Tool class _02


  • Automatically create each Excel Of Asset Generate classes and generate functions , Used to automatically generate Asset file

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _unity_03

  • Use Asset Automatic serialization of generated classes Excel Data to Asset file , It can be loaded and used directly when the project is running

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _ Game development _04


【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _unity_05

Realization principle :

Excel Configuration format :

  • The first 1 Lines correspond to special marks ( Validity can be set , Specify the file to create )
  • The first 2 The line corresponds to the Chinese description ( As a first 3 Comments for line fields )
  • The first 3 Row corresponding field name ( Automatically created field name )
  • The first 4 The row corresponds to the field type ( Automatically created field types , One to one correspondence with field name )
  • The first 5 Row and subsequent corresponding field values ( All the data , Analyze in behavioral units 、 Save the data )
  • The fixed fields in the first column are "id", Is the index of each line of data in the code Key

Excel Annotation operations :

  • Field name line , Add "//", You can annotate this field , Will not parse to C# class ;
  • Add "//", You can annotate a line of data , It won't be saved to Asset In file ;
  • Comments can be used to add a description line , Or eliminate the specified useless data .

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _unity_06

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _ Tool class _07

Generated C# Class format :

Row data class , Corresponding to each row of data :

      
      
[Serializable]
public class TestConfigExcelItem : ExcelItemBase
{
/// <summary>
///
/// </summary>>
public int id;
/// <summary>
///
/// </summary>>
public string testString;
/// <summary>
///
/// </summary>>
public int testInt;
/// <summary>
///
/// </summary>>
public float
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _ Tool class _08

Complete data class , Contains all rows of data 、 Initialization function 、Get function :

      
      
public class TestConfigExcelData : ExcelDataBase<TestConfigExcelItem>
{
public TestConfigExcelItem[] items;

public Dictionary<int,TestConfigExcelItem> itemDic = new Dictionary<int,TestConfigExcelItem>();

public void Init()
{
itemDic.Clear();
if(items != null && items.Length > 0)
{
for(int i = 0; i < items.Length; i++)
{
itemDic.Add(items[i].id, items[i]);
}
}
}

public TestConfigExcelItem GetTestConfigExcelItem(int)
{
if(itemDic.ContainsKey(id))
return itemDic[id];
else
return null;
}
#region

public string GetTestString(int)
{
var item = GetTestConfigExcelItem(id);
if(item == null)
return default;
return item.testString;
}

// ··· ···

#endregion
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _unity_09

Currently supported data structures :

character string

testString

Array of strings

testStringArray

Two dimensional array of strings

testStringArray2

Int

testInt

Int Array

testIntArray

Int Two dimensional array

testIntArray2

Float

testFloat

Float Array

testFloatArray

Float Two dimensional array

testFloatArray2

Bool

testBool

Bool Array

testBoolArray

Bool Two dimensional array

testBoolArray2

Enum| Enum name ( Or enumeration value )

testEnum

Enum Array

testEnumArray

Enum Two dimensional array

I won't support it

Vector2

testVector2

Vector2 Array

testVector2Array

Vector2 Two dimensional array

testVector2Array2

Vector3

testVector3

Vector3 Array

testVector3Array

Vector3 Two dimensional array

testVector3Array2

Vector2Int

testVector2Int

Vector2Int Array

testVector2IntArray

Vector2Int Two dimensional array

testVector2IntArray2

Vector3Int

testVector3Int

Vector3Int Array

testVector3IntArray

Vector3Int Two dimensional array

testVector3IntArray2

Color

testColor

Color Array

testColorArray

Color Two dimensional array

testColorArray2

Color32

testColor32

Color32 Array

testColor32Array

Color32 Two dimensional array

testColor32Array2

because Unity Cannot serialize a two-dimensional array , Here it is changed to a one-dimensional array + Structure is realized :

      
      
[Serializable]
public struct StringArr
{
public string[] array;
}

// Two dimensional array representation : StringArr[]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.


【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _ Tool class _10

Asset Data files :

In the process of automatically generating data C# Class time , Will be generated synchronously Asset File creation class , For automatic creation of Asset File and serialize data .

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _unity_11


advantage :

  • After data modification, you only need to regenerate with one click
  • Every Excel Corresponding to a class , Flexible use , Yes Excel Less restrictions
  • Automatically create C# class , There is no need for each Excel Write code manually , Each data corresponds to a field , There is no need to unpack and decorate
  • Automatically create ScriptableObject Of Asset file , Automatically serialize data , Convenient view , You can manually modify and adjust , There is no need to change every time Excel In the operation
  • Read directly in the game Asset Of ScriptableObject Subclass , No need for extra operation , The business layer directly accesses data fields

Usage method :

  • Configure in standard format Excel
  • One click generation C# class 、Asset file
  • The project runtime loads Asset resources , call Init initialization ,Get Function to get the corresponding field value

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _ Game development _12

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _unity_13


Complete code :

Expand Unity Editor window :

      
      
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System.Linq;

public class BuildExcelWindow : EditorWindow
{
[MenuItem("MyTools/Excel Window",priority = 100)]
public static void ShowReadExcelWindow()
{
BuildExcelWindow window = GetWindow<BuildExcelWindow>(true);
window.Show();
window.minSize = new Vector2(475,475);
}

//Excel Read path , Absolute path , Put it in Assets Peer path
private static string excelReadAbsolutePath;

// Automatic generation C# Class file path , Absolute path
private static string scriptSaveAbsolutePath;
private static string scriptSaveRelativePath;
// Automatic generation Asset File path , Relative paths
private static string assetSaveRelativePath;

private List<string> fileNameList = new List<string>();
private List<string> filePathList = new List<string>();

private void Awake()
{
titleContent.text = "Excel Configuration table read ";

excelReadAbsolutePath = Application.dataPath.Replace("Assets","Excel");
scriptSaveAbsolutePath = Application.dataPath + CheckEditorPath("/Script/Excel/AutoCreateCSCode");
scriptSaveRelativePath = CheckEditorPath("Assets/Script/Excel/AutoCreateCSCode");
assetSaveRelativePath = CheckEditorPath("Assets/AssetData/Excel/AutoCreateAsset");
}

private void OnEnable()
{
RefreshExcelFile();
}

private void OnDisable()
{
fileNameList.Clear();
filePathList.Clear();
}

private Vector2 scrollPosition = Vector2.zero;
private void OnGUI()
{
GUILayout.Space(10);

scrollPosition = GUILayout.BeginScrollView(scrollPosition,GUILayout.Width(position.width),GUILayout.Height(position.height));

// Show the way
GUILayout.BeginHorizontal(GUILayout.Height(20));
if(GUILayout.Button("Excel Read path ",GUILayout.Width(100)))
{
EditorUtility.OpenWithDefaultApp(excelReadAbsolutePath);
Debug.Log(excelReadAbsolutePath);
}
if(GUILayout.Button("Script Save the path ",GUILayout.Width(100)))
{
SelectObject(scriptSaveRelativePath);
}
if(GUILayout.Button("Asset Save the path ",GUILayout.Width(100)))
{
SelectObject(assetSaveRelativePath);
}
GUILayout.EndHorizontal();

GUILayout.Space(5);

//Excel list

GUILayout.Label("Excel list :");
for(int i = 0; i < fileNameList.Count; i++)
{
GUILayout.BeginHorizontal("Box",GUILayout.Height(40));

GUILayout.Label($"{i}:","Titlebar Foldout",GUILayout.Width(30),GUILayout.Height(35));
GUILayout.Box(fileNameList[i],"MeTransitionBlock",GUILayout.MinWidth(200),GUILayout.Height(35));
GUILayout.Space(10);

// Generate CS Code
if(GUILayout.Button("Create Script",GUILayout.Width(100),GUILayout.Height(30)))
{
ExcelDataReader.ReadOneExcelToCode(filePathList[i],scriptSaveAbsolutePath);
}
// Generate Asset file
if(GUILayout.Button("Create Asset",GUILayout.Width(100),GUILayout.Height(30)))
{
ExcelDataReader.CreateOneExcelAsset(filePathList[i],assetSaveRelativePath);
}

GUILayout.EndHorizontal();
GUILayout.Space(5);
}
GUILayout.Space(10);

// One click processing all Excel

GUILayout.Label(" One click operation :");
GUILayout.BeginHorizontal("Box",GUILayout.Height(40));

GUILayout.Label("all","Titlebar Foldout",GUILayout.Width(30),GUILayout.Height(35));
GUILayout.Box("All Excel","MeTransitionBlock",GUILayout.MinWidth(200),GUILayout.Height(35));
GUILayout.Space(10);

if(GUILayout.Button("Create Script",GUILayout.Width(100),GUILayout.Height(30)))
{
ExcelDataReader.ReadAllExcelToCode(excelReadAbsolutePath,scriptSaveAbsolutePath);
}
if(GUILayout.Button("Create Asset",GUILayout.Width(100),GUILayout.Height(30)))
{
ExcelDataReader.CreateAllExcelAsset(excelReadAbsolutePath,assetSaveRelativePath);
}
GUILayout.EndHorizontal();

//
GUILayout.Space(20);
//
GUILayout.EndScrollView();
}

// Read the... Under the specified path Excel file name
private void RefreshExcelFile()
{
fileNameList.Clear();
filePathList.Clear();

if(!Directory.Exists(excelReadAbsolutePath))
{
Debug.LogError(" Invalid path :" + excelReadAbsolutePath);
return;
}
string[] excelFileFullPaths = Directory.GetFiles(excelReadAbsolutePath,"*.xlsx");

if(excelFileFullPaths == null || excelFileFullPaths.Length == 0)
{
Debug.LogError(excelReadAbsolutePath + " Not found under path Excel file ");
return;
}

filePathList.AddRange(excelFileFullPaths);
for(int i = 0; i < filePathList.Count; i++)
{
fileNameList.Add(Path.GetFileName(filePathList[i]));
}
Debug.Log(" find Excel file :" + fileNameList.Count + " individual ");
}

private void SelectObject(string)
{
Object targetObj = AssetDatabase.LoadAssetAtPath<Object>(targetPath);
EditorGUIUtility.PingObject(targetObj);
Selection.activeObject = targetObj;
Debug.Log(targetPath);
}

private static string CheckEditorPath(string)
{
#if
return path.Replace("/","\\");
#elif
return path.Replace("\\","/");
#else
return path;
#endif
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _unity_14

Excel Data reading class : 

      
      
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using Excel;
using System.Reflection;
using System;
using System.Linq;

public class ExcelDataReader
{
//Excel The first 1 Lines correspond to special marks
private const int specialSignRow = 0;
//Excel The first 2 The line corresponds to the Chinese description
private const int excelNodeRow = 1;
//Excel The first 3 Row corresponding field name
private const int excelNameRow = 2;
//Excel The first 4 The row corresponds to the field type
private const int excelTypeRow = 3;
//Excel The first 5 Row and subsequent corresponding field values
private const int excelDataRow = 4;

// Mark comment lines / Column
private const string annotationSign = "//";

#region

// establish Excel Corresponding C# class
public static void ReadAllExcelToCode(string allExcelPath,string)
{
// Read all Excel file
// The full name of the file in the specified directory that matches the specified search pattern and options ( Inclusion path ) Array of ; If no files are found , Is an empty array .
string[] excelFileFullPaths = Directory.GetFiles(allExcelPath,"*.xlsx");
if(excelFileFullPaths == null || excelFileFullPaths.Length == 0)
{
Debug.Log("Excel file count == 0");
return;
}
// Traverse all of Excel, establish C# class
for(int i = 0; i < excelFileFullPaths.Length; i++)
{
ReadOneExcelToCode(excelFileFullPaths[i],codeSavePath);
}
}

// establish Excel Corresponding C# class
public static void ReadOneExcelToCode(string excelFullPath,string)
{
// analysis Excel Get intermediate data
ExcelMediumData excelMediumData = CreateClassCodeByExcelPath(excelFullPath);
if(excelMediumData == null)
{
Debug.LogError($" Read Excel Failure : {excelFullPath}");
return;
}
if(!excelMediumData.isValid)
{
Debug.LogError($" Read Excel Failure ,Excel Mark failure : {excelMediumData.excelName}");
return;
}

if(!excelMediumData.isCreateCSharp && !excelMediumData.isCreateAssignment)
{
Debug.LogError($" Read Excel Failure ,Excel Generation of CSCode : {excelMediumData.excelName}");
return;
}

// Generate... From data C# Script
string classCodeStr = ExcelCodeCreater.CreateCodeStrByExcelData(excelMediumData);
if(string.IsNullOrEmpty(classCodeStr))
{
Debug.LogError($" analysis Excel Failure : {excelMediumData.excelName}");
return;
}

// Check the export path
if(!Directory.Exists(codeSavePath))
Directory.CreateDirectory(codeSavePath);
// Class name
string codeFileName = excelMediumData.excelName + "ExcelData";
// Writing documents , Generate CS Class file
StreamWriter sw = new StreamWriter($"{codeSavePath}/{codeFileName}.cs");
sw.WriteLine(classCodeStr);
sw.Close();
//
UnityEditor.AssetDatabase.SaveAssets();
UnityEditor.AssetDatabase.Refresh();
//
Debug.Log($" Generate Excel Of CS success : {excelMediumData.excelName}");
}

#endregion

#region

// establish Excel Corresponding Asset Data files
public static void CreateAllExcelAsset(string allExcelPath,string)
{
// Read all Excel file
// The full name of the file in the specified directory that matches the specified search pattern and options ( Inclusion path ) Array of ; If no files are found , Is an empty array .
string[] excelFileFullPaths = Directory.GetFiles(allExcelPath,"*.xlsx");
if(excelFileFullPaths == null || excelFileFullPaths.Length == 0)
{
Debug.Log("Excel file count == 0");
return;
}
// Traverse all of Excel, establish Asset
for(int i = 0; i < excelFileFullPaths.Length; i++)
{
CreateOneExcelAsset(excelFileFullPaths[i],assetSavePath);
}
}

// establish Excel Corresponding Asset Data files
public static void CreateOneExcelAsset(string excelFullPath,string)
{
// analysis Excel Get intermediate data
ExcelMediumData excelMediumData = CreateClassCodeByExcelPath(excelFullPath);
if(excelMediumData == null)
{
Debug.LogError($" Read Excel Failure : {excelFullPath}");
return;
}
if(!excelMediumData.isValid)
{
Debug.LogError($" Read Excel Failure ,Excel Mark failure : {excelMediumData.excelName}");
return;
}

if(!excelMediumData.isCreateAsset)
{
Debug.LogError($" Read Excel Failure ,Excel Generation of Asset : {excelMediumData.excelName}");
return;
}

//// Get the current assembly
//Assembly assembly = Assembly.GetExecutingAssembly();
//// Create an instance of a class , Return to object type , A cast is required ,assembly.CreateInstance(" The fully qualified name of the class ( Including the namespace )");
//object class0bj = assembly.CreateInstance(excelMediumData.excelName + "Assignment",true);

// You must traverse all assemblies to get the type . The current in Assembly-CSharp-Editor in , The target type is Assembly-CSharp in , Different programs will not be able to get types
Type assignmentType = null;
string assetAssignmentName = excelMediumData.excelName + "AssetAssignment";
foreach(var asm in AppDomain.CurrentDomain.GetAssemblies())
{
// Find the target type
Type tempType = asm.GetType(assetAssignmentName);
if(tempType != null)
{
assignmentType = tempType;
break;
}
}
if(assignmentType == null)
{
Debug.LogError($" Creation boundary Asset Failure , Not found Asset Generating classes : {excelMediumData.excelName}");
return;
}

// Reflection acquisition method
MethodInfo methodInfo = assignmentType.GetMethod("CreateAsset");
if(methodInfo == null)
{
if(assignmentType == null)
{
Debug.LogError($" Creation boundary Asset Failure , Not found Asset Create a function : {excelMediumData.excelName}");
return;
}
}

methodInfo.Invoke(null,new object[] { excelMediumData,assetSavePath });
// establish Asset File successfully
Debug.Log($" Generate Excel Of Asset success : {excelMediumData.excelName}");
}

#endregion

#region

// analysis Excel, Create intermediate data
private static ExcelMediumData CreateClassCodeByExcelPath(string)
{
if(string.IsNullOrEmpty(excelFileFullPath))
return null;

excelFileFullPath = excelFileFullPath.Replace("\\","/");
// Read Excel
FileStream stream = File.Open(excelFileFullPath,FileMode.Open,FileAccess.Read);
if(stream == null)
return null;
// analysis Excel
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
// Invalid Excel
if(excelReader == null || !excelReader.IsValid)
{
Debug.Log("Invalid excel : " + excelFileFullPath);
return null;
}

Debug.Log(" Start parsing Excel : " + excelReader.Name);

// Record Excel data
ExcelMediumData excelMediumData = new ExcelMediumData();

//Excel name
excelMediumData.excelName = excelReader.Name;

// Currently traversed rows
int curRowIndex = 0;
// Start reading , Go through... By line
while(excelReader.Read())
{
// No data is read in this line , Treat as invalid row data
if(excelReader.FieldCount <= 0)
{
curRowIndex++;
continue;
}
// Read the complete data of each row
string[] datas = new string[excelReader.FieldCount];
for(int j = 0; j < excelReader.FieldCount; ++j)
{
// You can directly read the specified type of data , However, only limited data types are supported , Read uniformly here string, Then data conversion
//excelReader.GetInt32(j); excelReader.GetFloat(j);

// Read every cell data
datas[j] = excelReader.GetString(j);
}

switch(curRowIndex)
{
case specialSignRow:
// Special mark line
string specialSignStr = datas[0];
if(specialSignStr.Length >= 4)
{
excelMediumData.isValid = specialSignStr[0] == 'T';
excelMediumData.isCreateCSharp = specialSignStr[1] == 'T';
excelMediumData.isCreateAssignment = specialSignStr[2] == 'T';
excelMediumData.isCreateAsset = specialSignStr[3] == 'T';
}
else
{
Debug.LogError(" Not resolved to special tag ");
}
break;
case excelNodeRow:
// Data comment line
excelMediumData.propertyNodeArray = datas;
break;
case excelNameRow:
// Data name row
excelMediumData.propertyNameArray = datas;
// Comment column number
for(int i = 0; i < datas.Length; i++)
{
if(string.IsNullOrEmpty(datas[i]) || datas[i].StartsWith(annotationSign))
excelMediumData.annotationColList.Add(i);
}
break;
case excelTypeRow:
// Data type row
excelMediumData.propertyTypeArray = datas;
break;
default:
// Data content line
excelMediumData.allRowItemList.Add(datas);
// Comment line number
if(string.IsNullOrEmpty(datas[0]) || datas[0].StartsWith(annotationSign))
excelMediumData.annotationRowList.Add(excelMediumData.allRowItemList.Count - 1);
break;
}
//
curRowIndex++;
}

if(CheckExcelMediumData(ref excelMediumData))
{
Debug.Log(" Read Excel success ");
return excelMediumData;
}
else
{
Debug.LogError(" Read Excel Failure ");
return null;
}
}

// check Excel data
private static bool CheckExcelMediumData(ref)
{
if(mediumData == null)
return false;

// Check data validity

if(!mediumData.isValid)
{
Debug.LogError("Excel Marked invalid ");
return false;
}

if(string.IsNullOrEmpty(mediumData.excelName))
{
Debug.LogError("Excel The name is empty. ");
return false;
}

if(mediumData.propertyNameArray == null || mediumData.propertyNameArray.Length == 0)
{
Debug.LogError(" Data name not resolved ");
return false;
}
if(mediumData.propertyTypeArray == null || mediumData.propertyTypeArray.Length == 0)
{
Debug.LogError(" Not resolved to data type ");
return false;
}
if(mediumData.propertyNameArray.Length != mediumData.propertyTypeArray.Length)
{
Debug.LogError(" The data name is inconsistent with the number of data types ");
return false;
}
if(mediumData.allRowItemList.Count == 0)
{
Debug.LogError(" The data content is empty ");
return false;
}

if(mediumData.propertyNameArray[0] != "id")
{
Debug.LogError(" The first field must be id Field ");
return false;
}

return true;
}

#endregion
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.
  • 312.
  • 313.
  • 314.
  • 315.
  • 316.
  • 317.
  • 318.
  • 319.
  • 320.
  • 321.
  • 322.
  • 323.
  • 324.
  • 325.
  • 326.
  • 327.
  • 328.
  • 329.
  • 330.
  • 331.
  • 332.
  • 333.
  • 334.
  • 335.
  • 336.
  • 337.
  • 338.
  • 339.

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _unity_15

C# Code generation class :

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

public class ExcelCodeCreater
{

// Create code , Generate the data C# class
public static string CreateCodeStrByExcelData(ExcelMediumData excelMediumData)
{
if(excelMediumData == null)
return null;

// Row data class name
string itemClassName = excelMediumData.excelName + "ExcelItem";
// Overall data class name
string dataClassName = excelMediumData.excelName + "ExcelData";

// Start generating classes
StringBuilder classSource = new StringBuilder();
classSource.AppendLine("/*Auto Create, Don't Edit !!!*/");
classSource.AppendLine();
// Add reference
classSource.AppendLine("using UnityEngine;");
classSource.AppendLine("using System.Collections.Generic;");
classSource.AppendLine("using System;");
classSource.AppendLine("using System.IO;");
classSource.AppendLine();
// Generate CSharp Data class
if(excelMediumData.isCreateCSharp)
{
// Generate row data class , Record each line of data
classSource.AppendLine(CreateExcelRowItemClass(itemClassName,excelMediumData));
classSource.AppendLine();
// Generate overall data class , Record the whole Excel All rows of data
classSource.AppendLine(CreateExcelAllDataClass(dataClassName,itemClassName,excelMediumData));
classSource.AppendLine();
}
// Generate Asset Create a class
if(excelMediumData.isCreateAssignment)
{
// Generate Asset Operation class , For automatic creation of Excel Corresponding Asset File and assign
classSource.AppendLine(CreateExcelAssetClass(excelMediumData));
classSource.AppendLine();
}
//
return classSource.ToString();
}

//----------

// Generate row data class
private static string CreateExcelRowItemClass(string)
{
// Generate Excel Row data class
StringBuilder classSource = new StringBuilder();
// Class name
classSource.AppendLine("[Serializable]");
classSource.AppendLine($"public class {itemClassName});
classSource.AppendLine("{");
// Declare all fields
for(int i = 0; i < excelMediumData.propertyNameArray.Length; i++)
{
// Skip comment field
if(excelMediumData.annotationColList.Contains(i))
continue;

// Add notes
if(i < excelMediumData.propertyNodeArray.Length)
{
string propertyNode = excelMediumData.propertyNodeArray[i];
if(!string.IsNullOrEmpty(propertyNode))
{
classSource.AppendLine("\t/// <summary>");
classSource.AppendLine($"\t/// {propertyNode}");
classSource.AppendLine("\t/// </summary>>");
}
}

// Declare the fields of the row data class
string propertyName = excelMediumData.propertyNameArray[i];
string propertyType = excelMediumData.propertyTypeArray[i];
string typeStr = GetPropertyType(propertyType);
classSource.AppendLine($"\tpublic {typeStr} {propertyName};");
}
classSource.AppendLine("}");
return classSource.ToString();
}

//----------

// Generate overall data class
private static string CreateExcelAllDataClass(string dataClassName,string)
{
StringBuilder classSource = new StringBuilder();
// Class name
classSource.AppendLine($"public class {dataClassName} : ExcelDataBase<{itemClassName}>");
classSource.AppendLine("{");
// Declaration field , Row data class array
classSource.AppendLine($"\tpublic {itemClassName}[] items;");
classSource.AppendLine();
//id Field type
string idTypeStr = GetPropertyType(excelMediumData.propertyTypeArray[0]);
// Declaration Dictionary
classSource.AppendLine($"\tpublic Dictionary<{idTypeStr},{itemClassName}> itemDic = new Dictionary<{idTypeStr},{itemClassName}>();");
classSource.AppendLine();
// Field initialization method
classSource.AppendLine("\tpublic void Init()");
classSource.AppendLine("\t{");
classSource.AppendLine("\t\titemDic.Clear();");
classSource.AppendLine("\t\tif(items != null && items.Length > 0)");
classSource.AppendLine("\t\t{");
classSource.AppendLine("\t\t\tfor(int i = 0; i < items.Length; i++)");
classSource.AppendLine("\t\t\t{");
classSource.AppendLine("\t\t\t\titemDic.Add(items[i].id, items[i]);");
classSource.AppendLine("\t\t\t}");
classSource.AppendLine("\t\t}");
classSource.AppendLine("\t}");
classSource.AppendLine();
// Dictionary acquisition method
classSource.AppendLine($"\tpublic {itemClassName} Get{itemClassName}({idTypeStr});
classSource.AppendLine("\t{");
classSource.AppendLine("\t\tif(itemDic.ContainsKey(id))");
classSource.AppendLine("\t\t\treturn itemDic[id];");
classSource.AppendLine("\t\telse");
classSource.AppendLine("\t\t\treturn null;");
classSource.AppendLine("\t}");

// Each field Get function
classSource.AppendLine("\t#region --- Get Method ---");
classSource.AppendLine();

for(int i = 1; i < excelMediumData.propertyNameArray.Length; i++)
{
if(excelMediumData.annotationColList.Contains(i))
continue;
string propertyName = excelMediumData.propertyNameArray[i];
string propertyType = excelMediumData.propertyTypeArray[i];
// Each field Get function
classSource.AppendLine(CreateCodePropertyMethod(itemClassName,idTypeStr,propertyName,propertyType));
}
classSource.AppendLine("\t#endregion");
classSource.AppendLine("}");
return classSource.ToString();
}

// The generated data field corresponds to Get Method
private static string CreateCodePropertyMethod(string itemClassName,string idTypeStr,string propertyName,string)
{
StringBuilder methodBuilder = new StringBuilder();
string itemNameStr = propertyName.FirstOrDefault().ToString().ToUpper() + propertyName.Substring(1);
string itemTypeStr = GetPropertyType(propertyType);
// Field Get function
methodBuilder.AppendLine($"\tpublic {itemTypeStr} Get{itemNameStr}({idTypeStr});
methodBuilder.AppendLine("\t{");
methodBuilder.AppendLine($"\t\tvar item = Get{itemClassName}(id);");
methodBuilder.AppendLine("\t\tif(item == null)");
methodBuilder.AppendLine("\t\t\treturn default;");
methodBuilder.AppendLine($"\t\treturn item.{propertyName};");
methodBuilder.AppendLine("\t}");
// If it's a one-dimensional array
if(propertyType.Contains("[]"))
{
//typeStr:int[] or IntArr[] , Return value :int or IntArr
//string itemTypeStr1d = GetPropertyType(propertyType.Replace("[]",""));
string itemTypeStr1d = itemTypeStr.Replace("[]","");
methodBuilder.AppendLine($"\tpublic {itemTypeStr1d} Get{itemNameStr}({idTypeStr});
methodBuilder.AppendLine("\t{");
methodBuilder.AppendLine($"\t\tvar item0 = Get{itemClassName});
methodBuilder.AppendLine("\t\tif(item0 == null)");
methodBuilder.AppendLine("\t\t\treturn default;");
methodBuilder.AppendLine($"\t\tvar item1 = item0.{propertyName};");
methodBuilder.AppendLine("\t\tif(item1 == null || index < 0 || index >= item1.Length)");
methodBuilder.AppendLine("\t\t\treturn default;");
methodBuilder.AppendLine("\t\treturn item1[index];");
methodBuilder.AppendLine("\t}");
}
// If it's a two-dimensional array
if(propertyType.Contains("[][]"))
{
//propertyType:int[][], Return value :int
string itemTypeStr1d = GetPropertyType(propertyType.Replace("[][]",""));
methodBuilder.AppendLine($"\tpublic {itemTypeStr1d} Get{itemNameStr}({idTypeStr});
methodBuilder.AppendLine("\t{");
methodBuilder.AppendLine($"\t\tvar item0 = Get{itemClassName}(id);");
methodBuilder.AppendLine("\t\tif(item0 == null)");
methodBuilder.AppendLine("\t\t\treturn default;");
methodBuilder.AppendLine($"\t\tvar item1 = item0.{propertyName};");
methodBuilder.AppendLine("\t\tif(item1 == null || index1 < 0 || index1 >= item1.Length)");
methodBuilder.AppendLine("\t\t\treturn default;");
methodBuilder.AppendLine("\t\tvar item2 = item1[index1];");
methodBuilder.AppendLine("\t\tif(item2.array == null || index2 < 0 || index2 >= item2.array.Length)");
methodBuilder.AppendLine("\t\t\treturn default;");
methodBuilder.AppendLine("\t\treturn item2.array[index2];");
methodBuilder.AppendLine("\t}");
}
//
return methodBuilder.ToString();
}

//----------

// Generate Asset Create a class
private static string CreateExcelAssetClass(ExcelMediumData excelMediumData)
{
string itemClassName = excelMediumData.excelName + "ExcelItem";
string dataClassName = excelMediumData.excelName + "ExcelData";
string assignmentClassName = excelMediumData.excelName + "AssetAssignment";

StringBuilder classSource = new StringBuilder();
classSource.AppendLine("#if UNITY_EDITOR");
// Class name
classSource.AppendLine($"public class {assignmentClassName}");
classSource.AppendLine("{");
// Method name
classSource.AppendLine("\tpublic static bool CreateAsset(ExcelMediumData excelMediumData, string excelAssetPath)");
// Method body , If necessary, you can join try/catch
classSource.AppendLine("\t{");
classSource.AppendLine("\t\tvar allRowItemDicList = excelMediumData.GetAllRowItemDicList();");
classSource.AppendLine("\t\tif(allRowItemDicList == null || allRowItemDicList.Count == 0)");
classSource.AppendLine("\t\t\treturn false;");
classSource.AppendLine();
classSource.AppendLine("\t\tint rowCount = allRowItemDicList.Count;");
classSource.AppendLine($"\t\t{dataClassName} excelDataAsset = ScriptableObject.CreateInstance<{dataClassName}>();");
classSource.AppendLine($"\t\texcelDataAsset.items = new {itemClassName}[rowCount];");
classSource.AppendLine();
classSource.AppendLine("\t\tfor(int i = 0; i < rowCount; i++)");
classSource.AppendLine("\t\t{");
classSource.AppendLine("\t\t\tvar itemRowDic = allRowItemDicList[i];");
classSource.AppendLine($"\t\t\texcelDataAsset.items[i] = new {itemClassName}();");

for(int i = 0; i < excelMediumData.propertyNameArray.Length; i++)
{
if(excelMediumData.annotationColList.Contains(i))
continue;
string propertyName = excelMediumData.propertyNameArray[i];
string propertyType = excelMediumData.propertyTypeArray[i];
classSource.Append($"\t\t\texcelDataAsset.items[i].{propertyName});
classSource.Append(AssignmentCodeProperty(propertyName,propertyType));
classSource.AppendLine(";");
}
classSource.AppendLine("\t\t}");
classSource.AppendLine("\t\tif(!Directory.Exists(excelAssetPath))");
classSource.AppendLine("\t\t\tDirectory.CreateDirectory(excelAssetPath);");
classSource.AppendLine($"\t\tstring fullPath = Path.Combine(excelAssetPath,typeof({dataClassName}).Name) + \".asset\";");
classSource.AppendLine("\t\tUnityEditor.AssetDatabase.DeleteAsset(fullPath);");
classSource.AppendLine("\t\tUnityEditor.AssetDatabase.CreateAsset(excelDataAsset,fullPath);");
classSource.AppendLine("\t\tUnityEditor.AssetDatabase.Refresh();");
classSource.AppendLine("\t\treturn true;");
classSource.AppendLine("\t}");
//
classSource.AppendLine("}");
classSource.AppendLine("#endif");
return classSource.ToString();
}

// Statement Asset Operation field
private static string AssignmentCodeProperty(string propertyName,string)
{
string stringValue = $"itemRowDic[\"{propertyName}\"]";
string typeStr = GetPropertyType(propertyType);
switch(typeStr)
{
// Field
case "int":
return "StringUtility.StringToInt(" + stringValue + ")";
case "float":
return "StringUtility.StringToFloat(" + stringValue + ")";
case "bool":
return "StringUtility.StringToBool(" + stringValue + ")";
case "Vector2":
return "StringUtility.StringToVector2(" + stringValue + ")";
case "Vector3":
return "StringUtility.StringToVector3(" + stringValue + ")";
case "Vector2Int":
return "StringUtility.StringToVector2Int(" + stringValue + ")";
case "Vector3Int":
return "StringUtility.StringToVector3Int(" + stringValue + ")";
case "Color":
return "StringUtility.StringToColor(" + stringValue + ")";
case "Color32":
return "StringUtility.StringToColor32(" + stringValue + ")";
case "string":
return stringValue;
// A one-dimensional
case "int[]":
return "StringUtility.StringToIntArray(" + stringValue + ")";
case "float[]":
return "StringUtility.StringToFloatArray(" + stringValue + ")";
case "bool[]":
return "StringUtility.StringToBoolArray(" + stringValue + ")";
case "Vector2[]":
return "StringUtility.StringToVector2Array(" + stringValue + ")";
case "Vector3[]":
return "StringUtility.StringToVector3Array(" + stringValue + ")";
case "Vector2Int[]":
return "StringUtility.StringToVector2IntArray(" + stringValue + ")";
case "Vector3Int[]":
return "StringUtility.StringToVector3IntArray(" + stringValue + ")";
case "Color[]":
return "StringUtility.StringToColorArray(" + stringValue + ")";
case "Color32[]":
return "StringUtility.StringToColor32Array(" + stringValue + ")";
case "string[]":
return "StringUtility.StringToStringArray(" + stringValue + ")";
// A two-dimensional
case "IntArr[]":
return "StringUtility.StringToIntArray2D(" + stringValue + ")";
case "FloatArr[]":
return "StringUtility.StringToFloatArray2D(" + stringValue + ")";
case "BoolArr[]":
return "StringUtility.StringToBoolArray2D(" + stringValue + ")";
case "Vector2Arr[]":
return "StringUtility.StringToVector2Array2D(" + stringValue + ")";
case "Vector3Arr[]":
return "StringUtility.StringToVector3Array2D(" + stringValue + ")";
case "Vector2IntArr[]":
return "StringUtility.StringToVector2IntArray2D(" + stringValue + ")";
case "Vector3IntArr[]":
return "StringUtility.StringToVector3IntArray2D(" + stringValue + ")";
case "ColorArr[]":
return "StringUtility.StringToColorArray2D(" + stringValue + ")";
case "Color32Arr[]":
return "StringUtility.StringToColor32Array2D(" + stringValue + ")";
case "StringArr[]":
return "StringUtility.StringToStringArray2D(" + stringValue + ")";
default:
// enumeration
if(propertyType.StartsWith("enum"))
{
string enumType = propertyType.Split('|').FirstOrDefault();
string enumName = propertyType.Split('|').LastOrDefault();
if(enumType == "enum")
return "StringUtility.StringToEnum<" + enumName + ">(" + stringValue + ")";
else if(enumType == "enum[]")
return "StringUtility.StringToEnumArray<" + enumName + ">(" + stringValue + ")";
else if(enumType == "enum[][]")
return "StringUtility.StringToEnumArray2D<" + enumName + ">(" + stringValue + ")";
}
return stringValue;
}
}

// Determine the field type
private static string GetPropertyType(string)
{
string lowerType = propertyType.ToLower();
switch(lowerType)
{
case "int":
return "int";
case "int[]":
return "int[]";
case "int[][]":
return "IntArr[]";
case "float":
return "float";
case "float[]":
return "float[]";
case "float[][]":
return "FloatArr[]";
case "bool":
return "bool";
case "bool[]":
return "bool[]";
case "bool[][]":
return "BoolArr[]";
case "string":
return "string";
case "string[]":
return "string[]";
case "string[][]":
return "StringArr[]";

case "vector2":
return "Vector2";
case "vector2[]":
return "Vector2[]";
case "vector2[][]":
return "Vector2Arr[]";
case "vector2int":
return "Vector2Int";
case "vector2int[]":
return "Vector2Int[]";
case "vector2int[][]":
return "Vector2IntArr[]";

case "vector3":
return "Vector3";
case "vector3[]":
return "Vector3[]";
case "vector3[][]":
return "Vector3Arr[]";
case "vector3int":
return "Vector3Int";
case "vector3int[]":
return "Vector3Int[]";
case "vector3int[][]":
return "Vector3IntArr[]";

case "color":
return "Color";
case "color[]":
return "Color[]";
case "color[][]":
return "ColorArr[]";
case "color32":
return "Color32";
case "color32[]":
return "Color32[]";
case "color32[][]":
return "Color32Arr[]";

default:
if(propertyType.StartsWith("enum"))
{
string enumType = propertyType.Split('|').FirstOrDefault();
string enumName = propertyType.Split('|').LastOrDefault();
switch(enumType)
{
case "enum":
return enumName;
case "enum[]":
return $"{enumName}[]";
case "enum[][]":
return $"EnumArr<{enumName}>[]";
default:
break;
}
}
return "string";
}
}

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.
  • 312.
  • 313.
  • 314.
  • 315.
  • 316.
  • 317.
  • 318.
  • 319.
  • 320.
  • 321.
  • 322.
  • 323.
  • 324.
  • 325.
  • 326.
  • 327.
  • 328.
  • 329.
  • 330.
  • 331.
  • 332.
  • 333.
  • 334.
  • 335.
  • 336.
  • 337.
  • 338.
  • 339.
  • 340.
  • 341.
  • 342.
  • 343.
  • 344.
  • 345.
  • 346.
  • 347.
  • 348.
  • 349.
  • 350.
  • 351.
  • 352.
  • 353.
  • 354.
  • 355.
  • 356.
  • 357.
  • 358.
  • 359.
  • 360.
  • 361.
  • 362.
  • 363.
  • 364.
  • 365.
  • 366.
  • 367.
  • 368.
  • 369.
  • 370.
  • 371.
  • 372.
  • 373.
  • 374.
  • 375.
  • 376.
  • 377.
  • 378.
  • 379.
  • 380.
  • 381.
  • 382.
  • 383.
  • 384.
  • 385.
  • 386.
  • 387.
  • 388.
  • 389.
  • 390.
  • 391.
  • 392.
  • 393.
  • 394.
  • 395.
  • 396.
  • 397.
  • 398.
  • 399.
  • 400.
  • 401.
  • 402.
  • 403.
  • 404.
  • 405.
  • 406.
  • 407.
  • 408.
  • 409.
  • 410.
  • 411.
  • 412.
  • 413.
  • 414.
  • 415.
  • 416.
  • 417.
  • 418.
  • 419.
  • 420.
  • 421.
  • 422.
  • 423.
  • 424.
  • 425.
  • 426.
  • 427.
  • 428.
  • 429.
  • 430.
  • 431.
  • 432.
  • 433.
  • 434.
  • 435.
  • 436.
  • 437.
  • 438.

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _unity_16

 Excel Data intermediate class :

      
      
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//Excel Intermediate data
public class ExcelMediumData
{
//Excel name
public string excelName;

//Excel Whether it works
public bool isValid = false;
// Whether to generate CSharp Data class
public bool isCreateCSharp = false;
// Whether to generate Asset Create a class
public bool isCreateAssignment = false;
// Whether to generate Asset file
public bool isCreateAsset = false;

// Data annotation
public string[] propertyNodeArray = null;
// Data name
public string[] propertyNameArray = null;
// data type
public string[] propertyTypeArray = null;
//List< Data content of each line >
public List<string[]> allRowItemList = new List<string[]>();

// Comment line number
public List<int> annotationRowList = new List<int>();
// Comment column number
public List<int> annotationColList = new List<int>();

//List< Each line of data >,List<Dictionary< Cell field name , Cell field value >>
public List<Dictionary<string,string>> GetAllRowItemDicList()
{
if(propertyNameArray == null || propertyNameArray.Length == 0)
return null;
if(allRowItemList.Count == 0)
return null;

List<Dictionary<string,string>> allRowItemDicList = new List<Dictionary<string,string>>(allRowItemList.Count);

for(int i = 0; i < allRowItemList.Count; i++)
{
string[] rowArray = allRowItemList[i];
// Skip empty data
if(rowArray == null || rowArray.Length == 0)
continue;
// Skip annotation data
if(annotationRowList.Contains(i))
continue;

// Each line of data , Corresponding field name and field value
Dictionary<string,string> rowDic = new Dictionary<string,string>();
for(int j = 0; j < propertyNameArray.Length; j++)
{
// Skip comment field
if(annotationColList.Contains(j))
continue;

string propertyName = propertyNameArray[j];
string propertyValue = j < rowArray.Length ? rowArray[j] : null;
rowDic[propertyName] = propertyValue;
}
allRowItemDicList.Add(rowDic);
}
return
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _excel_17

Excel Data base class 、 The extension class :

      
      
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System;

public class ExcelDataBase<T> : ScriptableObject where T : ExcelItemBase
{

}

public class ExcelItemBase
{

}


[Serializable]
public struct StringArr
{
public string[] array;
}
[Serializable]
public struct IntArr
{
public int[] array;
}
[Serializable]
public struct FloatArr
{
public float[] array;
}
[Serializable]
public struct BoolArr
{
public bool[] array;
}

[Serializable]
public struct Vector2Arr
{
public Vector2[] array;
}
[Serializable]
public struct Vector3Arr
{
public Vector3[] array;
}
[Serializable]
public struct Vector2IntArr
{
public Vector2Int[] array;
}
[Serializable]
public struct Vector3IntArr
{
public Vector3Int[] array;
}
[Serializable]
public struct ColorArr
{
public Color[] array;
}
[Serializable]
public struct Color32Arr
{
public Color32[] array;
}

//// Generic enumeration serialization is not supported
//[Serializable]
//public struct EnumArr<T> where T : Enum
//{
// public T[] array;
//}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _excel_18

String utility class :

      
      
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text.RegularExpressions;
using System;
using System.Text;
using System.Linq;
using System.Runtime.CompilerServices;

public static class StringUtility
{

#region

public static string AddColor(object)
{
return AddColor(obj,color);
}
public static string AddColor(this string)
{
// Convert the color to 16 Base string , Add to rich text
return string.Format("<color=#{0}>{1}</color>",ColorUtility.ToHtmlStringRGBA(color),str);
}
public static string AddColor(string str1,string)
{
return AddColor(str1 + str2,color);
}
public static string AddColor(string str1,string str2,string)
{
return AddColor(str1 + str2 + str3,color);
}

#endregion

#region

/// <summary>
///
/// </summary>
/// <param name="targetStr"></param>
/// <param name="targetLength"> Target length , English characters ==1, Chinese characters ==2</param>
/// <returns></returns>
public static string AbbrevStringWithinLength(string targetStr,int targetLength,string)
{
//C# Actual statistics : The length of a Chinese character ==1, English character length ==1
//UI Display requirements : The length of a Chinese character ==2, English character length ==1

// Calibration parameters
if(string.IsNullOrEmpty(targetStr) || targetLength <= 0)
return targetStr;
// String length * 2 <= Target length , Even if it is all Chinese, it is within the length range
if(targetStr.Length * 2 <= targetLength)
return targetStr;
// Traversal character
char[] chars = targetStr.ToCharArray();
int curLen = 0;
for(int i = 0; i < chars.Length; i++)
{
// Accumulate string length
if(chars[i] >= 0x4e00 && chars[i] <= 0x9fbb)
curLen += 2;
else
curLen += 1;

// If the cumulative length of the current position exceeds the target length , take 0~i-1, namely Substring(0,i)
if(curLen > targetLength)
return targetStr.Substring(0,i) + abbrevPostfix;
}
return targetStr;
}

#endregion

#region

//string

public static byte StringToByte(string)
{
byte value;
if(byte.TryParse(valueStr,out value))
return value;
else
return 0;
}

public static string[] StringToStringArray(string valueStr,char splitSign = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
return valueStr.Split(splitSign);
}

public static StringArr[] StringToStringArray2D(string valueStr,char splitSign1 = '&',char splitSign2 = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
string[] strArr1 = valueStr.Split(splitSign1);
if(strArr1.Length == 0)
return null;

StringArr[] arrArr = new StringArr[strArr1.Length];
for(int i = 0; i < strArr1.Length; i++)
{
arrArr[i] = new StringArr()
{
array = strArr1[i].Split(splitSign2)
};

}
return arrArr;
}

//int

public static int StringToInt(string)
{
int value;
if(int.TryParse(valueStr,out value))
return value;
else
return 0;
}

public static int[] StringToIntArray(string valueStr,char splitSign = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;

string[] valueArr = valueStr.Split(splitSign);
if(valueArr == null || valueArr.Length == 0)
return null;

int[] intArr = new int[valueArr.Length];
for(int i = 0; i < valueArr.Length; i++)
{
intArr[i] = StringToInt(valueArr[i]);
}
return intArr;
}

public static IntArr[] StringToIntArray2D(string valueStr,char splitSign1 = '&',char splitSign2 = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
string[] strArr1 = valueStr.Split(splitSign1);
if(strArr1.Length == 0)
return null;

IntArr[] arrArr = new IntArr[strArr1.Length];
for(int i = 0; i < strArr1.Length; i++)
{
arrArr[i] = new IntArr()
{
array = StringToIntArray(strArr1[i],splitSign2)
};

}
return arrArr;
}

//float

public static float StringToFloat(string)
{
float value;
if(float.TryParse(valueStr,out value))
return value;
else
return 0;
}

public static float[] StringToFloatArray(string valueStr,char splitSign = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;

string[] valueArr = valueStr.Split(splitSign);
if(valueArr == null || valueArr.Length == 0)
return null;

float[] floatArr = new float[valueArr.Length];
for(int i = 0; i < valueArr.Length; i++)
{
floatArr[i] = StringToFloat(valueArr[i]);
}
return floatArr;
}

public static FloatArr[] StringToFloatArray2D(string valueStr,char splitSign1 = '&',char splitSign2 = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
string[] strArr1 = valueStr.Split(splitSign1);
if(strArr1.Length == 0)
return null;

FloatArr[] arrArr = new FloatArr[strArr1.Length];
for(int i = 0; i < strArr1.Length; i++)
{
arrArr[i] = new FloatArr()
{
array = StringToFloatArray(strArr1[i],splitSign2)
};

}
return arrArr;
}

//bool

public static bool StringToBool(string)
{
bool value;
if(bool.TryParse(valueStr,out value))
return value;
else
return false;
}

public static bool[] StringToBoolArray(string valueStr,char splitSign = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;

string[] valueArr = valueStr.Split(splitSign);
if(valueArr == null || valueArr.Length == 0)
return null;

bool[] boolArr = new bool[valueArr.Length];
for(int i = 0; i < valueArr.Length; i++)
{
boolArr[i] = StringToBool(valueArr[i]);
}
return boolArr;
}

public static BoolArr[] StringToBoolArray2D(string valueStr,char splitSign1 = '&',char splitSign2 = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
string[] strArr1 = valueStr.Split(splitSign1);
if(strArr1.Length == 0)
return null;

BoolArr[] arrArr = new BoolArr[strArr1.Length];
for(int i = 0; i < strArr1.Length; i++)
{
arrArr[i] = new BoolArr()
{
array = StringToBoolArray(strArr1[i],splitSign2)
};

}
return arrArr;
}

//enum

public static T StringToEnum<T>(string) where
{
if(string.IsNullOrEmpty(valueStr))
return (T)default;

// First verify whether the string is an enumeration value
int intValue;
if(int.TryParse(valueStr,out intValue))
{
if(Enum.IsDefined(typeof(T),intValue))
return (T)Enum.ToObject(typeof(T),intValue);
}
// If it is not an enumerated value , Treat as enum name
try
{
T t = (T)Enum.Parse(typeof(T),valueStr);
if(Enum.IsDefined(typeof(T),t))
return t;
}
catch(Exception e)
{
Debug.LogError(e);
}
Debug.LogError(string.Format(" Parsing enumeration error {0} : {1}",typeof(T),valueStr));
return (T)default;
}

public static T[] StringToEnumArray<T>(string valueStr,char splitSign = '|') where
{
if(string.IsNullOrEmpty(valueStr))
return null;

string[] valueArr = valueStr.Split(splitSign);
if(valueArr == null || valueArr.Length == 0)
return null;

T[] enumArr = new T[valueArr.Length];
for(int i = 0; i < valueArr.Length; i++)
{
enumArr[i] = StringToEnum<T>(valueArr[i]);
}
return enumArr;
}

//// Generic enumeration serialization is not supported
//public static EnumArr<T>[] StringToEnumArray2D<T>(string valueStr,char splitSign1 = '&',char splitSign2 = '|') where T : Enum
//{
// if(string.IsNullOrEmpty(valueStr))
// return null;
// string[] strArr1 = valueStr.Split(splitSign1);
// if(strArr1.Length == 0)
// return null;

// EnumArr<T>[] arrArr = new EnumArr<T>[strArr1.Length];
// for(int i = 0; i < strArr1.Length; i++)
// {
// arrArr[i] = new EnumArr<T>()
// {
// array = StringToEnumArray<T>(strArr1[i],splitSign2)
// };

// }
// return arrArr;
//}

//vector2

public static Vector2 StringToVector2(string valueStr,char splitSign = ',')
{
Vector2 value = Vector2.zero;
if(!string.IsNullOrEmpty(valueStr))
{
string[] stringArray = valueStr.Split(splitSign);
if(stringArray != null && stringArray.Length >= 2)
{
value.x = StringToFloat(stringArray[0]);
value.y = StringToFloat(stringArray[1]);
return value;
}
}
Debug.LogWarning("String to Vector2 error");
return value;
}

public static Vector2[] StringToVector2Array(string valueStr,char splitSign = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;

string[] stringArray = valueStr.Split(splitSign);
if(stringArray == null || stringArray.Length == 0)
return null;

Vector2[] vector2s = new Vector2[stringArray.Length];
for(int i = 0; i < stringArray.Length; i++)
{
vector2s[i] = StringToVector2(stringArray[i]);
}
return vector2s;
}

public static Vector2Arr[] StringToVector2Array2D(string valueStr,char splitSign1 = '&',char splitSign2 = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
string[] strArr1 = valueStr.Split(splitSign1);
if(strArr1.Length == 0)
return null;

Vector2Arr[] arrArr = new Vector2Arr[strArr1.Length];
for(int i = 0; i < strArr1.Length; i++)
{
arrArr[i] = new Vector2Arr()
{
array = StringToVector2Array(strArr1[i],splitSign2)
};
}
return arrArr;
}

//vector3

public static Vector3 StringToVector3(string valueStr,char splitSign = ',')
{
Vector3 value = Vector3.zero;
if(!string.IsNullOrEmpty(valueStr))
{
string[] stringArray = valueStr.Split(splitSign);
if(stringArray.Length >= 3)
{
value.x = StringToFloat(stringArray[0]);
value.y = StringToFloat(stringArray[1]);
value.z = StringToFloat(stringArray[2]);
return value;
}
}
Debug.LogWarning("String to Vector3 error");
return value;
}

public static Vector3[] StringToVector3Array(string valueStr,char splitSign = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;

string[] stringArray = valueStr.Split(splitSign);
if(stringArray == null || stringArray.Length == 0)
return null;

Vector3[] vector3s = new Vector3[stringArray.Length];
for(int i = 0; i < stringArray.Length; i++)
{
vector3s[i] = StringToVector3(stringArray[i]);
}
return vector3s;
}

public static Vector3Arr[] StringToVector3Array2D(string valueStr,char splitSign1 = '&',char splitSign2 = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
string[] strArr1 = valueStr.Split(splitSign1);
if(strArr1.Length == 0)
return null;

Vector3Arr[] arrArr = new Vector3Arr[strArr1.Length];
for(int i = 0; i < strArr1.Length; i++)
{
arrArr[i] = new Vector3Arr()
{
array = StringToVector3Array(strArr1[i],splitSign2)
};
}
return arrArr;
}

//vector2Int

public static Vector2Int StringToVector2Int(string valueStr,char splitSign = ',')
{
Vector2Int value = Vector2Int.zero;
if(!string.IsNullOrEmpty(valueStr))
{
string[] stringArray = valueStr.Split(splitSign);
if(stringArray != null && stringArray.Length >= 2)
{
value.x = StringToInt(stringArray[0]);
value.y = StringToInt(stringArray[1]);
return value;
}
}
Debug.LogWarning("String to Vector2Int error");
return value;
}

public static Vector2Int[] StringToVector2IntArray(string valueStr,char splitSign = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;

string[] stringArray = valueStr.Split(splitSign);
if(stringArray == null || stringArray.Length == 0)
return null;

Vector2Int[] vector2Ints = new Vector2Int[stringArray.Length];
for(int i = 0; i < stringArray.Length; i++)
{
vector2Ints[i] = StringToVector2Int(stringArray[i]);
}
return vector2Ints;
}

public static Vector2IntArr[] StringToVector2IntArray2D(string valueStr,char splitSign1 = '&',char splitSign2 = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
string[] strArr1 = valueStr.Split(splitSign1);
if(strArr1.Length == 0)
return null;

Vector2IntArr[] arrArr = new Vector2IntArr[strArr1.Length];
for(int i = 0; i < strArr1.Length; i++)
{
arrArr[i] = new Vector2IntArr()
{
array = StringToVector2IntArray(strArr1[i],splitSign2)
};
}
return arrArr;
}

//vector3Int

public static Vector3Int StringToVector3Int(string valueStr,char splitSign = ',')
{
Vector3Int value = Vector3Int.zero;
if(!string.IsNullOrEmpty(valueStr))
{
string[] stringArray = valueStr.Split(splitSign);
if(stringArray.Length >= 3)
{
value.x = StringToInt(stringArray[0]);
value.y = StringToInt(stringArray[1]);
value.z = StringToInt(stringArray[2]);
return value;
}
}
Debug.LogWarning("String to Vector3 error");
return value;
}

public static Vector3Int[] StringToVector3IntArray(string valueStr,char splitSign = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;

string[] stringArray = valueStr.Split(splitSign);
if(stringArray == null || stringArray.Length == 0)
return null;

Vector3Int[] vector3Ints = new Vector3Int[stringArray.Length];
for(int i = 0; i < stringArray.Length; i++)
{
vector3Ints[i] = StringToVector3Int(stringArray[i]);
}
return vector3Ints;
}

public static Vector3IntArr[] StringToVector3IntArray2D(string valueStr,char splitSign1 = '&',char splitSign2 = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
string[] strArr1 = valueStr.Split(splitSign1);
if(strArr1.Length == 0)
return null;

Vector3IntArr[] arrArr = new Vector3IntArr[strArr1.Length];
for(int i = 0; i < strArr1.Length; i++)
{
arrArr[i] = new Vector3IntArr()
{
array = StringToVector3IntArray(strArr1[i],splitSign2)
};
}
return arrArr;
}

//color

public static Color StringToColor(string valueStr,char splitSign = ',')
{
if(string.IsNullOrEmpty(valueStr))
return Color.white;

string[] stringArray = valueStr.Split(splitSign);
if(stringArray.Length < 3)
return Color.white;

Color color = new Color()
{
r = StringToFloat(stringArray[0]),
g = StringToFloat(stringArray[1]),
b = StringToFloat(stringArray[2]),
a = stringArray.Length < 4 ? 1 : StringToFloat(stringArray[3])
};
return color;
}
public static Color32 StringToColor32(string valueStr,char splitSign = ',')
{
if(string.IsNullOrEmpty(valueStr))
return Color.white;

string[] stringArray = valueStr.Split(splitSign);
if(stringArray.Length < 3)
return Color.white;

Color32 color = new Color32()
{
r = StringToByte(stringArray[0]),
g = StringToByte(stringArray[1]),
b = StringToByte(stringArray[2]),
a = stringArray.Length < 4 ? (byte)1 : StringToByte(stringArray[3])
};
return color;
}

public static Color[] StringToColorArray(string valueStr,char splitSign = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;

string[] stringArray = valueStr.Split(splitSign);
if(stringArray == null || stringArray.Length == 0)
return null;

Color[] colors = new Color[stringArray.Length];
for(int i = 0; i < stringArray.Length; i++)
{
colors[i] = StringToColor(stringArray[i]);
}
return colors;
}

public static Color32[] StringToColor32Array(string valueStr,char splitSign = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;

string[] stringArray = valueStr.Split(splitSign);
if(stringArray == null || stringArray.Length == 0)
return null;

Color32[] colors = new Color32[stringArray.Length];
for(int i = 0; i < stringArray.Length; i++)
{
colors[i] = StringToColor32(stringArray[i]);
}
return colors;
}

public static ColorArr[] StringToColorArray2D(string valueStr,char splitSign1 = '&',char splitSign2 = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
string[] strArr1 = valueStr.Split(splitSign1);
if(strArr1.Length == 0)
return null;

ColorArr[] arrArr = new ColorArr[strArr1.Length];
for(int i = 0; i < strArr1.Length; i++)
{
arrArr[i] = new ColorArr()
{
array = StringToColorArray(strArr1[i],splitSign2)
};
}
return arrArr;
}
public static Color32Arr[] StringToColor32Array2D(string valueStr,char splitSign1 = '&',char splitSign2 = '|')
{
if(string.IsNullOrEmpty(valueStr))
return null;
string[] strArr1 = valueStr.Split(splitSign1);
if(strArr1.Length == 0)
return null;

Color32Arr[] arrArr = new Color32Arr[strArr1.Length];
for(int i = 0; i < strArr1.Length; i++)
{
arrArr[i] = new Color32Arr()
{
array = StringToColor32Array(strArr1[i],splitSign2)
};
}
return arrArr;
}

#endregion

#region

public static string GetRandomString(int)
{
StringBuilder builder = new StringBuilder();
string abc = "abcdefghijklmnopqrstuvwxyzo0123456789QWERTYUIOPASDFGHJKLZXCCVBMN";
for(int i = 0; i < length; i++)
{
builder.Append(abc[UnityEngine.Random.Range(0,abc.Length - 1)]);
}
return builder.ToString();
}

public static string Join<T>(T[] arr,string join = ",")
{
if(arr == null || arr.Length == 0)
return null;

StringBuilder builder = new StringBuilder();
for(int i = 0; i < arr.Length; i++)
{
builder.Append(arr[i]);
if(i < arr.Length - 1)
builder.Append(join);
}
return builder.ToString();
}

/// <summary>
///
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string ToDBC(string)
{
char[] c = input.ToCharArray();
for(int i = 0; i < c.Length; i++)
{
if(c[i] == 12288)
{
c[i] = (char)32;
continue;
}
if(c[i] > 65280 && c[i] < 65375)
c[i] = (char)(c[i] - 65248);
}
return new string(c);
}

/// <summary>
///
/// </summary>
/// <param name="character"></param>
/// <returns></returns>
public static int Asc(string)
{
if(character.Length == 1)
{
System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
int intAsciiCode = (int)asciiEncoding.GetBytes(character)[0];
return (intAsciiCode);
}
Debug.LogError("Character is not valid.");
return -1;
}

/// <summary>
///
/// </summary>
/// <param name="asciiCode"></param>
/// <returns></returns>
public static string Chr(int)
{
if(asciiCode >= 0 && asciiCode <= 255)
{
System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
byte[] byteArray = new byte[] { (byte)asciiCode };
string strCharacter = asciiEncoding.GetString(byteArray);
return (strCharacter);
}
Debug.LogError("ASCII Code is not valid.");
return string.Empty;
}

/// <summary>
///
/// </summary>
/// <returns>The emoji.</returns>
/// <param name="str">String.</param>
public static string FilterEmoji(string)
{
List<string> patten = new List<string>() { @"\p{Cs}",@"\p{Co}",@"\p{Cn}",@"[\u2702-\u27B0]" };
for(int i = 0; i < patten.Count; i++)
{
str = Regex.Replace(str,patten[i],"");// shielding emoji
}
return str;
}

/// <summary>
///
/// </summary>
/// <returns>The emoji.</returns>
/// <param name="str">String.</param>
public static bool IsFilterEmoji(string)
{
bool bEmoji = false;
List<string> patten = new List<string>() { @"\p{Cs}",@"\p{Co}",@"\p{Cn}",@"[\u2702-\u27B0]" };
for(int i = 0; i < patten.Count; i++)
{
bEmoji = Regex.IsMatch(str,patten[i]);
if(bEmoji)
{
break;
}
}
return bEmoji;
}

#endregion

#region

/// <summary>
///
/// </summary>
/// <param name="dic"></param>
/// <param name="prefix"> Prefix , It can be an empty reference or an empty string , Means there is no prefix .</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IEnumerable<IGrouping<string,(string, object)>> GetValuesWithoutPrefix(this IReadOnlyDictionary<string,object> dic,string prefix = null)
{
//prefix ??= string.Empty;
prefix = prefix ?? string.Empty;

var coll = from tmp in dic.Where(c => c.Key.StartsWith(prefix)) // Only for the key value of the specified prefix
let p3 = tmp.Key.Get3Segment(prefix)
group (p3.Item2, tmp.Value) by p3.Item3;
return coll;
}

/// <summary>
///
/// </summary>
/// <param name="str"></param>
/// <param name="prefix"> Prefix , It can be an empty reference or an empty string , Means there is no prefix .</param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (string, string, string) Get3Segment(this string str,string prefix = null)
{
//prefix ??= string.Empty;
prefix = prefix ?? string.Empty;

// The length of the last decimal digit tail string
int suffixLen = Enumerable.Reverse(str).TakeWhile(c => char.IsDigit(c)).Count();
// Get decimal digit suffix
//string suufix = str[^suffixLen..]; //^suffixLen: Reverse subscript ;suffixLen..: From the specified position to the end
string suufix = str.Substring(str.Length - suffixLen);

//return (prefix, str[prefix.Length..^suufix.Length], suufix);
string middle = str.Substring(prefix.Length,str.Length - prefix.Length - suufix.Length);
return (prefix, middle, suufix);
}

#endregion
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.
  • 312.
  • 313.
  • 314.
  • 315.
  • 316.
  • 317.
  • 318.
  • 319.
  • 320.
  • 321.
  • 322.
  • 323.
  • 324.
  • 325.
  • 326.
  • 327.
  • 328.
  • 329.
  • 330.
  • 331.
  • 332.
  • 333.
  • 334.
  • 335.
  • 336.
  • 337.
  • 338.
  • 339.
  • 340.
  • 341.
  • 342.
  • 343.
  • 344.
  • 345.
  • 346.
  • 347.
  • 348.
  • 349.
  • 350.
  • 351.
  • 352.
  • 353.
  • 354.
  • 355.
  • 356.
  • 357.
  • 358.
  • 359.
  • 360.
  • 361.
  • 362.
  • 363.
  • 364.
  • 365.
  • 366.
  • 367.
  • 368.
  • 369.
  • 370.
  • 371.
  • 372.
  • 373.
  • 374.
  • 375.
  • 376.
  • 377.
  • 378.
  • 379.
  • 380.
  • 381.
  • 382.
  • 383.
  • 384.
  • 385.
  • 386.
  • 387.
  • 388.
  • 389.
  • 390.
  • 391.
  • 392.
  • 393.
  • 394.
  • 395.
  • 396.
  • 397.
  • 398.
  • 399.
  • 400.
  • 401.
  • 402.
  • 403.
  • 404.
  • 405.
  • 406.
  • 407.
  • 408.
  • 409.
  • 410.
  • 411.
  • 412.
  • 413.
  • 414.
  • 415.
  • 416.
  • 417.
  • 418.
  • 419.
  • 420.
  • 421.
  • 422.
  • 423.
  • 424.
  • 425.
  • 426.
  • 427.
  • 428.
  • 429.
  • 430.
  • 431.
  • 432.
  • 433.
  • 434.
  • 435.
  • 436.
  • 437.
  • 438.
  • 439.
  • 440.
  • 441.
  • 442.
  • 443.
  • 444.
  • 445.
  • 446.
  • 447.
  • 448.
  • 449.
  • 450.
  • 451.
  • 452.
  • 453.
  • 454.
  • 455.
  • 456.
  • 457.
  • 458.
  • 459.
  • 460.
  • 461.
  • 462.
  • 463.
  • 464.
  • 465.
  • 466.
  • 467.
  • 468.
  • 469.
  • 470.
  • 471.
  • 472.
  • 473.
  • 474.
  • 475.
  • 476.
  • 477.
  • 478.
  • 479.
  • 480.
  • 481.
  • 482.
  • 483.
  • 484.
  • 485.
  • 486.
  • 487.
  • 488.
  • 489.
  • 490.
  • 491.
  • 492.
  • 493.
  • 494.
  • 495.
  • 496.
  • 497.
  • 498.
  • 499.
  • 500.
  • 501.
  • 502.
  • 503.
  • 504.
  • 505.
  • 506.
  • 507.
  • 508.
  • 509.
  • 510.
  • 511.
  • 512.
  • 513.
  • 514.
  • 515.
  • 516.
  • 517.
  • 518.
  • 519.
  • 520.
  • 521.
  • 522.
  • 523.
  • 524.
  • 525.
  • 526.
  • 527.
  • 528.
  • 529.
  • 530.
  • 531.
  • 532.
  • 533.
  • 534.
  • 535.
  • 536.
  • 537.
  • 538.
  • 539.
  • 540.
  • 541.
  • 542.
  • 543.
  • 544.
  • 545.
  • 546.
  • 547.
  • 548.
  • 549.
  • 550.
  • 551.
  • 552.
  • 553.
  • 554.
  • 555.
  • 556.
  • 557.
  • 558.
  • 559.
  • 560.
  • 561.
  • 562.
  • 563.
  • 564.
  • 565.
  • 566.
  • 567.
  • 568.
  • 569.
  • 570.
  • 571.
  • 572.
  • 573.
  • 574.
  • 575.
  • 576.
  • 577.
  • 578.
  • 579.
  • 580.
  • 581.
  • 582.
  • 583.
  • 584.
  • 585.
  • 586.
  • 587.
  • 588.
  • 589.
  • 590.
  • 591.
  • 592.
  • 593.
  • 594.
  • 595.
  • 596.
  • 597.
  • 598.
  • 599.
  • 600.
  • 601.
  • 602.
  • 603.
  • 604.
  • 605.
  • 606.
  • 607.
  • 608.
  • 609.
  • 610.
  • 611.
  • 612.
  • 613.
  • 614.
  • 615.
  • 616.
  • 617.
  • 618.
  • 619.
  • 620.
  • 621.
  • 622.
  • 623.
  • 624.
  • 625.
  • 626.
  • 627.
  • 628.
  • 629.
  • 630.
  • 631.
  • 632.
  • 633.
  • 634.
  • 635.
  • 636.
  • 637.
  • 638.
  • 639.
  • 640.
  • 641.
  • 642.
  • 643.
  • 644.
  • 645.
  • 646.
  • 647.
  • 648.
  • 649.
  • 650.
  • 651.
  • 652.
  • 653.
  • 654.
  • 655.
  • 656.
  • 657.
  • 658.
  • 659.
  • 660.
  • 661.
  • 662.
  • 663.
  • 664.
  • 665.
  • 666.
  • 667.
  • 668.
  • 669.
  • 670.
  • 671.
  • 672.
  • 673.
  • 674.
  • 675.
  • 676.
  • 677.
  • 678.
  • 679.
  • 680.
  • 681.
  • 682.
  • 683.
  • 684.
  • 685.
  • 686.
  • 687.
  • 688.
  • 689.
  • 690.
  • 691.
  • 692.
  • 693.
  • 694.
  • 695.
  • 696.
  • 697.
  • 698.
  • 699.
  • 700.
  • 701.
  • 702.
  • 703.
  • 704.
  • 705.
  • 706.
  • 707.
  • 708.
  • 709.
  • 710.
  • 711.
  • 712.
  • 713.
  • 714.
  • 715.
  • 716.
  • 717.
  • 718.
  • 719.
  • 720.
  • 721.
  • 722.
  • 723.
  • 724.
  • 725.
  • 726.
  • 727.
  • 728.
  • 729.
  • 730.
  • 731.
  • 732.
  • 733.
  • 734.
  • 735.
  • 736.
  • 737.
  • 738.
  • 739.
  • 740.
  • 741.
  • 742.
  • 743.
  • 744.
  • 745.
  • 746.
  • 747.
  • 748.
  • 749.
  • 750.
  • 751.
  • 752.
  • 753.
  • 754.
  • 755.
  • 756.
  • 757.
  • 758.
  • 759.
  • 760.
  • 761.
  • 762.
  • 763.
  • 764.
  • 765.
  • 766.
  • 767.
  • 768.
  • 769.
  • 770.
  • 771.
  • 772.
  • 773.
  • 774.
  • 775.
  • 776.
  • 777.
  • 778.
  • 779.
  • 780.
  • 781.
  • 782.
  • 783.
  • 784.
  • 785.
  • 786.
  • 787.
  • 788.
  • 789.
  • 790.
  • 791.
  • 792.
  • 793.
  • 794.
  • 795.
  • 796.
  • 797.
  • 798.
  • 799.
  • 800.
  • 801.
  • 802.
  • 803.
  • 804.
  • 805.
  • 806.
  • 807.
  • 808.
  • 809.
  • 810.
  • 811.
  • 812.
  • 813.
  • 814.
  • 815.
  • 816.
  • 817.
  • 818.
  • 819.
  • 820.
  • 821.
  • 822.

【Unity】 Upgraded version ·Excel Data analysis , Automatically create corresponding C# class , Automatically create ScriptableObject Generating classes , Automatic serialization Asset file _ Game development _19


原网站

版权声明
本文为[51CTO]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207061833046210.html