封装自己的代码为类库在Unity中调用

            使用版本为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

好像还有什么非常重要的东西我忘记了,等以后想起来在加 (挖坑)

猜你喜欢

转载自blog.csdn.net/MikuLingSSS/article/details/82317768