一、主要框架
二、模型
三、关键代码
Bullet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour {
//防御塔的引用
public GameObject tower;
//所有敌人的引用;
private EnemyController[] enemys;
//开始发射子弹的距离;
private float distance;
//最近的敌人;
private EnemyController nearestEnemy;
//判断塔与敌人的距离;
private float dis;
//子弹伤害值;静态的一般公开的才方便调用
public static float bulletDamage;
void Start () {
//定义伤害值
bulletDamage = 10f;
}
void Update () {
//寻找敌人的方法
//--------------------------------------------------------------
//设置最近距离;
distance = 500f;
//获取所有子物体;
enemys = FindObjectsOfType<EnemyController>();
//遍历所有子物体 以获取最近敌人;
for (int i = 0; i < enemys.Length; i++)
{
//获取两物体间的距离
dis = Vector3.Distance(tower.transform.position, enemys[i].transform.position);
//判断是否是防御距离二发射子弹;
if (dis < distance)
{
distance = dis;
nearestEnemy = enemys[i];
Debug.Log("最近敌人");
}
}
//--------------------------------------------------------------
//判断如果最近敌人不为空 就发射子弹;
if (nearestEnemy!=null)
{
//子弹的位置 从塔的位置移向到敌人的位置;
this.transform.position = Vector3.MoveTowards(this.transform.position,nearestEnemy.transform.position,10f); //参数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的工具状态 避免实例化就开始攻击;
EnemyController enemyController;
//播放音效
private AudioSource mAudioSource;
void Start () {
//获取敌人身上的动画组件
anim = this.GetComponent<Animator>();
//获取脚本组件;
enemyController = this.GetComponent<EnemyController>();
//获取音效的音频;
mAudioSource = this.GetComponent<AudioSource>();
}
void Update () {
//判断塔销毁的状态
if (TowerController.isDamage==false)
{
//获取EnemyControoler脚本上的布尔值 是否可以攻击
if (enemyController.isAttack == true)
{
//设置动画状态的布尔值
anim.SetBool("Attack", true); //参数1:动画条件 参数文2:动画值
anim.SetBool("Walk", true);
anim.SetBool("Idle", false);
}
}
else if (TowerController.isDamage == true)
{
//设置动画状态的布尔值
anim.SetBool("Attack", false); //参数1:动画条件 参数文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;
//设置布尔值;必须是公开的,方便调用
public bool isAttack;
//设置敌人的攻击力度 设置静态方便调用 不用实例化出来
public static float damage=10f;
//设置敌人的生命值;
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 () {
//只有塔还没被摧毁的时候才执行这个移动
if (TowerController.isDamage==false)
{
//移动到防御塔
// this.transform.position = Vector3.MoveTowards(this.transform.position,towerPrefab.transform.position,2f); //参数1:当前位置 参数2:目标位置 参数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);
//判断距离停止移动 并且播放攻击的动画;设置攻击为真
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
{
//防御塔预制体的引用
public GameObject towerPrefab;
//敌人的预制体的引用 数组 随机生成
public GameObject[] enemyPrefab;
//敌人的位置
// public Transform enemyPoint1;
public Transform[] enemyPoint;
//定时器 每隔2秒钟就生成一个敌人
public float timeGo = 3f;
//用来接收输入时间的
private float startTime ;
//避免update中的方法不断识别 定义一个标志位
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()
{
//判断塔的状态 只有不被销毁的时候才实例化敌人
if (TowerController.isDamage==false)
{
//时间递减
timeGo -= Time.deltaTime;
//如果时间归零并且满足条件为真
if (timeGo <= 0 && isFoundEnemy == true)
{
OnTrackingEnemyFound();
//时间回到初始化值
timeGo = startTime;
}
}
}
#region PRIVATE_METHODS
private void OnTrackingFound()
{
//识别防御塔时候实例化
GameObject Tower = GameObject.Instantiate(towerPrefab) as GameObject;
//设置父类
Tower.transform.parent = this.transform;
//设置位置
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() {
//找到了设置为真
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()
{
//没找到 设置为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 循环 逐个销毁、第一种方法
//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 {
//设置塔的生命值
private float towerLife = 100f;
//判断塔是否销毁(生命值为零时) 公开的 方便敌人停止攻击动画的控制
public static bool isDamage=false;
//获取画布的引用
private Canvas canvas;
//获取画布下的image;
private Image blood;
//子弹的预制体
public GameObject bulletPrefab;
//子弹生成时间 计时器
// private float timeGo = 0;
//播放音效
private AudioSource mAudioSource;
void Start () {
//给画布和血条赋值;
canvas = GetComponentInChildren<Canvas>();
blood = canvas.GetComponentInChildren<Image>();
//获取子弹发射的音频;
mAudioSource = this.GetComponent<AudioSource>();
}
void Update () {
//发射子弹的时间
//timeGo += Time.deltaTime;
//if (timeGo>0.3f)
//{
// //执行子弹生成的方法;
// CreateBullet();
// timeGo = 0f;
//}
//以上代码是测试时用
//--------------------------
//点击屏幕时调用
if (Input.GetMouseButtonDown(0))
{
CreateBullet();
//播放子弹发射音效;
mAudioSource.Play();
}
}
void OnTriggerEnter(Collider collider)
{
if (collider.gameObject.tag== "weapon")
{
towerLife -= EnemyController.damage; //调用敌人的破坏力
//测试塔的防御值
Debug.Log(towerLife);
//显示血条 画布下的属性
blood.fillAmount = towerLife / 100;
//判断生命力小于零的时候 销毁塔和设置为真
if (towerLife<=0)
{
Destroy(this.gameObject);
isDamage = true;
}
}
}
/// <summary>
/// 实例化子弹的方法
/// </summary>
void CreateBullet() {
//实例化子弹
GameObject bullet = GameObject.Instantiate(bulletPrefab) as GameObject;
//设置父类关系
bullet.transform.parent = this.transform;
//设置位置
bullet.transform.position = this.transform.position+new Vector3(0,200,0);
//设置子弹的随机颜色
bullet.GetComponent<MeshRenderer>().material.color = new Color(Random.Range(0f,1f),Random.Range(0f,1f),Random.Range(0f,1f));
Debug.Log("1111111111111");
}
}