在本文笔者将带大家走完 UPM(Unity PackageManager) 插件包的开发流程,在本文你将学会 UPM 插件包的正确构建与调试流程、GitHub发布、插件更新与下载使用。从此Github 将是你的超级在线插件包~
友情提示:建议从下往上翻, 或者上半部分快速翻阅,毕竟上面的内容较为过时了~

Tips :Unity 2018.3 及之后版本, Unity Package Manager (UPM) 已经支持 Git 了.
https://forum.unity.com/threads/git-support-on-package-manager.573673/
这个更新使得我们能够快速的安装那些托管在诸如 GitHub,Gitlab,Gitblit 等代码托管服务上的插件包。
这样,只要给个git链接就能安装插件/更新插件了,并且这个工作流可以让插件的开发和维护与用户工程的开发文件完全隔离,做到不污染用户工程又能将插件用于实际开发中,UPM 提供的这种便利在不远的将来将是 Unity developer 的一场狂欢,并且这一天并不遥远。
言归正传,下面我们创建一个 UPM 插件包吧~
本教程中,我们将开发一个名为 “RotateMe” 的插件包,它包含一些用于驱动游戏对象旋转的组件。
本文不涉及远程仓库的创建以及Git 安装
在本教程,我们使用 2 个分支来开发这个插件包。看个人喜好,如有必要可以增加分支(比如:develop 分支)。
请注意,不能直接往 upm 分支提交,也不要使用 git branch upm 的方式手动创建此分支。
UPM包的公共目录结构如下:

将上述插件包资源使用一个根节点统筹之,这个文件夹建议以插件名来命名,如下:

怎么样,是不是就像往常开发那样的流程呢?
开发插件包的过程无不透露着熟悉的味道哈。
OK,现在我们在 "master" 分支中开发并调试我们的插件。
首先撰写一个用于驱动物体旋转的示例代码并放在这个文件夹下:
Assets/RotateMe/Scripts/RotateMe.cs
示例代码如下:
using UnityEngine;
public class RotateMe : MonoBehaviour
{
public float angularVelocity = 10;
void Update ()
{
var rot = Quaternion.AngleAxis (angularVelocity * Time.deltaTime, Vector3.up);
transform.localRotation = rot * transform.localRotation;
}
}
当然,别忘了添加一个 Demo 场景。
要知道 Demo 场景可是一个可交互的手册呢,有了它用户就可以轻松的掌握怎么使用插件咯!

如果要开发包含脚本的插件包,这边建议您添加一个asmdef文件的呢,亲~
https://docs.unity3d.com/2018.3/Documentation/Manual/ScriptCompilationAssemblyDefinitionFiles.html
这个 asmdef 文件能将它所在的文件夹及其子文件夹的脚本打到一个独立的程序集中,表象上就是这些个脚本打到了独立的 dll 中了。
简单的说下 asmdef 文件的优势.
如下图,如果你勾选了 "Test Assembly",程序集只在编辑器下生效而不会出现在打包的程序中。

搬运的原教程中没有涉及到到 AssemblyDefinition 的相互引用关系,故而笔者在这里补充下。
建议使用Editor 文件夹汇总所有的编辑器脚本,而将运行时的脚本使用 Runtime 文件夹汇总,参考 TextMeshPro 插件包的结构:

Editor 文件夹下的 AssemblyDefinition 中 Platform 只能选择 Editor,并且 Reference 必须添加上 Runtime 中的那个 AssemblyDefiniion ,依旧参考 TextMeshPro :

UPM 插件包需要一个 package.json 包体描述文件,保存在如下路径:"Assets/RotateMe/package.json".(插件根节点)
{
"name": "com.coffee.rotate-me",
"displayName": "Rotate Me",
"description": "Rotate the object!",
"version": "1.0.0",
"unity": "2018.3",
"license": "MIT",
"dependencies": {
}
}
更多详情请见: https://docs.npmjs.com/files/package.json.
README.md, CHANGELOG.md, LICENSE.md 都可选但可以给用户带来更多信息。
将这些文档放在"Assets/RotateMe" 文件夹.
当然也可以放在"Assets/RotateMe/Document~",需要注意的是文件夹名称以~结尾不会显示在Project窗口
完成了上面的几步,我们的插件包就算是完成啦。
最终 "master" 分组看起来就像这样:

(如果你暂时不考虑 UPM ,可将这个文件夹导出成 unitypackage 发布)

如果想要发布 UPM 包,我们必须通过如下git 命令把插件包所在的文件夹创建为 subtree。
git subtree split --prefix=Assets/RotateMe --branch upm
这个命令将 "Assets/RotateMe" 目录放到“ upm” 分支。
通过这一步其他目录及文件不会出现在 upm 分支中。
接下来,为这个分支添加一个 tag 并推到远端。
推荐使用 semver作为 tag 的命名规则。
git tag 1.0.0 upm
git push origin upm --tags
大功告成!
这样,我们的 “RotateMe” UPM包就发布好了!
最终,分支图像这样子:

现在,我们试试把 RotateMe 使用 UPM 安装到其他工程中。
找到 "Packages/manifest.json" 插入如下一行:
{
"dependencies": {
"com.coffee.rotate-me": "https://github.com/mob-sakai/RotateMe.git#1.0.0",
...
},
}
回到编辑器 Unity 就能自动加载咱们的插件啦,就像这样:

或者使用 UpmGitExtension来安装。

