当前位置:   article > 正文

封装自己的代码为类库在Unity中调用_如何让自己写的类出现在unity编辑器里

如何让自己写的类出现在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;

     现在,先写一段测试代码

  1. using System;
  2. using UnityEngine;
  3. using Newtonsoft.json;
  4. namespace Test
  5. {
  6. public static class test
  7. {
  8. /// <summary>
  9. /// 测试类
  10. /// </summary>
  11. public static string printStr(string str)
  12. {
  13. return str + ":hello world";
  14. }
  15. }
  16. }

      上方,点击生成=>找到你的bin文件夹生成的相应Dll,将Newtonsoft.Json.dll,Test.dll,Test.XML拖到unity的Assets/Plugins文件夹之中(注:这个文件夹是自己创建的)

         此时,当你打开Test.xml时就会发现,里面就是我们刚才所写的  ///测试类   这个注释,这个相应的XML会动态解析到你的类中,只要相应的DLL和XML在同一文件夹下

      现在,让我们在Unity里面也写一个测试例子,

  1. using UnityEngine;
  2. using Test;
  3. class Test
  4. {
  5. ///不要惊讶 Unity里面真有这个方法 自动执行的 顺序是在OnEnable和Start之间
  6. public void Main()
  7. {
  8. Debug.Log(Test.print("Ling"));
  9. }
  10. }

     不出意外的话,运行之后你就会看到 Ling: hello world 这个输出

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

     但是我们可不会因为这些小事就费劲心力的去封装一个类库啊,我们需要的是封装一套明明逻辑不复杂,但是还要我每次都写一遍的那种, SO ↓

     改装一下刚才的代码

  1. using System;
  2. using UnityEngine;
  3. using Newtonsoft.json;
  4. namespace Test
  5. {
  6. public static class test
  7. {
  8. /// <summary>
  9. /// 测试类
  10. /// </summary>
  11. public static string printStr(string str)
  12. {
  13. return str + ":hello world";
  14. }
  15. public static string SerObjJson(object obj)
  16. {
  17. JsonConvert.SerializeObject(obj); // Newtonsoft.json里面的方法,将Obj转为Json
  18. }
  19. public static T DeSerObj<T>(string json)
  20. {
  21. T t = Defaule(T);
  22. t = JsonConvert.DeSerializeObject(json); //将Json转换为<T>Obj
  23. return t;
  24. }
  25. }
  26. }

         这几句比较简单,注释里有相关解释

再次更改 ,这里首先我们需要知道扩展方法

  1. public static T ExtendObj<T>(this object obj)
  2. {
  3. ///操作
  4. return JsonConvert.SerializeObject(obj);
  5. }
  6. ///调用的时候就可以
  7. object obj = null;
  8. string str = obj.ExtendObj<string>();
  1. using System;
  2. using UnityEngine;
  3. using Newtonsoft.json;
  4. namespace Test
  5. {
  6. public static class test
  7. {
  8. /// <summary>
  9. /// 测试类
  10. /// </summary>
  11. public static string printStr(string str)
  12. {
  13. return str + ":hello world";
  14. }
  15. public static string SerObjJson(object obj)
  16. {
  17. // Newtonsoft.json里面的方法,将Obj转为Json
  18. JsonConvert.SerializeObject(obj);
  19. }
  20. public static T DeSerObj<T>(string json)
  21. {
  22. T t = Defaule(T);
  23. t = JsonConvert.DeSerializeObject<T>(json); //将Json转换为<T>Obj
  24. return t;
  25. }
  26. ///使用泛型,以便后期如果有别的数据类型使用不必修改代码
  27. public static string SerList<T>(this List<T> list)
  28. {
  29. return SerObjJson(list);
  30. }
  31. ///楼上+1
  32. public static void DeList<T>(this List<T> list,string json)
  33. {
  34. list = JsonCOnvert.DeSerializeObject<List<T>>(json);
  35. }
  36. }
  37. }

          这里,可能有些小伙伴会问了,都是什么可以增加方法? Ha Ha Ha(又加三秒,美滋滋),其实我也不知道(抱头,Tan90反弹)

          比如DeBug我就写失败了,不过Transform 第一人称控制器是可以的 比如

  1. using UnityEngine;
  2. public static class TransExtend
  3. {
  4. ///相机为猪脚的子物体时
  5. public static void EulerRotation(this Transform target, float clampEulerMin, float clampEulerMax, float speed = 90, char axis = 'y')
  6. {
  7. euler = target.rotation.eulerAngles;
  8. if (axis == 'y')
  9. {
  10. 这里是为了防止速度太快导致下面的限制失效
  11. eulerTemp = Mathf.Clamp(-Input.GetAxis("Mouse Y"), -15, 15) * speed * Time.deltaTime;
  12. euler.x += eulerTemp;
  13. ///向上看 和 向下看的角度限制
  14. if (euler.x >= clampEulerMax && euler.x < 360 / 2)
  15. euler.x = clampEulerMax;
  16. else if (euler.x <= clampEulerMin && euler.x > 360 / 2)
  17. euler.x = clampEulerMin;
  18. }
  19. else if (axis == 'x')
  20. {
  21. eulerTemp = Mathf.Clamp(Input.GetAxis("Mouse X"), -15, 15) * speed * Time.deltaTime;
  22. euler.y += eulerTemp;
  23. }
  24. else
  25. {
  26. return;
  27. }
  28. target.rotation = Quaternion.Euler(euler);
  29. }
  30. }

