9. 角色的武器与发射子弹

专栏收录该内容

Hi I'm Shendi



修补上节小Bug

有两点

  • 方块落地后,角色触碰会导致游戏结束
  • 方块落地后,角色踩上方会导致方块散架

第一个问题是因为碰撞检测到角色是直接游戏结束了,而没有判断当前物体的标签是否为Box(落地就为WallBox了)

第二个问题主要是和想象中的功能不太一样,当角色踩在已经落地的方块上,因为方块还有重力组件,方块下面没有其他物体的话,会踩掉落下去,在完成时去掉刚体组件就能解决

将碰撞体部分代码改为以下代码问题解决

void OnCollisionEnter2D(Collision2D collision)
{
    switch (collision.gameObject.tag)
    {
        case "Wall":
        case "BoxWall":
            // 将父对象的所有子对象都执行完成
            for (var i = 0; i < transform.parent.childCount; i++)
            {
                var obj = transform.parent.GetChild(i);
                obj.tag = "BoxWall";
                obj.GetComponent<Box>().isOk = true;

                // 去掉刚体组件
                Destroy(obj.GetComponent<Rigidbody2D>());
            }
            break;
        case "Player":
            if (gameObject.tag == "Box")
            {
                Main._instance.StopGame();
            }
            break;
    }
}

上个效果图

效果图



制作角色武器

首先创建一个武器脚本,命名为 Weapon

其中包含了武器的信息,攻击力之类的,根据之前的策划,有三个数值

  • 攻击力
  • 冷却
  • 攻速

武器还有名称,金额等,在 Weapon 脚本中定义以下内容


首先制作默认的武器,外观就是最开始绘制Logo时与角色重合的长方形

将角色预制体拖到场景中,右键,创建一个正方形,拖拽成想要的形状和颜色,然后将新建的这个物体拖到预制体下方文件夹制作成预制体

武器


我这里新建了一个文件夹,命名为 Weapon,作为武器预制体的文件夹

预制体


在层级面板将武器删除,将武器预制体拖到角色下方,会发现武器的位置就是我们拖到预制体之前的位置

于是后续更改/生成武器只需要将武器放到角色下就可以了


制作完武器预制体,将武器脚本拖给预制体

武器脚本内定义以下参数

/** 攻击力 */
public float attack;
/** 冷却,单位秒 */
public float cool;
/** 攻速,单位方块 */
public float speed;
/** 武器名称 */
public string name;
/** 商店内的金额 */
public int gold;

将脚本内参数改为武器对应参数

武器参数



角色与武器的绑定

在 State 中定义角色默认的武器

/** 角色当前武器 */
public static GameObject playerWeapon = Resources.Load<GameObject>("Prefabs/Weapon/WeaponDefault");

接下来在角色实例化的时候同样实例化武器即可

需要注意的是,在实例化时就直接指定父物体(相当于直接把预制体拖到物体上)

而不是先实例化再指定父物体(这样会导致位置不正确)

State中角色实例化部分代码如下

/** 角色初始化,初始化完成后 playerInstance 将为实例化的角色 */
public static GameObject PlayerInit()
{
    playerInstance = GameObject.Instantiate(player);

    GameObject.Instantiate(playerWeapon, playerInstance.transform);

    return playerInstance;
}

运行游戏即可发现角色携带了武器了

角色带武器



子弹制作

不同武器可以有不同子弹,不过这里就只做一款子弹好了,直接在武器脚本增加一个新的变量作为子弹

/** 子弹 */
public GameObject bullet;

在层级面板新建一个圆形,按喜好来制作子弹样式,我这里直接就一个圆形了

新建一个脚本,命名为Bullet,拖到子弹上,并且给子弹增加刚体碰撞体组件,刚体重力0,碰撞体勾选触发器

效果


将其拖到预制体文件夹作为预制体即可,将预制体的x,y坐标改为0


然后点击武器,将子弹拖拽到武器脚本的空处



发射子弹


实例化子弹

首先需要生成子弹,在武器脚本中定义以下变量

/** 用于冷却的计数 */
private float coolTotol = 0;

生成的子弹不需要和其他物体有任何关联关系,子弹生成后就往上移动进行发射

子弹的速度,攻击力信息都在武器脚本内,于是需要传递给子弹脚本,在子弹脚本定义以下变量

/** 子弹移速 */
public float speed;
/** 攻击力 */
public float attack;

武器脚本内增加以下代码,来实现子弹生成并传递一些数值

void FixedUpdate()
{
    if (State.isGameStart)
    {
        coolTotol++;

        if (coolTotol / 50 >= cool)
        {
            var obj = GameObject.Instantiate(bullet);
            obj.transform.position = transform.position;

            var script = obj.GetComponent<Bullet>();
			script.speed = speed * State.boxSize / 50;
            script.attack = attack;

            coolTotol = 0;
        }
    }
}

这样,子弹就源源不断的在武器的位置生成了



发射

这部分就非常简单了,只有移动子弹的y轴就可以了

子弹需要设置销毁时间,避免特殊情况导致子弹无法销毁而依然占用资源的问题,就指定10秒后子弹销毁吧

代码如下

/** 销毁时间倒计时 */
private float timeTotol = 50 * 10;

void FixedUpdate()
{
    transform.position += new Vector3(0, speed);

    timeTotol--;
    // 存在时间不超过10秒
    if (timeTotol <= 0)
    {
        Destroy(gameObject);
    }
}

运行游戏后,可以看到子弹已经可以源源不断的发射了

子弹发射


不过发射的速度实在是太慢了,于是更改一下之前的策划

破烂铁筒 - 攻速 2 方块高/秒

精装铁筒 - 攻速 4 方块/秒

火箭筒 - 攻速 4 方块/秒


这里就不需要更改代码了,在Unity中点击武器预制体,更改武器的speed就可以了

最终效果如下

最终效果



本文链接:https://sdpro.top/blog/html/article/1069.html

♥ 赞助 ♥

尽管去做,或许最终的结果不尽人意,但你不付出,他不付出,那怎会进步呢?