随笔-15  评论-18  文章-9  trackbacks-0
  2016年5月9日
    最近游戏要开发二代,开始碰触角色动画那部分。由于动画部分之前不是我弄的,发现有很大的问题,角色模型和动画都是在一个fbx文件里面,并且新做的角色动画由于美术也不是同一个人,所以导出给我的动画也和原来的不同也是需要我来重新切分。
这样我认为有几个问题:
     1、文件过大,看了下我们那个fbx文件都10多m。
     2、后期维护麻烦,比如现在新加动画,就碰触到了原本的动画。
     3、美术为了一下修改预留了很多没用的帧在上面,这赤裸裸的浪费。
     4、更新调整也是问题
为此决定要把模型和动画分开,希通过一个没动作的fbx以及多个单独具体动作的fbx来处理,这样对于后期的维护,调整,以及更新都是很有好处。唯一的缺点就是对于美术麻烦点,美术认为太麻烦了,通过沟通,美术还是觉得要一个个动画分别导出很难处理,除非一开始就决定这样做(我是不太了解动作导出的)i╮(╯▽╰)╭。
      后来同事提醒可以把切好的动画Ctrl+D复制出来用,这确实是个方法,让美术导出一个没带动画的fbx这倒不难了吧,然后导出一个带动画的,我们把动画切好后,复制出来用,这样就ok了,就解决了导出问题!
      本来这样问题应该就解决了,但是一看就不想手动了,美术扔个txt文档制定动画对应的帧,一个角色用30多个动画,并且很多个没用的。我也不想自己手动去命名和切动画,必须用代码来做呀。
      如何通过代码来控制修改呢,这里用的是 通过继承AssetPostprocessor类, 在子类的OnPostprocessModel函数中处理。
      过程:
      1、通过一个与模型相同的名字txt指定动画名与帧的相关信息,首先搜索是否存在这样这样的txt,如果存在就读取txt里面的信息进行动画切分处理。
      2、如果fbx文件或动画配置有修改,只需选中fbx右键reImport就可以了。



      






    
posted @ 2016-05-09 22:22 木华 阅读(873) | 评论 (0)编辑 收藏
  2015年9月12日
          对于粒子特效Particle System,一般都是通过Play,Stop两个接口来控制播放与停止的。但是这次遇到到一个特效,Stop对其无效,还是继续发射粒子。这就奇怪了,其他特效都可以的。 自己新建场景,自己弄测试特效,经过多种恶心的测试对比,终于发现了,当Particle System的Emission 设置为Distence模式时 Stop 是无效的 ,无效的 无效的!!!!! 
翻看文档,并没找到那里有注明。难道他的stop,和 play 只是控制时间来控制发射器,不可理喻的做法。
          不死心,在unity5上测试,发现其Stop居然有效果,能正常运行。我们开发用的是4.6版本,不死心再回去4.6测试了一遍,我只想说 Fxxx Unity 了,没办法只能通过enableEmission 来控制了。

posted @ 2015-09-12 14:15 木华 阅读(1347) | 评论 (0)编辑 收藏
  2015年6月23日
   这段时间做unity3d的优化,主要的入手是减少draw call。
    1、代码上主要是把一些零碎的同材质的合并成一个大的mesh。
    2、减少不必要的全屏后期处理。把摄像机的rendering path,由deferred修改为forward。这样修改的原因是,我们场景中只是使用了一个灯光,延迟渲染并没有很有发挥其优势,另外使用向前渲染的话,引擎的动态合并会有很好的作用。
     经过上面两部分的操作,draw call 减少的非常多,并且游戏在目标平台上也能流畅的运行。但是发现一个非常明显的问题: 在两个物体紧紧挨着的边缘会明显的有裂痕在闪烁,比如一个赛段拼接另一个赛段的连接处。
    一开始以为是depth buffer 的精度问题导致的 depth fighting。所以调整了摄像机的near clip,但也还是会出现,只是调整near clip也有限制,否则会影响游戏,在调整near clip和把抗锯齿anti aliasing设置调整4* 或8* 裂缝的闪现会没那么明显,但是同样存在。想使用w buffer 来代替depth buffer来试下,但是无奈不清楚unity怎么处理,(当时想,如果最后没办法就程序把连接的网格自己合并,这样就不会出现裂缝了)所以先停下做其他的了。后来想到之前这种裂缝现象怎么没注意到呢,至少是不明显的。所以觉得会不会是rendering path,不同导致的呢。
    分别build两个程序,使用不同的rendering path。确实是使用延迟渲染的不会有裂缝闪现的现象,而向前渲染会有,这真是使人摸不着头脑呀,两种不同的渲染方式 怎么会出现这样的情况呢?还是不相信是由于不同的渲染方式导致的,继续找原因,发现两个有裂缝闪现的mesh,是用的相同材质,想到会不会是动态批处理的原因呢?   
    使用向前渲染时在play setting中去掉Dynamic batching 裂缝闪烁的现象就不会出现了,最终确定是引擎提供的动态批处理导致的问题。那为什么用延迟渲染时没呢,那是因为用延迟渲染的话,引擎对动态批处理很有限,(你在4.x版本的unity上,每添加一个cube,就要增加两个draw call,而向前渲染的话,会帮你动态批处理,并不会每个cube都增加draw call)。
    知道问题所在,修改也比较容易了,但是为什么其Dynamic batching 会导致裂缝闪烁,这个问题还是有待研究,但是unity内部是如何实现的不知道。希望了解这方面的人能指点一二!
