使用版本为VS2017+Unity2017.4.10
-----------------------------------------------------------第一次写博客,大佬们见谅= = ----------------------------------------------------
注意:在写类库的时候先在你的Unity里面写好,在封装起来,否则你会很头疼的,相信我
首先打开VS,新建一个类库,注意.Net Framewark版本不要高于你的Unity上限
如果在创建类库的时候没有注意到.net版本 则右键Vs里面你的项目名称=>属性=>将目标框架修改为3.5或以下
同时-在生成选项中勾选生成XML,这个是文档注释文件,如果没有勾选此选项,则生成之后按F12查看方法时会没有相应注释
-------------------------------------------------正文---------------------------------------------------
注意:我们新建的是一个类库,里面没有Main方法,没有程序入口,只是单纯的一个类库
1: 首先添加你需要的引用 ,其中Unity相关的 dll 位置是在=>C:\Program Files\Unity\Editor\Data\Managed\ 这个位置
:2:双击你的代码文件,添加相关using 此时我们会看到一个 namespace 不要去修改他,因为你在其他时候调用的时候需要用到 using XXXX; XXXX 就是namespace;
现在,先写一段测试代码
using System;
using UnityEngine;
using Newtonsoft.json;
namespace Test
{
public static class test
{
/// <summary>
/// 测试类
/// </summary>
public static string printStr(string str)
{
return str + ":hello world";
}
}
}
上方,点击生成=>找到你的bin文件夹生成的相应Dll,将Newtonsoft.Json.dll,Test.dll,Test.XML拖到unity的Assets/Plugins文件夹之中(注:这个文件夹是自己创建的)
此时,当你打开Test.xml时就会发现,里面就是我们刚才所写的 ///测试类 这个注释,这个相应的XML会动态解析到你的类中,只要相应的DLL和XML在同一文件夹下
现在,让我们在Unity里面也写一个测试例子,
using UnityEngine;
using Test;
class Test
{
///不要惊讶 Unity里面真有这个方法 自动执行的 顺序是在OnEnable和Start之间
public void Main()
{
Debug.Log(Test.print("Ling"));
}
}
不出意外的话,运行之后你就会看到 Ling: hello world 这个输出
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
但是我们可不会因为这些小事就费劲心力的去封装一个类库啊,我们需要的是封装一套明明逻辑不复杂,但是还要我每次都写一遍的那种, SO ↓
改装一下刚才的代码
using System;
using UnityEngine;
using Newtonsoft.json;
namespace Test
{
public static class test
{
/// <summary>
/// 测试类
/// </summary>
public static string printStr(string str)
{
return str + ":hello world";
}
public static string SerObjJson(object obj)
{
JsonConvert.SerializeObject(obj); // Newtonsoft.json里面的方法,将Obj转为Json
}
public static T DeSerObj<T>(string json)
{
T t = Defaule(T);
t = JsonConvert.DeSerializeObject(json); //将Json转换为<T>Obj
return t;
}
}
}
这几句比较简单,注释里有相关解释
再次更改 ,这里首先我们需要知道扩展方法
public static T ExtendObj<T>(this object obj)
{
///操作
return JsonConvert.SerializeObject(obj);
}
///调用的时候就可以
object obj = null;
string str = obj.ExtendObj<string>();
using System;
using UnityEngine;
using Newtonsoft.json;
namespace Test
{
public static class test
{
/// <summary>
/// 测试类
/// </summary>
public static string printStr(string str)
{
return str + ":hello world";
}
public static string SerObjJson(object obj)
{
// Newtonsoft.json里面的方法,将Obj转为Json
JsonConvert.SerializeObject(obj);
}
public static T DeSerObj<T>(string json)
{
T t = Defaule(T);
t = JsonConvert.DeSerializeObject<T>(json); //将Json转换为<T>Obj
return t;
}
///使用泛型,以便后期如果有别的数据类型使用不必修改代码
public static string SerList<T>(this List<T> list)
{
return SerObjJson(list);
}
///楼上+1
public static void DeList<T>(this List<T> list,string json)
{
list = JsonCOnvert.DeSerializeObject<List<T>>(json);
}
}
}
这里,可能有些小伙伴会问了,都是什么可以增加方法? Ha Ha Ha(又加三秒,美滋滋),其实我也不知道(抱头,Tan90反弹)
比如DeBug我就写失败了,不过Transform 第一人称控制器是可以的 比如
using UnityEngine;
public static class TransExtend
{
///相机为猪脚的子物体时
public static void EulerRotation(this Transform target, float clampEulerMin, float clampEulerMax, float speed = 90, char axis = 'y')
{
euler = target.rotation.eulerAngles;
if (axis == 'y')
{
这里是为了防止速度太快导致下面的限制失效
eulerTemp = Mathf.Clamp(-Input.GetAxis("Mouse Y"), -15, 15) * speed * Time.deltaTime;
euler.x += eulerTemp;
///向上看 和 向下看的角度限制
if (euler.x >= clampEulerMax && euler.x < 360 / 2)
euler.x = clampEulerMax;
else if (euler.x <= clampEulerMin && euler.x > 360 / 2)
euler.x = clampEulerMin;
}
else if (axis == 'x')
{
eulerTemp = Mathf.Clamp(Input.GetAxis("Mouse X"), -15, 15) * speed * Time.deltaTime;
euler.y += eulerTemp;
}
else
{
return;
}
target.rotation = Quaternion.Euler(euler);
}
}
这样我们就扩展出了一个Transform的方法,这个方法是第一人称移动视角,其中那个限制是向上看,和向下看的角度限制,而调用的时候直接可以
...命名空间所在
private Transform _camera;
void Start()
{
_camera = Camera.Main.transform;
}
void Update
{
//取出的角度,是在290 - 360, 0 - 90 之间的角度
transform.EulerRotation(290, 60, 90, 'x');
_camera.EulerRotation(280, 60, 90, 'y'); // 这个是相机
}
当你把你想实现的一些繁琐的代码封装完成后,就直接生成,拖到unity=>Assets/Plugin里面就行了 注意:你类库里面使用的外部类库也要一并放到同一文件夹中,Unity可以直接调用的除外,如System或者UnityEngine
通过上面的我们可以发现,其实对于我们而言,Dll只是把一些非常繁琐的代码封装为一个简洁的调用,这样可以大幅简化我们的代码,但是缺点也非常明显,当出错的时候我们会非常头疼,因为类库没法调试 而且如果dll里面代码很多的话,移植到Unity也够头疼的 = = 一个建议是写一个Log
.......
public static 类名 Instance{get;}
public static void Log(string errorInfo)
{
lock(Instance) // 防止多线程下 文件被并发占用 导致无法写入信息
using(StreamWrite sw = new StreamWrite(path)) //使用完毕 立即销毁
{
sw.WriteLine(InfoEvent.Instance.errorInfo);
InfoEvent.Instance.clear();
}
}
private 类名(){}
///===================================
public class InfoEvent
{
private static InfoEvent instance;
public static InfoEvent Instance{
get
{
return instance == null ? new instance():instance;
}
};
public List<string> errorInfo{get;};
public InfoEvent()
{
errorInfo = new List<string>();
}
public void Add(string errorInfo)
{
errorInfo.add(errorInfo);
}
public void clear()
{
errorInfo = new ...;
}
}
///===================================
public static class ExtendTransform
{
public static void Error(this Transform t)
{
try
{
...
}catch(exception ex)
{
InfoEvent.Add(ex.message);
}
}
}
其实 上面的代码只是为了确保在多线程下出错信息不回缺少
================================================================================================
在加几句,如果在Unity里面遇到没有找到namespace的话
只勾选 Any Platform 别的都不要 之后点一下Apply
好像还有什么非常重要的东西我忘记了,等以后想起来在加 (挖坑)