[Unity2D入门教程]简单制作仿植物大战僵尸游戏之⑥制作游戏失败和成功后执行的代码

在创建完我们所需要的敌人和防御者以后,我们还要为我们游戏场景添加失败和成功后添加新的Canvas以及播放下一关的场景,我们现在就来实现一下吧

制作游戏成功:

首先创建一个Canvas叫Level Complete Canvas,然后给它添加文字和阴影图片

除此之外我们还要在之前的Main Canvas(之前的,改了个名而已)创建新UI Slider,然后把Handle部分换一张SPrite比如狐狸那张,然后改变background和fill的颜色

 

制作失败的Canvas:

前面的和成功的Canvas一样,唯一不同的是要创建两个Button,一个是返回一个是重新开始本关

因此我们要创建两个Public方法供Button调用,这里我们创建个空对象就叫LevelController来管理我们的关卡

给它一个同名的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LevelController : MonoBehaviour
{
    [SerializeField] float waitToLoad = 3f;
    [SerializeField] GameObject winLabel;
    [SerializeField] GameObject lostLabel;
    int numberOfAttackers = 0;
    bool levelTimerFinished = false; //判断滑动条的Value是否到1
    
    private void Start()
    {
        //先把输赢的canvas隐藏
        winLabel.SetActive(false);
        lostLabel.SetActive(false);
    }
    public void AttackerSpawn()  //给Attacker调用
    {
        numberOfAttackers++;
    }
    public void AttackerKilled() //同样给attacker调用
    {
        numberOfAttackers--;
        if (numberOfAttackers <= 0 && levelTimerFinished)
        {
            StartCoroutine(HandleWinCondition());
        }
    }
    IEnumerator HandleWinCondition() //当关卡成功时候
    {
        winLabel.SetActive(true);
        GetComponent<AudioSource>().Play();
        yield return new WaitForSeconds(waitToLoad);
        FindObjectOfType<LevelLoader>().LoadNextScene();
    }
    public void HandleLoseCondition() //当关卡失败后
    {
        lostLabel.SetActive(true);
        Time.timeScale = 0;
    }
    public void LevelTimerFinished() //滑动条的值为1时候
    {
        levelTimerFinished = true;
        StopSpawners();
    }
    private void StopSpawners() //停止生产敌人
    {
        AttackSpawner[] spawnArray = FindObjectsOfType<AttackSpawner>();
        foreach (var spawner in spawnArray)
        {
            spawner.StopSpawning();
        }
    }
}

然后再挂载到上面

那我们怎么判断关卡是不是失败呢?和植物大战僵尸一样,当进入房子的敌人超过一定数量时游戏直接判负,显示游戏失败。 这里用一个空对象给它一个Trigger

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DamageCollider : MonoBehaviour
{
    private void OnTriggerEnter2D(Collider2D other)
    {
        FindObjectOfType<Lives>().TakeLife();
    }
}

在Main Canvas时我们又创建一个Text

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Lives : MonoBehaviour
{
    [SerializeField] int damage = 1;
    [SerializeField] int lives = 5;
    Text livesText;
    private void Start()
    {
        livesText = GetComponent<Text>();
        UpdateDisplay();
    }

    private void UpdateDisplay()
    {
        livesText.text = lives.ToString();
    }

    public void TakeLife()
    {
        lives -= damage;
        UpdateDisplay();

        if (lives <= 0)
        {
            FindObjectOfType<LevelController>().HandleLoseCondition();
            //FindObjectOfType<LevelLoader>().LoadYouLose();
        }
    }
}

之前的LevelLoader已经不需要了,取而代之的是LevelController

 制作完以上两点后,我们也可以设置一个让不同路生成不同种类的敌人。用数组的形式在AttackerSpawner上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AttackSpawner : MonoBehaviour
{
    [SerializeField] Attacker[] attackPrefabArray;
    [SerializeField] float minSpawnDelay = 1f;
    [SerializeField] float maxSpawnDelay = 5f;
    bool spawn = true;
    IEnumerator Start()
    {
        while (spawn)
        {
            yield return new WaitForSeconds(Random.Range(minSpawnDelay, maxSpawnDelay)); //延迟生成Attacker对象
            SpawnAttack();
        }
    }
    private void SpawnAttack()
    {
        var attackerIndex = Random.Range(0, attackPrefabArray.Length);
        Spawn(attackPrefabArray[attackerIndex]);
    }
    public void StopSpawning()
    {
        spawn = false;
    }
    private void Spawn(Attacker myAttacker)
    {
        Attacker newattacker = Instantiate(myAttacker, transform.position, transform.rotation) as Attacker;
        newattacker.transform.SetParent(transform); //并把对象转化为我们Spawenr的子对象,简化hierarchy窗口
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Attacker : MonoBehaviour
{
    GameObject currentTarget;
    [Range(0, 5)]
    float currentSpeed = 1f;

    private void Awake()
    {
        FindObjectOfType<LevelController>().AttackerSpawn();
    }
    private void OnDestroy()
    {
        LevelController level = FindObjectOfType<LevelController>();
        if (level != null)
        {
            level.AttackerKilled();
        }
    }
    void Update()
    {
        transform.Translate(Vector2.left * currentSpeed * Time.deltaTime);
        UpdateAnimationState();
    }

    private void UpdateAnimationState()
    {
        if (!currentTarget)
        {
            GetComponent<Animator>().SetBool("isAttacking", false); 
        }
    }

    public void SetMovementSpeed(float speed)
    {
        currentSpeed = speed;
    }
    public void Attack(GameObject target)
    {
        GetComponent<Animator>().SetBool("isAttacking", true); //播放吃植物动画
        currentTarget = target;//锁定植物
    }
    public void StrikeCurrentTarget(float damage)
    {
        if (!currentTarget) return;
        Health health = currentTarget.GetComponent<Health>();
        if (health)
        {
            health.DealDamage(damage);//扣植物的血
        }
    }

}

游戏效果:

猜你喜欢

转载自blog.csdn.net/dangoxiba/article/details/124192348
今日推荐