Membuat Pokemon Go Style Augmented Reality Game Dengan Vuforia: Sasaran Gambar
() translation by (you can also view the original English article)
Dalam tutorial ini kita akan menyelam kembali ke perpustakaan Vuforia Augmented Reality (AR), menjelajahi salah satu sumber daya yang paling menarik - Image Target. Kita akan memperluas permainan Shoot the Cubes yang kita buat di pelajaran sebelumnya, menambahkan level baru dimana pemain harus mempertahankan basis mereka dari menyerang kubus.

This Tutorial ini bisa diselesaikan sendiri, walaupun jika anda ingin pengenalan AR dengan Vuforia dan Unity3D, lihatlah posting sebelumnya di seri ini.
- PENGEMBANGAN MOBILEPokémon GO Style Augmented Reality Dengan VuforiaTin Megali
- PENGEMBANGAN MOBILEMembuat Pokemon GO Style Augmented Reality Game Dengan VuforiaTin Megali
Sasaran gambar
Setiap jenis gambar bisa jadi Vuforia Image Target. Namun, semakin detail dan rumit gambarnya, semakin baik ia akan dikenali oleh algoritma.
Banyak faktor akan menjadi bagian dari penghitungan pengenalan, namun pada dasarnya gambar harus memiliki tingkat kontras, resolusi, dan elemen pembeda yang wajar. Foto langit biru tidak akan bekerja dengan baik, tapi gambar rumput akan bekerja dengan anggun. Sasaran Gambar dapat dikirimkan bersama aplikasi, diupload ke aplikasi melalui cloud, atau langsung dibuat di app oleh pengguna.
Menambahkan Target
Mari kita mulai dengan menambahkan sebuah elemen ImageTarget
untuk proyek Unity kita.
Pertama, download aset kursus dari tombol di sidebar. Kemudian, di proyek Unity anda, buatlah sebuah scene baru yang disebut DefendTheBase: di Proyek jendela, pilih folder Scenes dan klik Create > Scene. Sekarang buka scene tersebut dan hapus semua objek scene default dari hirarki.
Selanjutnya kita akan menambahkan cahaya dan kamera. Klik Add > Light > Directional Light untuk menambahkan cahaya arah. Pilih lampu dan setingan baru ini Soft Shadow sebagai pilihan Shadow Type.
Setelah itu, seret dan jatuhkan sebuah objek ARCamera dari Vuforia > Prwfabs. Pilih ARCamera objek dan di panel inspektur, atur App License Key yang dibuat di halaman pengembang Vuforia (lihat tutorial pertama untuk petunjuk). Pilih DEVICE_TRACKING Untuk World Center Mod.
Akhirnya, seret dan jatuhkan ImageTarget ke hirarki dari Vuforia > Prefabs.
Sekarang kita harus menambahkan Database Vuforia. Pertama, navigasikan ke https://developer.vuforia.com/target-manager . Klik Tambahkan Database dan pilih nama.
Ada tiga jenis Database yang bisa dipilih:
- Device: Database disimpan di perangkat dan semua target diperbarui secara lokal.
- Cloud: database pada server Vuforia.
- VuMark: database eksklusif untuk target VuMark. Hal ini juga disimpan pada perangkat.
Dalam hal ini, pilih Device pilihan dan klik Create.
Pilih database baru sehingga kita bisa mulai menambahkan target untuk itu. Sekarang saatnya menambahkan target ke database. Untuk saat ini, kita hanya akan menggunakan pilihan Gambar tunggal.
Arahkan ke file download sebelumnya, pilih ImageTarget1, dan atur Lebar menajdi 1 dan klik Add. (Catatan: Jika anda ingin membuat Image Target sendiri, pertama baca Petunjuk.)



Sekarang anda bisa mendownload database, pilih Editor Unity sebagai peron yang terpilih. Buka file dan pilih semua elemen yang akan diimpor. Kita juga harus mempersiapkan secene Unity kita untuk mengenali ImageTarget dengan database yang kita buat.
Di editor Unity, klik objek ImageTarget. Pertama, temukan dan kembangkan Image Target Behavior di inspektur objek. Pilih Type dari Predefined. Pilih target gambar yang telah kita buat sebelumnya untuk Database. Akhirnya, pastikan bahwa pilihan Enable Extended Tracking dan Enable Smart Terrain dinonaktifkan.



