Unity学习笔记(2)飞机大战第二章

一、实现效果

效果图

在这里插入图片描述

功能列表

  1. 飞机定时无限发射
  2. 左右键控制飞机左右移动
  3. 随机生成怪物,怪物有不同
  4. 子弹射中怪物后,子弹和怪物一起被摧毁

二、知识点

刚体

  • 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的文件夹中移出,也不能这样说,总的来说是要看准到底谁是预制体。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>