下面我們開始今天的Unity3D技能培訓。 我們學習Unity3D培訓目標:讓U3D初學者可以更快速的掌握U3D技術,自行製作修改素材,可以獨立完成2D、3D小規模遊戲及網頁遊戲開發。
今天我們來做點簡單的東西,做個什麼呢?答案就是截屏。作爲一名熱愛單機遊戲的玩家,每次在玩遊戲的同時截取遊戲中比較喜歡的畫面,特別是學習了Unity3D以後玩遊戲的時候更多地是從一個遊戲設計者的角度來看待遊戲,換句話說,可能關注技術的成分更多一點吧。比如在寫《Unity3D遊戲開發之自由視角下的角色控制》和《Unity3D遊戲開發之角色控制漫談》這兩篇文章時,碰到無法把握的問題的時候就是通過玩遊戲來體會的,在玩遊戲的過程中總是會抓取比較喜歡的畫面,如圖,下面是收集的部分截圖:
好了,欣賞完美麗的風景,下面我們就來一起學習在Unity3D實現截屏,先給出實現截屏的三種實現方式:
[csharp] view plaincopyprint?
/// <summary>
/// 使用Application類下的CaptureScreenshot()方法實現截圖
/// 優點:簡單,可以快速地截取某一幀的畫面、全屏截圖
/// 缺點:不能針對攝像機截圖,無法進行局部截圖
/// </summary>
/// <param name="mFileName">M file name.</param>
private void CaptureByUnity(string mFileName)
{
Application.CaptureScreenshot(mFileName,0);
}
/// <summary>
/// 根據一個Rect類型來截取指定範圍的屏幕
/// 左下角爲(0,0)
/// </summary>
/// <param name="mRect">M rect.</param>
/// <param name="mFileName">M file name.</param>
private IEnumerator CaptureByRect(Rect mRect,string mFileName)
{
//等待渲染線程結束
yield return new WaitForEndOfFrame();
//初始化Texture2D
Texture2D mTexture=new Texture2D((int)mRect.width,(int)mRect.height,TextureFormat.RGB24,false);
//讀取屏幕像素信息並存儲爲紋理數據
mTexture.ReadPixels(mRect,0,0);
//應用
mTexture.Apply();
//將圖片信息編碼爲字節信息
byte[] bytes = mTexture.EncodeToPNG();
//保存
System.IO.File.WriteAllBytes(mFileName, bytes);
//如果需要可以返回截圖
//return mTexture;
}
private IEnumerator CaptureByCamera(Camera mCamera,Rect mRect,string mFileName)
{
//等待渲染線程結束
yield return new WaitForEndOfFrame();
//初始化RenderTexture
RenderTexture mRender=new RenderTexture((int)mRect.width,(int)mRect.height,0);
//設置相機的渲染目標
mCamera.targetTexture=mRender;
//開始渲染
mCamera.Render();
//激活渲染貼圖讀取信息
RenderTexture.active=mRender;
Texture2D mTexture=new Texture2D((int)mRect.width,(int)mRect.height,TextureFormat.RGB24,false);
//讀取屏幕像素信息並存儲爲紋理數據
mTexture.ReadPixels(mRect,0,0);
//應用
mTexture.Apply();
//釋放相機,銷燬渲染貼圖
mCamera.targetTexture = null;
RenderTexture.active = null;
GameObject.Destroy(mRender);
//將圖片信息編碼爲字節信息
byte[] bytes = mTexture.EncodeToPNG();
//保存
System.IO.File.WriteAllBytes(mFileName,bytes);
//如果需要可以返回截圖
//return mTexture;
}
}
接下來,我們來調用這三個方法實現一個簡單的截圖的例子:
[csharp] view plaincopyprint?
//定義圖片保存路徑
private string mPath1;
private string mPath2;
private string mPath3;
//相機
public Transform CameraTrans;
void Start()
{
//初始化路徑
mPath1=Application.dataPath+"\\ScreenShot\\ScreenShot1.png";
mPath2=Application.dataPath+"\\ScreenShot\\ScreenShot2.png";
mPath3=Application.dataPath+"\\ScreenShot\\ScreenShot3.png";
}
//主方法,使用UGUI實現
void OnGUI()
{
if(GUILayout.Button("截圖方式1",GUILayout.Height(30))){
CaptureByUnity(mPath1);
}
if(GUILayout.Button("截圖方式2",GUILayout.Height(30))){
StartCoroutine(CaptureByRect(new Rect(0,0,1024,768),mPath2));
}
if(GUILayout.Button("截圖方式3",GUILayout.Height(30))){
//啓用頂視圖相機
CameraTrans.camera.enabled=true;
//禁用主相機
Camera.main.enabled=false;
StartCoroutine(CaptureByCamera(CameraTrans.camera,new Rect(0,0,1024,768),mPath3));
}
}
在第三中截圖方式中,在場景裏放了一個名爲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的文件夾,希望大家以後做相關項目的時候注意一下吧。好了,這就是今天的內容了,希望大家喜歡啊。