ImageTarget prefab terbuat dari serangkaian komponen, termasuk beberapa skrip seperti Image Target Behavior, Turn Off Behavior, dan Default Tracker Event Handler. Jika anda ingin memahami secara mendalam bagaimana sistem ini bekerja, baca skrip tersebut dan cobalah untuk memahami hubungan mereka terhadap komponen lainnya
Untuk tutorial ini, kita tidak akan menggali terlalu dalam. Kita hanya perlu berkonsentrasi pada Default Tracker Event Handler, yang menerima panggilan saat status pelacakan target gambar mengalami perubahan. Jadi mari kita gunakan skrip ini sebagai dasar untuk membuat perilaku skrip kita sendiri.
Buat salinan naskah ini yang bisa kita perpanjang. Pilih dulu Standar Tracker Event Handler, klik pada pilihan dan pilih Mengedit Script. Sekarang, buat salinan naskahnya. Jika anda menggunakan MonoDevelop, klik File > Save As dan simpan sebagai ImageTargetBehavior, simpan ke dalam folder Scripts.
Skrip TargetBehaviorScript
Kita tidak akan membutuhkan namespace Vuforia
dalam naskah kita. Hapus garis “namespace Vuforia
” dan kurung. Itu berarti kita perlu secara eksplisit referensi Vuforia
namespace saat kita ingin mengakses kelasnya:
1 |
using UnityEngine; |
2 |
using System.Collections; |
3 |
public class BaseScript : MonoBehaviour, Vuforia.ITrackableEventHandler |
4 |
{
|
5 |
// code here |
6 |
}
|
Metode yang paling penting di kelas ini adalah metode OnTrackableStateChanged
yang menerima panggilan saat target gambar ditemukan atau hilang oleh perangkat kamera. Menurut status target, ia memanggil OnTrackingFound
or OnTrackingLost
, dan kita harus mengedit metode mereka juga. Tapi pertama, mari kita pikirkan bagaimana kita menginginkan target gambar berperilaku.
Dalam game ini, pengguna akan mempertahankan basis yang muncul pada target gambar. Mari pertimbangkan mekanika permainan berikut ini:
- Begitu target dikenali oleh sistem, markas muncul dan musuh mulai bertelur dan terbang menuju markas dengan gaya kamikaze.
- Setiap kali musuh menyerang markas, markas akan menerima beberapa kerusakan dan musuh akan hancur.
- Untuk memenangkan permainan, pengguna harus menembak dan menghancurkan semua musuh sebelum markas hancur.
- Jika target gambar hilang (tidak lagi terlihat dari kamera perangkat), game akan memulai penghitung waktu mundur. Jika timer sampai ke nol, permainan hilang. Sementara targetnya hilang, semua musuh akan berhenti maju menuju markas.
Jadi kita harus menyesuaikan mekanika permainan di atas apa yang kita bangun di tutorial terakhir. Kita akan membuat logika pemijahan musuh di bagian selanjutnya dengan sebuah objek kosong bernama _SpawnController, menggunakan logika yang sama diterapkan dalam bagian pertama dari permainan.
Untuk saat ini, mari kita lihat logika pencarian yang ditemukan.
1 |
private void OnTrackingFound () |
2 |
{
|
3 |
EnableRendererAndCollider (); |
4 |
// Inform the system that the target was found
|
5 |
StartCoroutine (InformSpawnCtr (true)); |
6 |
}
|
7 |
|
8 |
private void OnTrackingLost () |
9 |
{
|
10 |
DisableRendererAndCollider (); |
11 |
// Inform the system that the target was lost
|
12 |
StartCoroutine (InformSpawnCtr (false)); |
13 |
}
|
14 |
|
15 |
// inform SpanController that base was founded
|
16 |
private IEnumerator InformSpawnCtr (bool isOn) |
17 |
{
|
18 |
// move spawning position
|
19 |
GameObject spawn = GameObject.FindGameObjectWithTag ("_SpawnController"); |
20 |
|
21 |
yield return new WaitForSeconds (0.2f); |
22 |
|
23 |
// inform SpanController
|
24 |
if (isOn) { |
25 |
spawn.GetComponent<SpawnScript2> ().BaseOn (transform.position); |
26 |
} else { |
27 |
spawn.GetComponent<SpawnScript2> ().BaseOff (); |
28 |
}
|
29 |
}
|
Kembali di editor Unity, kita bisa membuat objek dasar yang akan dikembangkan oleh spawn controller.
Pertama, di objek ImageTarget , nonaktifkan skrip Default Trackable Event Handler.
Selanjutnya, klik Add Component dan pilih Target Behavior Script. Dari Hirarki panel, klik kanan pada ImageTarget dan buat kubus baru bernama "Base". Kubus ini harus dimasukkan ke dalam objek ImageTarget.
Pastikan bahwa Base mengaktifkan Box Collider dan Mesh Renderer.
Opsional, anda juga bisa memasukkan objek Pesawat di dalam ImageTarget menggunakan ImageTarget yang diajukan sebelumnya di Vuforia sebagai tekstur. Hal ini akan menciptakan efek yang menarik, memproyeksikan bayangan dari sasaran dan menciptakan pengalaman yang lebih kaya.