这样我们就扩展出了一个Transform的方法,这个方法是第一人称移动视角,其中那个限制是向上看,和向下看的角度限制,而调用的时候直接可以

  1. ...命名空间所在
  2. private Transform _camera;
  3. void Start()
  4. {
  5. _camera = Camera.Main.transform;
  6. }
  7. void Update
  8. {
  9. //取出的角度,是在290 - 360, 0 - 90 之间的角度
  10. transform.EulerRotation(290, 60, 90, 'x');
  11. _camera.EulerRotation(280, 60, 90, 'y'); // 这个是相机
  12. }

当你把你想实现的一些繁琐的代码封装完成后,就直接生成,拖到unity=>Assets/Plugin里面就行了 注意:你类库里面使用的外部类库也要一并放到同一文件夹中,Unity可以直接调用的除外,如System或者UnityEngine

通过上面的我们可以发现,其实对于我们而言,Dll只是把一些非常繁琐的代码封装为一个简洁的调用,这样可以大幅简化我们的代码,但是缺点也非常明显,当出错的时候我们会非常头疼,因为我们很难判断出错的位置是在我们的代码还是DLL中,一个建议是,DLL里面的东西尽量模块化,也就是尽可能少的写耦合很高的代码,这样一旦出错,我们可以很快的定位错误位置,并且因为可以将代码块单独拉出来进行单元测试

================================================================================================

        在加几句,如果在Unity里面遇到没有找到namespace的话

只勾选 Any Platform 别的都不要 之后点一下Apply

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

================================================================================================    如果你原本新建的就是一个Win32 那么

=============================================2018.12.18==========================================

        今天无意间发现了vs可以直接打出so和jar包,所以略微尝试一番---------------------------

下面这个应该是我以前装C++的时候无意添加上去的,但是添加的到底是什么,哈哈~那就需要小伙伴们慢慢试了 ~~~Σ(っ °Д °;)っ

测试一下so,

使用上面那个路径里面的ndk也可以直接打包 -> https://blog.csdn.net/yangxuan0261/article/details/52420833

分别打包(注意你打出的包会是libxxx.so,不用惊讶,我们在调用的时候只需要把lib和.so去掉就可以了,这个NDK应该也是我安装C++的时候添加上的,不过模糊记得好像这个是需要访问google才可以的),将两个so包放入  Assets\Plugins\Android\libs\armeabi-v7a 和 x86之中,声明,除了so文件之外,其他的文件夹都是我创建的

  1. // SharedObject1.h
  2. #pragma once
  3. #ifndef __INCLUDE_H__
  4. #define __INCLUDE_H__
  5. #if 0
  6. #define EXPORT_DLL __declspec(dllexport) //导出dll声明
  7. #else
  8. #define EXPORT_DLL
  9. #endif
  10. #endif
  11. extern "C"
  12. {
  13. EXPORT_DLL int addTest(int a, int b);
  14. }
  15. // SharedObject1.cpp
  16. #include "SharedObject1.h"
  17. extern "C"
  18. {
  19. int addTest(int a, int b)
  20. {
  21. return a + b;
  22. }
  23. }
  24. // unity 测试代码
  25. using System.Runtime.InteropServices;
  26. using UnityEngine;
  27. using System;
  28. using UnityEngine.UI;
  29. public class Test : MonoBehaviour
  30. {
  31. [DllImport("SharedObject1")]
  32. public static extern int addTest(int x, int y); // 我c++里面代码
  33. public Text text;
  34. void Start()
  35. {
  36. string str = "";
  37. try
  38. {
  39. str += addTest(1, 2).ToString();
  40. }
  41. catch (Exception ex)
  42. {
  43. str += "Error:" + ex.Message;
  44. }
  45. text.text = str;
  46. }
  47. }

之后直接打出手机包就行了。。。jar过几天在试好了,openGL + shader 还在研究ing

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/89007
推荐阅读
相关标签
  

闽ICP备14008679号