一、实现效果
效果图
功能列表
- 飞机定时无限发射
- 左右键控制飞机左右移动
- 随机生成怪物,怪物有不同
- 子弹射中怪物后,子弹和怪物一起被摧毁
二、知识点
刚体
- Dynamic 普通刚体 有质量
- Static 静态刚体 质量无穷(地面)
- Kinematic 运动学刚体 质量为0(物理规律不起作用,一般用于碰撞检测)
- 设置刚体:Physics 2D ->RigidBody 2D -> Body Type -> Dynamic/Static/Kinematic
碰撞体
- Physics 2D -> Box/Circle Collider 2D -> is Trigger
碰撞检测
- 设置可碰撞:添加碰撞组件Physics 2D ->Box Collider2D->is Trigger 打勾
- 添加碰撞检测函数(例):
private void OnTriggerEnter2D(Collider2D collision){Debug.Log("检测到了碰撞");}
Collider2D collision表示对方的碰撞组件
collision.gameObject——对方
collision.name——对方节点名称
collision.tag —— 对方的节点的Tag
collision.transform——对方的Transform组件
- 碰撞事件回调:
1、OnTriggerEnter2D,两碰撞体开始相遇
2、OnTriggerStay2D,两碰撞体接触中
3、OnTriggerExit2D,两碰撞体离开
随机数
value=Random.Range(min,max);
eg:float x=Random.Range(-2,2);
定时器
InvokeRepeating(method, delay,interval);//delay 多长时间后执行第一次,interval 几秒钟重复一次方法调用
eg:InvokeRepeating(“CreatePig”,0.1f ,2f);
随机选择图片
int index = Random.Range(0, images.Length);
SpriteRenderer renderer = monster.GetComponent();
renderer.sprite = this.images[index];
三、代码实现
MyGame.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyGame : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Application.targetFrameRate = 60;
}
// Update is called once per frame
void Update()
{
}
}
MyBullet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyBullet : MonoBehaviour
{
public float speed = 2.0f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
float dy = speed * Time.deltaTime;
transform.Translate(0, dy, 0, Space.Self);
Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);
if(sp.y>Screen.height)
{
Destroy(this.gameObject);
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.tag.Equals("Monster"))
{
Destroy(collision.gameObject);
Destroy(this.gameObject);
}
}
}
MyJet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyJet : MonoBehaviour
{
public float speed = 2.0f;
public GameObject bulletPrefab;
private float count = 0;
private float interval = 0.4f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
count += Time.deltaTime;
if(count >interval )
{
count = 0;
Fire();
}
float step = speed * Time.deltaTime;
if(Input.GetKey(KeyCode.LeftArrow))
{
transform.Translate(-step, 0, 0);
}
if (Input.GetKey(KeyCode.RightArrow))
{
transform.Translate(step, 0, 0);
}
}
void Fire()
{
Vector3 pos = transform.position + new Vector3(0, 1, 0);
GameObject bullet = Instantiate(bulletPrefab, pos, transform.rotation);
}
}
Monster.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Monster : MonoBehaviour
{
public float speed = 1.0f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
float dy = speed * Time.deltaTime;
transform.Translate(0, -dy, 0, Space.Self);
Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);
if (-sp.y*2 > Screen.height)
{
Destroy(this.gameObject);
}
}
}
MonsterCtrl.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterCtrl : MonoBehaviour
{
public GameObject MonsterPrefab;
public Sprite[] images;
// Start is called before the first frame update
void Start()
{
InvokeRepeating("CreateMonster", 0.1f, 2f);
}
// Update is called once per frame
void Update()
{
}
void CreateMonster()
{
float x = Random.Range(-2, 2);
float y = 5;
GameObject monster = Instantiate(MonsterPrefab);
monster.transform.position = new Vector3(x, y, 0);
//
int index = Random.Range(0, images.Length);//6张图片
SpriteRenderer renderer = monster.GetComponent<SpriteRenderer>();
renderer.sprite = this.images[index];
}
}
四、遇到了一个非常头疼的问题
报错: The object of type ‘xxx’ has been destroyed but you are still trying to access it
但我的逻辑明明没有错误,也是照着老师的步骤来的,怎么会在摧毁上一个预制体后不能成功创建下一个预制体呢?????然后搜索了很多,怀疑是因为程序调用的时候虽然逻辑上预制体被摧毁了,但其实程序滞留,在创建预制体时访问的是上一个空的预制体,所以访问不了。woc,这啥呀这是,关键是人家老师为啥能行,我就不行,我电脑可是apple M1啊,按道理cpu速度也是行的啊😭😭😭
皆大欢喜!!!!👏👏👏😃😃😃解决了!!!
我是sabi叭,完全是因为预制体移错了,贴图警告⚠️
不知道为什么,当路径二的怪物变蓝后我就自认为它就变成预制体了,但其实并不是,只能从Prefab的文件夹中移出,也不能这样说,总的来说是要看准到底谁是预制体。