Unity打開攝像頭占滿全屏
AR項目需求,Unity打開攝像頭作為背景渲染占滿全屏~ Unity對設備硬件操作的API並不是太友好~打開一個攝像頭,渲染到屏幕上也都得自己寫,雖然步驟少,提取攝像頭texture,渲染到UGUI上(本文采取的是UGUI的方案),這時候涉及到一個屏幕適配的問題,以及Unity層級問題。。。
下面先貼上代碼和場景配置~ 再說一些坑。。
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class STCamDeviceController : MonoBehaviour
{
WebCamTexture camTexture;
CanvasScaler CanScaler;
Camera ca;
Image img;
void Start () {
img = GetComponentInChildren<Image>();
CanScaler = GetComponentInChildren<CanvasScaler> ();
CanScaler.referenceResolution = new Vector2 (Screen.width, Screen.height);
ca = GetComponentInChildren<Camera> ();
ca.orthographicSize = Screen.width / 100.0f/ 2.0f;
img.transform.localScale = new Vector3 (-1, -1, -1);
img.rectTransform.anchorMin = new Vector2 (0.5f, 0.5f);
img.rectTransform.anchorMax = new Vector2 (0.5f, 0.5f);
img.rectTransform.pivot = new Vector2(0.5f,0.5f);
img.rectTransform.SetSizeWithCurrentAnchors (RectTransform.Axis.Horizontal, Screen.height);
img.rectTransform.SetSizeWithCurrentAnchors (RectTransform.Axis.Vertical, Screen.width);
// 設備不同的坐標轉換
#if UNITY_IOS || UNITY_IPHONE
img.transform.Rotate (new Vector3 (0, 180, 90));
#elif UNITY_ANDROID
img.transform.Rotate (new Vector3 (0, 0, 90));
#endif
StartCoroutine(CallCamera());
}
IEnumerator CallCamera()
{
yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
if (Application.HasUserAuthorization(UserAuthorization.WebCam))
{
if (camTexture != null)
camTexture.Stop();
WebCamDevice[] cameraDevices = WebCamTexture.devices;
string deviceName = cameraDevices[0].name;
camTexture = new WebCamTexture(deviceName,Screen.height,Screen.width,60);
img.canvasRenderer.SetTexture(camTexture);
camTexture.Play();
}
}
}
此腳本掛在作為打開相機渲染背景的Canvas上~ (UI是另外一個相對獨立的Canvas)。。場景里面的配置如下~
再看CameraGBCanvas 和 CameraBG 的配置~ 因為背景image的大小約束都是通過代碼動態設置的~
配置如上~ 說說實現思路和一些坑~
首先,第一步。打開相機~
在Start方法里通過 IEnumerator 開啟了相機。判斷用戶是否給了攝像頭哦權限,接下來獲取設備列表,取第0個就是后置攝像頭,取出texture並且渲染到 image上,,這里可以看到取出的texture的 寬等於其高,,高等於其寬,,那是因為取出的textur繞z軸旋轉了90度。這里先做了寬高對調~
第二步,渲染成功后背景Image屏幕適配問題。。
a. 首先調整屏幕適配寬高參考值,就為當前屏幕寬高
代碼:
CanScaler = GetComponentInChildren<CanvasScaler> ();
CanScaler.referenceResolution = new Vector2 (Screen.width, Screen.height);
b.攝像頭渲染背景的相機已經調整為正交模式了,其中有一個正交大小的值 orthographicSize 。。根據官方文檔的說法是當處於垂直轉台的時候等於高的一半,也就是代碼如下~
ca = GetComponentInChildren<Camera> ();
ca.orthographicSize = Screen.width / 100.0f/ 2.0f;
c. 接着做image旋轉處理
img.transform.localScale = new Vector3 (-1, -1, -1);
img.rectTransform.anchorMin = new Vector2 (0.5f, 0.5f);
img.rectTransform.anchorMax = new Vector2 (0.5f, 0.5f);
img.rectTransform.pivot = new Vector2(0.5f,0.5f);
img.rectTransform.SetSizeWithCurrentAnchors (RectTransform.Axis.Horizontal, Screen.height);
img.rectTransform.SetSizeWithCurrentAnchors (RectTransform.Axis.Vertical, Screen.width);
d.最后根據設備不同,判斷image的rotae,這一點感覺Unity一點兒都不友好,為什么不能自己判斷設備自動適配坐標系統叻? Unity API 給我的感覺是發展空間還挺大的,好多地方都需要改進~
// 設備不同的坐標轉換
#if UNITY_IOS || UNITY_IPHONE
img.transform.Rotate (new Vector3 (0, 180, 90));
#elif UNITY_ANDROID
img.transform.Rotate (new Vector3 (0, 0, 90));
#endif