25.敌人-固定不动的敌人
25.1 知识点
明确固定不动的敌方坦克的需求
固定不动的敌方坦克需要具备以下特点和功能:
- 在场景中固定不动,不会主动移动。
- 自动旋转炮台,实现攻击目标的射击行为。
- 每隔一段时间发射子弹,攻击玩家或其他目标。
- 当受到伤害时,不会死亡,但可以受到伤害效果。
拖拽炮台资源,给炮台要旋转的子对象添加旋转脚本,拖成预制体
- 找到炮台资源。
- 给炮台上要旋转的子对象添加旋转脚本,确保其能够自动旋转。
- 将调整好的炮台预制体拖拽成预制体,以备后续使用。
新建固定不动的敌人脚本,自动旋转已经添加旋转脚本完成了,处理每隔一段时间发射子弹和重写不受伤逻辑即可
// 固定不动的敌人脚本
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