25.不动的敌人

25.敌人-固定不动的敌人


25.1 知识点

明确固定不动的敌方坦克的需求

固定不动的敌方坦克需要具备以下特点和功能:

  1. 在场景中固定不动,不会主动移动。
  2. 自动旋转炮台,实现攻击目标的射击行为。
  3. 每隔一段时间发射子弹,攻击玩家或其他目标。
  4. 当受到伤害时,不会死亡,但可以受到伤害效果。

拖拽炮台资源,给炮台要旋转的子对象添加旋转脚本,拖成预制体

  1. 找到炮台资源。
  2. 给炮台上要旋转的子对象添加旋转脚本,确保其能够自动旋转。
  3. 将调整好的炮台预制体拖拽成预制体,以备后续使用。

新建固定不动的敌人脚本,自动旋转已经添加旋转脚本完成了,处理每隔一段时间发射子弹和重写不受伤逻辑即可

// 固定不动的敌人脚本
public class MonsterTower : TankBaseObj
{
    // 自动旋转已经添加旋转脚本完成了

    // 间隔开火
    public float fireOffsetTime = 1; // 间隔时间
    private float nowTime = 0; // 记录累加时间

    // 发射位置
    public Transform[] shootPos;
    // 子弹预设体
    public GameObject bulletObj;
    
    void Update()
    {
        // 不停的累加时间并记录下来
        nowTime += Time.deltaTime;
        // 当时间超过间隔时间时就开火
        if (nowTime >= fireOffsetTime)
        {
            Fire();
            nowTime = 0;
        }
    }

    // 开火
    public override void Fire()
    {
        for (int i = 0; i < shootPos.Length; i++)
        {
            // 实例化子弹
            GameObject obj = Instantiate(bulletObj, shootPos[i].position, shootPos[i].rotation);
            // 设置子弹的拥有者
            BulletObj bullet = obj.GetComponent<BulletObj>();
            bullet.SetFather(this);
        }
    }

    // 重写受伤函数
    public override void Wound(TankBaseObj other)
    {
        // 空实现,不受伤
    }
}

修改子弹对象碰撞触发逻辑,如果是敌对阵营也要碰撞检测,假如碰撞体有挂载坦克基类,就让他受伤。Unity允许获得父类脚本得到子类脚本。

// 子弹对象碰撞触发逻辑
private void OnTriggerEnter(Collider other)
{
    // 判断碰撞对象是否为立方体或是与敌对阵营的坦克
    if (other.CompareTag("Cube") ||
        (other.CompareTag("Player") && fatherObj.CompareTag("Monster")) ||
        (other.CompareTag("Monster") && fatherObj.CompareTag("Player")))
    {
        // 获取碰撞到的对象上是否挂载了坦克相关脚本
        TankBaseObj obj = other.GetComponent<TankBaseObj>();
        // 如果有,则让其受伤
        if (obj != null)
            obj.Wound(fatherObj);

        // 当子弹销毁时,创建爆炸特效
        if (effObj != null)
        {
            GameObject eff = Instantiate(effObj, transform.position, transform.rotation);
            AudioSource audioS = eff.GetComponent<AudioSource>();
            audioS.volume = GameDataMgr.Instance.musicData.soundValue;
            audioS.mute = !GameDataMgr.Instance.musicData.isOpenSound;
        }

        Destroy(gameObject);
    }
}

25.2 知识点代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//固定不动
public class MonsterTower : TankBaseObj
{
    //自动旋转 不用我们自己实现了 因为已经挂载了一个 专门管旋转的脚本

    //间隔开火
    // 应该有一个 间隔时间 
    public float fireOffsetTime = 1;
    //记录累加时间 用于 间隔开火判断
    private float nowTime = 0;
    // 发射位置
    public Transform[] shootPos;
    // 子弹预设体 关联
    public GameObject bulletObj;
    
    void Update()
    {
        //不停的累加时间 并记录下来
        nowTime += Time.deltaTime;
        //当时间超过间隔时间时  就开火
        if( nowTime >= fireOffsetTime )
        {
            Fire();
            nowTime = 0;
        }
    }

    //开火
    public override void Fire()
    {
        for (int i = 0; i < shootPos.Length; i++)
        {
            //实例化几个子弹
            GameObject obj = Instantiate(bulletObj, shootPos[i].position, shootPos[i].rotation);
            //这里是设置子弹的拥有者 方便之后 进行属性计算
            BulletObj bullet = obj.GetComponent<BulletObj>();
            bullet.SetFather(this);
        }
    }

    //重写受伤函数
    public override void Wound(TankBaseObj other)
    {
        //这里面什么内容都不写 
        //目的就是 让这个 固定不动的坦克 它可以不被伤害 永远不会死亡
    }

}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