Mengadaptasi SpawnScript
Sekarang kita akan menyesuaikan _SpawnController yang digunakan dalam tutorial terakhir. Simpan scene saat ini dan buka ShootTheCubesMain dari tutorial terakhir. Di dalam Hirarki panel, pilih _SpawnController dan seret ke Prefabs folder untuk membuatnya Unity prefab.
Simpan scene baru ini dan buka kembali DefendTheBase. Seret _SpawnController dari folder prefabs ke Hirarki panel. Dengan _SpawnController yang dipilih, klik Tambahkan Tag pada panel Inspector. Namai tag baru _SpawnController dan terapkan pada objek.
Di jendela Project, pilih elemen Cube dalam folder Prefab dan atur Tag nya kembali pada inspektur, untuk 'Enemy'.



Akhirnya, buka folder Scripts dan buka SpawnScript. Kita perlu membuat skrip ini menyesuaikan diri dengan scene yang dimuat.
1 |
using UnityEngine; |
2 |
using UnityEngine.SceneManagement; |
3 |
using System.Collections; |
4 |
using System.Collections.Generic; |
5 |
|
6 |
using Vuforia; |
7 |
|
8 |
public class SpawnScript : MonoBehaviour |
9 |
{
|
10 |
|
11 |
#region VARIABLES |
12 |
private bool mSpawningStarted = false; |
13 |
|
14 |
// Cube element to spawn
|
15 |
public GameObject mCubeObj; |
16 |
// Qtd of Cubes to be Spawned
|
17 |
public int mTotalCubes = 10; |
18 |
|
19 |
private int mCurrentCubes = 0; |
20 |
|
21 |
// Time to spawn the Cubes
|
22 |
public float mTimeToSpawn = 1f; |
23 |
|
24 |
private int mDistanceFromBase = 5; |
25 |
|
26 |
private List<GameObject> mCubes; |
27 |
|
28 |
private bool mIsBaseOn; |
29 |
private Scene mScene; |
30 |
|
31 |
#endregion // VARIABLES |
32 |
|
33 |
|
34 |
#region UNITY_METHODS |
35 |
|
36 |
// Use this for initialization
|
37 |
void Start () |
38 |
{
|
39 |
mScene = SceneManager.GetActiveScene(); |
40 |
mCubes = new List<GameObject> (); |
41 |
|
42 |
if ( mScene.name == "ShootTheCubesMain" ) |
43 |
{
|
44 |
StartSpawn(); |
45 |
}
|
46 |
}
|
47 |
|
48 |
// Update is called once per frame
|
49 |
void Update () |
50 |
{
|
51 |
|
52 |
}
|
53 |
|
54 |
#endregion // UNITY_METHODS |
Selanjutnya, kita perlu membuat dua metode umum untuk menerima panggilan dari TargetBehaviorScript
ketika target ditemukan atau hilang:
-
BaseOn (Vector3 basePosition)
akan dipanggil saat target ditemukan oleh kamera dan objek Base ditampilkan. Ia akan mengubah posisi pemijahan, mulai prosesnya, dan informasikan semua kubus yang sebelumnya ditambahkan ke panggung bahwa base itu terlihat. -
Metode
BaseOff()
akan digunakan saat target hilang. Metode ini akan menghentikan proses pementasan dan menginformasikan semua elemen kubus bahwa basisnya hilang.
1 |
#region PUBLIC_METHODS
|
2 |
|
3 |
// Base was found by the tracker
|
4 |
public void BaseOn (Vector3 basePosition) |
5 |
{
|
6 |
Debug.Log ("SpawnScript2: BaseOn"); |
7 |
|
8 |
mIsBaseOn = true; |
9 |
|
10 |
// change position
|
11 |
SetPosition (basePosition); |
12 |
|
13 |
// start spawning process if necessary
|
14 |
StartSpawn (); |
15 |
|
16 |
// inform all cubes on screen that base appeared
|
17 |
InformBaseOnToCubes (); |
18 |
}
|
19 |
|
20 |
// Base lost by the tracker
|
21 |
public void BaseOff () |
22 |
{
|
23 |
mIsBaseOn = false; |
24 |
mSpawningStarted = false; |
25 |
|
26 |
// inform all cubes on screen that base is lost
|
27 |
InformBaseOffToCubes (); |
28 |
}
|
29 |
|
30 |
#endregion // PUBLIC_METHODS |
SetPosition (System.Nullable pos) menggunakan posisi target saat ini untuk memodifikasi objek x, y, dan sumbu z, dan juga dapat menerima nilai null
saat scene dimuat merupakan ShootTheCubesMain.
1 |
#region PRIVATE_METHODS
|
2 |
|
3 |
// We'll use a Coroutine to give a little
|
4 |
// delay before setting the position
|
5 |
private IEnumerator ChangePosition () |
6 |
{
|
7 |
Debug.Log ("ChangePosition"); |
8 |
yield return new WaitForSeconds (0.2f); |
9 |
// Define the Spawn position only once
|
10 |
|
11 |
// change the position only if Vuforia is active
|
12 |
if (VuforiaBehaviour.Instance.enabled) |
13 |
SetPosition (null); |
14 |
|
15 |
}
|
16 |
|
17 |
// Set position
|
18 |
private void SetPosition (System.Nullable<Vector3> pos) |
19 |
{
|
20 |
if (mScene.name == "ShootTheCubesMain") { |
21 |
// get the camera position
|
22 |
Transform cam = Camera.main.transform; |
23 |
|
24 |
// set the position 10 units ahead of the camera position
|
25 |
transform.position = cam.forward * 10; |
26 |
} else if (mScene.name == "DefendTheBase") { |
27 |
if (pos != null) { |
28 |
Vector3 basePosition = (Vector3)pos; |
29 |
transform.position = |
30 |
new Vector3 (basePosition.x, basePosition.y + mDistanceFromBase, basePosition.z); |
31 |
}
|
32 |
}
|
33 |
|
34 |
}
|
InformBaseOnToCubes()
dan InformBaseOffToCubes()
bertanggung jawab untuk menginformasikan semua tahapan kubus dari status dasar saat ini.
1 |
// Inform all spawned cubes of the base position
|
2 |
private void InformBaseOnToCubes () |
3 |
{
|
4 |
// Debug.Log("InformBaseOnToCubes");
|
5 |
foreach (GameObject cube in mCubes) { |
6 |
cube.GetComponent<CubeBehaviorScript> ().SwitchBaseStatus (mIsBaseOn); |
7 |
}
|
8 |
}
|
9 |
|
10 |
// Inform to all cubes that the base is off
|
11 |
private void InformBaseOffToCubes () |
12 |
{
|
13 |
// Debug.Log("InformBaseOffToCubes");
|
14 |
foreach (GameObject cube in mCubes) { |
15 |
cube.GetComponent<CubeBehaviorScript> ().SwitchBaseStatus (mIsBaseOn); |
16 |
}
|
17 |
}
|
Metode SpawnLoop()
dan SpawnElement()
menggunakan logika hampir sama dengan tutorial terakhir.
1 |
// Start spawning process
|
2 |
private void StartSpawn () |
3 |
{
|
4 |
if (!mSpawningStarted) { |
5 |
// begin spawn
|
6 |
mSpawningStarted = true; |
7 |
StartCoroutine (SpawnLoop ()); |
8 |
}
|
9 |
}
|
10 |
|
11 |
// Loop Spawning cube elements
|
12 |
private IEnumerator SpawnLoop () |
13 |
{
|
14 |
if (mScene.name == "ShootTheCubesMain") { |
15 |
// Defining the Spawning Position
|
16 |
StartCoroutine (ChangePosition ()); |
17 |
}
|
18 |
|
19 |
yield return new WaitForSeconds (0.2f); |
20 |
// Spawning the elements
|
21 |
while (mCurrentCubes <= (mTotalCubes - 1)) { |
22 |
// Start the process with different conditions
|
23 |
// depending on the current stage name
|
24 |
if (mScene.name == "ShootTheCubesMain" || |
25 |
(mScene.name == "DefendTheBase" && mIsBaseOn)) { |
26 |
|
27 |
mCubes.Add (SpawnElement ()); |
28 |
mCubes [mCurrentCubes].GetComponent<CubeBehaviorScript> ().SwitchBaseStatus (mIsBaseOn); |
29 |
mCurrentCubes++; |
30 |
|
31 |
}
|
32 |
|
33 |
yield return new WaitForSeconds (Random.Range (mTimeToSpawn, mTimeToSpawn * 3)); |
34 |
}
|
35 |
}
|
36 |
|
37 |
// Spawn a cube
|
38 |
private GameObject SpawnElement () |
39 |
{
|
40 |
// spawn the element on a random position, inside a imaginary sphere
|
41 |
GameObject cube = Instantiate (mCubeObj, (Random.insideUnitSphere * 4) + transform.position, transform.rotation) as GameObject; |
42 |
// define a random scale for the cube
|
43 |
float scale = Random.Range (0.5f, 2f); |
44 |
// change the cube scale
|
45 |
cube.transform.localScale = new Vector3 (scale, scale, scale); |
46 |
return cube; |
47 |
}
|
48 |
|
49 |
#endregion // PRIVATE_METHODS |
Menciptakan Musuh
Sekarang kita perlu membuat beberapa musuh. Kita akan menggunakan objek kubus yang kita buat di tutorial terakhir, membuat beberapa modifikasi pada skripnya.
Dalam folder Prefabs, tambahkan objek kubus ke hirarki. Kemudian pilih objek dan edit CubeBehaviorScript.
Kita akan menyimpan logika yang hampir sama dalam skrip ini, namun dengan perbedaan berikut:
- Kubus akan mengejar Base saat target ditemukan oleh kamera.
- Ketika kubus menghantam Base, ia akan menghancurkan dirinya sendiri dan memberikan beberapa kerusakan pada Base.
- Script perlu mengetahui nama scene yang dimuat dan menyesuaikan diri sesuai dengan itu.
1 |
using UnityEngine; |
2 |
using UnityEngine.SceneManagement; |
3 |
using System.Collections; |
4 |
|
5 |
public class CubeBehaviorScript : MonoBehaviour { |
6 |
|
7 |
#region VARIABLES |
8 |
|
9 |
public float mScaleMax = 1f; |
10 |
public float mScaleMin = 0.2f; |
11 |
|
12 |
public int mCubeHealth = 100; |
13 |
|
14 |
// Orbit max Speed
|
15 |
public float mOrbitMaxSpeed = 30f; |
16 |
|
17 |
public float velocityToBase = 0.4f; |
18 |
public int damage = 10; |
19 |
|
20 |
// Orbit speed
|
21 |
private float mOrbitSpeed; |
22 |
|
23 |
// Orbit direction
|
24 |
private Vector3 mOrbitDirection; |
25 |
|
26 |
// Max Cube Scale
|
27 |
private Vector3 mCubeMaxScale; |
28 |
|
29 |
// Growing Speed
|
30 |
public float mGrowingSpeed = 10f; |
31 |
private bool mIsCubeScaled = false; |
32 |
|
33 |
private bool mIsAlive = true; |
34 |
private AudioSource mExplosionFx; |
35 |
|
36 |
private GameObject mBase; |
37 |
private bool mIsBaseVisible = false; |
38 |
|
39 |
private Vector3 mRotationDirection; |
40 |
private Scene mScene; |
41 |
|
42 |
#endregion |
Jika nama scene itu adalah DefendTheBase
, ia harus menemukan objek Base dan mulai bergerak ke arah itu.
1 |
#region UNITY_METHODS
|
2 |
|
3 |
void Start () { |
4 |
// Get Scene name
|
5 |
mScene = SceneManager.GetActiveScene(); |
6 |
CubeSettings(); |
7 |
}
|
8 |
|
9 |
void Update () { |
10 |
// makes the cube orbit and rotate
|
11 |
RotateCube(); |
12 |
|
13 |
if ( mScene.name == "DefendTheBase" ) { |
14 |
// move cube towards the base, when it's visible
|
15 |
MoveToBase (); |
16 |
}
|
17 |
|
18 |
// scale cube if needed
|
19 |
if ( !mIsCubeScaled ) |
20 |
ScaleObj(); |
21 |
}
|
22 |
#endregion |
CubeSettings
() juga perlu beradaptasi sesuai dengan scene yang terisi. Kubus hanya mengorbit pada sumbu y untuk scene DefendTheBase
.
1 |
#region PRIVATE_METHODS
|
2 |
private void CubeSettings () |
3 |
{
|
4 |
// defining the orbit direction
|
5 |
float x = Random.Range ( -1f, 1f ); |
6 |
float y = Random.Range (-1f, 1f); |
7 |
float z = Random.Range ( -1f, 1f ); |
8 |
|
9 |
// TODO update tutorial with new code
|
10 |
// define settings according to scene name
|
11 |
if ( mScene.name == "ShootTheCubesMain" ) |
12 |
{
|
13 |
mOrbitDirection = new Vector3( x, y, z ); |
14 |
}
|
15 |
else if ( mScene.name == "DefendTheBase" ) |
16 |
{
|
17 |
// orbit only on y axis
|
18 |
mOrbitDirection = new Vector3 (0, y, 0); |
19 |
|
20 |
// scale size must be limited
|
21 |
mScaleMin = 0.05f; |
22 |
mScaleMax = 0.2f; |
23 |
|
24 |
velocityToBase = 0.2f; |
25 |
}
|
26 |
|
27 |
// rotating around its axis
|
28 |
float rx = Random.Range (-1f, 1f); |
29 |
float ry = Random.Range (-1f, 1f); |
30 |
float rz = Random.Range (-1f, 1f); |
31 |
|
32 |
mRotationDirection = new Vector3 (rx, ry, rz); |
33 |
|
34 |
|
35 |
// defining speed
|
36 |
mOrbitSpeed = Random.Range (5f, mOrbitMaxSpeed); |
37 |
|
38 |
// defining scale
|
39 |
float scale = Random.Range (mScaleMin, mScaleMax); |
40 |
mCubeMaxScale = new Vector3 (scale, scale, scale); |
41 |
|
42 |
// set cube scale to 0, to grow it later
|
43 |
transform.localScale = Vector3.zero; |
44 |
|
45 |
// getting Explosion Sound Effect
|
46 |
mExplosionFx = GetComponent<AudioSource> (); |
47 |
}
|
Kita akan menambahkan beberapa logika baru ke metode RotateCube
(). Objek kubus akan berputar mengelilingi Base ketika sasaran terlihat. Bila targetnya tidak terlihat, mereka akan terus berputar di sekitar kamera, menggunakan logika yang sama seperti pada tutorial terakhir.
1 |
// Rotate the cube around the base
|
2 |
private void RotateCube () |
3 |
{
|
4 |
// rotate around base or camera
|
5 |
if (mIsBaseVisible && mBase != null && mIsAlive) { |
6 |
// rotate cube around base
|
7 |
transform.RotateAround ( |
8 |
mBase.transform.position, mOrbitDirection, mOrbitSpeed * Time.deltaTime); |
9 |
} else { |
10 |
transform.RotateAround ( |
11 |
Camera.main.transform.position, mOrbitDirection, mOrbitSpeed * Time.deltaTime); |
12 |
}
|
13 |
transform.Rotate (mRotationDirection * 100 * Time.deltaTime); |
14 |
}
|
15 |
// Scale object from 0 to 1
|
16 |
private void ScaleObj(){ |
17 |
|
18 |
// growing obj
|
19 |
if ( transform.localScale != mCubeMaxScale ) |
20 |
transform.localScale = Vector3.Lerp( transform.localScale, mCubeMaxScale, Time.deltaTime * mGrowingSpeed ); |
21 |
else
|
22 |
mIsCubeScaled = true; |
23 |
}
|
Untuk memindahkan objek ke arah base, kita harus memeriksa dulu apakah basenya ada, dan kemudian menerapkan langkah-langkah posisi ke objek.
1 |
// Move the cube toward the base
|
2 |
private void MoveToBase () |
3 |
{
|
4 |
// make the cube move towards the base only if base is present
|
5 |
if (mIsBaseVisible && mIsAlive && gameObject != null && mBase != null) { |
6 |
float step = velocityToBase * Time.deltaTime; |
7 |
transform.position = Vector3.MoveTowards (transform.position, mBase.transform.position, step); |
8 |
}
|
9 |
}
|
Metode DestroyCube()
sama seperti sebelumnya, tapi sekarang kita akan menambahkan metode baru-metode TargetHit(GameObject)
-yang akan disebut saat base diserang. Perhatikan bahwa BaseHealthScript yang dirujuk di TargetHit()
belum diciptakan.
1 |
// make a damage on target
|
2 |
private void TargetHit (GameObject target) |
3 |
{
|
4 |
Debug.Log ("TargetHit: " + target.name); |
5 |
if (target.name == "Base") { |
6 |
// make damage on base
|
7 |
MyBase baseCtr = target.GetComponent<MyBase> (); |
8 |
baseCtr.TakeHit (damage); |
9 |
StartCoroutine (DestroyCube ()); |
10 |
}
|
11 |
}
|
12 |
|
13 |
// Destroy Cube
|
14 |
private IEnumerator DestroyCube(){ |
15 |
mIsAlive = false; |
16 |
|
17 |
mExplosionFx.Play(); |
18 |
|
19 |
GetComponent<Renderer>().enabled = false; |
20 |
|
21 |
yield return new WaitForSeconds(mExplosionFx.clip.length); |
22 |
Destroy(gameObject); |
23 |
}
|
24 |
|
25 |
#endregion |
Akhirnya, kami akan menambahkan metode umum untuk dipanggil saat kubus terkena hantaman, saat bertabrakan dengan base, atau saat status base berubah.
1 |
#region PUBLIC_METHODS
|
2 |
|
3 |
// Cube gor Hit
|
4 |
// return 'false' when cube was destroyed
|
5 |
public bool Hit( int hitDamage ){ |
6 |
mCubeHealth -= hitDamage; |
7 |
if ( mCubeHealth >= 0 && mIsAlive ) { |
8 |
StartCoroutine( DestroyCube()); |
9 |
return true; |
10 |
}
|
11 |
return false; |
12 |
}
|
13 |
|
14 |
public void OnCollisionEnter (Collision col) |
15 |
{
|
16 |
TargetHit (col.gameObject); |
17 |
}
|
18 |
|
19 |
// Receive current base status
|
20 |
public void SwitchBaseStatus (bool isOn) |
21 |
{
|
22 |
// stop the cube on the movement toward base
|
23 |
mIsBaseVisible = isOn; |
24 |
if (isOn) { |
25 |
mBase = GameObject.Find ("Base"); |
26 |
} else { |
27 |
mBase = null; |
28 |
}
|
29 |
}
|
30 |
|
31 |
#endregion |
Mengontrol Kesehatan Base
Musuh sedang dipentaskan dan terbang ke markas, tapi tidak menimbulkan kerusakan saat bertabrakan-tidak ke base maupun musuh. Kita perlu membuat skrip untuk merespon tabrakan dan juga tambahkan bilah kesehatan ke layar, sehingga pengguna tahu seberapa baik kinerjanya.
Mari mulai menambahkan baris kesehatan. Dalam panel Hirarki di editor Unity, klik Create > UI > Slider. Sebuah elemen Kanvas baru akan ditambahkan ke hirarki. Ia berisi elemen UI, termasuk Slider baru. Perluas Kanvas dan pilih Slider.
Ubah nama elemen slider menjadi UIHealth. Dalam panel Inspektur, luaskan Transformasi Rect dan atur Lebar menjadi 400 dan Tinggi 40. Atur Pos X menjadi -220, Pos Y 30, dan Pos Z 0.
Sekarang buka slider script dalam hirarki. Batalkan pilihan pilihan Interaktif. Untuk Target Grafis, klik pada 'titik' kecil di sisi kanan dan pilih gambar Latar Belakang.
- Atur Nilai Min menjadi 0 dan Nilai maks 100.
- Pilih Nomor Utuh.
- Atur Nilai menjadi 100



Sekarang, luaskan panel Slider untuk mengekspos elemen anak-anaknya: latar belakang, Fill Area, dan Handle Slide Area.
- Hapus Handle Slide Area.
- Pilih Latar Belakang dan atur Warna ke warna hijau gelap seperti
#2F568FF
. - Perluas Fill Area dan pilih Mengisi objek dan mengatur warnanya
#7FEA89FF
.
Begini Game Window sebaiknya terlihat dengan baris kesehatan.



Script Kesehatan Base
Kodenya sangat sederhana; ia hanya mengurangi kerusakan yang dilakukan oleh musuh dari jumlah total kesehatan dasar. Begitu kesehatan menjadi nol, pemain kehilangan permainan.Ini juga akan menambahkan animasi rotasi ke Base. Buat script C # baru yang disebut MyBase.
1 |
using UnityEngine; |
2 |
using UnityEngine.UI; |
3 |
using System.Collections; |
4 |
|
5 |
public class MyBase : MonoBehaviour |
6 |
{
|
7 |
#region VARIABLE |
8 |
|
9 |
public float rotationSpeed = 10f; |
10 |
|
11 |
public int health = 100; |
12 |
public AudioClip explosionSoundFx; |
13 |
public AudioClip hitSoundFx; |
14 |
// TODO choose a different sound for the Hit
|
15 |
|
16 |
private bool mIsAlive = true; |
17 |
private AudioSource mAudioSource; |
18 |
public Slider mHealthSlider; |
19 |
|
20 |
#endregion // VARIABLES |
21 |
|
22 |
|
23 |
#region UNITY_METHODS |
24 |
|
25 |
// Use this for initialization
|
26 |
void Start () |
27 |
{
|
28 |
mAudioSource = GetComponent<AudioSource> (); |
29 |
mHealthSlider.maxValue = health; |
30 |
mHealthSlider.value = health; |
31 |
}
|
32 |
|
33 |
// Update is called once per frame
|
34 |
void Update () |
35 |
{
|
36 |
RotateBase (); |
37 |
}
|
38 |
|
39 |
#endregion // UNITY_REGION |
40 |
|
41 |
#region PRIVATE_METHODS |
42 |
|
43 |
private void RotateBase () |
44 |
{
|
45 |
if ( mIsAlive && gameObject != null ) { |
46 |
// implement object rotation
|
47 |
transform.Rotate ( Vector3.up, rotationSpeed * Time.deltaTime); |
48 |
}
|
49 |
}
|
50 |
|
51 |
// Destroy base
|
52 |
private IEnumerator DestroyBase () |
53 |
{
|
54 |
mIsAlive = false; |
55 |
mAudioSource.clip = explosionSoundFx; |
56 |
mAudioSource.Play (); |
57 |
|
58 |
GetComponent<Renderer> ().enabled = false; |
59 |
|
60 |
// inform all Enemies that Base is Lost
|
61 |
GameObject[] enemies = GameObject.FindGameObjectsWithTag ("Enemy"); |
62 |
foreach (GameObject e in enemies) { |
63 |
e.gameObject.GetComponent<EnemyScript> ().SwitchBaseStatus (false); |
64 |
}
|
65 |
|
66 |
yield return new WaitForSeconds (mAudioSource.clip.length); |
67 |
Destroy (gameObject); |
68 |
|
69 |
}
|
70 |
|
71 |
#endregion // PRIVATE_METHODS |
72 |
|
73 |
#region PUBLIC_METHODS |
74 |
|
75 |
// receive damage
|
76 |
public void TakeHit (int damage) |
77 |
{
|
78 |
health -= damage; |
79 |
|
80 |
mHealthSlider.value = health; |
81 |
|
82 |
if (health <= 0) { |
83 |
StartCoroutine (DestroyBase ()); |
84 |
} else { |
85 |
mAudioSource.clip = hitSoundFx; |
86 |
mAudioSource.Play (); |
87 |
}
|
88 |
}
|
89 |
|
90 |
#endregion // PUBLIC_METHODS |
91 |
}
|
Sekarang kita perlu menambahkan dan mengkonfigurasi script.
Pilih Base dalam hirarki, klik Add Component, dan tambahkan Audio Source Sekarang seret MyBase ke elemen Base dan, di panel Inspektur, luaskan MyBase. Pilih efek suara untuk ledakan dan hantaman. Saya sudah menggunakan klip explosion yang digunakan di tutorial terakhir, tapi jangan ragu untuk menambahkan punya anda sendiri. Akhirnya, di Health Slider, pilih elemen UISlider.



Mempertahankan Base
Pengalaman permainan baru kita hampir selesai. Kita hanya perlu menembak beberapa laser untuk mulai mempertahankan base kita. Mari membuat skrip untuk laser!
Pertama seret _PlayerController dari folder Prefab ke hirarki. Perluas _PlayerController dan pilih _LaserController. Di panel Inspektur, temukan Laser Script dan klik Edit.
Satu-satunya hal yang perlu kita ubah dalam skrip ini adalah posisi laser.
1 |
// Shot the Laser
|
2 |
private void Fire () |
3 |
{
|
4 |
// Get ARCamera Transform
|
5 |
Transform cam = Camera.main.transform; |
6 |
|
7 |
// Define the time of the next fire
|
8 |
mNextFire = Time.time + mFireRate; |
9 |
|
10 |
// Set the origin of the RayCast
|
11 |
Vector3 rayOrigin = cam.position; |
12 |
|
13 |
// Show the Laser using a Coroutine
|
14 |
StartCoroutine (LaserFx ()); |
15 |
|
16 |
// Holds the Hit information
|
17 |
RaycastHit hit; |
18 |
|
19 |
// Set the origin position of the Laser Line
|
20 |
// It will add 10 units down from the ARCamera
|
21 |
// We adopted this logic for simplicity
|
22 |
Vector3 laserStartPos = new Vector3 (cam.position.x, cam.position.y -2f, cam.position.z); |
23 |
mLaserLine.SetPosition (0, laserStartPos); |
24 |
|
25 |
// Checks if the RayCast hit something
|
26 |
if (Physics.Raycast (rayOrigin, cam.forward, out hit, mFireRange)) { |
27 |
|
28 |
// Set the end of the Laser Line to the object hit
|
29 |
mLaserLine.SetPosition (1, hit.point); |
30 |
|
31 |
// check target type
|
32 |
if (hit.collider.tag == "Enemy") { |
33 |
|
34 |
CubeBehaviorScript cubeCtr = hit.collider.GetComponent<CubeBehaviorScript> (); |
35 |
if (cubeCtr != null) { |
36 |
if (hit.rigidbody != null) { |
37 |
hit.rigidbody.AddForce (-hit.normal * mHitForce); |
38 |
cubeCtr.Hit (mLaserDamage); |
39 |
}
|
40 |
}
|
41 |
}
|
42 |
|
43 |
} else { |
44 |
// Set the enfo of the laser line to be forward the camera
|
45 |
// using the Laser range
|
46 |
mLaserLine.SetPosition (1, cam.forward * mFireRange); |
47 |
}
|
48 |
}
|
Mencoba gamenya

Itu merupakan pekerjaan yang banyak, tapi sekarang sudah waktunya untuk memainkan gamenya! Cetak gambar target dan coba menjalankan permainan anda di ponsel atau tablet anda. Bersenang-senanglah dengan itu dan lihat apakah anda bisa menemukan beberapa cara untuk meningkatkan permainan!
Pada titik ini, anda memiliki pemahaman yang baik tentang bagaimana sistem Vuforia bekerja dan bagaimana menggunakannya dengan Unity. Saya berharap bahwa anda telah menikmati perjalanan ini seperti yang saya rasakan. Sampai jumpa lagi!
Untuk mempelajari lebih lanjut tentang Augmented Reality dengan Vuforia and Unity, lihat kursus video kami di Envato Tuts +!