cocos接入unity文檔

1.WorkSpace

實現(xiàn)cocos2dx項目和unity項目互相調(diào)用的方法就是依賴WorkSpace。
當一個 target 被多個不同的項目依賴班套,或者 project 之間互相引用晰骑,那么我們就需要把這些 projects 放到相同的層級上來泣洞。管理相同層級 projects 的容器就是 Workspace席舍。
workspace 是純粹的容器勒魔,不參與任何編譯鏈接過程践图,它主要管理:
1.Xcode 中的 projects掺冠,記錄它們在 Finder 中的引用位置。
2.一些用戶界面的自定義信息(窗口的位置码党,順序德崭,偏好等等)。

在我們的主工程中其實只做了一件事揖盘,引用了UnityFramework
引用UnityFramework.png

這樣cocos的工程和unity的工程耦合度非常低接癌。

unity工程中導出為ios項目時需要選擇導出為framework庫,方便我們的工程引用扣讼。
需要把data資源也指向UnityFramework缺猛,這樣所有內(nèi)容都封裝到單個框架中了。
最后需要把UnityFramework改為public的模式椭符,這樣就可以調(diào)用unity中的代碼了荔燎。
http://www.reibang.com/p/830cb9455c3b)可以參考這個文章,講的很詳細销钝。

2.窗口

  • unity和cocos2dx界面的相互切換實際上就是window在互相切換有咨。

  • 從cocos2dx返回到unity使用的方法是

先暫停cocos項目

cocos2d::Application::getInstance()->applicationDidEnterBackground();

初始化unity的窗口

[[self ufw] runEmbeddedWithArgc: gArgc argv: gArgv appLaunchOpts: appLaunchOpts];

調(diào)用此方法就可以展示unityWindow界面

[[self ufw] showUnityWindow];

使用此方法可以傳遞參數(shù)到unity中(這里我們用來傳遞登錄參數(shù))。

[self sendMsgToUnityWithName:"CocosLauncher" functionName:"RecvCocosData" message:[data UTF8String]];

  • 從unity返回到cocos2dx使用的方法是

卸載unity

unloadApplication

使主窗口顯示到屏幕的最前端蒸健。

[self.window makeKeyAndVisible];

然后調(diào)用

cocos2d::Application::getInstance()->applicationWillEnterForeground();

這個cocos的方法會發(fā)送一個事件event_will_enter_foreground

void AppDelegate::applicationWillEnterForeground() {
    Director::getInstance()->startAnimation();
    SimpleAudioEngine::getInstance()->setBackgroundMusicVolume(s_bgmVolume);
    SimpleAudioEngine::getInstance()->setEffectsVolume(s_effectsVolume);
    Director::getInstance()->getEventDispatcher()->dispatchCustomEvent("event_will_enter_foreground");
}

只需要在lua代碼中監(jiān)聽此事件座享,跳轉(zhuǎn)到LobbyScene.start()就回到了我們的大廳界面中婉商。

3.內(nèi)存優(yōu)化

使用了窗口切換的方式,我們在調(diào)用另一個窗口時渣叛,需要保持原窗口中的內(nèi)存占用量最小丈秩。

常態(tài)下的內(nèi)存占用.png

常態(tài)下打開大廳的內(nèi)存一般是181mb。
卸載內(nèi)存的兩個思路:第一個是卸載資源淳衙,第二個是卸載lua代碼蘑秽。
卸載lua內(nèi)存依靠的是lua的自動回收機制,就是在mian函數(shù)里的那三行代碼

--執(zhí)行一個完整的垃圾收集循環(huán)
collectgarbage("collect")

--setpause為100代表箫攀,垃圾收集不會停止
collectgarbage("setpause", 100)

--setsetpmul為5000代表是內(nèi)存分配速度的50倍
collectgarbage("setstepmul", 5000)

既然已經(jīng)有了自動回收機制我們能做的事情也就不多了肠牲,至于去刪除全局變量的東西,一是沒必要靴跛,二是很危險缀雳。

卸載資源的方法是

display.removeUnusedSpriteFrames()

這個方法中,cocos幫我們卸載了不用的資源占用梢睛。

function display.removeUnusedSpriteFrames()
    spriteFrameCache:removeUnusedSpriteFrames()
    textureCache:removeUnusedTextures()
end

所以肥印,解決方案就是:在需要喚起unity時先跳轉(zhuǎn)到一個新的scene上,卸載掉原先的資源內(nèi)存扬绪。于是代碼就順理成章的寫為:

//加載新的scene
local JumpScene = {}
local scene = display.newScene("JumpScene")
local node = BUI:loadCSB("Lobby/LobbyScene/CSB/JumpScene.csb", JumpScene)
scene:addChild(node)
display.runScene(scene, "FADE")
//卸載圖片資源
display.removeUnusedSpriteFrames()

由于runScene也就是replaceScene在跳轉(zhuǎn)到新的場景后會自動從內(nèi)存中刪除,再調(diào)用刪除無用的資源代碼裤唠,是不是就能獲得比較好的內(nèi)存結(jié)果了挤牛?


跳轉(zhuǎn)場景后直接進行回收資源操作.png

答案是no!
那么為什么呢种蘸?
這里得提到replaceScene切換場景墓赴,scene的生命周期

假設(shè)scene A是活動場景,現(xiàn)在我們用scene B來replaceScene替換A航瞭,A和B的生命周期是這樣的:

B ---- init();
A ---- onExit();
A ---- 析構(gòu)函數(shù)被調(diào)用
B ---- onEnter();
B ---- onEnterTransitionDidFinish();

答案就顯而易見了诫硕,A場景并不會立馬從內(nèi)存中刪除,所以調(diào)用removeUnusedSpriteFrames的效果并不好刊侯。
于是簡單的修改一下代碼章办,只需要加入

display.getRunningScene():removeAllChildren()

在去B場景前刪除A場景中的所有Node,然后就能獲得一個比較理想的內(nèi)存:

刪除所有Node后再進行資源回收.png

但是到這里就結(jié)束了嗎滨彻?
我測試了游戲界面直接進入到預(yù)跳轉(zhuǎn)界面的內(nèi)存是43mb左右藕届,還有10mb的內(nèi)存不對勁!
那么這部分是什么呢亭饵?
我在網(wǎng)上搜尋了一些答案休偶,發(fā)現(xiàn)有可能是spine動畫的泄露問題造成的!
于是一路查找spine動畫的問題辜羊,發(fā)現(xiàn)我們項目中的spine動畫都是使用
sp.SkeletonAnimation:create方法生成一個新的節(jié)點踏兜。
而這個方法的底層中會給每一個動畫都創(chuàng)建一個新的SkeletonRenderer類词顾,這個類會去讀取一份新的動畫紋理資源,并持有碱妆,這就導致了同一個動畫占用資源越來越多的情況肉盹!
我在cocos社區(qū)搜尋了一下答案,提出問題的很多山橄,但是都沒有解決方案垮媒。
直到看到了這個帖子:
https://www.cnblogs.com/chevin/p/5667768.html
原理也很簡單航棱,就是創(chuàng)建一個map,在創(chuàng)建紋理時存儲到該map中饮醇,然后再新建改動畫時,直接使用此紋理朴艰,就不用創(chuàng)建新紋理了观蓄。
正當我準備把這些代碼接入到我們工程中時,我發(fā)現(xiàn)已經(jīng)有前人接入過了侮穿,當然也有可能是官方加的……
新的方法就是

sp.SkeletonAnimation:createWithFileAndAddCache("spine name", "json file", "atlas file", scale)

當然毁嗦,他還提供了一系列其他的方法:

tolua_function(tolua_S,"setStartListener",lua_cocos2dx_spine_SkeletonAnimation_setStartListener);   
tolua_function(tolua_S,"setTrackEventListener",lua_cocos2dx_spine_SkeletonAnimation_setTrackEventListener);        
tolua_function(tolua_S,"setTrackCompleteListener",lua_cocos2dx_spine_SkeletonAnimation_setTrackCompleteListener);     
tolua_function(tolua_S,"getSkeletonData",lua_cocos2dx_spine_SkeletonAnimation_getSkeletonData);   
tolua_function(tolua_S,"setTrackStartListener",lua_cocos2dx_spine_SkeletonAnimation_setTrackStartListener);
tolua_function(tolua_S,"findAnimation",lua_cocos2dx_spine_SkeletonAnimation_findAnimation);
tolua_function(tolua_S,"setCompleteListener",lua_cocos2dx_spine_SkeletonAnimation_setCompleteListener);
tolua_function(tolua_S,"setTrackEndListener",lua_cocos2dx_spine_SkeletonAnimation_setTrackEndListener);
tolua_function(tolua_S,"setEventListener",lua_cocos2dx_spine_SkeletonAnimation_setEventListener);
tolua_function(tolua_S,"setMix",lua_cocos2dx_spine_SkeletonAnimation_setMix);
tolua_function(tolua_S,"setEndListener",lua_cocos2dx_spine_SkeletonAnimation_setEndListener);
tolua_function(tolua_S,"clearTracks",lua_cocos2dx_spine_SkeletonAnimation_clearTracks);
tolua_function(tolua_S,"clearTrack",lua_cocos2dx_spine_SkeletonAnimation_clearTrack);
tolua_function(tolua_S,"createWithBinaryFile", lua_cocos2dx_spine_SkeletonAnimation_createWithBinaryFile);
tolua_function(tolua_S,"readSkeletonDataToCache", lua_cocos2dx_spine_SkeletonAnimation_readSkeletonDataToCache);
tolua_function(tolua_S,"removeAllSkeletonData", lua_cocos2dx_spine_SkeletonAnimation_removeAllSkeletonData);
tolua_function(tolua_S,"create", lua_cocos2dx_spine_SkeletonAnimation_create);
tolua_function(tolua_S,"isExistSkeletonDataInCache", lua_cocos2dx_spine_SkeletonAnimation_isExistSkeletonDataInCache);
tolua_function(tolua_S,"createFromCache", lua_cocos2dx_spine_SkeletonAnimation_createFromCache);
tolua_function(tolua_S,"getSkeletonDataFromCache", lua_cocos2dx_spine_SkeletonAnimation_getSkeletonDataFromCache);
tolua_function(tolua_S,"createWithJsonFile", lua_cocos2dx_spine_SkeletonAnimation_createWithJsonFile);
tolua_function(tolua_S,"removeSkeletonData", lua_cocos2dx_spine_SkeletonAnimation_removeSkeletonData);