posted @ 2015-06-23 22:10 木华 阅读(2449) | 评论 (0)编辑 收藏
  2015年4月27日
     这几天接手了项目逻辑部分,发现ui这部分有些问题,也花了点时间处理。
     项目中ui主要是通过两种方式处理的,一、 通过AE插件导出数据直接使用; 二、通过NGUI。
     AE插件的好处是减轻了程序的负担,美术也方便,直接在AE上做好动画就可以了。但是有个问题就是AE的动画都是缺少交互,在上面不能写脚本代码,比如有些动画可以划分背景是一个Ae做的动画,在前面是得分显示,这样的话就不能全部用AE 只能把前面的数字用NGUI来做。这样一来问题就出现了,排序问题!!!!
    看其代码发现AE插件的渲染部分通过z位置来排序,并且为每一个原始图片一个新的材质,并且还要为其开个灯光,并无优化处理。 而ngui 可以通过控制渲染顺序和拼图达到一点的优化,减少批次,其排序并不与位置z有关系。所以他们的前后关系不是随随便便设置个z来决定的。

解决方法:
      一、通过多摄像机,分为AE层,和NGUI层用不同的摄像机。这样是可以控制前后关系。但是这样有时往往两个ui的摄像机都不够使用,并且添加太多摄像机也添加了管理的麻烦,比如做镜头的淡入淡出等等。
      二、修改AE插件中的渲染部分,让其使用NGUI的组件来做渲染。这样就好比把在不同坐标系的两者搬到同一坐标了,这样就好处理排序问题了。

最终,为了优化和以后的方便,加上Ae插件本身也bug,所以决定使用第二中方法解决。其修改也还比较容易,不拼图的用UITexture(开发过程中不拼图, 大图如背景图也不拼),拼图了的用UISprite作为渲染载体。主要注意2D的锚点位置,特别是裁了空白边拼图后描点的位置的变化,ae层次结构关系,ae合成内部的depth的设置等等。


posted @ 2015-04-27 21:28 木华 阅读(1116) | 评论 (0)编辑 收藏
  2015年4月11日
     由于一些原因,需要对一些预设进行修改,发现由于我们游戏中预设是有层级关系的,比如美术会完成一些基本预设,策划再通过这些基本预设编辑成一个更大的预设。这样预设就有了一种嵌套关系了。比如预设A有个子节点a。(其中 A,a 都是预设)
     我之前的理解(错误)是预设是链接关系,也就是当a预设变化了,那么A预设也跟着变化。但是发现情况不是这样的,A预设中的a已经和a源预设没有关系了。修改源预设a并不影响A预设中a。那只能理解成当在编辑预设A的时候,就已经吧a是一个拷贝了与源断开了联系。
     那这样我就不能通过修改基本预设来改变上层预设了(除非重新编辑上层预设,但是在后期是不可能的)。但这由于是游戏开发,需求的改动还是蛮频繁的。
     我的解决方法是:1 、在一开始时或不要有嵌套关联这种概念(并不是说不要编辑这种预设关系,而是不要想着能修改基本的,就把上层的也能修改好),把修改多的(涉及到逻辑的东西)剥离开来。
                            2、不改变基本预设,而是把要添加的东西作为另一Component挂上去。(如果是要修改的话,这可能就不行了)
                            3、自己通过基本的预设名,或其他id,把上层预设重新生成(这也就是和人肉重新编辑一次差不多,但是是通过代码实现)。
posted @ 2015-04-11 10:20 木华 阅读(1705) | 评论 (0)编辑 收藏
  2015年4月7日
   今天想对预设进行数据的设置和修改,但不想把预设拖来出来修改后再次保存成预设。
   但在过程中发现unity3d 对prefabs进行操作,通过GetComponentsInChildren(false),是获取不到的,必须是对一个预设Instance后才能获取到。后来发现是由于预设的Componets都是active 是 false。需要用GetComponentsInChildren(true)才能正常! 看不到实现,一点点坑都花了些时间去处理。
