程 萍
(西華大學(xué)機械工程學(xué)院四川成都610039)
隨著計算機圖形學(xué)的進步和快速發(fā)展的軟硬件技術(shù),虛擬現(xiàn)實技術(shù)(VR)越來越多的應(yīng)用到人們的工作、生活、娛樂之中。3D引擎作為一種底層工具支持高層圖形軟件開發(fā),可以把它看成是對3D API的封裝,對一些圖形通用算法的封裝,對一些底層工具的封裝;利用它可以快速開發(fā)3D應(yīng)用而不必關(guān)心底層細節(jié),如三維場景中旋轉(zhuǎn)、移動、碰撞、特效等。本文用3dsmax[1]對場景建模,導(dǎo)入U3D引擎中,進行腳本編程實現(xiàn)用戶的交互行為控制[2-4]。
本模擬系統(tǒng)主要用于駕校的場地考試模擬訓(xùn)練,三維模擬與傳統(tǒng)的現(xiàn)場考試相比,主要有以下優(yōu)勢:(1)便捷。人們可以隨時、隨地進行駕駛模擬訓(xùn)練;(2)便宜。不用花很多錢去上駕校;(3)省時。在有空時即可打開電腦訓(xùn)練一下,而不用讓自己的假期在學(xué)車中渡過。當然,本軟件有很多細節(jié)需要完善,特別是物理仿真這一塊。下面,主要介紹UI設(shè)計、汽車控制、腳本通信等主要部分。
圖1 系統(tǒng)的主要組成
為了提升用戶的交互體驗,利用UniSkin制作的按鈕來響應(yīng)鼠標事件,如移動、點擊等。此外,考慮不同用戶機的分辨率不同,制作按鈕時采用了顯示分辨率的自適應(yīng);在模式選擇和考試場地選擇時,為了給用戶眼前一亮的感覺,制作了一組多次放大的移動按鈕來吸引用戶的眼球。
考慮到用戶的屏幕分辨率有多種設(shè)置,而采用固定坐標的控件位置會出現(xiàn)錯誤。針對這種情況,設(shè)計一種默認分辯率;然后,獲取用戶屏幕分辨率,并計算2種分辯率的縮放比例;最后,應(yīng)用于控件的坐標。具體做法:(1)設(shè)計一種默認分辨率為m_fScreenWidth*m_fScreenHeight;(2)獲取當前屏幕分辨率 Screen.width*Screen.height;(3)計算縮放因子 m_fScaleWidth=(Screen.width)/m_fScreenWidth;m_fScaleHeight=(Screen.height)/m_fScreenHeight;(4)在控件代碼中加入縮放因子。
假設(shè) Button 控件位置(X,Y,Width,Height),其自適應(yīng)控件位置(X*m_fScaleWidth,Y*m_fS-caleHeight,Width*m_fScaleWidth,Height* m_fS-caleHeight),經(jīng)測試適用分辨率的自適應(yīng)。
多次放大移動的效果是:當點擊按鈕,按鈕自動多次放大并向你靠近。這是利用面板來代替按鈕;當點擊按鈕(面板)時改變按鈕的三維坐標和旋轉(zhuǎn)坐標,同時改變其縮放比例和背景圖片。其中,需要解決如下問題。
(1)如何使點擊的二維坐標響應(yīng)到面板的三維坐標系中?鼠標揀選是解決問題的關(guān)鍵,通過攝像機發(fā)出一條射線到點擊位置,獲取該點的三維坐標,以此判斷是否點擊到面板。關(guān)鍵代碼如下:
(2)獲取到按鈕被點擊的參數(shù)后,開始響應(yīng)按鈕的放大和移動??刂瓢粹o(面板)的縮放比例實現(xiàn)移動,改變按鈕到攝像機的距離實現(xiàn)放大。
圖2 按鈕的初始位置和效果
圖3 移動中放大按鈕的效果
汽車的控制主要是指汽車行駛、轉(zhuǎn)彎、引擎聲音的控制。
(1)轉(zhuǎn)向的計算
圖4 汽車轉(zhuǎn)向的計算
不考慮汽車側(cè)滑,汽車轉(zhuǎn)彎時各參量關(guān)系見圖4。
轉(zhuǎn)彎半徑:R=(L×ctgα -B)/cosβ (2-1)
R:后輪小圓半徑。向左轉(zhuǎn)彎則為左后輪轉(zhuǎn)彎半徑,向右轉(zhuǎn)彎則為右后輪轉(zhuǎn)彎半徑。
L:前輪轂與后輪轂中心距離。
B:車輛寬度,即左右兩輪外緣距離。
α和β:2個后輪的轉(zhuǎn)角。
圓心位置:在車后輪輪轂延長線上。如車輛向左轉(zhuǎn)彎,則圓心在后輪輪轂向左的延長線上;如車輛向右轉(zhuǎn)彎,則圓心在后輪輪轂向右的延長線上。根據(jù)轉(zhuǎn)彎半徑R即可確定圓心位置。
(2)汽車的控制
汽車的控制主要是通過檢測每一幀汽車的速度和轉(zhuǎn)彎角度來計算運動過程。
1)前進和后退
如按住w鍵,相當于汽車油門。如果一直按住,汽車會以加速度行駛。腳本語句為:
MoveSpeed+=Acceleration*Time.deltaTime
其中,MoveSpeed是汽車前一幀的速度,Acceleration是汽車的加速度,是一個固定值,Time.deltaTime是當前距離上一幀的時間。利用unity3d函數(shù)Translate(Vector3)讓汽車以Vector3這個三維向量的方向和大小移動。
2)轉(zhuǎn)彎
轉(zhuǎn)彎控制與汽車前進、后退類似,通過按鍵或者其他輸入設(shè)備來控制,腳本語句為:
RotAngle+=Va*Time.deltaTime
其中,RotAngle是轉(zhuǎn)彎角度,Va是一個常量,Time.deltaTime是當前距離上一幀的時間。利用RotateAround(Pos,axis,Angle)函數(shù)實現(xiàn);Pos 為旋轉(zhuǎn)中心即轉(zhuǎn)彎圓心,axis是轉(zhuǎn)彎繞axis軸,Angle是旋轉(zhuǎn)角度。
(3)引擎聲控制
利用引擎轉(zhuǎn)速來控制一個音效的音高。腳本語句為:
Voice.pitch=rotate/Maxrotate+1
rotate為當前轉(zhuǎn)速,Maxrotate為最高轉(zhuǎn)速。
程序中腳本通信是指2個或以上腳本中的變量或函數(shù)等能夠互相運用。本文主要是用在獲取考試場地(點擊選擇),以便能夠在考試場地中初始化汽車的位置。腳本通信涉及到j(luò)s與cs信息傳遞,例js調(diào)用cs中變量或函數(shù),因為U3D的腳本調(diào)用順序有先后,Standard Assets、Eidtor、Plugins 3個文件夾下面的腳本先調(diào),如果是cs調(diào)用js,那么js必須放在這3個文件夾之一中,否則報錯;如果是cs調(diào)用cs這種模式,2種cs文件都可以放在這3個文件夾之外,調(diào)用變量和函數(shù)方法如下。
cs調(diào)用cs的變量:被調(diào)用的變量必須是 static public類型;然后調(diào)用cs腳本名、函數(shù)名或變量名;
cs調(diào)用 js的變量:testMenu為 js腳本名,carState為js文件中變量,
testMenu c=(testMenu)gameObject.GetComponent<testMenu>();
state=testMenu.carState;
cs調(diào)用js的函數(shù):直接用js腳本名、變量名。
為了豐富場地的動態(tài)效果,增加趣味性,加入時間和天氣因素。UniSky插件能夠?qū)崿F(xiàn)天氣的改變以及時間控制。具體操作方式如下:
(1)在Unity3d編輯界面Project版塊中鼠標右鍵選擇Import Package引入本地包;
(2)綁定主攝像機;
(3)經(jīng)過一些設(shè)置即可運用。
最簡單的例子是:uniSky.SetTime(n)函數(shù)用于設(shè)置時間,其中n代表設(shè)置的時間點。
Unity3d抗鋸齒的設(shè)置。Unity3d中大部分模型存在鋸齒嚴重的情況。解決這一問題的方法是在
Editor- >Project Setting- >Quality- >Anti Aliasing設(shè)置中改成4X或更高,當然,這顯著增加了計算時間。只對獨立顯卡起作用,不適用于集成顯卡。效果見圖5和圖6。
圖5 抗鋸齒前效果
圖6 抗鋸齒后效果
[1]時代印象.3ds Max 2012/VRay效果圖制作完全自學(xué)教程[M].北京:人民郵電出版社,2012.
[2]李瑞森.Unity 3D游戲場景設(shè)計實例教程[M].北京:人民郵電出版社.2014.
[3]吳亞峰.Unity游戲案例開發(fā)大全[M].北京:人民郵電出版社,2014.
[4]萊莫爾斯.Unity著色器和屏幕特效開發(fā)秘笈[M].北京:機械工業(yè)出版社,2014.
[5]高雪峰.Unity 3D NGUI實戰(zhàn)教程[M].北京:人民郵電出版社,2015.