❤❤新課程需要你的寶貴意見❤❤

2020年7月4日 星期六

Unity 教學 打地鼠


Monster.cs

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

//陳間時光 http://www.morningfungame.com/
public class Monster : MonoBehaviour
{
    GameManager gameManager;
    public float maxSecondsOnScreen=2.5f;
    public float currentSecondsOnScreen=0;

    void Start()
    {
        Init ();
    }

    private void Init ()
    {
        gameManager = FindObjectOfType<GameManager> ().GetComponent<GameManager> ();
        ResetCurrentSecondsOnScreen ();
    }

    private void OnMouseDown ()
    {
        gameManager.AddScore ();
        ResetCurrentSecondsOnScreen ();
        Hide ();
    }

    private void Hide ()
    {
        gameManager.HideMonster ( gameObject );
    }

    public bool IsActive => gameObject.activeInHierarchy;
    bool OnScreenTimeUp => currentSecondsOnScreen < 0;

    void FixedUpdate()
    {
        TryCountDownToHide ();
    }

    private void TryCountDownToHide ()
    {
        if ( IsActive )
        {
            CountDownCurrentSecondsOnScrren ();
        }

        if ( OnScreenTimeUp )
        {
            ResetCurrentSecondsOnScreen ();
            Hide ();
        }
    }

    private void CountDownCurrentSecondsOnScrren ()
    {
        currentSecondsOnScreen -= Time.fixedDeltaTime;
    }

    private void ResetCurrentSecondsOnScreen ()
    {
        currentSecondsOnScreen = maxSecondsOnScreen;
    }
}


GameManager.cs

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

//陳間時光 http://www.morningfungame.com/
public class GameManager : MonoBehaviour
{
    [SerializeField] float showMonsterIntervalSeconds=2;
    [SerializeField] float countDownShowMonsterSeconds;
    int MAX_MONSTERS_ON_SCREEN=3;

    public List<Monster> monsters;
    Text score;
    int scoreNumber=0;

    public void HideMonster ( GameObject monster ) {
        monster.SetActive ( false );
    }

    void ShowMonster ( GameObject monster ) { 
        monster.SetActive (true);
    }
    
    public void AddScore () {
        scoreNumber += 10;
        score.text = scoreNumber.ToString();
    }

    void Start()
    {
        InitScore ();
        InitMonsterList ();
        HideAllMonsters ();
        //ShowRandomMonster ();
        ResetShowMonserSeconds ();
    }

    private void ResetShowMonserSeconds ()
    {
        countDownShowMonsterSeconds = showMonsterIntervalSeconds;
    }

    void HideAllMonsters () {
        foreach ( var m in monsters )
        {
            HideMonster ( m.gameObject );
        }
    }

    List<Monster> HiddenMonsters {
        get {
            var result=new List<Monster>();

            foreach ( var m in monsters )
            {
                if (!m.IsActive)
                {
                    result.Add(m);
                }
            }

            return result;
        }
    }

    int MonsterCountOnScreen {
        get {
            int result=0;
            foreach ( var m in monsters )
            {
                if ( m.IsActive )
                {
                    result += 1;
                }
            }
            return result;
        }
    }

    void ShowRandomMonster () {
        int r=Random.Range(0,HiddenMonsters.Count);
        Monster m=HiddenMonsters[r];
        ShowMonster ( m.gameObject );
    }

    private void InitMonsterList ()
    {
        monsters = GameObject.FindObjectsOfType<Monster> ().ToList ();
    }

    private void InitScore ()
    {
        score = GameObject.FindGameObjectWithTag ( "Score" ).GetComponent<Text> ();
        score.text = "";
    }

    void FixedUpdate()
    {
        TryCountDownToShowMonster ();
    }

    bool CountDownShowMonsterTimeUp => countDownShowMonsterSeconds <= 0;
    bool MonstersOnScreenAreFull => MonsterCountOnScreen >= MAX_MONSTERS_ON_SCREEN;

    private void TryCountDownToShowMonster ()
    {
        countDownShowMonsterSeconds -= Time.fixedDeltaTime;
        if (CountDownShowMonsterTimeUp)
        {
            ResetShowMonserSeconds ();

            if (!MonstersOnScreenAreFull)
            {
                ShowRandomMonster ();
            }
        }
    }
}