Unity截屏,Raycast射线,绕某条边旋转

时间:2022-01-15 20:42:40


    1.Physics.Raycast射线来检测碰撞,实现控制按键的选取,按下。头控加射线实现用户操作。      

     Raycast主要有两个:(引用自http://blog.sina.com.cn/s/blog_471132920101g6kt.html
     Physics.Raycast
     作用于任何物体,可以加限定,只检测某layer层
     RaycastHit hit;      Physics.Raycast(transform.position, forward, out hit, 1000)// 射线发射点位置,方向,存储发生碰撞物体的信息,射线发射的距离。

     Collider.Raycast
     只检测ray是否穿过该Collider

     RaycastHit hit;      Ray ray= new Ray(transform.position,Vector3.down);      if(collider.Raycast(ray,out hit,100)                   print("test");
注意:
     (1)无论是哪种raycast检测,从物体内部穿到外面的,都不视为穿过。只有从物体外穿到里面的才视为穿过。
     (2)可以绘制 可见线 来辅助开发。

     1.Debug.DrawLine(V3 start,V3 end);
     2.Gizmos.DrawLine   (可以在编辑模式下显示,可视化更强)

    如果在scene的Gizmos选项下 勾选 3D Gizmos, 那么线段位于真实3D空间里,有前后遮挡。
如果不勾选,则gizmo永远在最前显示。

    2. 读取图片设置成纹理进行显示。

    首先,加载图片,获取到字节流

    /// <summary>
/// 从指定图片全路径(包括文件名)加载图片,返回字节数组
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static byte[] LoadPNG(string path)
{

if (File.Exists(path))
{
FileStream fs = File.OpenRead(path);
long tempLength = fs.Length;
int fsLength = (int)fs.Length;
byte[] binary = new byte[fsLength];
int readLength = fs.Read(binary, 0, fsLength);
fs.Close();
return binary;
}
else
{
return null;
}

}

     其次,设置到相应的UI对象上,作为纹理:   

   Texture2D t2dL = new Texture2D(0, 0);
t2dL.LoadImage(ImageManager.LoadPNG(ImageManager.imgPathListSkyL[ImageManager.currPageSkyL].FullName));
mSphereL.GetComponent<Renderer>().material.mainTexture = t2dL;

    3.实现UI面板绕某一条边旋转。

    实现思路有两种:添加一个父物体,将要旋转的对象作为其子物体,设置其在父物体中的位置,然后对付物体进行旋转;另一种则可以设置要旋转空间的RectTransform的Pivot的位置,来实现。

    4.截屏功能的实现

    方法一:

 public IEnumerator GetCapture()
{
yield return new WaitForEndOfFrame();
int width = Screen.width;
int height = Screen.height;
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0, true);
byte[] imagebytes = tex.EncodeToPNG();//转化为png图//
tex.Compress(false);//对屏幕缓存进行压缩//
string imagePath = "";
//获取一个 DateTime 对象,该对象设置为此计算机上的当前日期和时间,表示为本地时间。//
Debug.Log("jm-------GetCapture" + imagebytes.Length);
string dateTime = System.DateTime.Now.ToString("HHmmssfff");
imagePath = @"/storage/emulated/0/UIHelper/SkyBoxL/" + dateTime + ".png";
File.WriteAllBytes(imagePath, imagebytes);//存储png图//
}

    在测试时发现,使用方法一可能出现截屏图片为Unity的Logo图片的情况,截取不到场景图(由于该APP中使用到了其他SDK导致)。于是采用了两一种方法:利用RenderTexture来进行截图。

  void CaptureCamera(Camera camera, Rect rect)
{

//建一个RenderTxture对象
RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 1);

//临时设置相关相机的targetTexture为rt,并手动渲染相关相机。
camera.targetTexture = rt;
camera.Render();

//激活这个rt,并从中读取像素。
RenderTexture.active = rt;
Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
screenShot.ReadPixels(rect, 0, 0);//这个时候,他是从RendureTexture.active中读取像素。
screenShot.Apply();

//充值相关参数,已使用camera继续在屏幕上显示
camera.targetTexture = null;
RenderTexture.active = null;
GameObject.Destroy(rt);

//最后将这些纹理数据,转成一个png图片文件

byte[] imagebytes = screenShot.EncodeToPNG();//转化为png图//
screenShot.Compress(false);//对屏幕缓存进行压缩//
string imagePath = "";
//获取一个 DateTime 对象,该对象设置为此计算机上的当前日期和时间,表示为本地时间。//
Debug.Log("jm-------GetCapture" + imagebytes.Length);
string dateTime = System.DateTime.Now.ToString("HHmmssfff");
imagePath = @"/storage/emulated/0/UIHelper/SkyBoxL/" + dateTime + ".png";
File.WriteAllBytes(imagePath, imagebytes);//存储png图//
// return null;

}


注意:想访问安卓设备sd card,其根目录地址为/storage/emulated/0/。使用举例如下,表示sd card根目录下的名为UI的文件夹。

DirectoryInfo folderL = new DirectoryInfo(@"/storage/emulated/0/UI");