首页 > 技术文章 > Unity 任务状态的获取 任务完成与游戏结束的判断和提示

haiyue-csdn 2020-06-11 00:55 原文

目录

 

任务完成条件:击杀n个敌人,n由关卡设定

游戏结束条件:没血

任务完成的判断依据:击杀目标数

任务完成的标志:方便其他函数和脚本调用

游戏结束代码

任务完成代码

详细代码


任务完成条件:击杀n个敌人,n由关卡设定

>>点此查看设定方式

游戏结束条件:没血

实现方式:

如果没血(curhealth==0),则游戏结束

利用挂载在主角身上的控制脚本进行计数,如果达到击杀数量就激活任务完成的提示文本

任务完成的判断依据:击杀目标数

每次击杀时,在子弹控制脚本BulletControl的OnCollisionEnter2D函数中修改该变量

任务完成的标志:方便其他函数和脚本调用

在玩家控制脚本中设定任务完成标记

类型为Static,以便其他脚本查询当前任务进度状态

当击杀数达到目标时,设定任务状态为1

在其他脚本调用时,使用PlayControl.showflag获取任务状态

格式 脚本名.参数名

记得在新的关卡开始的时候初始化为0

游戏结束代码

任务完成代码

第一部分、子弹脚本:

第二部分、玩家脚本(主要部分)

详细代码

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

public class PlayerControl : MonoBehaviour
{
    //主角速度
    public float speed = 8f;
    Rigidbody2D rbody;//定义2d刚体
    Animator anim;//定义动画
    Vector2 lookDirection = new Vector2(1, 0);//初始向x看

    GameObject robotObj;//定义一个机器人对象
    //最大健康值
    private int maxHealth=5;
    //当前健康值
    private int currentHealth;
    //其他脚本可获取最大健康值
    public int MyMaxHealth { get { return maxHealth; } }
    //其他脚本可获取当前健康值
    public int MyCurrentHealth { get { return currentHealth; } }
    //敌人剩余数量
    public static int enemyleft = 2;
    //public int curEnemyleft { get { return enemyleft; } }
    //无敌时间
    private float wuditime = 2f;
    //无敌计时器
    private float wuditimer;
    //无敌状态
    private bool isWudi;

    //子弹数量
    [SerializeField]
    private int curBulletCount=2;

    private int maxBulletCount=99;

    public int MyCurBulletCount { get { return curBulletCount; } }
    public int MyMaxBulletCount { get { return maxBulletCount; } }
    //子弹预制体
    public GameObject bulletPrefab;

    //游戏结束提示
    public GameObject GameOver;
    //指定为主角并销毁
    public GameObject GameOverPlayer;
    //任务完成提示
    public GameObject MissionCompleted;
    //无法实现在其他脚本中销毁提示,故在此脚本中限时销毁
    public float showTime = 4;
    private float showTimer;
    //显示标志,一场游戏中只显示一次
    private int showflag=0;

    //玩家音效
    public AudioClip hitClip;
    public AudioClip launchClip;

    // Start is called before the first frame update
    void Start()
    {
        //隐藏任务完成提示
        MissionCompleted.SetActive(false);
        //提示计时器设置为负值
        showTimer = -1;
        //重新开始游戏后初始化敌人数量
        enemyleft = 2;

        rbody = GetComponent<Rigidbody2D>();//获取2d刚体
        anim = GetComponent<Animator>();//获取动画组件
        //初始化生命值
        currentHealth = 2;
        //初始化无敌时间
        wuditimer = 0;
        //更新生命条与子弹数量
        UIManager.instance.UpdateHealthBar(currentHealth, maxHealth);
        UIManager.instance.UpdateBulletCount(curBulletCount, maxBulletCount);
    }

