Unityだけでカメラアプリっぽいものが作れないかなと思って調べた所、WebCamTextureというものが用意されたいたので試しに使ってみた内容を書いていこうと思います。
環境
Unity2018.3.0f2
XCode10.1
準備
iPhoneでカメラアクセスをする為には、Info.plistにNSCameraUsageDescriptionを追記する必要があったので、下記スクリプトを用意してAssets/Scripts/Editorフォルダ内に配置しておきました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
using System; using System.IO; using UnityEngine; using UnityEditor; using UnityEditor.Build; using UnityEditor.Build.Reporting; using UnityEditor.iOS.Xcode; public class PostProcessBuild : IPostprocessBuildWithReport { public int callbackOrder { get { return 0; } } public void OnPostprocessBuild(BuildReport report) { if ( report.summary.platform == BuildTarget.iOS ) { var path = report.summary.outputPath; var projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; var proj = new UnityEditor.iOS.Xcode.PBXProject(); proj.ReadFromString( File.ReadAllText( projPath ) ); proj.AddFrameworkToProject( proj.TargetGuidByName( "Unity-iPhone" ), "Photos.framework", false ); File.WriteAllText( projPath, proj.WriteToString() ); var plistPath = System.IO.Path.Combine( path, "Info.plist" ); var plist = new PlistDocument(); plist.ReadFromFile( plistPath ); plist.root.SetString( "NSCameraUsageDescription", "" ); plist.WriteToFile( plistPath ); } } } |
実装1
WebCamTextureはTextureクラスを継承している為、UGUIのRawImageのtexture変数に設定すればそのまま表示されるかな?と思ったので、RawImageを使ってみました。それに加えてWebCamTextureに用意されている変数も表示してみました。
Hierarchyはこんな感じに。

スクリプトはこんな感じに。
- カメラ利用をユーザー確認に確認する
- 利用できるカメラデバイス名を取得してWebCamTextureを生成
- RawImageに0番目のWebCamTextureを設定しPlay関数を呼びカメラ再生を開始
- Update関数内でWebCamTexture情報を表示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class WebCamera : MonoBehaviour { [SerializeField] private Text m_text = null; [SerializeField] private RawImage m_image = null; private List<WebCamTexture> m_webCameraTextures = new List<WebCamTexture>(); private IEnumerator Start () { // カメラ利用をユーザーに確認 yield return Application.RequestUserAuthorization( UserAuthorization.WebCam ); // 許可された確認 if( !Application.HasUserAuthorization( UserAuthorization.WebCam ) ) { yield break; } // 利用できるカメラデバイス数を確認 if ( WebCamTexture.devices.Length == 0 ) { yield break; } // 利用できるデイバイスの数だけ、WebCamTexture生成 foreach ( var d in WebCamTexture.devices ) { WebCamTexture texture = new WebCamTexture( d.name, Screen.currentResolution.width, Screen.currentResolution.height, 60 ); m_webCameraTextures.Add( texture ); } // カメラ再生開始、RawImageにWabCamTexture設定 const int index = 0; WebCamTexture active = m_webCameraTextures[index]; m_image.texture = active; active.Play(); } private void Update () { if ( m_webCameraTextures.Count <= 0 ) { return; } var sb = new System.Text.StringBuilder(); foreach ( var webcam in m_webCameraTextures ) { Vector2? autoFocusPoint = webcam.autoFocusPoint; sb.Append("autoFocusPoint:").AppendLine( (autoFocusPoint==null ? Vector2.zero.ToString() : autoFocusPoint.ToString() ) ); sb.Append("deviceName:").AppendLine(webcam.deviceName.ToString()); sb.Append("didUpdateThisFrame:").AppendLine(webcam.didUpdateThisFrame.ToString()); sb.Append("isDepth:").AppendLine(webcam.isDepth.ToString()); sb.Append("isPlaying:").AppendLine(webcam.isPlaying.ToString()); sb.Append("requestedFPS:").AppendLine(webcam.requestedFPS.ToString()); sb.Append("requestedHeight:").AppendLine(webcam.requestedHeight.ToString()); sb.Append("requestedWidth:").AppendLine(webcam.requestedWidth.ToString()); sb.Append("videoRotationAngle:").AppendLine(webcam.videoRotationAngle.ToString()); sb.Append("videoVerticallyMirrored:").AppendLine(webcam.videoVerticallyMirrored.ToString()); sb.AppendLine(""); } m_text.text = sb.ToString(); } } |
実際にiPhoneに転送して動かしてみたのものがこちらです。
RawImageもWebCamTexture情報も表示する事ができました!
実装2
先程、実装したものはRawImageに表示された向きが意図した向きではありませんでした。調べてみるとWebCamTexture情報を使って表示向きを調整する必要がありそうという事で、表示向きを調整しつつ全画面表示にしてみました。(Textの表示は無くしています)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class WebCamera : MonoBehaviour { [SerializeField] private RawImage m_image = null; private List<WebCamTexture> m_webCameraTextures = new List<WebCamTexture>(); private IEnumerator Start () { // カメラ利用をユーザーに確認 yield return Application.RequestUserAuthorization( UserAuthorization.WebCam ); // 許可された確認 if( !Application.HasUserAuthorization( UserAuthorization.WebCam ) ) { yield break; } // 利用できるカメラデバイス数を確認 if ( WebCamTexture.devices.Length == 0 ) { yield break; } // 利用できるデイバイスの数だけ、WebCamTexture生成 foreach ( var d in WebCamTexture.devices ) { WebCamTexture texture = new WebCamTexture( d.name, Screen.currentResolution.width, Screen.currentResolution.height, 60 ); m_webCameraTextures.Add( texture ); } // カメラ再生開始、RawImageにWabCamTexture設定 const int index = 0; WebCamTexture active = m_webCameraTextures[index]; m_image.texture = active; active.Play(); // 情報が更新されるのを待つ while ( active.width <= 16 ) { yield return null; } RectTransform rectTrans = m_image.gameObject.GetComponent<RectTransform>(); // 向き調整 Vector3 angles = rectTrans.eulerAngles; angles.y = WebCamTexture.devices[index].isFrontFacing ? 0 : 180; angles.z = -active.videoRotationAngle; rectTrans.eulerAngles = angles; // サイズ調整 float scale = Screen.width / (float)active.height; Vector2 size = rectTrans.sizeDelta; size.x = active.width * scale; size.y = active.height * scale; rectTrans.sizeDelta = size; } } |
実行したものがこちらです。
全画面表示で向きも意図した向きになりました。
まとめ
WebCamTextureを使用すればフロント、バックカメラで映ったもの簡単に表示することができました!映っているものをカメラロールに保存したい場合はネイティブコードを書かないと駄目なようですが、単に表示するだけであれば数時間でできたしまったのでとても便利だと思います。また、PostProcessingStackを使えば見た目も簡単に変えられそうな気がします!
参考url
- https://docs.unity3d.com/ja/current/ScriptReference/WebCamTexture.html
- https://nil-one.com/blog/article/2018/01/30/imageanalysisusingunity03/
- https://www.urablog.xyz/entry/2017/07/06/225444