Unity3D遊戲開發之如何用U3D截圖的技能培訓

七大黍發表於2014-10-15


       歡迎來到企業培訓教育專區,這裡有很多我們致力於打造業內培訓、學習第一品牌

今天我們來做點簡單的東西,做個什麼呢?答案就是截圖。如圖,下面是收集的部分截圖:


       好了,欣賞完美麗的風景,下面我們就來一起學習在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
 

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




相關文章