Unity3D遊戲開發之如何截屏的技能培訓

        下面我們開始今天的Unity3D技能培訓。 我們學習Unity3D培訓目標:讓U3D初學者可以更快速的掌握U3D技術,自行製作修改素材,可以獨立完成2D、3D小規模遊戲及網頁遊戲開發。      

       今天我們來做點簡單的東西,做個什麼呢?答案就是截屏。作爲一名熱愛單機遊戲的玩家,每次在玩遊戲的同時截取遊戲中比較喜歡的畫面,特別是學習了Unity3D以後玩遊戲的時候更多地是從一個遊戲設計者的角度來看待遊戲,換句話說,可能關注技術的成分更多一點吧。比如在寫Unity3D遊戲開發之自由視角下的角色控制》Unity3D遊戲開發之角色控制漫談》這兩篇文章時,碰到無法把握的問題的時候就是通過玩遊戲來體會的,在玩遊戲的過程中總是會抓取比較喜歡的畫面,如圖,下面是收集的部分截圖:


       好了,欣賞完美麗的風景,下面我們就來一起學習在Unity3D實現截屏,先給出實現截屏的三種實現方式:

[csharp] view plaincopyprint?

  1. /// <summary>  

  2.     /// 使用Application類下的CaptureScreenshot()方法實現截圖  

  3.     /// 優點:簡單,可以快速地截取某一幀的畫面、全屏截圖  

  4.     /// 缺點:不能針對攝像機截圖,無法進行局部截圖  

  5.     /// </summary>  

  6.     /// <param name="mFileName">M file name.</param>  

  7.     private void CaptureByUnity(string mFileName)  

  8.     {  

  9.         Application.CaptureScreenshot(mFileName,0);  

  10.     }  

  11.   

  12.     /// <summary>  

  13.     /// 根據一個Rect類型來截取指定範圍的屏幕  

  14.     /// 左下角爲(0,0)  

  15.     /// </summary>  

  16.     /// <param name="mRect">M rect.</param>  

  17.     /// <param name="mFileName">M file name.</param>  

  18.     private IEnumerator CaptureByRect(Rect mRect,string mFileName)  

  19.     {  

  20.         //等待渲染線程結束  

  21.         yield return new WaitForEndOfFrame();  

  22.         //初始化Texture2D  

  23.         Texture2D mTexture=new Texture2D((int)mRect.width,(int)mRect.height,TextureFormat.RGB24,false);  

  24.         //讀取屏幕像素信息並存儲爲紋理數據  

  25.         mTexture.ReadPixels(mRect,0,0);  

  26.         //應用  

  27.         mTexture.Apply();  

  28.           

  29.           

  30.         //將圖片信息編碼爲字節信息  

  31.         byte[] bytes = mTexture.EncodeToPNG();    

  32.         //保存  

  33.         System.IO.File.WriteAllBytes(mFileName, bytes);  

  34.           

  35.         //如果需要可以返回截圖  

  36.         //return mTexture;  

  37.     }  

  38.   

  39.     private IEnumerator  CaptureByCamera(Camera mCamera,Rect mRect,string mFileName)  

  40.     {  

  41.         //等待渲染線程結束  

  42.         yield return new WaitForEndOfFrame();  

  43.   

  44.         //初始化RenderTexture  

  45.         RenderTexture mRender=new RenderTexture((int)mRect.width,(int)mRect.height,0);  

  46.         //設置相機的渲染目標  

  47.         mCamera.targetTexture=mRender;  

  48.         //開始渲染  

  49.         mCamera.Render();  

  50.           

  51.         //激活渲染貼圖讀取信息  

  52.         RenderTexture.active=mRender;  

  53.           

  54.         Texture2D mTexture=new Texture2D((int)mRect.width,(int)mRect.height,TextureFormat.RGB24,false);  

  55.         //讀取屏幕像素信息並存儲爲紋理數據  

  56.         mTexture.ReadPixels(mRect,0,0);  

  57.         //應用  

  58.         mTexture.Apply();  

  59.           

  60.         //釋放相機,銷燬渲染貼圖  

  61.         mCamera.targetTexture = null;     

  62.         RenderTexture.active = null;   

  63.         GameObject.Destroy(mRender);    

  64.           

  65.         //將圖片信息編碼爲字節信息  

  66.         byte[] bytes = mTexture.EncodeToPNG();    

  67.         //保存  

  68.         System.IO.File.WriteAllBytes(mFileName,bytes);  

  69.           

  70.         //如果需要可以返回截圖  

  71.         //return mTexture;  

  72.     }  

  73.   

  74. }  


      接下來,我們來調用這三個方法實現一個簡單的截圖的例子:

