解决在Unity中使用FairyGUI遇到的坑

作者:超人不会死 时间:2023-10-27 13:04:24 

首先!首先!首先!

首先,我们由于历史问题,项目用的UI编辑器不是大众使用的GUI或者NGUI, 而是使用不知道算不算小众的FairyGUI,这个UI系统使用挺方便的,也提供了很多UI编码的案例,至少从直接使用来说方便了不少。

但是!但是!但是!

可能用到这个UI编辑器的不是那么多,项目上遇到的问题在网上百度出来的结果很少,基本自己断点查找bug。

最后!最后!最后!

我这个从没写过几次技术博客的人,要写这篇技术贴的原因是:昨晚加班到四五点钟查找BUG回到屋里,发现由于没有关好自己卧室的门,室友养的猫进我屋里尿了我一床,所以不得不马上更换棉被,才取睡觉!

1.关于在FairyGUI中使用Unity项目里的Sprite问题

在FairyGUI中使用Unity的Sprite需要使用控件GLoader来装载Sprite.官方给予的使用方法是


//Unity, 这里加载的是路径为Assets/Resources/demo/aimage的一个贴图
aLoader.url = “demo/aimage”;

如果Sprite是在一个Sprite图集中,则需要重写自己的GLoader类,


class MyGLoader  : GLoader
{
   override protected function LoadExternal()
   {
       /*
       开始外部载入,地址在url属性
       载入完成后调用OnExternalLoadSuccess
       载入失败调用OnExternalLoadFailed
       注意:如果是外部载入,在载入结束后,调用OnExternalLoadSuccess或OnExternalLoadFailed前,
       比较严谨的做法是先检查url属性是否已经和这个载入的内容不相符。
       如果不相符,表示loader已经被修改了。
       这种情况下应该放弃调用OnExternalLoadSuccess或OnExternalLoadFailed。
       */
   }
   override protected function FreeExternal(NTexture texture)
   {
       //释放外部载入的资源
   }
}

并且注册自己的GLoader


UIObjectFactory.SetLoaderExtension(typeof(MyGLoader));

但是这里并没有告诉我们该怎样具体加载Sprite.

实际上只需要自己查找到Sprite载入就行


 protected override void LoadExternal()
       {
        // 这里使用成员变量url查找Sprite载入即可
           if (url.Length > 0)
           {
            Sprite tSprite= Resources.Load<Sprite>(url);
             this.onExternalLoadSuccess(new NTexture(tSprite));
           }

this.onExternalLoadFailed();
       }

但是如果Sprite是在一个图集中,图片就显示不正确了。

查找了很久才发现FairyGUI使用的图集和Unity中使用的图集Y轴相反,需要重新计算Rect才能正确加载。即


protected override void LoadExternal()
{
if (url.Length > 0)
    {
     Sprite[] tSprites= Resources.LoadAll<Sprite>(url);
     Sprite tSprite = tSprites[0];
     // 这里需要将Y轴反转
     Rect tShowRect = new Rect(tSprite.textureRect.x, tSprite.texture.height - tSprite.textureRect.y - tSprite.textureRect.height,
             tSprite.textureRect.width, tSprite.textureRect.height);
        this.onExternalLoadSuccess(new NTexture(tSprite.texture, tShowRect));
    }
}

基本上这样子就解决了GLoader使用Unity的Sprite 问题。

2.使用Sprite Atlas打包图集遇到的问题

由于美术给予的图片都是单个的图片,并没有将打包成为一张图片,所以需要程序自行打包。在多次询问谷哥和度娘以后,才知道Unity有个新的图集打包插件Sprite Atlas很好使用

1.创建Sprite Atlas:

解决在Unity中使用FairyGUI遇到的坑

2.选择需要打包的图片或者图片所在的文件夹

(这里会将文件夹内的图片和子文件夹内的图片一起打包)

也可以打包预制体

解决在Unity中使用FairyGUI遇到的坑

3.设置在编辑器模式下也可以使用打包功能

解决在Unity中使用FairyGUI遇到的坑

这里就已经完成图集打包了。

一切似乎都很完美,图片显示,打包都有了。

但是!但是!但是

图集+Gloader显示图片后,图片显示不出来了,

查了很久才知道


// 获取精灵在其纹理上使用的矩形。如果这个精灵被紧紧地打包在一个地图集中,则引发一个异常。
textureRect   Get the rectangle this sprite uses on its texture. Raises an exception if this sprite is tightly packed in an atlas.

我TM一万匹草泥马奔过,这TM也是我昨晚查了一晚上,Debug了好久查找怎么正确获取textureRect,或者说能正常显示图片。

我发现如果要显示图片可以使用GGraph:


// FairyGUI官方给予的案例
GGraph holder = new GGraph();
holder.SetSize(100, 100);
holder.DrawRect(...);
aComponent.AddChild(holder);
holder.SetNativeObject(aSprite);

但是这里装载的aSprite是一个GameObject对象,相当于我创建了一个GameObject挂载到了FairyGUI上。

这里我不可能1.将所有的GLoader改成GGraph吧,2.为每张需要用到的图片创建GameObject吧。

后来根据官方的案例发现可以,


Texture2D tTx2D = Resources.Load<Texture2D>(strPath);
this.onExternalLoadSuccess(new NTexture(tTx2D));

但是这里加载的Texture2D是整个图片,如果是图片中的某块区域(图集中的一张图片)则无法正常显示。

最后我发现,在创建Sprite Atlas时,取消勾选Tight Packing(取消紧凑打包),属性textureRect就可以正常获取了。

解决在Unity中使用FairyGUI遇到的坑

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

来源:https://blog.csdn.net/xiaohu57362/article/details/98185906

标签:Unity,FairyGUI
0
投稿

猜你喜欢

  • 利用flutter实现炫酷的list

    2022-08-02 01:15:01
  • C#实现鼠标移动到曲线图上显示值的方法

    2023-06-01 00:56:06
  • SpringBoot利用拦截器实现避免重复请求

    2022-02-07 00:21:53
  • java关于字符串的常用API

    2022-09-13 22:19:03
  • Java 获取当前时间及实现时间倒计时功能【推荐】

    2022-08-21 16:08:27
  • Springboot webscoket自定义定时器

    2023-02-12 05:34:02
  • Java多线程之Semaphore实现信号灯

    2023-09-19 23:04:51
  • Java 栈与队列实战真题训练

    2021-06-11 01:46:08
  • Java命令行下Jar包打包小结

    2023-01-04 19:25:44
  • .net与javascript脚本的交互方法总结

    2021-09-11 09:21:32
  • C#实现开机自动启动设置代码分享

    2021-10-08 20:45:14
  • C#基于简单工厂模式实现的计算器功能示例

    2023-06-19 12:40:10
  • Android编程实现类似天气预报图文字幕垂直滚动效果的方法

    2022-08-02 08:16:50
  • Android开发中ImageLoder进行图片加载和缓存

    2023-08-18 10:14:30
  • Android中Notification通知用法详解

    2023-02-24 02:37:51
  • 在Java中按值调用和按引用调用

    2021-12-26 20:09:21
  • Android应用中Back键的监听及处理实例

    2022-09-26 02:00:47
  • 详解C++中的指针、数组指针与函数指针

    2023-04-11 05:35:24
  • Android Gradle同步优化详解

    2023-09-20 18:17:48
  • elasticsearch数据信息索引操作action support示例分析

    2022-03-18 02:09:07
  • asp之家 软件编程 m.aspxhome.com