在ios8中,要在plist裡加上NSLocationWhenInUseUsageDescription這個property,否則LocationManager的didUpdateLocations 不會正確被呼叫到。
NSLocationWhenInUseUsageDescription是在iOS8才出現的關鍵字。
http://stackoverflow.com/questions/24874997/core-location-not-working-in-ios-8
http://stackoverflow.com/questions/24717547/ios-8-map-kit-obj-c-cannot-get-users-location
2014年7月24日 星期四
2014年5月20日 星期二
Unity上開啟WebView(iOS/Android)
Unity上有提供Application.OpenURL(string)的函式來開啟網頁,但是這功能其實是開啟safari/chorme中的網頁,而不是在Unity的app中打開網頁。那麼,要如何做到在Unity app中內嵌一個網頁呢?
https://github.com/Kogarasi/Unity-Webview
gitHub是我們的好朋友~XD
這個專案看來應該是延續gree的webView做修改的:
https://github.com/gree/unity-webview
使用上並不難,看一下它的範例檔就可以了。但是我有碰到幾個問題:
1.開啟了第一個url後,如果要開另一個url的話會沒有反應,會閃一下然後又開啟第一個url。這個問題在Mac上沒有發生,但是在iOS上會出現,我不確定PC/Android是否也有這個問題。
解決方法是Destroy第一個webView後,另建一個新的WebView來開啟新的url。
2.在Android上有碰到網頁雖然開啟了,但是卻無法操作的狀況,在討論中有提到怎麼解決:
https://github.com/Kogarasi/Unity-Webview/issues/2
基本上就是改動AndroidManifest.xml中的設定,在Unity官網上其實本來就有講到這個部份,不過我跟Android不熟就是了XDD
http://docs.unity3d.com/Documentation/Manual/PluginsForAndroid.html
以上
2014年4月7日 星期一
iGov
在FB上說好的五毛黨遊戲prototype。
雖然到這場運動都要暫時喘一口氣時才生出來一個prototype,但總算還是弄出了點東西。
https://github.com/stanley1108/iGov
雖然到這場運動都要暫時喘一口氣時才生出來一個prototype,但總算還是弄出了點東西。
https://github.com/stanley1108/iGov
2014年3月9日 星期日
[翻譯]Unity, C#, .Net Mono的記憶體節省方法
[翻譯]Unity, C#, .Net Mono的記憶體節省方法
這篇斷斷續續混了好久才翻完....
==以下為翻譯內文=================================================
iOS上的Unity使用非常早期的Mono heap記憶體管理機制。這個機制不包裝中介層,所以一旦你讓heap碎片化,它會直接抓一塊新的記憶體給你。我的印象中Unity的實驗室怪傑們在做一個新的heap管理機制來處理這個問題,但現在即使是一個沒有memory leak的遊戲也會因為不斷增加的記憶體數量而耗盡記憶體。
C#是個有趣的程式語言,可讓你在不犧牲可讀性的狀況下快速寫出功能強大的的程式碼。然而事情的另一面是撰寫C#程式碼會自然的生出許多的garbage collection,解決掉這問題的唯一方法就是消除或是減少heap allocation。我在不減少功能性的情況下列了個簡單的解決方案清單。
最終的效果就是你的C#程式碼會看起來更像是C++,而且你將失去一些C#所帶來的威力,不過這就是人生。作為獎勵,heap的alloc在CPU上會比stack alloc更加集中(應該是指不會那麼頻繁alloc),所以你應該可以節省下一些frame time。
要標定記憶體削減目標時,Unity profiler可以幫你找到哪些function做了很多allocation。它並沒有提供很多資訊,但至少有。打開Profiler後啟動你的遊戲,選擇CPU profiler並點選GC Alloc欄位,這樣可以依照GC狀況的糟糕程度來排出先後。先使用下列的方針來處理這些function:
- 避免使用foreach()。這會在你的list type中呼叫GetEnumerator(),進而allocate一個很快就會被殺掉的enumerator在heap中,你得改用更囉唆的c++ for(;;)語法才行。
- 避免使用string。string在.NET中是建立在heap中且長度不可變的。你無法像c語言的版本一樣操作string。就UI而言,使用StringBuilders來建立一個string會是個對記憶體較有效率的作法,它會延遲轉換成string的時機直到最後需要的時候才做。你依然可以用string作為keys(應該是指Directory的key),因為literals應該要指到記憶體中的同一個instance,但是別太過度去操作string。
- 使用struct。Struct型別在mono是allocate在stack中,所以當你有個工具類別不想要放掉,用struct。記住struct是傳值(而不是傳reference),使用到struct時可以加個ref的修飾字在函式參數前以避免copy的效能損耗。
- 用structs取代固定大小且在scope內array。如果你有個固定大小而且在scope內的array(像是只在某function內存在),考慮建立一個member array(class內)或是一個struct來代替(或暫存)它。我曾經將每個frame中呼叫spline class都要建立的Vector3[4]改成用一個有四個欄位的ControlList struct代替。我只需要多加一個[]屬性來做為index存取用,而這省下了大量使用該函式而產生的allocation。(註,簡單說來就是用多一些stack或是事先建立好暫存的資料來避免動態allocation)
- 填入ref傳入的lists優先於回傳一個新的lists。傳進去時我們還是需要heap-alloc一個list,所以聽來像是沒有省下什麼東西?但是這讓我們可以使用下一個最佳化的骯髒手段。
- 考慮暫存一個常使用的function內的資料為class member。如果你有個funciton每次呼叫時都要用到很大的list,把那個list存成class member讓該資料空間可以一直保存下來。在C#中呼叫.Clear()並不會清掉buffer,所以在下一個frame時我們幾乎或不會有任何的allocs。這看起來很髒也讓程式碼不好讀,但是可以產生很大的效能差異。
(註,一樣是用事先暫存的手段) - 避免IEnumerable extension methods。不用說,大多的Linq IEnumerable extension methods就如同他們有多好用一樣的也同樣會建立一些allocations。然而令我驚訝的是,在IList<>中呼叫.Any()應該只是呼叫一個Count>0的虛擬函式計算,在這裡卻會觸發一個allocation。其他在IList<>中微不足道的操作在IEnumerable中都會有同樣狀況,像是First()以及Last()。如果有人可以告訴我原因的話我會很感激的。基於如此以及foreach()的問題,我目前會說避免使用IEnumerable abstraction作為interface,改用IList<>。
- 盡量減少使用function pointer。將一個類別方法放到delegate或是一個Func<>中會導致box(轉型成c#物件的動作,http://msdn.microsoft.com/zh-tw/library/25z57t8s(v=vs.80).aspx),而這會觸發一次記憶體配置。我找不到可以儲存一個method link而不觸發boxing的方法。我留下了大部分的function pointer,因為它在解耦物件關係上有極大幫助,所以對我來說還好,但我也處理掉了一些。
- 小心複製material。如果你從任何的renderer中取得material property,這個material會在你即使沒做任何事的狀況下也會clone一份。這個clone出來的material不會被GC掉,除非你換了關卡或是呼叫了Resources.UnloadUnusedAssets(),否則它不會被清掉。如果你沒有要改動該material,改用myRenderer.sharedMaterial。
歡迎各位給予指教。
2014年1月6日 星期一
貓也會的:如何用Unity iOS開啟另一個Unity程式
其實很簡單,是利用URL Scheme的方式。
先假設要被開啟的APP叫做BeenOpenAPP,然後要開啟別的程式的APP叫RootAPP。
第一件事當然是先建立BeenOpenAPP這個APP,但要注意的是不要直接在Unity中Build and Run,接下來必須要在XCode project中做一些手腳。
第二件事是在Unity所建立的BeenOpenAPP專案檔中的Info.plist中加上我們要作為識別用的URL Scheme:
在這個例子裡我就直接設定叫做BeenOpen。
然後,在RootAPP的Unity程式碼中找個你想要開啟BeenOpenAPP的地方,加上:
Application.OpenURL("BeenOpen://test");
這樣會去開啟有BeenOpen這個URL Scheme的app(也就是我們的BeenOpenAPP)。
而後面所帶的"test"可以用另外的方式在native code中取出來,但會需要修改到BeenOpenAPP的XCode專案檔,再用UnitySendMessage()的方式由iOS的native code傳送這個訊息到Unity中。
我自己試驗的時候有意外碰到一個小問題,是Unity所建立出來的App都會是同一個,也就是說我建好的BeenOpenAPP會在Build出RootAPP時被蓋掉。
解決方法是在Xcode Build Setting中設好Product Name,因為從Unity直接Build出來的Xcode Project會預設Product Name就是"Product Name",所以才導致後build的App會蓋掉先前的。
Build Setting->Packaging->Product Name
參考資料:
http://fredandrandall.com/blog/2011/07/30/how-to-launch-your-macios-app-with-a-custom-url/
先假設要被開啟的APP叫做BeenOpenAPP,然後要開啟別的程式的APP叫RootAPP。
第一件事當然是先建立BeenOpenAPP這個APP,但要注意的是不要直接在Unity中Build and Run,接下來必須要在XCode project中做一些手腳。
第二件事是在Unity所建立的BeenOpenAPP專案檔中的Info.plist中加上我們要作為識別用的URL Scheme:
在這個例子裡我就直接設定叫做BeenOpen。
然後,在RootAPP的Unity程式碼中找個你想要開啟BeenOpenAPP的地方,加上:
Application.OpenURL("BeenOpen://test");
這樣會去開啟有BeenOpen這個URL Scheme的app(也就是我們的BeenOpenAPP)。
而後面所帶的"test"可以用另外的方式在native code中取出來,但會需要修改到BeenOpenAPP的XCode專案檔,再用UnitySendMessage()的方式由iOS的native code傳送這個訊息到Unity中。
我自己試驗的時候有意外碰到一個小問題,是Unity所建立出來的App都會是同一個,也就是說我建好的BeenOpenAPP會在Build出RootAPP時被蓋掉。
解決方法是在Xcode Build Setting中設好Product Name,因為從Unity直接Build出來的Xcode Project會預設Product Name就是"Product Name",所以才導致後build的App會蓋掉先前的。
Build Setting->Packaging->Product Name
參考資料:
http://fredandrandall.com/blog/2011/07/30/how-to-launch-your-macios-app-with-a-custom-url/
2013年6月24日 星期一
20130511_Unity BootCamp筆記
以下是我參加會議的筆記,並參考他們Blog做修正。
+Chrome NaCl支援Chrome用C++ base,不需另外安裝plugin。
+與FB談好在FB預設自動安裝Unity plugin
----實現Code動態更新
+Andorid:Include scripts in AssetBundle.去看TextAsset的binary data一節
+iOS:把第一關以及原始碼包成一個App,其他的資料做成AssetBundle
+加密程式碼:看Protecting content一節。
----
+NUGI目前不支援動態字體,2.6版後會有
+500個半透明粒子可以讓mobile的FPS降到7
+mobile硬體主要對triangle做最佳化,而不是對pixel
+推薦用easyTouch做為手勢判別
+Object.Destroy()並不會release material/mesh/texture等資源。
+GUI的使用上仍然推薦用NUGI而不是UNITY內建的GUI
----關於MMO
+大規模場景需要AsserBundle、ScriptableObject
+NavMesh:
NavMesh.Triangulate()可以輸出mesh。(應該是讓企劃或美術在Unity中編
輯後輸出給美術再作編輯)
----
+2D推薦工具有
-2D toolkit
-Sprite Manager 2
-ex2D
+不再推薦使用AssetServer,會在editor支援SVN、Perforce
----3D mobile Game最佳化
+主角/怪物
-300~2000面
-只用一個Skin mesh renderer
-材質1~3個
-bone數量小於30
+動態物體
-用Dynamic batching
+靜態物體
-少於500面
-標記為static
-不要加上Animation component
+地形
-長寬小於257(預設為2000)
-一個terrain物件不要超過4個貼圖
+貼圖
-建議png或tga
-長寬小於等於1024
-使用mipmap
-UV盡量不要超過0~1,因為貼圖合併實比較不會出問題。
+聲音
-BGM用.ogg或.mp3
-音效用.wav或.aif
+Light
-能用lightMap或light probe就盡量用
-Important light設為0或1個,一般會用在方向光,各數越多Drawcall會越
多
-Pixel light數量設為1~2。(在Quality setting中)
+Camera
-使用camera.layerCullDistances來讓某些layer下的物件只在夠近
的距離中才被繪製。
+粒子
-螢幕上同時出現少於200顆
-每個Emitter最多放50個粒子
-粒子的size盡量小
-非常小的粒子的話,拿掉alpha channel(只留顏色/貼圖或是只用1 bit alpha)
-盡量不要用粒子碰撞
+物理
-最好不要用mesh collider
+動畫
-沒有使用動畫的gameObject要拿掉animation controller(手動)
-不需要縮放的話可以在animation editor中手動拿掉scaleCurves,可減少
33%的blending time
-只有一個animation clip的話,改回用原來的animation system
-使用Body mask
-IK用generic mode比較好,用Humanoid Mode的話會套用兩次所以很慢
(一般Bone套用成Humanoid mode,算完IK後再套回去bone)
-Macanim system在有些Android設備上有問題,硬體不支援NEON的會
有問題
+Render
-避免Alpha blending/testing,都很慢。盡量減少需要這樣做的pixel數量。
-使用Static Batching,會需要用到靜態的vertex buffer及動態的
index buffer,會用多一點 memory
-使用Dynamic Batching,會動到動態的vertex buffer及動態的index buffer,
限制是只能用在900面以下的mesh,如果vertex format較複雜的話,其點
數限制會更嚴格。
-設好Occlution culling,建議用PVS and Dynamic Object
+程式碼
-事先cache起來transform等常用的component,直接取用transform等同
於getComponent(),最好在Start()時用
myTransform = transform存起來,在update時只用myTransform
-減少FixedDeltaTime,設在0.04~0.067,可減少物理運算量
-iOS build時使用Fast and Exception Unsupported的build setting選項,
Slow and Safe 會比較慢。
+Shader
-不要用discard指令(用來放棄繼續執行的指令)
-少用sin/cos/sqrt之類的數學運算,用查表代替。
-在PowerVR上用兩個Vec2來而不是合併成一個Vec4,這跟文件上不同
但是測試後是這樣沒錯。
+如何做好最佳化
-多用Profiler
-優化做的再好,不如規劃好
-不停試驗
----AssetBundle工作流程
+Resource資料夾下只能放2G資料。(以後的版本會慢慢捨棄Resource的
功能,改用AssetBundle)
+WWW.Load不會在本地留下cache。
WWW.LoadFromCacheOrDownload()會留Cache。
+AssetBundle.CreateFromMemory()主要用在加解密資料
+用AB的依賴關係可以減少Memory的使用:
Push/PopAssetDependcies()
+描述場景依賴關係的檔案可以用ScriptableObject
+AssetBundle有版本可以查詢,可以強迫使用者下載新的AssetBundle:
LoadFromCache(url, version, crc)
同時也可以檢查CRC
----Unity Shader
嗯...去看官方文件比較快
+用 #pragma debug可以打開Shader code中被Unity隱藏的程式碼。
+有提到一個#pragma multi_compile,不過不太確定其用途。
參考資料
2013年6月12日 星期三
XCode 5 beta 初體驗
+Build setting如果Deployment Device設成iPad,會無法在Build的時候選擇模擬器,要設為iPhone或是Universal才行。
目前看來應該是因為Simulator還沒有iPad版的樣子,我切到Universal也是沒有iPad模擬器可選。
+XCode5雖說有開始支援CI的功能,但是需要有Mac server的支援......
+iOS 7 多了一個GCController class,用來處理搖桿輸入的。
---這篇會持續更新 (吧..... 2014.0310看來是不會更新了 = =)
目前看來應該是因為Simulator還沒有iPad版的樣子,我切到Universal也是沒有iPad模擬器可選。
+XCode5雖說有開始支援CI的功能,但是需要有Mac server的支援......
+iOS 7 多了一個GCController class,用來處理搖桿輸入的。
---這篇會持續更新 (吧..... 2014.0310看來是不會更新了 = =)
訂閱:
文章 (Atom)
