Unity Assembly Def

Unity默认程序集和自定义程序集在编辑器模式下都生成在“盘符:\Unity工程文件夹\Library\ScriptAssemblies”里

使用Unity的自定义程序集时,定义的程序集并没有真正生成一个库,不能使用using指令来引用其他的程序集。我们需要在程序集定义的Inspector面板中的“References”里面添加依赖,按下加号然后将需要引用的dll拖拽进来。

Unity默认CSharp.dll自动引用所有程序集。

Unity真正编译出来的程序集名和程序集定义的Inspector面板中的“Name”一致,尽量让Editor内程序集定义文件名和Inspector面板中的一致。

如果程序集定义中勾选了“Test Assemblies”,那么此程序集内的代码都不会被打包,可以利用此功能将需要测试的代码和拓展编辑器的代码放在Test程序集里。

Unity资源加载方式

AssetBundle

首先将需要加载的Prefab设定一个AssetBundle名称,然后在Editor文件夹内设定编辑器脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;
using UnityEditor;

public class BundleEditor
{
[MenuItem("Tools/Build AssetBundle")]
public static void Build()
{
BuildPipeline.BuildAssetBundles
(
Application.streamingAssetsPath,//注意要在编辑器环境下新建StreamingAssets文件夹
BuildAssetBundleOptions.ChunkBasedCompression,
EditorUserBuildSettings.activeBuildTarget
);

AssetDatabase.Refresh();
}

}

这样在编辑器的StreamingAssets文件夹内就出现的打包好的Asset Bundle了,注意StreamingAssets文件夹内的文件都是不能直接查看的,我们生成的文件一般有同名的两份,一份是主要的AssetBundle,另一份则是此Bundle的Manifest,记录了此Bundle的依赖关系

我们按照下面的代码加载AssetBundle

1
2
3
4
5
6
7
8
9
10
11
12
using UnityEngine;

public class ResourceTest : MonoBehaviour
{
void Start()
{
AssetBundle assetbundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/attack");
GameObject objPrefab = assetbundle.LoadAsset<GameObject>("attack");
GameObject obj = Instantiate(objPrefab);
}
}

AssetDataBase

这是一个编辑器API,加载资源时需要Assets文件夹内完整路径名和文件拓展名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using UnityEditor;
using UnityEngine;

public class ResourceTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{

GameObject objPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Prefabs/Attack.prefab");
}

}

XML序列化

将类转化成Xml

使用xml特性标记相关的类,更方便地序列化

新建一个用于序列化的类TestSerialize

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System.Collections.Generic;
using System.Xml.Serialization;

[System.Serializable]
public class TestSerialize
{
[XmlAttribute("Id")]
public int Id { get; set; }

[XmlAttribute("Name")]
public string Name { get; set; }

[XmlElement("Items")]//也可以使用[XmlArray("Items")]
public List<int> Items { get; set; }
}

我们在脚本中序列化这个类

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
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Xml.Serialization;

public class ResourceTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//AssetBundle assetbundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/attack");
//GameObject objPrefab = assetbundle.LoadAsset<GameObject>("attack");
//GameObject obj = Instantiate(objPrefab);
SerializeTest();
}

void SerializeTest()
{
TestSerialize testSerialize = new TestSerialize
{
Id = 1,
Name = "test",
Items = new List<int>(3) { 1, 2, 2 }
};

using(FileStream fs = new FileStream(Application.dataPath + "/test.xml", FileMode.Create, FileAccess.ReadWrite,FileShare.ReadWrite))//使用文件流
{
using(StreamWriter sw = new StreamWriter(fs,System.Text.Encoding.UTF8))//使用写入流
{
XmlSerializer xml = new XmlSerializer(typeof(TestSerialize));//使用序列化器
xml.Serialize(sw,testSerialize);
}
}
}
}

生成的文件

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<TestSerialize xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Id="1" Name="test">
<Items>1</Items>
<Items>2</Items>
<Items>2</Items>
</TestSerialize>

反序列化

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
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Xml.Serialization;

public class ResourceTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//...
DeserializeTest();
}

//...
void DeserializeTest()
{
var test = XmlDeSerilize<TestSerialize>(Application.dataPath + "/test.xml");
Debug.Log(test.Id + " " + test.Name);
}
T XmlDeSerilize<T>(string path) where T : class
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
XmlSerializer xs = new XmlSerializer(typeof(T));
var result = xs.Deserialize(fs) as T;
return result;
}
}
}

二进制序列化

将类转化成二进制

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
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

public class ResourceTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{

SerializeTest();
}

void SerializeTest()
{
TestSerialize testSerialize = new TestSerialize
{
Id = 1,
Name = "test",
Items = new List<int>(3) { 1, 2, 2 }
};

BinarySerialize(testSerialize);
}

void BinarySerialize(TestSerialize testSerialize)
{
using(FileStream fs = new FileStream(Application.dataPath + "/test.bytes",FileMode.Create,FileAccess.ReadWrite, FileShare.ReadWrite))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, testSerialize);
}
}
}

反序列化二进制文件

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
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

public class ResourceTest : MonoBehaviour
{

void Start()
{
DeserializeTest();
}

void DeserializeTest()
{
var test = BinaryDeserialize();
Debug.Log(test.Id + " " + test.Name);
}

TestSerialize BinaryDeserialize()
{
TextAsset textAsset = UnityEditor.AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/test.bytes");
using(MemoryStream ms = new MemoryStream(textAsset.bytes))
{
BinaryFormatter bf = new BinaryFormatter();
TestSerialize result = (TestSerialize)bf.Deserialize(ms);
return result;
}
}
}

注意二进制文件的拓展名一定要为“bytes”,否则TextAsset类无法读取内容