一政己、主要框架
二、模型
三晨炕、關(guān)鍵代碼
Bullet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour {
//防御塔的引用
public GameObject tower;
//所有敵人的引用衫画;
private EnemyController[] enemys;
//開始發(fā)射子彈的距離;
private float distance;
//最近的敵人瓮栗;
private EnemyController nearestEnemy;
//判斷塔與敵人的距離削罩;
private float dis;
//子彈傷害值;靜態(tài)的一般公開的才方便調(diào)用
public static float bulletDamage;
void Start () {
//定義傷害值
bulletDamage = 10f;
}
void Update () {
//尋找敵人的方法
//--------------------------------------------------------------
//設(shè)置最近距離费奸;
distance = 500f;
//獲取所有子物體弥激;
enemys = FindObjectsOfType<EnemyController>();
//遍歷所有子物體 以獲取最近敵人;
for (int i = 0; i < enemys.Length; i++)
{
//獲取兩物體間的距離
dis = Vector3.Distance(tower.transform.position, enemys[i].transform.position);
//判斷是否是防御距離二發(fā)射子彈愿阐;
if (dis < distance)
{
distance = dis;
nearestEnemy = enemys[i];
Debug.Log("最近敵人");
}
}
//--------------------------------------------------------------
//判斷如果最近敵人不為空 就發(fā)射子彈微服;
if (nearestEnemy!=null)
{
//子彈的位置 從塔的位置移向到敵人的位置;
this.transform.position = Vector3.MoveTowards(this.transform.position,nearestEnemy.transform.position,10f); //參數(shù)3:移動速度缨历;
//塔的方向 朝向 最近敵人的位置职辨;
tower.transform.LookAt(nearestEnemy.transform);
if (this.transform.position==nearestEnemy.transform.position)
{
//判斷子彈到達最近敵人時候 銷毀子彈
Destroy(this.gameObject);
Debug.Log("子彈銷毀");
//釋放資源
Resources.UnloadUnusedAssets();
}
else
{
Destroy(this.gameObject,1f);
}
}
//如果敵人為空 那就把子彈銷毀掉,不要停在半空中戈二;
if (nearestEnemy==null)
{
Destroy(this.gameObject);
//釋放資源
Resources.UnloadUnusedAssets();
}
}
}
EnemyAnimation
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 控制敵人動畫
/// </summary>
public class EnemyAnimation : MonoBehaviour {
//獲取 動畫 組件
private Animator anim;
//獲取EnemyController的工具狀態(tài) 避免實例化就開始攻擊舒裤;
EnemyController enemyController;
//播放音效
private AudioSource mAudioSource;
void Start () {
//獲取敵人身上的動畫組件
anim = this.GetComponent<Animator>();
//獲取腳本組件;
enemyController = this.GetComponent<EnemyController>();
//獲取音效的音頻觉吭;
mAudioSource = this.GetComponent<AudioSource>();
}
void Update () {
//判斷塔銷毀的狀態(tài)
if (TowerController.isDamage==false)
{
//獲取EnemyControoler腳本上的布爾值 是否可以攻擊
if (enemyController.isAttack == true)
{
//設(shè)置動畫狀態(tài)的布爾值
anim.SetBool("Attack", true); //參數(shù)1:動畫條件 參數(shù)文2:動畫值
anim.SetBool("Walk", true);
anim.SetBool("Idle", false);
}
}
else if (TowerController.isDamage == true)
{
//設(shè)置動畫狀態(tài)的布爾值
anim.SetBool("Attack", false); //參數(shù)1:動畫條件 參數(shù)文2:動畫值
anim.SetBool("Walk", false);
anim.SetBool("Idle",true);
}
}
/// <summary>
/// 播放砍塔的聲音 只需在動畫中插入這個事件就好腾供,不要加括號
/// </summary>
public void KanTa() {
//播放砍塔音效;
mAudioSource.Play();
}
}
EnemyController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 敵人控制腳本
/// </summary>
public class EnemyController : MonoBehaviour {
//防御塔的引用
public GameObject towerPrefab;
//敵人移動速度鲜滩;
private float speed=2f;
//用來判斷敵人與塔的距離伴鳖;
private float distance;
//設(shè)置布爾值;必須是公開的徙硅,方便調(diào)用
public bool isAttack;
//設(shè)置敵人的攻擊力度 設(shè)置靜態(tài)方便調(diào)用 不用實例化出來
public static float damage=10f;
//設(shè)置敵人的生命值榜聂;
public float enemyLife = 80f;
//獲取畫布的組件以及敵人血條image;
private Canvas canvas;
private Image blood;
void Start () {
//剛開始時 不攻擊
isAttack = false;
//獲取畫布的組件嗓蘑;
canvas = this.GetComponentInChildren<Canvas>();
//獲取血條顯示圖片须肆;
blood = canvas.GetComponentInChildren<Image>();
}
void Update () {
//只有塔還沒被摧毀的時候才執(zhí)行這個移動
if (TowerController.isDamage==false)
{
//移動到防御塔
// this.transform.position = Vector3.MoveTowards(this.transform.position,towerPrefab.transform.position,2f); //參數(shù)1:當(dāng)前位置 參數(shù)2:目標(biāo)位置 參數(shù)3:移動時間
this.transform.position = Vector3.MoveTowards(this.transform.position, towerPrefab.transform.position, speed);
//測試
//if (this.transform.position==towerPrefab.transform.position)
//{
// Debug.Log("兵臨城下");
//}
//返回2點之間的距離;
distance = Vector3.Distance(this.transform.position, towerPrefab.transform.position);
//判斷距離停止移動 并且播放攻擊的動畫桩皿;設(shè)置攻擊為真
if (distance <= 120f)
{
speed = 0;
isAttack = true;
}
}
}
/// <summary>
///子彈與敵人碰撞
/// </summary>
/// <param name="other"></param>
private void OnTriggerEnter(Collider collider)
{
if (collider.gameObject.tag=="bullet")
{
Debug.Log("敵人被攻擊了");
//敵人受傷害
enemyLife -= Bullet.bulletDamage;
//測試敵人生命值豌汇;
Debug.Log("敵人生命值:"+enemyLife);
//顯示血條的圖片;
blood.fillAmount = enemyLife / 80;
if (enemyLife<=0)
{
Destroy(this.gameObject);
Debug.Log("敵人消滅了泄隔!");
// enemyLife = 80;
}
}
}
}
MyTrackableEventHandler
using UnityEngine;
namespace Vuforia
{
/// <summary>
/// A custom handler that implements the ITrackableEventHandler interface.
/// </summary>
public class MyTrackableEventHandler : MonoBehaviour,
ITrackableEventHandler
{
//防御塔預(yù)制體的引用
public GameObject towerPrefab;
//敵人的預(yù)制體的引用 數(shù)組 隨機生成
public GameObject[] enemyPrefab;
//敵人的位置
// public Transform enemyPoint1;
public Transform[] enemyPoint;
//定時器 每隔2秒鐘就生成一個敵人
public float timeGo = 3f;
//用來接收輸入時間的
private float startTime ;
//避免update中的方法不斷識別 定義一個標(biāo)志位
bool isFoundEnemy;
#region PRIVATE_MEMBER_VARIABLES
private TrackableBehaviour mTrackableBehaviour;
#endregion // PRIVATE_MEMBER_VARIABLES
#region UNTIY_MONOBEHAVIOUR_METHODS
void Start()
{
//給時間賦值
startTime = timeGo;
//剛開始不可識別拒贱;
isFoundEnemy = false;
mTrackableBehaviour = GetComponent<TrackableBehaviour>();
if (mTrackableBehaviour)
{
mTrackableBehaviour.RegisterTrackableEventHandler(this);
}
}
#endregion // UNTIY_MONOBEHAVIOUR_METHODS
#region PUBLIC_METHODS
/// <summary>
/// Implementation of the ITrackableEventHandler function called when the
/// tracking state changes.
/// </summary>
public void OnTrackableStateChanged(
TrackableBehaviour.Status previousStatus,
TrackableBehaviour.Status newStatus)
{
if (newStatus == TrackableBehaviour.Status.DETECTED ||
newStatus == TrackableBehaviour.Status.TRACKED ||
newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
{
//事件中識別防御塔的方法;
OnTrackingFound();
//重新識別之后塔沒有被破壞
TowerController.isDamage = false;
//事件中是識別敵人的方法;
OnTrackingEnemyFound();
}
else
{
OnTrackingLost();
}
}
#endregion // PUBLIC_METHODS
//不斷識別敵人
void Update()
{
//判斷塔的狀態(tài) 只有不被銷毀的時候才實例化敵人
if (TowerController.isDamage==false)
{
//時間遞減
timeGo -= Time.deltaTime;
//如果時間歸零并且滿足條件為真
if (timeGo <= 0 && isFoundEnemy == true)
{
OnTrackingEnemyFound();
//時間回到初始化值
timeGo = startTime;
}
}
}
#region PRIVATE_METHODS
private void OnTrackingFound()
{
//識別防御塔時候?qū)嵗? GameObject Tower = GameObject.Instantiate(towerPrefab) as GameObject;
//設(shè)置父類
Tower.transform.parent = this.transform;
//設(shè)置位置
Tower.transform.position = this.transform.position;
////識別敵人
//GameObject Enemy = GameObject.Instantiate(enemyPrefab[Random.Range(0,3)]) as GameObject;
//Enemy.transform.parent = this.transform;
//// Enemy.transform.position = this.transform.position+new Vector3(3,0,3); //加個位置
////敵人的位置
//Enemy.transform.position = enemyPoint[Random.Range(0, 3)].position;
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
}
/// <summary>
/// 識別敵人的方法
/// </summary>
private void OnTrackingEnemyFound() {
//找到了設(shè)置為真
isFoundEnemy = true;
//識別敵人
GameObject Enemy = GameObject.Instantiate(enemyPrefab[(int)Random.Range(0, 3)]) as GameObject;
Enemy.transform.parent = this.transform;
// Enemy.transform.position = this.transform.position+new Vector3(3,0,3); //加個位置
//敵人的位置
// Enemy.transform.position = enemyPoint1.position;
//位置信息隨機
int random = (int)Random.Range(0, 3);
Enemy.transform.position = enemyPoint[random].position;
//敵人的朝向 第一種方法
//if (random == 0)
//{
// Enemy.transform.rotation = Quaternion.AngleAxis(120, Vector3.up);
//}
//if (random==1)
//{
// Enemy.transform.rotation = Quaternion.AngleAxis(240,Vector3.up);
//}
//if (random==2)
//{
// Enemy.transform.rotation = Quaternion.AngleAxis(320,Vector3.up);
//}
//敵人的朝向 第二種方法
Enemy.transform.LookAt(towerPrefab.transform);
}
private void OnTrackingLost()
{
//沒找到 設(shè)置為false
isFoundEnemy = false;
//防御塔沒找到的時候
TowerController tower = GetComponentInChildren<TowerController>();
//判斷一下沒找的時候銷毀
if (tower!=null)
{
//銷毀
DestroyImmediate(tower.gameObject);
//釋放資源
Resources.UnloadUnusedAssets();
}
//同樣 識別丟失的時候敵人銷毀
//EnemyController enemy = GetComponentInChildren<EnemyController>();
EnemyController[] enemy = GetComponentsInChildren<EnemyController>();
if (enemy!=null)
{
//for 循環(huán) 逐個銷毀逻澳、第一種方法
//for (int i = 0; i < enemy.Length; i++)
//{
// EnemyController E = enemy[i];
// Destroy(E.gameObject);
//}
foreach (EnemyController E in enemy)
{
DestroyImmediate(E.gameObject);
Resources.UnloadUnusedAssets();
}
//DestroyImmediate(enemy.gameObject);
//Resources.UnloadUnusedAssets();
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
}
#endregion // PRIVATE_METHODS
}
}
TowerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TowerController : MonoBehaviour {
//設(shè)置塔的生命值
private float towerLife = 100f;
//判斷塔是否銷毀(生命值為零時) 公開的 方便敵人停止攻擊動畫的控制
public static bool isDamage=false;
//獲取畫布的引用
private Canvas canvas;
//獲取畫布下的image闸天;
private Image blood;
//子彈的預(yù)制體
public GameObject bulletPrefab;
//子彈生成時間 計時器
// private float timeGo = 0;
//播放音效
private AudioSource mAudioSource;
void Start () {
//給畫布和血條賦值;
canvas = GetComponentInChildren<Canvas>();
blood = canvas.GetComponentInChildren<Image>();
//獲取子彈發(fā)射的音頻斜做;
mAudioSource = this.GetComponent<AudioSource>();
}
void Update () {
//發(fā)射子彈的時間
//timeGo += Time.deltaTime;
//if (timeGo>0.3f)
//{
// //執(zhí)行子彈生成的方法苞氮;
// CreateBullet();
// timeGo = 0f;
//}
//以上代碼是測試時用
//--------------------------
//點擊屏幕時調(diào)用
if (Input.GetMouseButtonDown(0))
{
CreateBullet();
//播放子彈發(fā)射音效;
mAudioSource.Play();
}
}
void OnTriggerEnter(Collider collider)
{
if (collider.gameObject.tag== "weapon")
{
towerLife -= EnemyController.damage; //調(diào)用敵人的破壞力
//測試塔的防御值
Debug.Log(towerLife);
//顯示血條 畫布下的屬性
blood.fillAmount = towerLife / 100;
//判斷生命力小于零的時候 銷毀塔和設(shè)置為真
if (towerLife<=0)
{
Destroy(this.gameObject);
isDamage = true;
}
}
}
/// <summary>
/// 實例化子彈的方法
/// </summary>
void CreateBullet() {
//實例化子彈
GameObject bullet = GameObject.Instantiate(bulletPrefab) as GameObject;
//設(shè)置父類關(guān)系
bullet.transform.parent = this.transform;
//設(shè)置位置
bullet.transform.position = this.transform.position+new Vector3(0,200,0);
//設(shè)置子彈的隨機顏色
bullet.GetComponent<MeshRenderer>().material.color = new Color(Random.Range(0f,1f),Random.Range(0f,1f),Random.Range(0f,1f));
Debug.Log("1111111111111");
}
}