Unity制作王者荣耀笔记(八)箭塔创建子弹攻击小兵,血条减血

一、当有敌人进入箭塔范围内时生成子弹,并让子弹瞄准攻击目标:

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;
    }

}
发布了152 篇原创文章 · 获赞 24 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_40229737/article/details/103631589