Unityでのスクリーンショットは非常に簡単に実装できます。
1 2 3 4 5 6 7 8 |
void SavePic(){ StartCoroutine (SavePicIE()); } IEnumerator SavePicIE(){ yield return new WaitForEndOfFrame(); int w = Screen.width; int h = Screen.height; Texture2D tex = new Texture2D (w, h, TextureFormat.RGB24, false); tex.ReadPixels (new Rect(0,0,w,h), 0, 0); } |
部分的なスクリーンショットをとる場合にはRectangleを変更する必要があります。
スマホは解像度の違いがありケースバイケースで条件を変える必要があります。
Canvas要素の保存
まず Canvas の UI Scale Mode を確認します。
ConstantScale Size であれば単純な計算で出来きるけど予想以上に小さい解像度では
ReadPixels outside of RenderTexture bounds
のエラーが出る。
Scale With Screen Size なら基本サイズを1080×1920として、横幅固定にすることが多いと思うので以下で img 上の部分を保存できる。
1 2 3 4 5 6 7 8 |
float _s = Screen.width/1080f;//縦長対応ならScreen.height/1920f float _w = img.rectTransform.sizeDelta.x*_s; float _h = img.rectTransform.sizeDelta.y*_s; w=(int)_w; h=(int)_h; x=(int)(img.rectTransform.position.x-_w/2); y=(int)(img.rectTransform.position.y-_h/2); tex.ReadPixels (new Rect(x,y,w,h), 0, 0); |
ちなみに Constant Physical Size は通常使わないと思います。
3Dオブジェクトの存在範囲に合わせて保存
CanvasでなくQuadなんかの描画を保存したいケース。
projection が Orthographic であれば以下の計算で保存出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public Camera maincamera; public GameObject target; ... //カメラから見たスクリーンサイズ float wh = Camera.main.orthographicSize * 2f; float ww = wh * maincamera.aspect; //ターゲットサイズ float tw = target.GetComponent<Renderer>().bounds.size.x; float th = target.GetComponent<Renderer>().bounds.size.y; //矩形サイズ float w = Screen.width * tw/ww; float h = Screen.height * th/wh; float x = maincamera.WorldToScreenPoint(target.transform.position).x - w/2; float y = maincamera.WorldToScreenPoint(target.transform.position).y - h/2; yield return new WaitForEndOfFrame(); Texture2D tex = new Texture2D ((int)w, (int)h, TextureFormat.RGB24, false); tex.ReadPixels (new Rect((int)x,(int)y,(int)w,(int)h), 0, 0); |
小数点以下の計算が続くのでスクリーンショット取得時にキャストしてます。
カメラに回転をかけていると微妙にずれます。
これも対象がスクリーン外に出るとエラーです。
所感
解像度は基本 1080×1920 と 1200×1920 を抑えていればいいと思う。
色んな解像度で問題を起こさないようにするなら今回のように計算する必要がある。
Canvas だと Scale With Screen Size を使うのが汎用性が高い。
3Dオブジェクトなら、スクリーンを目いっぱい使わなければ問題は起きにくい。
また3D で Perspective の場合はかなり面倒な計算が必要になる上、きれいに切り取れないと思います。