`
vanadiumlin
  • 浏览: 504884 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

深入剖析U3D的Miss Mono Behaviour问题

 
阅读更多
我相信u3d稍微大一点的项目,大家都是用unitypackage来传递资源和工作共享的吧?

问题是这样的,美术给我们的unitypackage在程序这边导入之后,总是会出现Miss Mono Behaviour的问题,也就是脚本丢失了,不知道大家有没遇到过。出现很多次了,终于在两天前怒了,想要彻底解决这个破事。

本文就是解决这个问题时的一些经验,最后发现,在良好的工作规范之下,这个问题几乎不应该出现,我们项目出现了多是历史遗留问题,metaFile应该在项目最早期就开启,并受SVN版本管理。



Meta File

U3D是自带文件版本管理的,在project setting - editor - Version Control 可以选择,一般都是选择生成Meta Files 的方式来管理。

meta file 从内容上讲,记录了

1、u3d当前的的文件格式版本号

2、每个文件的唯一标示:guid。

3、一些具体文件类型相关的信息,比如是脚本文件,会记录executionOrder之类的额外信息,png文件,会记录贴图尺寸,mipmap之类的信息

这中间,最重要的就是GUID了,稍后会讲到。



由于Miss Mono Behaviour主要是处理脚本,所以我以脚本对象举例,其实本文的技巧可以推广到任意类型的文件,只是繁简程度。

脚本文件: .cs文件

容器文件: .unity 和 .prefab文件

这样区分是因为脚本文件只能作为组件对象挂在到GameObject上,而GameObject只会在scene(.unity)和prefab(.prefab)中出现,容器文件的处理方式是一致的,我仅以.unity文件为例。



容器文件和其他相关文件

二进制打开.unity文件,工具我推荐fairdellhexcmp.exe,可以搜索到引用的脚本组件,比如"abc.cs" ,我们可以看到,unity文件记录了

1、以Assets目录开始的 PathName , 比如 "Assets/artcode/abc.cs"

2、GUID的串行化形式

3、脚本的cache文件所在地 , library/cache/c9/c9123456789012eec9123456789012ee

相关文件包括Library目录下的

1、guidmapper文件

2、metadata目录

3、cache目录

4、assetdatabase3文件

文件guidmapper记录的是 短文件名 和 GUID 的对应关系。

assetDatabase3 记录的是 文件全路径 和 cache文件的对应关系。

metadata , cache 则是记录的当前的脚本文件格式信息和内容信息,也就是U3D的版本管理核心数据。

当脚本文件内容发生变化的时候,实际上GUID是不会发生变化的。而且U3D其实并不基于文件内容增量变化的版本管理,而是覆盖式的。这也从一个方面说明为什么它大部分文件都是二进制的。





GUID的产生和它的使用者

GUID是文件唯一标示,容器文件里的关联关系都是基于GUID而不是基于文件名和文件路径的。当一个新文件创建之后,U3D会自动给它生成一个GUID。

现在假设这样一个情况,我们新建了脚本abc.cs , U3D给他分配了GUID : c9123456789012eec9123456789012ee, 记录在 abc.cs.meta 文件里

然后我们把这个脚本挂到 scene 中的某个对象上,并且把这个场景保存为 sss.unity.

现在可以知道 sss.unity 里记录了GUID, abc.cs.meta文件里也记录了GUID ,之前列出来的4个相关文件里也发生了变化,这六个变化是GUID产生之时U3D自动做的事情。





Miss Mono Behaviour问题的产生

我机器上sss.unity里记录的abc.cs的GUID是 AAA,但是如果我只给你abc.cs,而不同时给你abc.cs.meta文件,那么你的机器会自己生成一个GUID,而这个GUID和我的是不一样的BBB,于是问题就产生了,在这之后,如果你导入我给你的sss.unitypackage的话,你就会发生Miss Mono Behaviour问题。

这是因为你机器上的 sss.unity引用的abc.cs 的 GUID还是AAA,但实际上相关4文件里都没有这个GUID的文件记录。

这个问题本质上是不理解U3D版本管理导致的使用错误,在项目初期非常普遍,大家也不清楚到底肿么了,导致这个错误被扩散到相当多的scene中。这个就十分要命了,不得不总是小心翼翼的,看哪个脚本有没丢。



如何解决

基本上来说就是保持各处GUID都一致,分别是

【人工改】脚本的meta文件

【人工改】容器文件里的引用

【U3D自动改】library/cache里以GUID命名的文件

【U3D自动改】library/metadata里以GUID命名的文件

【U3D自动改】library/guidmapper里的对应关系

【U3D自动改】library/assetDatabase3里的对应关系

如果只是sss.unity里的是AAA, 自己机器上的是BBB,只需要将AAA那台机器的meta file拷贝过来就可以了



复杂情况

(总有但是,不是么)

在解决的过程中,实际上发现错误情况不止一种,而是

1、GUID在两台机器不一致

2、容器文件内的GUID引用在两台机器的不一致

3、脚本路径不一致

4、脚本文件没了

上述4种错误会任意混合出现,都是因为多人协作流程不规范导致的问题,而要做到规范是不可能的,总有人会犯点错不是?



我基于上述的分析,做了针对项目实际情况的自动化工具,在美术、策划、和程序之间维护文件GUID的同步,C#处理二进制文件写起来真够恶心的。这个工具的源码在公司内网,带不出来了,不过相信知道这个问题的成因之后,理解决它也没多远了,加油吧少年们。
分享到:
评论

相关推荐

    Mono环境winform开发

    Mono环境下的WinForm开发是一种跨平台的技术,它允许开发者使用C#语言和.NET框架构建的Windows应用程序在非Windows系统上运行,比如Linux。这个技术基于Mono项目,一个开源的.NET实现,旨在提供与Microsoft .NET ...

    Reactor教程Mono和Flux例子

    Mono的常见操作包括`just`(创建一个包含单个值的Mono)、`empty`(创建一个无值的Mono)和`fromCallable`(从Callable中创建Mono)。 Flux则代表0到N个值的发布者,它可以处理一系列的值,如读取文件或从流中接收...

    Unity协程(Coroutine)原理深入剖析再续

    通过对协程的深入理解和合理使用,开发者可以提高游戏性能,避免主线程被长时间阻塞,提高用户体验。 总结来说,Unity协程是一种强大的工具,它允许我们编写非阻塞的异步代码,通过`yield`关键字控制执行流程。`...

    【Dnspy】Unity-debugging相关mono补丁

    【Dnspy】Unity-debugging相关mono补丁 在Unity引擎的开发过程中,调试是必不可少的一个环节。...在实际使用中,结合对Unity和Mono的深入理解,可以解决许多棘手的编程问题,实现更高效、更稳定的游戏开发。

    Mono6.4.0(MAC)

    此指南针对MacOS,没有更改安装路径操作方法(文件太大故此放到百度网盘中,如被和谐,可邮箱联系我) 检查是否安装成功 /Library/Frameworks/Mono....打开Finder,前往文件夹:/etc/paths.d/,删除mono-commands。

    mono下载安装过程实录以及模块分析

    本文档记录了作者在安装 Mono 过程中的经验和教训,从中可以看到作者的反复尝试和解决问题的过程,涵盖了 Mono 的下载、安装、配置和调试等方面的内容。 在安装 Mono 之前,作者首先介绍了 Mono 的概念和特点,指出...

    Practical Mono(PDF扫描版)

    你将学习如何使用Mono的调试工具,找出和修复代码中的问题,以及如何通过优化代码来提升应用的性能。 最后,书中可能会包含一些高级主题,如AOT( Ahead-Of-Time)编译和IL2CPP(Intermediate Language to C++),...

    mono+sqlite

    在Unity3D(通常简称为u3d)这样的游戏开发引擎中,Mono是默认的脚本执行环境,因此开发者经常需要处理如资源管理、用户数据存储等问题。SQLite由于其轻便和高效,常被用作在Unity中存储游戏数据的解决方案。通过...

    docker的mono镜像

    在docker的mono镜像中加入一些基本命令包,方便开发(公司内网有些不能下)。有需求的直接下载,同时不需要再到仓库龟速下载了。送上安装命令: docker load -i mono.tar

    Ubuntu 下Mono环境Asp.Net的部署及问题解决方案v1.0

    【知识点详解】 ...以上就是Ubuntu环境下基于Mono和Nginx部署Asp.Net应用的全过程,以及可能出现的问题及解决方案。在实际操作中,要根据具体的应用需求和环境进行适当调整,确保系统的稳定性和安全性。

    Xamarin Mono For Android

    【Xamarin Mono for Android】是Xamarin公司提供的一款开发工具,它允许开发者使用C#语言来构建原生的Android应用程序。Xamarin Mono for Android结合了.NET框架的Mono实现,为开发者提供了与Java SDK类似的开发环境...

    DotNet框架技术及mono总结

    Microsoft.Net和Mono.Net,并不是“同一个.Net”,它毕竟是“两套不同的.Net”。虽然这两套.Net之间绝大多数特性是可互相兼容、可互相移植的,但依然有一些特性,要么是Microsoft.Net具备而Mono.Net不具备,例如WPF...

    mono-2.0-bdwgc.zip

    当遇到这个错误时,开发者可能需要更新或替换相关的DLL文件来解决问题,这里提供的"mono-2.0-bdwgc.dll"可能就是一个潜在的解决方案。 Unity3D是一个跨平台的游戏开发工具,基于C#的Mono运行环境,广泛应用于PC、...

    mono2.4源码,了解.net

    Mono源码分析可以从以下几个方面深入: 1. **C#编译器(mcs)**:Mono中的C#编译器负责将C#源代码转换成中间语言(IL),这是.NET执行环境可以理解的语言。通过查看源码,你可以了解C#语法是如何被解析和转化为IL...

    MONO 开发手册

    首先,让我们深入了解一下MONO项目。MONO是由Xamarin公司(现已被微软收购)开发的,旨在提供一个跨平台的.NET运行环境。它实现了.NET Framework的主要部分,包括Common Language Runtime (CLR)和大部分.NET类库。...

    mono编程初级入门

    License 授权:Mono 的 License 可是要注意欧,它是开源软件,当然你免费的使用它当然没问题,可是如果你想在上面进行二次开发可要注意了,必须遵守他的许可。Mono 的 License 采用的是双许可协议,包括 GPL 协议、...

    NPgsql及Mono.Security各版本支持文件

    本文将深入探讨这两个库的细节,以及它们的不同版本如何协同工作以确保兼容性和安全性。 首先,NPgsql是一款.NET Framework和.NET Core下的PostgreSQL数据库驱动程序,它允许.NET开发者使用C#、VB.NET或其他.NET...

    mono for Android API

    本文将深入探讨Mono for Android API的关键知识点,包括其核心特性、开发环境、类库支持以及如何进行应用开发。 1. **核心特性** - **跨平台兼容性**:Mono for Android API 允许开发者用C#编写代码,这可以与...

    VINS-Mono代码注释,仅供学习

    4. **非线性优化**:VINS-Mono通常采用基于因子图的优化框架,如g2o或Ceres Solver,解决SLAM问题。理解因子图模型和Levenberg-Marquardt等优化算法是必要的。 5. **状态估计**:包括位姿估计、里程计(odometry)...

    dotnet程序可否跨平台检测工具MONO-Moma

    MONO-Moma(Mono Migration Analyzer)是用于评估.NET应用程序在Mono框架下运行时可能遇到的问题的工具。 首先,我们需要理解.NET Framework和Mono之间的关系。.NET Framework是由Microsoft开发的一个全面的开发...

Global site tag (gtag.js) - Google Analytics