筆者介紹:姜雪偉,IT公司技術合伙人,IT高級講師,CSDN社區專家,特邀編輯,暢銷書作者,國家專利發明人;已出版書籍:《手把手教你架構3D游戲引擎》電子工業出版社和《Unity3D實戰核心技術詳解》電子工業出版社等。
Avatar換裝系統又稱為紙娃娃系統,在游戲開發中是使用非常廣泛的技術,特別是在MMOARPG或是MMORPG等網絡游戲中,玩家創建的3D角色都具有Avatar換裝功能,在游戲開發中常常需要對角色更換設備,比如角色在戰役進程中獲得到新的盔甲要穿著在身上或新的武器要更換等等。要實現該技術所使用的引擎都必須具有支持Avatar換裝系統的骨骼掛節點,比如市面上的Unity引擎,UE4引擎等都提供了這類掛接骨骼方法,獲得到骨骼掛節點后,可以直接將武器掛接到需要綁定的骨骼上。實現的效果以下圖:
場景中的3個角色彩用了Avatar換裝技術,它們采取的是同1套骨架,將需要更換的各個Mesh模型都掛接到對應的骨架上,從而構成了Avatar換裝系統。而本書介紹的Cocos2d-x引擎也不例外,該引擎也提供了支持Avatar技術的功能,實現該功能的類是AttachNode。下面介紹實現掛接結點的步驟,不論是掛接Mesh還是在角色身上掛接武器都需要根據骨骼掛接,這就要用到AttachNode類實現的功能,實現的函數以下所示:
AttachNode* AttachNode::create(Bone3D* attachBone) { auto attachnode = new (std::nothrow) AttachNode(); attachnode->_attachBone = attachBone; attachnode->autorelease(); return attachnode; }
首先是創建需要掛接的骨骼,骨骼動畫是需要矩陣支持的,骨骼動畫它在世界坐標系中的變換都需要轉換到世界變換矩陣,這些實現進程也需要引擎提供,下面把接口的函數給讀者展現以下:
Mat4 AttachNode::getWorldToNodeTransform() const { static Mat4 mat; mat.setIdentity(); auto parent = getParent(); if (parent) { mat=parent->getWorldToNodeTransform() * _attachBone->getWorldMat() * Node::getNodeToParentTransform(); } else { mat=_attachBone->getWorldMat() * Node::getNodeToParentTransform(); } return mat; }
getWorldToNodeTransform函數的實現原理是把模型掛接到骨骼上,該骨骼是需要掛接模型的父結點,父結點運動會帶動所綁的模型運動,從而保證掛接到骨骼結點的武器能夠與骨骼動畫1致。這個實現進程是與矩陣相干的,通過案例把實現的代碼片斷給讀者展現以下:
//Girl.c3b里保存了女角色所履行動畫的所有零件(姑且這么叫吧)包括衣服,鞋子等等 std::string fileName = "Sprite3DTest/Girl.c3b"; auto sprite = Sprite3D::create(fileName); sprite->setScale(4); sprite->setRotation3D(Vec3(0,0,0)); addChild(sprite); sprite->setPosition( Vec2( p.x, p.y⑹0) ); auto animation = Animation3D::create(fileName); if (animation) { auto animate = Animate3D::create(animation); sprite->runAction(RepeatForever::create(animate)); } _sprite = sprite; _curSkin[SkinType::UPPER_BODY] = "Girl_UpperBody01"; _curSkin[SkinType::PANTS] = "Girl_LowerBody01"; _curSkin[SkinType::SHOES] = "Girl_Shoes01"; _curSkin[SkinType::HAIR] = "Girl_Hair01"; _curSkin[SkinType::FACE] = "Girl_Face01"; _curSkin[SkinType::HAND] = "Girl_Hand01"; _curSkin[SkinType::GLASSES] = "";
//函數getMeshCount獲得動畫所有零件數目 for (ssize_t i = 0; i < _sprite->getMeshCount(); i++) { auto mesh = _sprite->getMeshByIndex(static_cast<int>(i)); bool isVisible = false; for (auto& it : _curSkin) { if (mesh->getName() == it.second) { isVisible = true; break; } } //通過索引來獲得零件并設置可見性 _sprite->getMeshByIndex(static_cast<int>(i))->setVisible(isVisible); }
下面給大家展現利用案例代碼以下所示:
std::string str = _curSkin[SkinType::HAIR]; if (str == "Girl_Hair01") _curSkin[SkinType::HAIR] = "Girl_Hair02"; else _curSkin[SkinType::HAIR] = "Girl_Hair01";
場景中的角色褲子、頭發、鞋子都產生了改變,完成換裝。關于換裝,筆者在CSDN學院出版1個免費的視頻講座《游戲Avatar換裝系統》,供開發者參考。
下一篇 學習資料