一、当有敌人进入箭塔范围内时生成子弹,并让子弹瞄准攻击目标:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Tower : MonoBehaviour {
//定义箭塔类型
public int towerType;
//创建一个集合,当小兵移动到箭塔范围之内把其添加到集合里,否则将其移除集合
public List<GameObject> listSolider = new List<GameObject>();
//创建一个集合,当英雄移动到箭塔范围之内把其添加到集合里,否则将其移除集合
public List<GameObject> listHero = new List<GameObject>();
[SerializeField]
private GameObject bulletPrefab;//子弹
[SerializeField]
private Transform bulletStart;//子弹生成时所在的位置
[SerializeField]
private Transform parent;//生成的子弹放在这个物体下
void Start()
{
//有了标签为什么还要定义int towerType,主要是跟小兵类型有个对应
//防止我方箭塔去攻击我方小兵
if (this.gameObject.tag.Equals("Tower"))
{
towerType = 0;//我方箭塔
}
else
{
towerType = 1;//敌方箭塔
}
InvokeRepeating("CreateBullet", 0.1f, 1.3f);
}
//生成子弹
public void CreateBullet()
{
//没有敌人,不生成子弹
if (listHero.Count == 0 && listSolider.Count == 0) return;
//否则生成子弹
GameObject bullet = (GameObject)Instantiate(bulletPrefab,bulletStart.position,Quaternion.identity);
bullet.transform.parent = parent;
BulletTarget(bullet);//设置子弹攻击目标
}
//塔是先射击小兵,没有小兵再射击英雄
public void BulletTarget(GameObject bullet)
{
if (listSolider.Count > 0)
{
//把列表里的第一个小兵作为攻击对象
bullet.GetComponent<Bullet>().SetTarget(listSolider[0]);
}
else
{
//把列表里的第一个英雄作为攻击对象
bullet.GetComponent<Bullet>().SetTarget(listHero[0]);
}
}
//小兵进入到箭塔范围,箭塔从集合中找攻击目标
private void OnTriggerEnter(Collider other)
{
//进入箭塔是英雄
if (other.gameObject.tag == "Player")
{
listHero.Add(other.gameObject);
}
else
{
//进入箭塔是小兵
SmartSolider solider = other.GetComponent<SmartSolider>();
//当小兵不为空时,判断小兵与箭塔类型是否一致,不一致表示可以攻击
if (solider && solider.type != towerType)
{
listSolider.Add(other.gameObject);//小兵放在可攻击的列表内
}
}
}
//人物退出范围,移除列表
private void OnTriggerExit(Collider other)
{
if (other.gameObject.tag == "Player")
{
listHero.Remove(other.gameObject);
}
else
{
listSolider.Remove(other.gameObject);
}
}
}
创建子弹预制体bullet,并手动设置每种箭塔子弹的生成位置:blueStartPoint
子弹物体上的组件设置如下:Bullet脚本在文末附上
二、给Player 、小兵、还有箭塔创建血条,分别作为他们的子物体:
血条设置如下,导入的背景图片类型设置:
蓝色背景线条框:其中Sprite Slider脚本在文末附上
红色图片:
创建的脚本SpriteSlider.cs修正红色血条本身的大小以及位置,value值决定了红色血条的位置和大小:
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class spriteSlider : MonoBehaviour {
[SerializeField]
private Transform front;
public float m_value;
public float Value
{
get
{
return m_value;
}
set
{
m_value = value;
front.localScale = new Vector3(value, 1, 1);
front.localPosition = new Vector3((1 - m_value) * -0.8f, 0);//这个式子可以自己设置数值关观察下
}
}
}
创建减血方法的脚本Health.cs挂在带有血条的对象身上
using UnityEngine;
using System.Collections;
public class Health : MonoBehaviour {
public spriteSlider hp;
private uint value=1;//uint 表示值不可能为负
// Use this for initialization
void Start () {
hp=GetComponentInChildren<spriteSlider>();//代码找到组建,不用一个个拖拽
Init();
}
public void Init()
{
hp.Value = value;//血条初始化值为1
}
//减血的方法
public void TakeDamage(float damage)
{
hp.Value -= damage;
}
}
给人物附上标签:
英雄设置:
Bullet.cs脚本:
using UnityEngine;
using System.Collections;
public class Bullet : MonoBehaviour {
private GameObject target;
public float speed=20f;
public Tower tower;
void Start () {
tower = GetComponentInParent<Tower>();
//生成之后1秒内就要销毁,因为可能是子弹已经存在攻击目标,但是目标跑出了射程之外,所以我们规定子弹存在时间为1秒
Destroy(this.gameObject, 1f);
}
//子弹撞到士兵或者英雄
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag=="solider")
{
//获取人物身上的血量值,调用减血方法
Health hp = other.GetComponent<Health>();
if (hp)
{
hp.TakeDamage(0.5f);
if (hp.hp.Value <= 0)
{ //子弹碰到小兵,且小兵血量此时为0,从列表中移除小兵
tower.listSolider.Remove(other.gameObject);
Destroy(other.gameObject);
}
Destroy(this.gameObject);
}
}
else if (other.gameObject.tag == "Player")
{
//获取人物身上的血量值,调用减血方法
Health hp = other.GetComponent<Health>();
if (hp)
{
hp.TakeDamage(0.5f);
if (hp.hp.Value <= 0)
{ //子弹碰到小兵,且小兵血量此时为0,从列表中移除
tower.listHero.Remove(other.gameObject);
Destroy(other.gameObject);
}
Destroy(this.gameObject);
}
}
}
void Update () {
//攻击目标不为空,子弹移动
if (target)
{
Vector3 dir = target.transform.position - transform.position;
GetComponent<Rigidbody>().velocity = dir.normalized * speed;
}
else
{
//子弹在向小兵移动的过程中,小兵可能已经消失了,此时要消失子弹
Destroy(this.gameObject);
}
}
//得到子弹攻击的目标
public void SetTarget(GameObject target)
{
this.target = target;
}
}