posted @ 2015-04-07 20:46 木华 阅读(1169) | 评论 (0)编辑 收藏
  2015年3月27日
突然发现很久没写过了,快4年没写过东西了~
posted @ 2015-03-27 22:26 木华 阅读(64) | 评论 (0)编辑 收藏
  2011年9月13日
    由于需求,要实现stencil picking,也就是利用模板缓冲来拾取。这里有Delta3D中是如何实现的介绍。看了相关的模板测试的相关资料后,发现这个过程也是很简单的,自己想的过程和Delta3D的实现是类似的,虽然没接触过
 Delta3D的代码,但是上面所提及的那文章里看到相关的函数的状态设置还是与想法吻合的。
步骤如下:
   1,同屏最多只能有255个可点选的渲染物,以为stencil buffer 最多也才8位【0, 255】其中0代表不可选的东西。这样的话就需要动态的给在当前屏幕的每个可渲染物中加上一个id。改id该id 范围是【0,255】,如果一个物体的id 设置为0 的话则该物体不可选中。
   2, 设置模板参考值 为 id , SetRenderState(D3DRS_STENCILREF, id);
   3,设置模板测试总是成功。  SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
   4,设置模板的更新为,D3DSTENCILOP_REPLACE 当模板测试成功则把 模板参考值写入到模板缓冲中。
   5,当鼠标点击时,读取当前模板缓冲区的值,该值就是前面我们设置的id。通过id可以找到相应的选中物体。
但是郁闷的是在对上述想法进行验证的时候去碰的了一个问题,如何取得stencil buffer的值?
我是通过GetDepthStencilSurface来获取,代码如下:

IDirect3DSurface9* pStencilSurface;
    HRESULT hr 
= Device->GetDepthStencilSurface(&pStencilSurface);
    
if ( FAILED(hr) )
    {
        ::MessageBox(NULL, 
"error""get surface failed", MB_OK);
        
return 0;
    }
    D3DLOCKED_RECT lockedRect;
    
    hr 
= pStencilSurface->LockRect(&lockedRect, NULL, D3DLOCK_READONLY);
    
if ( FAILED(hr) )
    {
        ::MessageBox(NULL, 
"""LockRect failed", MB_OK);
        
return 0;
    }

但是郁闷的是 LockRect出错,lock不了,网上查了下发现opengl可以但是dx9好像不行 ,如果要lock 后缓冲区需要改变格式。但这样又不符合我要是有stencil的要求了,不知道有没其他途径可以读取到stencil的值,继续找找资料吧~
posted @ 2011-09-13 23:43 木华 阅读(271) | 评论 (0)编辑 收藏
  2011年9月4日

      今天在写一个mfc程序。但是老是出现error LNK2005的错误,之前也碰到过类似的错误,但是如何解决的就忘记了。折腾了很久才在网上找到这个原因,在此记录一下。
原来我的mfc中有一个.h文件里面定义了一些工具函数。没有使用inline。
下面记录一下网友终结出来的:
编写MFC程序时,自定义类(未用MFC类生成向导定义的类,类定义与成员函数都放在.h头文件里),若其成员函数放在类定义外,必须成员函数定义处必须加上“inline”,即将成员函数定义为内置函数!否则,链接时就会出现“error LNK2005:…… already defined in”错误!
此类错误解决办法:
1、将成员函数定义移入类定义内;
2、在成员函数定义加上“inline”,即将成员函数定义为内置函数
3、改用MFC类生成向导定义类

posted @ 2011-09-04 19:56 木华 阅读(167) | 评论 (0)编辑 收藏
  2011年7月30日

      昨天在导出actionscript的发行版本时候出现了堆栈上溢的错误,但是郁闷的是debug版本没事。也无法调试所以只好网上查资料,也有童鞋碰到了类似的问题,他们讨论的问题是:是否有死循环,代码上的错误,编译器的问题,类之间的循环初始化等等。但是仔细检查检查后发现都不是这些问题呀。最后觉得是否是函数之间的调用导致了它的问题呢?因为我在那个出错的代码中有类似的调用:
      类A 中的函数aF1(),aF2()  ,类B中的bF1();其中 aF1()中调用了B类中的bF1(),并且B类中的bF1()调用了A类的aF2()。这样很平常的函数调用呀,并且在同一个项目中也有类似的写法。无奈之下只好改变这种写法试试。果不其然,修改后代码就没问题了,导出的发行版本也就ok了。其中的原因可能是发行版本进行了一些压缩,优化等导致了堆栈的限制。哎,是flash 太内个,还是自己程序设计太烂了呢 ~~~

posted @ 2011-07-30 07:33 木华 阅读(769) | 评论 (0)编辑 收藏
仅列出标题  下一页