一、开启相机
1.新建一个类命名为“WebCamManager”(代码如下)
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
/// <summary>摄像头管理</summary>
public class WebCamManager : MonoBehaviour
{
/// <summary>视频画面渲染在UI上</summary>
public RawImage rawImage;
private WebCamTexture webCamTexture;
private void Start()
{
OpenCamera();
}
/// <summary>打开摄像机</summary>
public void OpenCamera()
{
StartCoroutine(openCameraAsyn());
}
private IEnumerator openCameraAsyn()
{
int maxl=(Screen.height > Screen.width)? Screen.height: Screen.width;
// 申请摄像头权限
yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
if (Application.HasUserAuthorization(UserAuthorization.WebCam))
{
if (webCamTexture != null)
{
webCamTexture.Stop();
}
// 监控第一次授权,是否获得到设备(因为很可能第一次授权了,但是获得不到设备,这里这样避免)
// 多次 都没有获得设备,可能就是真没有摄像头,结束获取 camera
int i = 0;
while (WebCamTexture.devices.Length <= 0 && 1 < 300)
{
yield return new WaitForEndOfFrame();
i++;
}
WebCamDevice[] devices = WebCamTexture.devices;//获取可用设备
if (WebCamTexture.devices.Length <= 0)
{
Debug.LogError("没有摄像头设备,请检查");
}
else
{
string devicename = devices[0].name;
webCamTexture = new WebCamTexture(devicename, maxl, maxl == Screen.height ? Screen.width : Screen.height, 30)
{
wrapMode = TextureWrapMode.Repeat
};
// 渲染到 UI
if (rawImage != null) rawImage.texture = webCamTexture;
webCamTexture.Play();
}
}
else
{
Debug.LogError("未获得读取摄像头权限");
}
}
private void OnApplicationPause(bool pause)
{
// 应用暂停的时候暂停camera,继续的时候继续使用
if (webCamTexture != null)
{
if (pause)
{
webCamTexture.Pause();
}
else
{
webCamTexture.Play();
}
}
}
private void OnDestroy()
{
if (webCamTexture != null)
{
webCamTexture.Stop();
}
}
}
2.创建一个 Raw Image 对象
3.选择 Canvas 对象,设置UI尺寸
4.选择 RawImage 对象,将RawImage 全屏显示
5.新建一个空对象命名为“WebCamManager”
6.将“WebCamManager.cs”脚本添加到上面创建出来的“WebCamManager”对象上,并给其赋值(如下图所示)
二、添加陀螺仪控制
1.新建一个脚本,命名为“GyroController”。(代码如下)
using UnityEngine;
/// <summary>
/// 陀螺仪控制
/// </summary>
public class GyroController : MonoBehaviour
{
#region 数据申明
private bool gyroEnabled = true;
private const float lowPassFilterFactor = 0.2f;
private readonly Quaternion baseIdentity = Quaternion.Euler(90, 0, 0);
private readonly Quaternion landscapeRight = Quaternion.Euler(0, 0, 90);
private readonly Quaternion landscapeLeft = Quaternion.Euler(0, 0, -90);
private readonly Quaternion upsideDown = Quaternion.Euler(0, 0, 180);
private Quaternion cameraBase = Quaternion.identity;
private Quaternion calibration = Quaternion.identity;
private Quaternion baseOrientation = Quaternion.Euler(90, 0, 0);
private Quaternion baseOrientationRotationFix = Quaternion.identity;
private Quaternion referanceRotation = Quaternion.identity;
private bool debug = true;
#endregion
#region Unity函数
protected void Start ()
{
Input.gyro.enabled = true;
AttachGyro();
}
protected void Update()
{
if (!Application.isEditor && gyroEnabled)
{
transform.rotation = Quaternion.Slerp(transform.rotation,cameraBase *
(ConvertRotation(referanceRotation * Input.gyro.attitude) * GetRotFix()), lowPassFilterFactor);
}
}
#endregion
#region 公共方法
/// <summary>
/// 将陀螺控制器附加到对象
/// </summary>
private void AttachGyro()
{
gyroEnabled = true;
ResetBaseOrientation();
UpdateCalibration(true);
UpdateCameraBaseRotation(true);
RecalculateReferenceRotation();
}
/// <summary>
/// 从对象中分离陀螺控制器
/// </summary>
private void DetachGyro()
{
gyroEnabled = false;
}
#endregion
#region 私有方法
private void UpdateCalibration(bool onlyHorizontal)
{
if (onlyHorizontal)
{
var fw = (Input.gyro.attitude) * (-Vector3.forward);
fw.z = 0;
if (fw == Vector3.zero)
{
calibration = Quaternion.identity;
}
else
{
calibration = (Quaternion.FromToRotation(baseOrientationRotationFix * Vector3.up, fw));
}
}
else
{
calibration = Input.gyro.attitude;
}
}
private void UpdateCameraBaseRotation(bool onlyHorizontal)
{
if (onlyHorizontal)
{
var fw = transform.forward;
fw.y = 0;
if (fw == Vector3.zero)
{
cameraBase = Quaternion.identity;
}
else
{
cameraBase = Quaternion.FromToRotation(Vector3.forward, fw);
}
}
else
{
cameraBase = transform.rotation;
}
}
private static Quaternion ConvertRotation(Quaternion q)
{
return new Quaternion(q.x, q.y, -q.z, -q.w);
}
private Quaternion GetRotFix()
{
#if UNITY_3_5
if (Screen.orientation == ScreenOrientation.Portrait)
return Quaternion.identity;
if (Screen.orientation == ScreenOrientation.LandscapeLeft || Screen.orientation == ScreenOrientation.Landscape)
return landscapeLeft;
if (Screen.orientation == ScreenOrientation.LandscapeRight)
return landscapeRight;
if (Screen.orientation == ScreenOrientation.PortraitUpsideDown)
return upsideDown;
return Quaternion.identity;
#else
return Quaternion.identity;
#endif
}
private void ResetBaseOrientation()
{
baseOrientationRotationFix = GetRotFix();
baseOrientation = baseOrientationRotationFix * baseIdentity;
}
private void RecalculateReferenceRotation()
{
referanceRotation = Quaternion.Inverse(baseOrientation)*Quaternion.Inverse(calibration);
}
#endregion
}
文件资料
源码下载链接: https://pan.baidu.com/s/1Fjk1t8udKrdkLgW9INrdjA 密码: ikvt
欢迎对AR技术感兴趣的朋友,加入QQ群:883655607 讨论