這里不展開贅述亲茅,唯一需要講的就是此方法需要自己管理內(nèi)存,我會在返回大廳時刪除所有的紋理緩存狗准,避免游戲中忘記管理自己的內(nèi)存克锣。

ok腔长∠睿回到正題捞附,那么這最后10mb內(nèi)存是由于spine導致的嗎?
答案是想鹰,no药版。
使用create方法創(chuàng)建的動畫雖然會每次都占一點內(nèi)存,但是他們在節(jié)點刪除時也會自動卸載內(nèi)存槽片,所以方向并不對肢础。
內(nèi)存包含所有Malloc的部分碌廓,比如聲音資源,全局產(chǎn)量慨蛙,數(shù)組等纪挎,如果把這些都想卸載干凈,下一次在回到大廳的時候可能會出現(xiàn)問題异袄,而且需要重新加載,所以綜合考慮下就忽略了封孙。

那么讽营,到這里就結(jié)束了嗎?
最終測試的時候還遇到了一個問題:
unity返回到cocos窗口中時橱鹏,調(diào)用的applicationWillEnterForeground方法,分發(fā)event_will_enter_foreground事件無效蚀瘸!
在lua代碼中監(jiān)聽此事件會返回到大廳里庶橱,否則就一直停留在過渡場景了贮勃。
那么這個問題是什么呢……
最后問題又回到了cocos的場景切換流程苏章。
在切換場景時,會關(guān)閉所有的事件分發(fā)枫绅,直到場景加載完成了,才會重新啟用事件分發(fā)寓搬。
so……
我決定不跳轉(zhuǎn)場景了县耽,直接刪除該場景下所有的節(jié)點镣典,刪除無用資源唾琼,加載跳轉(zhuǎn)界面。
完結(jié)……撒花……

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赶舆,一起剝皮案震驚了整個濱河市祭饭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夕晓,老刑警劉巖悠咱,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件析既,死亡現(xiàn)場離奇詭異躬贡,居然都是意外死亡眼坏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門檐蚜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闯第,“玉大人缀拭,你說我怎么就攤上這事≈肓埽” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵勾效,是天一觀的道長。 經(jīng)常有香客問我绘迁,道長卒密,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任膛腐,我火速辦了婚禮鼎俘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘勘天。我一直安慰自己捉邢,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布伏伐。 她就那樣靜靜地躺著,像睡著了一般藐翎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堤器,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天末贾,我揣著相機與錄音,去河邊找鬼圈暗。 笑死裕膀,一個胖子當著我的面吹牛勇哗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼渺鹦,長吁一口氣:“原來是場噩夢啊……” “哼蛹含!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吸耿,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤酷窥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后妆棒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沸伏,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年放接,在試婚紗的時候發(fā)現(xiàn)自己被綠了留特。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡苟蹈,死狀恐怖右核,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情菱鸥,我是刑警寧澤躏鱼,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站染苛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏躯概。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一牧牢、第九天 我趴在偏房一處隱蔽的房頂上張望姿锭。 院中可真熱鬧,春花似錦献幔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至情连,卻和暖如春览效,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锤灿。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工但校, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人状囱。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像袭艺,于是被迫代替她去往敵國和親奶栖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容