王毅
DOI:10.19392/j.cnki.16717341.201714051
摘要:本文主要簡(jiǎn)述如何使用Unity及增強(qiáng)現(xiàn)實(shí)技術(shù)在移動(dòng)端上實(shí)現(xiàn)虛擬3D吉祥物的展示。
關(guān)鍵詞:Unity;增強(qiáng)現(xiàn)實(shí);蘇州園博會(huì)吉祥物
1 制作分析
該應(yīng)用最終發(fā)布在Android及Ios平臺(tái),主要利用手機(jī)的攝像機(jī)對(duì)園博會(huì)吉祥物圖片進(jìn)行識(shí)別,然后利用EasyAR增強(qiáng)現(xiàn)實(shí)插件結(jié)合Unity游戲引擎對(duì)識(shí)別的結(jié)果進(jìn)行比對(duì),建立空間矩陣,然后回調(diào)相應(yīng)的吉祥物3D虛擬人物進(jìn)行表演。
2 實(shí)現(xiàn)方法
1)首先使用Maya等三維軟件進(jìn)行吉祥物的3D模型和動(dòng)畫(huà)的制作,并導(dǎo)入U(xiǎn)nity場(chǎng)景(將模型中心放置在世界坐標(biāo)原點(diǎn)上)、設(shè)置燈光背景等。圖1示例了該Unity場(chǎng)景模型效果。
2)使用Unity的UI制作插件NGUI制作本應(yīng)用的登錄界面與3D虛擬人物展示界面,如圖2所示(左側(cè)為登錄和引導(dǎo)界面、右側(cè)為增強(qiáng)現(xiàn)實(shí)識(shí)別展示界面)。展示界面預(yù)留了用戶幫助模塊、3D虛擬人物動(dòng)畫(huà)播放模塊、聲音切換模塊功能。
圖1吉祥物Unity場(chǎng)景模型圖2 應(yīng)用界面
3)Unity導(dǎo)入EasyAR增強(qiáng)現(xiàn)實(shí)模塊。EasyAR是國(guó)內(nèi)最專(zhuān)業(yè)的AR引擎,是國(guó)內(nèi)首款投入應(yīng)用的AR SDK。EasyAR官網(wǎng)上下載相應(yīng)插件并導(dǎo)入U(xiǎn)nity場(chǎng)景,在EasyAR官網(wǎng)注冊(cè)相應(yīng)的應(yīng)用iD并生成相應(yīng)的Key值,將Key值填入U(xiǎn)nity EasyAR節(jié)點(diǎn)相應(yīng)的Key屬性中。
4)在EasyAR 配套Unity基礎(chǔ)場(chǎng)景中的ImageTargetJsonFileidback節(jié)點(diǎn)中將步驟D的吉祥物模型、相應(yīng)的吉祥物識(shí)別卡片都放置在該節(jié)點(diǎn)下。當(dāng)EasyAR調(diào)用成功時(shí),攝像頭開(kāi)啟后就可以對(duì)卡片進(jìn)行識(shí)別,如果目標(biāo)卡片與ImageTargetJsonFileidback節(jié)點(diǎn)下的卡片匹配,則會(huì)顯示3D吉祥物,如果攝像頭跟蹤丟失那么3D吉祥物消失。
5)進(jìn)行模型展示功能的開(kāi)發(fā)。其中,多點(diǎn)觸控來(lái)控制3D模型的旋轉(zhuǎn)、縮放的核心代碼如下:
public class ScaleAndRotate : MonoBehaviour
{
private Touch oldTouch1;∥上次觸摸點(diǎn)1(手指1)
private Touch oldTouch2;∥上次觸摸點(diǎn)2(手指2)
void Start() {}
GameObject Capsule_bady = null;
private float rotateN = 1.5f;
void Update()
{
Capsule_bady = GameObject.Find(“Capsule_bady”);∥查找相應(yīng)的3D吉祥物
if (Input.touchCount <= 0 || Capsule_badynull) { return ; } //沒(méi)有觸摸返回
if (1 Input.touchCount)∥單點(diǎn)觸摸,水平上下旋轉(zhuǎn)
{
Touch touch = Input.GetTouch(0);
Vector2 deltaPos = touch.deltaPosition; ∥獲得單點(diǎn)滑動(dòng)的矢量
Capsule_bady.transform.Rotate(1*Vector3.up * deltaPos.x * rotateN);∥進(jìn)行旋轉(zhuǎn)
}
//多點(diǎn)觸摸, 放大縮小
Touch newTouch1 = Input.GetTouch(0);∥獲得第1個(gè)觸摸點(diǎn)
Touch newTouch2 = Input.GetTouch(1); ∥獲得第2個(gè)觸摸點(diǎn)
if (newTouch2.phase == TouchPhase.Began) ∥第2點(diǎn)剛開(kāi)始接觸屏幕,不做處理
{
oldTouch2 = newTouch2;
oldTouch1 = newTouch1;
return;
}
∥計(jì)算以前的兩點(diǎn)距離和新的兩點(diǎn)間距離,變大要放大模型,變小要縮放模型
float oldDistance = Vector2.Distance(oldTouch1.position, oldTouch2.position);
float newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);
∥兩個(gè)距離之差,為正表示放大手勢(shì),為負(fù)表示縮小手勢(shì)
float offset = newDistance oldDistance;
∥放大因子, 一個(gè)像素按 0.01倍來(lái)算(100可調(diào)整)
float scaleFactor = offset / 100f;
Vector3 localScale = Capsule_bady.transform.localScale;
Vector3 scale = new Vector3(localScale.x + scaleFactor,
localScale.y + scaleFactor,
localScale.z + scaleFactor);
if ((scale.x > 0.7f && scale.y > 0.7f && scale.z > 07f&&scale.x < 1.4f && scale.y < 1.4f && scale.z < 14f))∥最大縮放為1.4倍,最小縮放為0.7倍
{Capsule_bady.transform.localScale = scale; }
oldTouch1 = newTouch1;∥記住最新的觸摸點(diǎn),下次使用
oldTouch2 = newTouch2;
}}
基金項(xiàng)目:本文為校社科基金項(xiàng)目《基于傳統(tǒng)文化傳承的兒童繪本影像化研究》(項(xiàng)目編號(hào):YN1431)