    // Update is called once per frame
    void Update()
    {
        //任务完成提示计时
        showTimer -= Time.deltaTime;

        //Debug.Log(showTimer);

        //超过时间就取消显示任务完成提示
        if (showTimer < 0)
        {   
            MissionCompleted.SetActive(false);
        }
        //敌人数量为0,并且是第一次达到0,之前没有完成任务,任务完成
        if (enemyleft==0 && showflag != 1)
        {
            //给倒计时器赋值,以此显示提示
            showTimer = showTime;
            //已经完成任务了,标记一下,之后不再显示
            showflag = 1;
            //显示任务完成提示
            MissionCompleted.SetActive(true);
        }
        
        //如果生命值为0,显示游戏结束字样,并销毁主角
        if (currentHealth==0)
        {
            GameOver.SetActive(true);
            Destroy(GameOverPlayer);
        }
        
        //获取运动矢量
        float moveX = Input.GetAxisRaw("Horizontal");
        float moveY = Input.GetAxisRaw("Vertical");

        Vector2 moveVector = new Vector2(moveX, moveY);

        if(moveX!=0||moveY!=0)
        {
            lookDirection = moveVector;
        }

        Vector2 position = transform.position;
        position.x += moveX * speed * Time.deltaTime;
        position.y += moveY * speed * Time.deltaTime;

        transform.position = new Vector2(position.x, position.y);
        rbody.MovePosition(position);//用刚体移动可以消除画面抖动

        anim.SetFloat("move X",lookDirection.x);//为动画集赋值
        anim.SetFloat("move Y",lookDirection.y);
        anim.SetFloat("runspeed", moveVector.magnitude);//状态集的切换由运动矢量决定
        //赋值必须与状态集命名一样

        //--------------------------------------------------
        //如果处于无敌状态,就计时
        if(isWudi)
        {
            wuditimer -= Time.deltaTime;
            //计时器归0,就不处于无敌状态了
            if(wuditimer<0)
            {
                isWudi = false;
            }
        }
        //-------------------------------------
        //当按下J,并且子弹大于0,开火
        if(Input.GetKeyDown(KeyCode.J) && curBulletCount>0)
        {
            ChangeBulletCount(-1);
            anim.SetTrigger("Launch");
            AudioManager.instance.AudioPlay(launchClip);
            GameObject bullet = Instantiate(bulletPrefab, rbody.position+Vector2.up*0.5f, Quaternion.identity);
            BulletControl bc = bullet.GetComponent<BulletControl>();
            if(bc!=null)
            {
                bc.Shoot(lookDirection, 300);
            }
        }
        //按E与npc交互
        if(Input.GetKeyDown(KeyCode.E))
        {
            RaycastHit2D hit = Physics2D.Raycast(rbody.position, lookDirection, 2f, LayerMask.GetMask("NPC"));
            if(hit.collider!=null)
            {
                Debug.Log("hit npc!");
                NPCManager npc = hit.collider.GetComponent<NPCManager>();
                if(npc!=null)
                {
                    npc.ShowDialog();
                }
            }
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        //踩到雷区,自动生成僵尸
        float robotX = Random.Range(-3, 5);
        float robotY = Random.Range(-3, 5);
        Vector2 position_robot = new Vector2(robotX, robotY);

        if(collision.gameObject.tag=="bomb")//如果碰到雷区
        {
            print("other.tag=" + collision.gameObject.tag);//这句一定要有,不然出不来
            robotObj = Instantiate(Resources.Load("Prefabs/Robot"),position_robot,Quaternion.identity)as GameObject;//加载资源,生成一个预制体,做成一个对象
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        //离开雷区,僵尸消失
        if(collision.gameObject.tag=="bomb")
        {
            Destroy(robotObj);
        }
    }

    public void chnageHealth(int amount)
    {
        //可能是受到伤害,也可能是加血
        if(amount<0)
        {
            //如果是受伤,设置无敌状态,则2秒内不能受伤
            if(isWudi==true)
            {
                return;
            }
            isWudi = true;
            //播放受伤动画
            anim.SetTrigger("Hit");
            //播放受伤音效
            AudioManager.instance.AudioPlay(hitClip);
            //为无敌计时器赋值
            wuditimer = wuditime;
        }
        //更改健康值
        currentHealth = Mathf.Clamp(currentHealth+amount,0,maxHealth);
        //更新血条
        UIManager.instance.UpdateHealthBar(currentHealth, maxHealth);
        //调试
        Debug.Log(currentHealth + "/" + maxHealth);
    }

    public void ChangeBulletCount(int amount)
    {
        //改变子弹数
        curBulletCount = Mathf.Clamp(curBulletCount + amount, 0, maxBulletCount);
        //改变UI子弹数
        UIManager.instance.UpdateBulletCount(curBulletCount, maxBulletCount);
    }
}

减少剩余敌人数,是在子弹脚本中实现的

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

public class BulletControl : MonoBehaviour
{
    Rigidbody2D rbody;
    //子弹命中声
    public AudioClip hitClip;

// Start is called before the first frame update
void Awake()
    {
        rbody = GetComponent<Rigidbody2D>();
        //2秒后不管打没打中,子弹销毁子弹
        Destroy(this.gameObject, 2f);
    }

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

    }

    //子弹发射,射击
    public void Shoot(Vector2 moveDirection,float moveForce)
    {
        rbody.AddForce(moveDirection * moveForce);
    }

    //子弹命中
    private void OnCollisionEnter2D(Collision2D collision)
    {
        //调用机器人控制脚本的修复函数,修改机器人的状态
        RobotControl ec = collision.gameObject.GetComponent<RobotControl>();
        if (ec!=null)
        {
            Debug.Log("命中敌人了");
            ec.Fixed();//杀敌
            //更改玩家控制中的击杀数,以此判断任务是否完成,格式:脚本名.静态变量--;
            PlayerControl.enemyleft--;
        }
        //播放命中声
        AudioManager.instance.AudioPlay(hitClip);
        //立即销毁子弹
        Destroy(this.gameObject);
    }
}

附完整教程:

Unity2d Rubys Adventure 课程设计报告

推荐阅读