Unity入门第四天:子弹接触物体的反应

本篇讲述了当子弹遇到玩家,基地,砖墙和铁墙时的不同情况。

这几天打不起精神,结果昨天继续学unity的时候竟然遇上了瓶颈,子弹没有接触物体的效果,可谓是雪上加霜。好在今天检查了半天终于看出来了,也写在后面希望以此为戒。

玩家死亡处理

在坦克大战中,玩家与敌人都可以发射子弹,为了玩家可以死亡区别不同的子弹,我们设置一个布尔值:public bool isPlayerBullet;//默认false,并在之前搭的switch statement框架中添加:

1
2
3
4
5
6
case "Tank":
if(!isPlayerBullet)//如果不是玩家自己的子弹
{
collision.SendMessage("Die");//调用player脚本中的“die”方法
}
break;

在player(坦克)的脚本中,Die方法如下(⚠️方法名必须一致否则无法调用!):

1
2
3
4
5
6
7
8
9
10
11
12
13
//爆炸预制件prefab:
public GameObject explosionPrefab;
//坦克的死亡方法
private void Die(){
//检测玩家是不是处于被保护状态,如果是,直接return不进行下面的死亡特效
if(isDefended == true){
return;
}
//产生爆炸特效
Instantiate(explosionPrefab, transform.position, transform.rotation);
//死亡
Destroy(gameObject);
}

基地被攻击

我们的预想是当基地被攻击时,老鹰旗将变为一面战痕累累的旗帜,同样,在switch条件下进行对战败方法的调用:

1
2
3
4
case "Heart":
collision.SendMessage("Die");
break;
}

而创建新的Heart脚本后,我们载入预制件并设定调用Die方法后将会调用预制件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Heart : MonoBehaviour
{
//2D渲染需要拿一下sprite renderer的组件
private SpriteRenderer sr;
//添加游戏输了时的图片
public Sprite BrokenSprite;

// Start is called before the first frame update
void Start()
{
sr = GetComponent<SpriteRenderer>();
}

// Update is called once per frame
void Update()
{}

public void Die()
{
sr.sprite = BrokenSprite;
}
}

砖墙与铁墙被攻击

当砖墙被子弹击中时,子弹与砖墙都应该消失;当铁墙和空气墙被击中时,只有子弹消失:

1
2
3
4
5
6
7
8
case "Wall":
Destroy(collision.gameObject);//如果碰到的是墙,游戏物体(墙)就会被销毁掉
Destroy(gameObject);//销毁自身
break;
case "Barrier":
//碰到墙和空气墙,只能销毁子弹,对障碍无作用
Destroy(gameObject);
break;

令人哭笑不得的problem

  • 第一个问题是一开始写OnTriggerEnter2D的时候系统不允许我写private,一开始我还以为是版本问题,没有在意,后来真正运行时发现这个方法完全没有调用,而设置成private void又报错。反复对比后才发现自己把这个方法写在Update()里面了,真是无语…
  • 第二件事情是自己的子弹在写完以上代码后仍然可以穿过墙体,在确认代码无误,排查了很久很久之后,才发现是因为我给hierarchy中的物体装上了Box Collider 2D, Rigidbody 2D,但在prefab中没有装上,也没有在prefab的脚本里更新Sprite Renderer的图片,就算我override了很多遍,但这几个地方都没有更新,不知道是不是我的打开方式不对…
  • 经验就是以后在hierarchy中更新的东西要记得在prefab中查看有没有同步好!

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2020-2024 Yangyang Cui

请我喝杯咖啡吧~

支付宝
微信