【持续更新】Sprite3D在ui层的绘制和遮挡

有很多朋友对sprite3D在ui层的绘制和遮挡不太明白,这里稍微说明一下。
并且有其他疑问也可以回帖,然后会持续更新一些想要的功能。
引擎版本: cocos2dx 3.6
语言: C++

绘制顺序是按照这种顺序绘制的,

  1. globalz<0的物体

  2. 3D不透明的物体,如果3D物体的globalZ为0,3D物体都在这里绘制,否则根据他们的globalZ决定绘制顺序

  3. 3D透明物体,如果3D透明物体的globalZ为0,都在这里绘制,否则根据他们的globalZ决定绘制顺序,粒子属于3D透明物体,默认在这里绘制。

  4. globalZ=0的物体

  5. globalZ>0的物体

截图:

和骨骼动画的绘制对比
经过我的测试,骨骼动画和sprite3D,他们的绘制顺序是根据globlezorder值 来定的,
在zorder值相同的时候,先绘制骨骼动画,后绘制sprite3D。
否则先绘制zorder值高的物体,没图说个JB,上图!

并且,sprite3D是不会吞噬触摸事件的
附上class文件和resource资源: Resources.zip (373 KB)

CCArmature 创建的动画对象,即使设置的 globalZOrder 比 3D模型低(比如 -1000000),仍然会显示到3D模型的上面
请问这个有什么办法解决?

上个代码和资源。

求教:CCArmature 动画如何同3D模型做层级遮挡啊?

ccs.ArmatureDataManager:getInstance():addArmatureFileInfo(“armature/Cowboy.ExportJson”)
local armAttack1Down = ccs.Armature:create(“Cowboy”)
gWorldScene:addChild(armAttack1Down)
armAttack1Down:setPosition(cc.p(200, 200))
armAttack1Down:setGlobalZOrder(-2000)
armAttack1Down:getAnimation():playWithIndex(0)

local sprite3D = cc.Sprite3D:create(“Sprite3DTest/tortoise.c3b”)
gWorldScene:addChild(sprite3D)
sprite3D:setPosition(cc.p(200, 200))
sprite3D:setGlobalZOrder(-1)

就用TEST里面的资源,动画 setGlobalZOrder(-2000),3D模型setGlobalZOrder(-1)
结果动画仍然在3D模型的上面

gWorldScene 请换成你测试代码里面的 scene

楼主有方法可以实现动画和3D模型间的层级么?

正在测试,等了你半天也 没等到你的资源,我从test中已找到资源,稍等。

已解决,请刷新本网页。:7::7::7::7::7:

绘制顺序是按照这种顺序绘制的,

  1. globalz<0的物体

对于小于0的物体,永远是骨骼动画在前面。你需要设置值为正值就行了。

真的非常感谢楼主如此热情的帮忙解决问题!!!

因为游戏中有UI,所以想把Armature动画和3D模型的globalZOrder设置为负值,这样UI就能显示在最上层。

现在把3D模型的globalZOrder设置成2,然后创建一个UIButton对象,设置这个UIButton对象的globalZOrder为300,会发现 UIxxxx(UILabel,UIImageView…) 类型的对象无法显示在3D模型的上面…

经过测试发现,UIxxx 类型对象的 globalZOrder 似乎没有什么作用

local button = ccui.Button:create()
gWorldScene:addChild(button)
button:loadTextures(“cocosui/animationbuttonnormal.png”, “cocosui/animationbuttonpressed.png”, “”)
button:setPosition(cc.p(250, 230))
button:setGlobalZOrder(300)

local imageView = ccui.ImageView:create(“cocosui/CloseSelected.png”)
gWorldScene:addChild(imageView)
imageView:setPosition(cc.p(250, 230))
imageView:setGlobalZOrder(200)

imageView 的 globalZOrder 比 button 小,但是 imageView 却显示在 button 的上面…

:2:渲染管线解释的很清晰,但是这边的需求有这样的

1:先绘制背景 GLOBALZ_NEG 大地图世界
2:再绘制3d对象 OPAQUE_3D TRANSPARENT_3D 小伙伴们欢乐的奔跑
3:再绘制UI层 GLOBALZ_ZERO 查看主角界面
4:UI层上绘制3d对象 GLOBALZ_ZERO 主角
5:然后再在ui层上弹出窗口盖住这个3d对象 GLOBALZ_ZERO 其他对话框

问题在于,如果在4绘制之后,因为4绘制的3d对象的z为0(视为2d对象),所以在和2的对象混合的时候,会被2透明遮挡部分,demo见这个
http://pan.baidu.com/s/1mgwzDsk

关于这个,是否有解决方案?

版主在么?能否帮忙解决下11楼的问题?

:2:版主人呢,赶快来解决下12楼的问题。。

这个是3D互穿的问题,预计在3.7修复,但是3.7beta0版本有人反馈这个问题还没修复好,所以我需要测试一下3.7的beta0版本。

这是引擎组反馈给我的一段话,我先贴上,你可以先瞅瞅。

hi, 看了一下你的DEMO,也看到的“穿透”的表现。

某种意义上来说是正常的。因为引擎自从有了3D属性的相机后,所有的对象其实都是3D的,你创建的那个怪物跟它下面的Sprite的Z值都为0,故怪物是会互相穿透,就象怪物“站在墙里面一样”。你用这个坐标测试下就会知道了:orcFront->setPosition3D(Vec3(origin.x + visibleSize.width/2,origin.y + visibleSize.height/2, 10));

至于为什么互相穿透的部分为什么会显示成透明,是因为3D与2D混用的这种用法并不是预期的使用方式,故在绘制时会存在些BUG。

你的这个2D和3D图层互相叠加的做法,一般是把2D和3D分开用不同的相机。不过我已测试了,在3.6版本里即使这样写也还是有问题,是BUG,3.7版本正修复这个问题。

看15楼,抱歉,久等了。

首先非常感谢版主解决问题!

因为要做背包,需要在背包上显示3D角色,可以动态查看换装,这样就要把3D角色放在背包界面上。
同时,点击物品图标,需要弹出二级TIPS面板,这个二级面板又需要压住3D角色。
目前使用COCOS3.4,无法把一个3D角色显示在两个UIXXX类型对象的中间。

按版主给出的解决方法,就是给UIXXX类型对象设置一个Z值,结果如下:

可以看到按钮影响了乌龟的部分渲染。

local sprite3D = cc.Sprite3D:create(“Sprite3DTest/tortoise.c3b”)
gWorldScene:addChild(sprite3D)
sprite3D:setPosition3D(cc.vec3(200, 200, 0))
sprite3D:setGlobalZOrder(1)
sprite3D:setScale(0.2)

local button = ccui.Button:create()
gWorldScene:addChild(button)
button:loadTextures(“cocosui/animationbuttonnormal.png”, “cocosui/animationbuttonpressed.png”, “”)
button:setPosition3D(cc.vec3(250, 230, 100))
button:setGlobalZOrder(300)

总之,目前3.4版本3D和2D对象之间的层级关系非常难控制,有时用setGlobalZOrder(),有时要用setPositionZ(),非常混乱。
希望3.7版本能解决这个问题,能把3D对象显示在两个2D UI对象的中间。

为什么我用你的代码,3d 模型依然挡着UI?求解

如何设置不受相机影响的node?就是camera移动,该node不移动,test里面的效果我没看懂怎么做到的。
如何切换相机?