unity开发遇到的几个坑(UGUI等)

 

unity开发遇到的几个坑(UGUI等)

  39396人阅读  评论(20)  收藏  举报
  分类:
游戏开发及技术(59) 

最近开始研究unity,准备将之前自己业余时间做的一款游戏(金庸群侠传X)发行移动端版本(我不是游戏公司从业人员,业余时间自己做着玩,大神轻喷)。由于之前使用silverlight(C#)做的,所以移植unity有天然的语言优势。

看了一下unity的更新公告,4.6出的UGUI我比较喜欢,因为之前也用过NGUI,总感觉不是很顺畅。那么,即使有坑,我们也来趟趟吧。

到现在陆陆续续大概已经趟了一个月的坑了,总的感觉是,对于unity还是比较满意的:非常简单容易上手,功能还算齐全——现在DEMO版本已经能够在android、ios上较好的运行。上两张截图吧

现在总结一下我在开发中碰到的几个“坑”——当然,话说在前头,因为我也是刚开始学习unity,目前我自己认为的坑也可能是我自己的理解不够,如果大家有更好的解决方法,欢迎指正!楼主写这篇博客的时候是2015年1月13日,使用的是当前最新的unity 4.6f1版本。

1、scroll rect的各种问题

(2015年02月9日:这个是我自己搞错了,unity有提供方法,只是我之前用错了,请移步这篇博文,这一条下面写的大家就当看个笑话吧 :D)

很多界面需要用到滚屏,unity提供scroll rect控件。具体的组织方式为:

每个ScrollRect对应一个scrollcontent,ScrollContent定义内容的排版组织方式,如Grid Layout Group或者Vertical Layout Group。(这里比较像silverlight中的StackPanel和GridPanel)

我使用以后发现一个最大的问题是,scroll content无法根据其包含的内容自动伸缩。也就是说,scroll content的宽和高需要手动指定,如果其中内容超出了它的范围,那么超出的内容将无法滚屏过去。

这一点实在是把我恶心到爆了,于是出现了诸如以下的代码

[csharp]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. if (Mode == SelectMenuMode.Vertical)  
  2. {  
  3.     selectContent.GetComponent<VerticalLayoutGroup>().enabled = true;  
  4.     selectContent.GetComponent<GridLayoutGroup>().enabled = false;  
  5.   
  6.     float spacing = selectContent.GetComponent<VerticalLayoutGroup>().spacing;  
  7.     //by cg:  
  8.     //unity每次需要手动设置scroll content的大小  
  9.     float height = spacing;  
  10.     foreach (Transform s in selectContent)  
  11.     {  
  12.         height += s.GetComponent<RectTransform>().rect.height - spacing;  
  13.     }  
  14.   
  15.     float width = selectContent.GetComponent<RectTransform>().rect.width;  
  16.     selectContent.GetComponent<RectTransform>().sizeDelta = new Vector2(width, height);  
  17.       
  18. }  
  19. else if (Mode == SelectMenuMode.Grid)  
  20. {  
  21.     selectContent.GetComponent<VerticalLayoutGroup>().enabled = false;  
  22.     selectContent.GetComponent<GridLayoutGroup>().enabled = true;  
  23.   
  24.     float cellX = selectContent.GetComponent<GridLayoutGroup>().cellSize.x;  
  25.     float cellY = selectContent.GetComponent<GridLayoutGroup>().cellSize.y;  
  26.     float spacingX = selectContent.GetComponent<GridLayoutGroup>().spacing.x;  
  27.     float spacingY = selectContent.GetComponent<GridLayoutGroup>().spacing.y;  
  28.     float width = selectContent.GetComponent<RectTransform>().rect.width;  
  29.     float height = Mathf.CeilToInt(selectContent.childCount / (width / (cellX + spacingX))) * (cellY + spacingY);  
  30.     selectContent.GetComponent<RectTransform>().sizeDelta = new Vector2(width, height);  
  31. }  

每次需要手动去设置scroll Content的RectTranform的sizeDelta属性。这样代码很丑陋且极其不灵活。如果对于内容的宽高和排列可以预期,那还好。假如内容是一个文本,那岂不是还要算字体所占宽高、行间距等等…… 

其次的一个问题是:scroll content的position设置貌似是有BUG。

为了实现大地图滑动滚屏的效果,我将大地图放到一个scroll content中,然后可以由玩家手指滑动来进行拖拽,这个unity实现都没有问题。问题是,我需要由代码实现“滚屏”到某个点,则问题来了——

我手动在unity editor的运行时态设置的scoll content的x,y都是OK的,放到代码里去设置transform.localPosition,就完全错位了。

最后经过反复尝试,代码写成了这样……

[csharp]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. <span style="white-space:pre">    </span>//大地图卷屏  
  2.         if(location.name.Equals(RuntimeData.Instance.GetLocation(RuntimeData.Instance.CurrentBigMap)))  
  3.         {  
  4.             float x = -location.X + 640; //减去半个屏幕宽度,居中  
  5.             float y = -location.Y - 320; //减去半个屏幕高度,居中  
  6.             if (x < -1140) x = -1140; //边界限制  
  7.             if (y > 640) y = 640;  
  8.             if (x > 0) x = 0;  
  9.             if (y < 0) y = 0;  
  10.             //by cg: 这里对齐的逻辑有点奇怪,应该是unity的BUG,没处理好对齐锚点。先手动修正。  
  11.             BigMap.transform.localPosition = new Vector3(-570f + x, 320f + y, 0);  
  12.         }  

原因应该是我将scroll content的Anchor Pivot设置成了(0,1),但unity设置localPosition却没有写参考这个锚点的逻辑,需要手动修正。

 

还有比较大的一个问题,ScrollRect所在的GameObject的Image组件,alpha设置有个BUG

按道理来说,这个Image只是scrollRect的一个背景,不影响其内容。但在把alpha设置到特别小的时候,不管是在editor上还是在运行环境中,scroll content都将显示不出来。我试了大概是设到4-8以下就会完蛋。。所以我们需要获得一个背景透明的scroll content,还不能把背景设置得太过于透明了……

2、LINQ不能在IOS上使用

在PC、EDITOR、MAC、ANDROID都没有问题的代码,放到IOS真机(IPHONE、IPAD)上出问题。原因搜了一下大概意思应该是苹果不允许出现动态代码。

这个是unity一直的问题了,貌似有办法通过第三方的LINQ实现来保证。总之我是放弃使用LINQ了。

3、unity新版动画系统Mecanim使用中碰到的问题

我的游戏中人物分几种动画,如 站立、移动、攻击。我使用Mecanim的状态机来实现,动画之间使用SetTrigger来实现切换。

我发现一个动画在切换后如果没有播放完毕,再调用SetTrigger的话,有时就会出现动画状态错乱。我的状态机是这样的:

所以我代码里现在是每次需要等待一段时间后,再进行切换。。

4、sprite editor中的BUG

在sprite editor中通过鼠标调整锚点为custom,第一次保存(这时候unity已经自动将类型切换为custom了)会失败!需要保存两次——但是第二次必须又和第一次不是同一个锚点,否则保存按钮点不下去!

或者先手动将锚点类型改为custom,然后再保存才可以。

好了,吐槽了这么多问题,总之unity新版本我还是很支持的。毕竟原生态的GUI系统还是比NGUI等硬往上“套”的UI系统要好很多。对于unity3d使用C#编程语言也是更加好顶赞。我不是一个喜欢讨论哪个编程语言好的人,就我来说,我至少使用过10多种语言编写过代码,目前来说感觉比较酸爽的还是C#。

 
 

猜你喜欢

转载自hypercube.iteye.com/blog/2322130