一、开启相机

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 对象

AR红包雨特效 一_#if

3.选择 Canvas 对象,设置UI尺寸

AR红包雨特效 一_AR_02

4.选择 RawImage 对象,将RawImage 全屏显示

AR红包雨特效 一_AR_03

5.新建一个空对象命名为“WebCamManager”

AR红包雨特效 一_陀螺仪_04

AR红包雨特效 一_#if_05

6.将“WebCamManager.cs”脚本添加到上面创建出来的“WebCamManager”对象上,并给其赋值(如下图所示)

AR红包雨特效 一_ide_06

二、添加陀螺仪控制

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 讨论