[csharp] view plaincopyprint?

  1. //定義圖片保存路徑  

  2.     private string mPath1;  

  3.     private string mPath2;  

  4.     private string mPath3;  

  5.   

  6.     //相機  

  7.     public Transform CameraTrans;  

  8.   

  9.     void Start()  

  10.     {  

  11.         //初始化路徑  

  12.         mPath1=Application.dataPath+"\\ScreenShot\\ScreenShot1.png";  

  13.         mPath2=Application.dataPath+"\\ScreenShot\\ScreenShot2.png";  

  14.         mPath3=Application.dataPath+"\\ScreenShot\\ScreenShot3.png";  

  15.     }  

  16.   

  17.     //主方法,使用UGUI實現  

  18.     void OnGUI()  

  19.     {  

  20.         if(GUILayout.Button("截圖方式1",GUILayout.Height(30))){  

  21.             CaptureByUnity(mPath1);  

  22.         }  

  23.         if(GUILayout.Button("截圖方式2",GUILayout.Height(30))){  

  24.             StartCoroutine(CaptureByRect(new Rect(0,0,1024,768),mPath2));  

  25.         }  

  26.         if(GUILayout.Button("截圖方式3",GUILayout.Height(30))){  

  27.             //啓用頂視圖相機  

  28.             CameraTrans.camera.enabled=true;  

  29.             //禁用主相機  

  30.             Camera.main.enabled=false;  

  31.             StartCoroutine(CaptureByCamera(CameraTrans.camera,new Rect(0,0,1024,768),mPath3));  

  32.         }  

  33.     }  

  34.   

  35.   

  36.       

       在第三中截圖方式中,在場景裏放了一個名爲TopCamera的攝像機,它垂直向下投影到遊戲場景裏,這樣可以使玩家看到場景的頂視圖。這裏我們用這個相機來測試第三個方法,此時需要先激活該相機。場景設置如圖:

        我們下面來看三種方法截圖的效果:


        從截圖的效果來看,第一種方法的效果是最好的,不過定製化是個問題。第二種方法效果一般吧,感覺這裏TextureFormat沒有選好吧。第三種效果基本達到了想要的要求,不過攝像機的投影範圍似乎沒有設計好。這裏我們發現第二張截圖會把編輯器的窗口渲染到裏面,認爲是程序運行的時候,即使將Game窗口放到最大,仍然會受到窗口的影響,後來就把程序編譯成可執行文件,不過程序運行完之後,卻沒有找到對應的截圖。後來查找了官方的API才知道原因是這樣的:

Description

Contains the path to the game data folder (Read Only).

The value depends on which platform you are running on:

Unity Editor: <path to project folder>/AssetsMac player: <path to player app bundle>/ContentsiPhone player: <path to player app bundle>/<AppName.app>/DataWin player: <path to executablename_Data folder>Web player: The absolute url to the player data file folder (without the actual data file name)Flash: The absolute url to the player data file folder (without the actual data file name)Note that the string returned on a PC will use a forward slash as a folder separator

 更多精彩請點擊http://www.gopedu.com/article

        顯然,我們從這裏可以知道Application.datapath在不同的平臺上對應的位置。對於可執行(.exe,Windows平臺)的文件,它對應在和應用程序對應的一個文件夾裏,例如可執行文件的名字叫做UnityGame,那麼對應的位置就是UnityGame_Data這個文件啦。所以問題應該是出在沒有在這裏建一個ScreenShot的文件夾,希望大家以後做相關項目的時候注意一下吧。好了,這就是今天的內容了,希望大家喜歡啊。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章