Unity3D游戏开发之如何用U3D截图的技能培训

时间:2023-02-07 18:39:48


       欢迎来到企业培训教育专区,这里有很多我们致力于打造业内培训、学习*

今天我们来做点简单的东西,做个什么呢?答案就是截屏。如图,下面是收集的部分截图:

Unity3D游戏开发之如何用U3D截图的技能培训


       好了,欣赏完美丽的风景,下面我们就来一起学习在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的摄像机,它垂直向下投影到游戏场景里,这样可以使玩家看到场景的顶视图。这里我们用这个相机来测试第三个方法,此时需要先激活该相机。场景设置如图:

Unity3D游戏开发之如何用U3D截图的技能培训

        我们下面来看三种方法截图的效果:

Unity3D游戏开发之如何用U3D截图的技能培训


Unity3D游戏开发之如何用U3D截图的技能培训

Unity3D游戏开发之如何用U3D截图的技能培训

        从截图的效果来看,第一种方法的效果是最好的,不过定制化是个问题。第二种方法效果一般吧,感觉这里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的文件夹,希望大家以后做相关项目的时候注意一下吧。好了,这就是今天的内容了,希望大家喜欢啊。