如此简单~
你也可以把已经存在的仓库使用同样的操作将其适配 UPM 。
本教程测试用的仓库如下,不受限使用。
https://github.com/mob-sakai/RotateMe
仅需几步,就能将 git 仓库直接变得支持 UPM。
如果 Github 上的Unity 工程都支持 UPM 那会有多棒!?
现在,就把你工程的 UPM 支持搞起来吧~
"com.bshsf.commoncode":"file:../../Common",可以将UnityPackage包放在本地,这样多个工程就可以使用一个公共代码,也方便同步修改,比如在socket通信的客户端与服务端使用这种方式同步消息数据结- 来自笔者的示例。
file:Common ,那你的插件包请放在Packages文件夹下。"com.bshsf.commoncode":"file:../../Common" 表示这个插件包是跟工程根目录同级的了。"C:\Program Files\Git\mingw64\libexec\git-core" ,非默认安装路径的自行合理拼接 。在新版的Unity中(笔者使用的是Unity 2019.4.12),PackageManager 支持直接输入 git 链接了,这样带来两个好处:
依旧支持打tag 做插件包的更新哦!

随着 UPM 的日趋完善,现在这个工具已经支持配置自定义 Scope Registry 了,如此一来便解决了包的依赖问题了。
安装目标插件时,UPM 会自动根据你声明的依赖包 id 从你配置的 Scope Registry 服务器上拉取依赖的包。
目前,OpenUPM 作为野生 Unity 插件包的集聚地已然是独具规模了,通过它你可以公开发布你的插件,同时还可以轻轻松松(写上依赖包ID就行)随意引用和依赖这个Registry 中的其他开发者的包。
如果你正在找这方面的教程,你可以看看这个良心之作:使用OpenUPM发布自己的Unity项目-有木酱的小屋
当然,你也可以搭建 Scope Registry 私服,MixedRealityToolkit-Unity就是微软自己的Scope Registry,我相信你也可以搭建成功的(PS:OpenUPM 开源哦~)。
UPM Scope Registry 在哪儿设置:
UPM上找到齿轮点击进去就到这个界面了
在有些没有外网的公司,UPM 会报错:Cannot perform upm operation:connect ETIMEDOUT 35.238.138:443 [NotFound] 以及一个 Error Searching for packages报错,如图示。

有朋友问我提交新版本可不可以不打 tag 值,开发阶段频繁更新 tag 对同事不友好。
回答是可以不打,因为打 Tag 主要只是告诉 git 插件目录在哪儿,其次才是附加值:标记插件版本、触发 UPM 加载
其实,笔者知道的,要访问插件目录,不限于这种https://github.com/mob-sakai/RotateMe.git#1.0.0带 Tag 形式的 git 链。
还有以下 3 种形式:
https://github.com/mob-sakai/RotateMe.git#upm 通过直接指定分支名称。https://github.com/wlgys8/LitTask.git不带 tag 的 git 链,其特点是插件目录本身即为 git 仓库。https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask 的带 QuaryString 参数的 git 链 (需要新版本 Unity 以支持对 querystring 参数解析)↑ 鉴于笔者并非 git 精通,故而只能列举四种方式,毋需置疑,这些肯定也只是冰山一角。如果笔者见到了新的方式亦会慢慢补全↑
关于终端用户不友好,遵循这种工作流就不会产生困惑了:
对于开发者,累计功能点阶段性推版本
对于终端用户,小迭代自发更新,大迭代提醒强制更新。
最后
上一次更新说到的 UPM 支持 4 种协议,现在可以更新一下了,下面是更完善的支持的协议说明:
官方中文手册 :https://docs.unity3d.com/cn/current/Manual/upm-git.html
另外,Unity Registry 托管的插件包支持直接将形如 com.unity.learn.iet-framework@2.0.0 这种 【包ID+版本】链接写入到UPM git url 中获取插件包,下面是参考链接以及其上下文截图:
Tutorial Authoring Tools | 1.0.0

Unity 已经开发出了 UPM Package 开发工具,只需要简单一步就能够创建 Package 大致框架,剩下的仅仅是代码的搬运了。
目前,这个 UPM 开发工具还是预览阶段,有可能在 UPM 的 Unity Registry 中还看不到。
点击 + 号 ? 点击“Add Package from git” ? 粘贴上 com.unity.upm.develop ? 点击 “Add” 即可安装。




还是要说一下,除了 .asmdef 文件,Unity 还给了一个 .asmref 文件,全称为: Assembly Definition Reference,这个文件能够解决咱们在架构插件时 .asmdef 不能跨文件夹的痛点。
有了 .asmref 文件,可以将各处的文件夹的源文件打进一个程序集中,很多时候避免了目录结构的非必要重构。
使用也是很方便,只要你对着文件夹点右键,选中 Assembly Definition Reference ,接下来的操作便能够心领神会了。
插件中部分代码想要选择性的参与编译,可以通过在 Assembly Definition File 中 的 Version Define 自定义宏,并选择宏开启的条件,条件一般为:
0.0.0 或 “0”或者留空即可
注意:
com.unity.modules.ui 仅作演示,宏:UNITY_UGUI_ENABLED 也是随手写的,用户需自行修改为存在性存疑的程序集UNITY_UGUI_ENABLED 即可约定哪些代码是准备选择性编译的啦。
如果想要自己整理的 upm 插件导入时自动安装依赖(的 upm),只需要在你的插件的 package.json 的 dependencied 成员中加入依赖包的 id 和 版本号即可,如下图所示。

default 代替具体的版本号试试吧本文部分内容由笔者搬运并翻译自 Tutorial: How to develop a package for UnityPackageManager
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,