Unity 任務狀態的獲取 任務完成與游戲結束的判斷和提示


目錄

 

任務完成條件:擊殺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 課程設計報告


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM