原創(chuàng)文章查蓉,請勿轉(zhuǎn)載。感謝Q酱颉矢赁!
適合人群
必須會Unity3D引擎基礎(chǔ),對C#腳本編程有一定經(jīng)驗
使用插件
本案列使用前還必須導入以下這些插件
DoTween
優(yōu)秀的動畫插件
FairyGUI
本案例用的是FairyGUI系統(tǒng)贬丛,基礎(chǔ)知識可以到FairyGUI官網(wǎng)學習撩银,當然你可以將UI改造為UGUI系統(tǒng)。
游戲介紹
太空戰(zhàn)機是一款通過識別對應(yīng)的AR游戲卡片結(jié)合實景的敏捷躲避AR游戲豺憔,游戲采用UNITY3D引擎和EasyAR聯(lián)合開發(fā)额获。游戲主要操作方法是利用手機重力感應(yīng)來控制飛機左右移動躲避障礙物,并且有各種各樣的道具輔助玩家獲得高分數(shù)排名恭应。
游戲前期策劃
游戲初期策劃是占一個重要成分抄邀,前期策劃做得好,后期游戲的制作流程會更加明了昼榛,我們可以先坐下來境肾,用筆或紙記錄自己的一點一點的創(chuàng)意,最后整理集合成一個游戲策劃方案。
對于太空戰(zhàn)機這個游戲奥喻,由于玩法比較簡單驼抹,所以策劃方案也不會太復雜定续,游戲策劃大概列出下面這幾點:
- 利用EasyAR識別圖片后,出現(xiàn)開始界面奔垦,并且出現(xiàn)飛機绣硝,此時飛機不可以被玩家控制
- 點擊開始按鈕后進入倒數(shù)界面插龄,倒數(shù)5秒上遥,出現(xiàn)游戲界面辩诞,此時飛機可以被玩家控制
- 用重力感應(yīng)控制飛機左右移動
- 圓環(huán)和道具從遠處不斷向飛機直線移動,碰到圓環(huán)損失1血酒朵,從圓環(huán)中心通過桦锄,獎勵1分
- 道具分別是能量包和隕石扎附,能量包用于恢復生命蔫耽,隕石碰撞到后損失2血
- 當血量為0時,游戲結(jié)束留夜,出現(xiàn)排行版
當然這個初期策劃方案的功能并不是十分完善匙铡,例如后期會增加飛機選擇界面,增加購買飛機商城碍粥,增加更多的道具鳖眼,這些需由你自己去完4善策劃內(nèi)容,這樣你會從中學習到更多的策劃經(jīng)驗嚼摩。
游戲素材準備
通常我們做游戲前钦讳,都需要準備制作該游戲的一些美術(shù)資源,音效資源枕面,如果平時有收集整理自己的素材庫愿卒,那素材的問題很快可以解決,如果平時沒有這個習慣潮秘,可以到UNITY官方資源商店購買下載合適的素材琼开,本案例中的資源包都會通過百度盤共享,可以直接拿來使用枕荞。
申請AppKey
我們首先要到EasyAR官網(wǎng)注冊賬號柜候,然后進入開發(fā)中心,創(chuàng)建一個新應(yīng)用躏精,應(yīng)用名為ARSpaceShip渣刷,注意Bundle ID(iOS) Package Name(Android)這一列,其格式通常為com.公司名.項目名矗烛,所以我們這里按照自己的實際需求來填寫飞主,本案例填寫為com.game4u.arspaceship,最后點擊顯示按鈕,出現(xiàn)AppKey碌识。
如何制作識別度高的識別圖
識別圖如果識別度比較高碾篡,那么識別后,模型相對會穩(wěn)定筏餐,并且不會出現(xiàn)抖動現(xiàn)象开泽,那么我們應(yīng)該怎樣制作識別度高得識別圖呢?以下我總結(jié)出來幾點經(jīng)驗:
- 避免重復元素大量出現(xiàn):大量圓圈魁瞪、方形穆律、菱形或者其他相同的形狀,容易出現(xiàn)識別錯誤
- 避免圖案元素分布不均勻:圖案有區(qū)域出現(xiàn)大片空白导俘、單一顏色或者分布不均勻峦耘,會導致識別錯誤
- 避免圖案元素過于簡單:識別跟蹤更喜歡“雜亂無章”的圖案,太簡單的圖案旅薄,有可能會導致掃描錯誤
- 避免圖案全是文字:圖案全部都是文字辅髓,掃描識別圖有可能會出現(xiàn)識別錯誤
- 避免圖案明暗對比度不明顯:如果圖案全是亮色或者暗色,有可能會導致識別錯誤
- 避免圖案模糊:圖案需要清晰的細節(jié)才能掃描少梁,如果細節(jié)很模糊洛口,識別圖有可能掃描出錯
- 避免圖案高度反光: :如果圖案反光嚴重,很容易導致識別圖掃描出錯
- 避免圖案上印有二維碼:請將二維碼區(qū)域設(shè)置為空白凯沪。當識別圖提供給用戶掃描的時候第焰,可以在空白區(qū)域補充二維碼,不影響識別結(jié)果
- 避免使用png格式圖
同樣妨马,本案例的識別圖可以在資源包里找到挺举。
制作識別圖數(shù)據(jù)
我們先來制作一下數(shù)據(jù)文件。這個數(shù)據(jù)文件是一個json數(shù)據(jù)烘跺,我們輸入以下內(nèi)容湘纵,并保存文件為targets.json。
{"images" :
[
{
"image" : "arspaceship.jpg",
"name" : "arspaceship"
}
]
}```
****
#游戲框架初步搭建
素材準備好了后液荸,我們開始制作太空戰(zhàn)機AR游戲瞻佛,打開Unity引擎并創(chuàng)建一個新項目,首先將下載好的EasyAR的unity package導入到項目里娇钱,如圖
![導入EasyAR unity package](http://upload-images.jianshu.io/upload_images/3353184-8b068541ebb29051.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
導入完成后伤柄,我們右鍵Asset文件夾,新建一個自己的游戲文件夾文搂,命名為ARSpaceShip适刀,在這個文件夾里再分別建立Scene(用于放置場景文件),Scripts(用于放置腳本)煤蹭,Modles(用于放置模型)笔喉,Textures(用于放置貼圖)取视,Materials(用于放置材質(zhì)),Prefabs(用于放置預置物)常挚。
如果項目里沒有StreamingAssets和Resources文件夾作谭,我們也應(yīng)該右鍵新建此文件夾,如圖
![建立文件夾](http://upload-images.jianshu.io/upload_images/3353184-335eb2b33ecb7823.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
現(xiàn)在我們在Scene文件夾里新建一個場景奄毡,命名為GameScene折欠,雙擊打開該場景,刪除掉里面的MainCamera和Diretorly Light吼过,找到EasyAR的Prefab目錄锐秦,將EasyAR_Startup組件拖到場景里,然后填寫在官網(wǎng)里注冊的AppKey盗忱,如圖
![填寫AppKey](http://upload-images.jianshu.io/upload_images/3353184-cf736ee08088efdf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
此時我們還需修改一下EasyAR_Startup里面的RenderCamera相機組件的視野屬性酱床,將Clipping Planes的Near和Far分別修改為 0.01和2000,如下圖:
![RenderCamera屬性](http://upload-images.jianshu.io/upload_images/3353184-2f4eba3c7c6da899.png)
我們將識別圖和target.json一起放到StreamingAssets文件夾里趟佃,EasyAR會通過腳本訪問此文件夾獲得資源和數(shù)據(jù)扇谣。接下來同樣在EasyAR的Prefab目錄下的Primitives里將ImageTarget組件拖到場景里,并且將ImageTargetBehaviour腳本移除揖闸。
![5.png](http://upload-images.jianshu.io/upload_images/3353184-f72b8da11a91a2c9.png)
然后在我們的項目文件夾的Scripts目錄右鍵揍堕,新建一個EasyImageTargetBehaviour腳本料身,輸入以下代碼:
using UnityEngine;
namespace EasyAR
{
public class EasyImageTargetBehaviour : ImageTargetBehaviour
{
protected override void Awake()
{
base.Awake();
TargetFound += OnTargetFound;
TargetLost += OnTargetLost;
}
protected override void Start()
{
base.Start();
HideObjects(transform);
}
void HideObjects(Transform trans)
{
for (int i = 0; i < trans.childCount; ++i)
HideObjects(trans.GetChild(i));
if (transform != trans)
gameObject.SetActive(false);
}
void ShowObjects(Transform trans)
{
for (int i = 0; i < trans.childCount; ++i)
ShowObjects(trans.GetChild(i));
if (transform != trans)
gameObject.SetActive(true);
}
void OnTargetFound(ImageTargetBaseBehaviour behaviour)
{
ShowObjects(transform);
}
void OnTargetLost(ImageTargetBaseBehaviour behaviour)
{
HideObjects(transform);
}
}
}
把這段代碼拖到ImageTarget中汤纸,這段代碼的作用是EasyAR如果識別到圖片后,控制ImageTarget里面的所有子物體的顯示和隱藏芹血。然后填寫一下ImageTarget屬性面版里面的一些屬性贮泞,注意Storage需要選擇為Asset模式,如圖:
![輸入識別圖信息](http://upload-images.jianshu.io/upload_images/3353184-d059e9bd65273eb6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**Storages說明**
>**App**
app路徑幔烛,對于不同設(shè)備會有不同路徑啃擦。
Android: 程序持久化數(shù)據(jù)目錄(注意,這個目錄與Unity的Application.persistentDataPath可能不同)
iOS: 程序沙盒目錄
Windows: 可執(zhí)行文件(exe)目錄
Mac: 可執(zhí)行文件目錄(如果app是一個bundle饿悬,這個目錄在bundle內(nèi)部)
>**Assets**
StreamingAssets路徑
>**Absolute**
絕對路徑(json/圖片路徑或視頻文件路徑)或url(僅視頻文件)
>**Json**
表示json string的標志位令蛉,在Target.Load中使用
大家有沒發(fā)現(xiàn)上面的ImageTarget沒有材質(zhì),不太好看狡恬,那么我們可以在自己項目文件夾里的Matertials文件夾右鍵新建一個材質(zhì)ImageTargetMat珠叔,然后拖到ImageTarget的MeshRenderer組件的Materials里面,改變材質(zhì)為Legacy Shaders/Self-Illumin/Diffuse弟劲,把識別圖復制一份到Textures文件夾里拖到材質(zhì)里面祷安,如圖:
![改變ImageTarget材質(zhì)](http://upload-images.jianshu.io/upload_images/3353184-389f13a88fbbbad5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最后,我們在ImageTarget里建立一個空的GameObject兔乞,命名為GameWorld汇鞭,此時游戲初步框架完成凉唐。
![建立GameWorld](http://upload-images.jianshu.io/upload_images/3353184-4ccb4e200f0173b5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
****
#制作游戲地面
在GameWorld里新建一個GameObject命名為Map,然后在里面新建一個Quad物體命名為Ground霍骄,調(diào)整他的Rotation X軸為90台囱,目的是讓它平放。我們再在Materials文件夾里新建一個GroundMat材質(zhì)读整,將這個材質(zhì)拖動到Ground物體玄坦,最后將識別圖作為貼圖賦值給材質(zhì),并調(diào)整合適大小绘沉,如圖:
![制作游戲地面](http://upload-images.jianshu.io/upload_images/3353184-88b533980c89fcf0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
****
#制作太空戰(zhàn)機
在GameWorld里新建一個GameObject命名為SpaceShipCotroller煎楣,并設(shè)置tag為Player,然后在素材包里面找到太空戰(zhàn)機的模型的文件夾车伞,將它復制到Modles文件夾里择懂,將模型文件拖動到SpaceShipCotroller里作為子物體并將模型的Scale調(diào)為0.008,0.008,0.008,如圖:
![飛機模型](http://upload-images.jianshu.io/upload_images/3353184-f4a1dfde696b34c9.png)
此時如果沒有材質(zhì)另玖,可以將材質(zhì)重新拖到飛機模型上關(guān)聯(lián)即可困曙。我們再調(diào)整一下SpaceShipController的物體的Y軸位置為0.13,Z軸位置為-0.28谦去,如圖:
![調(diào)整飛機大小位置](http://upload-images.jianshu.io/upload_images/3353184-bc747c92e1faf963.png)
在Scripts文件夾里新建一個腳本慷丽,命名為SpaceShipController,拖動到SpaceShipController物體處鳄哭,輸入以下代碼:
using System;
using UnityEngine;
public class SpaceShipController : MonoBehaviour
{
//移動速度
public float Speed = 20f;
//方向
private Vector3 _dir = Vector3.zero;
void Start()
{
}
void Update()
{
Move();
}
/// <summary>
/// 飛機移動邏輯
/// </summary>
void Move()
{
_dir.x = Input.acceleration.x;
if (_dir.sqrMagnitude > 1) _dir.Normalize();
transform.Translate(Time.deltaTime * _dir * Speed);
}
}
這段代碼的作用是用來控制太空戰(zhàn)機要糊。我們策劃的時候是要通過手機重力感應(yīng)來控制戰(zhàn)機左右移動,UnityAPI提供了移動設(shè)備重力感應(yīng)方法`Input.acceleration`妆丘,只需要通過x值來判斷左右移動锄俄。我們還需要在SpaceShipController的屬性面板中輸入Speed的值,并且調(diào)試一下是否是自己想要的戰(zhàn)機移動速度勺拣,本案例的速度填寫為500奶赠,然后在手機上發(fā)布看看實際效果。此時你掃描識別圖后药有,左右搖動手機毅戈,戰(zhàn)機也跟著左右移動了。
現(xiàn)在看起來戰(zhàn)機移動沒問題愤惰,但是給人感覺有點生硬苇经,需要加一個左右移動的時候機身會跟著側(cè)飛,那么我們選中場景中的SpaceShipController物體羊苟,右鍵新建一個GameObject命名為RotateObject塑陵,然后把我們的模型拖到RotateObject里作為子物體,如下圖:
![RotateObject](http://upload-images.jianshu.io/upload_images/3353184-374aab3aee1d63b1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
雙擊SpaceController腳本蜡励,給它增加兩個屬性:
//旋轉(zhuǎn)速度
public float RotateSpeed = 20f;
//需要旋轉(zhuǎn)的物體
public Transform RotateObject;
然后增加多一個側(cè)飛的方法:
/// <summary>
/// 側(cè)飛
/// </summary>
void Rotate()
{
//根據(jù)方向判斷是左旋轉(zhuǎn)還是右旋轉(zhuǎn)
if (_dir.x < 0)
{
RotateObject.localRotation = Quaternion.Lerp(RotateObject.localRotation,Quaternion.Euler(new Vector3(0, 0, 30f)), Time.deltaTime * RotateSpeed);
}
else
{
RotateObject.localRotation = Quaternion.Lerp(RotateObject.localRotation,Quaternion.Euler(new Vector3(0, 0, -30f)),Time.deltaTime * RotateSpeed);
}
}
然后在Update方法處令花,添加Rotate方法:
void Update()
{
Move();
Rotate();
}
最終的SpaceController腳本應(yīng)該如下:
using System;
using UnityEngine;
public class SpaceShipController : MonoBehaviour
{
//移動速度
public float Speed = 20f;
//方向
private Vector3 _dir = Vector3.zero;
//旋轉(zhuǎn)速度
public float RotateSpeed = 20f;
//需要旋轉(zhuǎn)的物體
public Transform RotateObject;
void Start()
{
}
void Update()
{
Move();
Rotate();
}
/// <summary>
/// 飛機移動邏輯
/// </summary>
void Move()
{
_dir.x = Input.acceleration.x;
if (_dir.sqrMagnitude > 1) _dir.Normalize();
transform.Translate(Time.deltaTime * _dir * Speed);
}
/// <summary>
/// 側(cè)飛
/// </summary>
void Rotate()
{
if (_dir.x < 0)
{
RotateObject.localRotation = Quaternion.Lerp(RotateObject.localRotation, Quaternion.Euler(new Vector3(0, 0, 30f)),
Time.deltaTime * RotateSpeed);
}
else
{
RotateObject.localRotation = Quaternion.Lerp(RotateObject.localRotation, Quaternion.Euler(new Vector3(0, 0, -30f)),
Time.deltaTime * RotateSpeed);
}
}
}
寫完代碼后阻桅,再次點擊場景中的SpaceShipController物體,會發(fā)現(xiàn)多了RotateSpeed和RotateObject屬性兼都,先設(shè)置RotateSpeed為2嫂沉,再將場景中的RotateObject拖動到RotateObject屬性l里,如圖:
![設(shè)置屬性](http://upload-images.jianshu.io/upload_images/3353184-6d8e6e4a247ff9a9.png)
現(xiàn)在飛機看起來沒有倒影顯得不是那么真實扮碧,我們可以再素材庫將SpaceShipShadow.png復制到Textures文件夾下趟章,在場景中的SpaceShipController物體右鍵新建一個Quad物體命名為Shadow,去掉組件MeshCollider慎王,在Materials文件夾中新一個SpaceShipShadow材質(zhì)蚓土,將SpaceShipShadow.png拖到材質(zhì)里然后再設(shè)置為透明材質(zhì),設(shè)置完成后將材質(zhì)關(guān)聯(lián)給場景中Shadow物體赖淤,最后調(diào)整Shadow物體的Position Y軸為-0.2蜀漆, Rotation X軸為90度,Scale為0.16,0.16,0.16咱旱,效果如下圖:
![調(diào)整效果](http://upload-images.jianshu.io/upload_images/3353184-f3d41697a4b26de0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
飛機飛行的時候還需要有個噴射效果确丢,在Modles文件夾的SpaceShip文件夾找到SpaceShipEngines的模型,拖動到場景中的SpaceShip模型里面吐限,設(shè)置好大小和材質(zhì)關(guān)聯(lián)鲜侥,效果如圖:
![噴射效果制作](http://upload-images.jianshu.io/upload_images/3353184-4de7afc8fe8b0c6e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
現(xiàn)在讓我們用DoTween來模擬飛行噴射粒子動畫,在場景中的SpaceShip里找到Ship_1_Engines 1物體诸典,添加DoTweenAnimation組件描函,輸入合適的參數(shù),如下圖:
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/3353184-803953d748f6bdcd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最后我們在Prefab文件夾下新建一個Prefab命名為SpaceShipController搂赋,將場景里的SpaceShipController拖動到這個預置物完成飛機的制作赘阀。
****
#制作圓環(huán)敵人
在GameWorld這個GameObject里益缠,新建一個GameObject命名為RingController脑奠,然后在素材包里面找到圓環(huán)的模型,拖動到RingEnemy里作為子物體調(diào)整好合適的大小幅慌,將Rotation的Y值變?yōu)?80度宋欺,然后在Scripts文件夾里新建一個腳本命名為RingController,拖動到RingController物體處胰伍,輸入以下代碼:
using UnityEngine;
using System.Collections;
public class RingController : MonoBehaviour
{
//移動速度
public float Speed = 20f;
void Start()
{
}
void Update()
{
Move();
}
/// <summary>
/// 移動邏輯
/// </summary>
void Move()
{
transform.Translate(Vector3.forward * Speed * Time.deltaTime);
if (transform.localPosition.z < -1f)
{
Destroy(gameObject);
}
}
}```
這段代碼的作用是用來控制圓環(huán)的齿诞,程序會控制它不斷向前移動,如圖:
最后在Prefab文件夾下骂租,新建一個Prefab祷杈,命名為RingController,將場景里的RingController拖動到這個預置物渗饮,刪掉場景中的RingController但汞,后面我們要動態(tài)創(chuàng)建圓環(huán)宿刮。
完善游戲框架
制作好游戲模型的預制物后,我們開始通過程序動態(tài)創(chuàng)建圓環(huán)私蕾。在Scripts文件夾右鍵僵缺,新建SimpleSpawn腳本,輸入以下代碼:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SimpleSpwan : MonoBehaviour
{
//敵人Prefab列表
public List<GameObject> monsterList = new List<GameObject>();
//敵人生成的Delegate事件
public delegate void CreateObjectDelegate(GameObject spawnObject);
public CreateObjectDelegate CreateObjectEvent;
//生成的間隔時間
public float spawnTimer;
//生成的最大數(shù)量
public int limitSpawn = 1;
//記錄復制出來的敵人列表
private GameObject[] spawnList = new GameObject[] { };
//計數(shù)生成數(shù)量
private int coutnSpawn = 0;
//容器
private Transform _container;
void Start()
{
spawnList = new GameObject[limitSpawn];
_container = transform;
}
public void DoSpawn()
{
InvokeRepeating("Spawn", 0.5f, spawnTimer);
}
/// <summary>
/// 生成怪物
/// </summary>
public void Spawn()
{
for (int i = 0; i < spawnList.Length; i++)
{
if (spawnList[i] == null)
{
GameObject monsterSpawn = (GameObject)GameObject.Instantiate(monsterList[Random.Range(0, monsterList.Count)]);
monsterSpawn.transform.SetParent(_container, false);
SpwanObject ss = monsterSpawn.AddComponent<SpwanObject>();
ss.spawnerOwner = gameObject;
spawnList[i] = monsterSpawn;
coutnSpawn++;
if (coutnSpawn >= limitSpawn)
{
//生成敵人超過指定數(shù)量踩叭,停止執(zhí)行函數(shù)
CancelInvoke("Spawn");
}
if (CreateObjectEvent != null)
{
CreateObjectEvent(monsterSpawn);
}
return;
}
}
}
/// <summary>
/// 偵聽物體Destroy事件
/// </summary>
/// <param name="spwanObject"></param>
public void OnSpawnerObjectDestory(GameObject spwanObject)
{
for (int i = 0; i < spawnList.Length; i++)
{
if (spawnList[i] == spwanObject)
{
spawnList[i] = null;
//敵人死亡后磕潮,通知事件,如果已經(jīng)是最大值容贝,那么就回復時間繼續(xù)生成
if (coutnSpawn >= limitSpawn)
{
Debug.Log("less then limitspawn , restart Invoke");
InvokeRepeating("Spawn", spawnTimer, spawnTimer);
}
coutnSpawn--;
return;
}
}
}
/// <summary>
/// 停止所有生成并清空
/// </summary>
public void DespawnAllAndStop()
{
for (int i = 0; i < spawnList.Length; i++)
{
if (spawnList[i] != null)
{
Destroy(spawnList[i]);
spawnList[i] = null;
}
coutnSpawn = 0;
CancelInvoke("Spawn");
}
}
/// <summary>
/// 暫停生成
/// </summary>
public void Stop()
{
coutnSpawn = 0;
CancelInvoke("Spawn");
}
}
這段代碼作用是通過計時器控制程序每隔指定秒數(shù)生成一個圓環(huán)物體自脯。核心代碼在public void Spawn()
,通過檢測spawnList的元素是否有數(shù)據(jù)斤富,如果沒有數(shù)據(jù)就開始生成一個新的敵人冤今。
接著繼續(xù)在Scripts文件夾右鍵,新建SimpleSpawnObject腳本茂缚,輸入以下代碼:
using UnityEngine;
using System.Collections;
public class SpwanObject : MonoBehaviour
{
//物體所有者
public GameObject spawnerOwner;
void OnDestroy()
{
//物體Destroy后發(fā)送事件給SimpleSpwan
if (spawnerOwner != null)
{
spawnerOwner.SendMessage("OnSpawnerObjectDestory", gameObject, SendMessageOptions.DontRequireReceiver);
}
}
}```
這段代碼是在物體Destory后戏罢,發(fā)送消息通知SimpleSpawn腳本刪除該物體的引用。
最后脚囊,我們將SimpleSpawn掛到ImageTarget里的GameWorld物體里龟糕,給SimpleSpawn的monsterList的size改為1,然后將RingController預置物拖到屬性里悔耘,將SpawnTimer設(shè)置為3秒讲岁,LimitSpawn設(shè)置為5,如圖:
![設(shè)置SimpleSpawn屬性](http://upload-images.jianshu.io/upload_images/3353184-a73a4c863a783077.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
那么我們?nèi)绾慰刂七@個SimpleSpawn生成物體呢衬以?在場景里右鍵建立一個GameObject命名為Controllers缓艳,然后在Controllers右鍵再建立一個GameObject命名為GameController。然后再Scripts文件夾新建一個GameController腳本看峻,拖動到場景里的GameController物體處阶淘,輸入以下代碼:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GameController : MonoBehaviour
{
//飛機控制器
public SpaceShipController _ShipController;
//生成物體系統(tǒng)
public SimpleSpwan SpwanSystem;
//物體的線路位置
public List<float> ItemPostion = new List<float>();
void Start()
{
Init();
}
/// <summary>
/// 游戲初始化
/// </summary>
void Init()
{
SpwanSystem.DoSpawn();
//SpwanSystem每生成一個物體,都會發(fā)送通知,并且返回這個物體
SpwanSystem.CreateObjectEvent = (GameObject spawnObject) =>
{
Vector3 newpos = spawnObject.transform.localPosition;
newpos.x = ItemPostion[Random.Range(0, ItemPostion.Count)];
newpos.z = 1.2f;
spawnObject.transform.localPosition = newpos;
};
}
}
我們在屬性面板處將SpaceShipController拖到SpaceShipController屬性里,將GameWorld物體拖動到SpawnSystem屬性里互妓,設(shè)置ItemPostion的值為3溪窒,如圖:
![設(shè)置GameController屬性](http://upload-images.jianshu.io/upload_images/3353184-31c948c6ed52f382.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
發(fā)布到手機運行測試后,你會發(fā)現(xiàn)圓環(huán)會在前方復制冯勉,并且不停移動澈蚌,但是圓環(huán)并不會自動消失,因為我們還沒有給圓環(huán)限制一個范圍灼狰。雙擊RingController腳本宛瞄,我們改寫一下Move方法,給Move方法增加一個移動判斷交胚,代碼如下:
/// <summary>
/// 移動邏輯
/// </summary>
void Move()
{
transform.Translate(Vector3.forward * Speed * Time.deltaTime);
if (transform.localPosition.z < -1f)
{
Destroy(gameObject);
}
}
這段代碼的作用是當圓環(huán)的Z軸到-1后Destory自身份汗,在手機上發(fā)布我們會看到伐厌,圓環(huán)移動到Z軸為-1的位置后消失了,并且SimpleSpawn會重新生成新的圓環(huán)裸影。
****
#添加碰撞
**飛機增加剛體**
給場景中的SpaceShipController物體增加BoxCollider組件和Rigidbody組件挣轨,Rigidbody組件不需要使用重力,參數(shù)調(diào)整如下圖:
![設(shè)置碰撞屬性](http://upload-images.jianshu.io/upload_images/3353184-1e7e9b1e2bec1198.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)將剛體調(diào)整到只有機身部分點擊Apply按鈕即可轩猩,當然你可以擴大剛體范圍卷扮,不過這樣游戲會增大難度。
**圓環(huán)增加剛體**
將Prefabs文件夾的RingController物體拖動到GameWorld里均践,給圓環(huán)整體增加一個BoxCollider組件晤锹,參數(shù)調(diào)整如下圖:
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/3353184-cb4663877502ed83.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
考慮到飛機可以從圓環(huán)中間穿過,所以我們需要一點技巧來制作多一個剛體彤委,在RingController右鍵建立一個新的GameObject命名為CrossCollider鞭铆,增加一個BoxCollider組件,移動這個BoxCollider的位置焦影,讓這個BoxCollider比圓環(huán)的BoxCollider更加靠前车遂,這樣做的目的是當飛機碰撞到CrossCollider物體后,取消圓環(huán)的剛體碰撞斯辰,讓飛機可以順利穿越舶担,具體參數(shù)調(diào)整如下圖:
![CrossCollider](http://upload-images.jianshu.io/upload_images/3353184-1826228c7539711a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最終效果如下圖:
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/3353184-f67773ac880545be.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
****
#未完待續(xù)占坑
#
#
#
#
#
#
#
#
****
#制作游戲UI
#發(fā)布游戲