【问题标题】:Unity 2D: How to start timer when player loses all of livesUnity 2D:当玩家失去所有生命时如何启动计时器
【发布时间】:2016-07-28 15:19:34
【问题描述】:

我想在我的玩家当前生命值达到 0 时开始我的计时器倒计时。到目前为止,我的计时器已连接到我的游戏面板,当玩家失去所有心(生命)时,该面板会向下滑动。当我玩应用程序(游戏)时,计时器会自动启动,并在我的游戏结束面板滑下时停止。这不是我想要的。我想做的是在玩家失去所有心(生命)并且游戏结束面板滑下时启动计时器。

这是我的玩家的健康脚本:

public int curHealth;
public int maxHealth = 3;
Vector3 startPosition;
public PlayerHealth playerhealthRef;
float counter;
public Animator anima; // drag the panel in here again
private UI_ManagerScripts UIM;
private PandaScript ps;
DateTime currentDate;
DateTime oldDate;


void Start ()
{
    curHealth = maxHealth;
    startPosition = transform.position;
    ps = GameObject.FindGameObjectWithTag("PandaScript").GetComponent <PandaScript> ();
    currentDate = System.DateTime.Now;      
}


void Update ()
{

    if (curHealth > maxHealth) {
        curHealth = maxHealth;
    }
    if (curHealth <= 0) {

        Die ();
    }
}

void Awake()
{
    UIM = GameObject.Find ("UIManager").GetComponent<UI_ManagerScripts> ();
}

void Die(){

    if (PlayerPrefs.HasKey ("Highscore")) {
        if (PlayerPrefs.GetInt ("Highscore") < ps.Score) {
            PlayerPrefs.SetInt ("Highscore", ps.Score);
        }
    } else 
    {
        PlayerPrefs.SetInt ("Highscore", ps.Score);
    }

    UIM.EnableBoolAnimator(anima);
    PlayerPrefs.SetInt("RemainingLives", curHealth);
    print("Remanining Lives: " + curHealth);
    PlayerPrefs.Save();
}

void OnApplicationQuit()
{
    PlayerPrefs.SetString("sysString", System.DateTime.Now.ToBinary().ToString());
    print("Saving this date to prefs: " + System.DateTime.Now);
}

void LoadSaveData()
{
    PlayerPrefs.GetInt ("RemainingLives",0);
    OnApplicationQuit ();
}

public void Damage(int dmg)
{
    curHealth -= dmg;
    Reset();
}

void Reset ()
{
    transform.position = startPosition;
    GotoMouse.target = startPosition;

}   
}

这是我的计时器脚本:

public Text timer;
int minutes = 1;
int seconds = 0;
float miliseconds = 0;

public int curHealth;
public int maxHealth = 3;

[Range(1, 59)]
public int defaultStartMinutes = 1;
public bool allowTimerRestart = false;
public bool useElapsedTime = true;

private int savedSeconds;
private bool resetTimer = false;

private DateTime centuryBegin = new DateTime(2001, 1, 1);

void Start ()
{
    curHealth = maxHealth;
}

void Awake ()
{
    minutes = defaultStartMinutes;
    if (PlayerPrefs.HasKey("TimeOnExit"))
    {
        miliseconds = PlayerPrefs.GetFloat("TimeOnExit");
        savedSeconds = (int)miliseconds;

        if (useElapsedTime && PlayerPrefs.HasKey("CurrentTime"))
        {
            int elapsedTicks = (int)(DateTime.Now.Ticks / 10000000);
            int ct = PlayerPrefs.GetInt("CurrentTime", elapsedTicks);
            PlayerPrefs.DeleteKey("CurrentTime");
            elapsedTicks -= ct;
            if (elapsedTicks < miliseconds)
            {
                miliseconds -= elapsedTicks;
            }
            else
            {
                miliseconds = 0;
            }
        }

        minutes = (int)miliseconds / 60;
        miliseconds -= (minutes * 60);

        seconds = (int)miliseconds;
        miliseconds -= seconds;

        PlayerPrefs.DeleteKey("TimeOnExit");

    }
    savedSeconds = 0;
}

public void Update()
{
    // count down in seconds
    miliseconds += Time.deltaTime;
    if (resetTimer)
    {
        ResetTime();
    }
    if (miliseconds >= 1.0f)
    {
        miliseconds -= 1.0f;
        if ((seconds > 0) || (minutes > 0))
        {
            seconds--;
            if (seconds < 0)
            {
                seconds = 59;
                minutes--;
            }
        }
        else
        {
            resetTimer = allowTimerRestart;
        }
    }

    if (seconds != savedSeconds)
    {
        //  Show current time
        timer.text = string.Format("{0}:{1:D2}", minutes, seconds);
        savedSeconds = seconds;
    }
}

void ResetTime()
{
    minutes = defaultStartMinutes;
    seconds = 0;
    savedSeconds = 0;
    miliseconds = 1.0f - Time.deltaTime;
    resetTimer = false;
}

private void OnApplicationQuit()
{
    int numSeconds = ((minutes * 60) + seconds);
    if (numSeconds > 0)
    {
        miliseconds += numSeconds;
        PlayerPrefs.SetFloat("TimeOnExit", miliseconds);

        if (useElapsedTime)
        {
            int elapsedTicks = (int)(DateTime.Now.Ticks / 10000000);
            PlayerPrefs.SetInt("CurrentTime", elapsedTicks);
        }
    }
}
}

【问题讨论】:

    标签: c# unity3d timer


    【解决方案1】:

    使用这个免费且非常有用的资产:https://www.assetstore.unity3d.com/en/#!/content/17276

    然后这样写:

    Observable.EveryUpdate()
        .Where(_ => currentHealth <= 0)
        .Subscribe(_ =>
        {
            //Do something...
            //Ex. Die();
        });
    

    .Subscribe 中的所有内容都会在 where 条件返回 true 时执行。在 Start() 而不是 Update() 中使用它。

    哦……如果你想要一些简单的计时器,例如:

    Observable.Timer(TimeSpan.FromMilliseconds(1000))
        .Subscribe(_ =>
        {
    
        });
    

    【讨论】:

      【解决方案2】:

      你在 Awake() 和 Update() 方法中有你的代码,但我没有看到任何告诉它等待玩家输掉的东西。当您希望计时器开始时,您可以设置标志或启用计时器脚本。

      您似乎也在将 PlayerPrefs 用于一些他们不一定需要的事情。除非您想在游戏退出并重新启动后跟踪剩余生命(这甚至没有多大意义),否则最好使用实例甚至类变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-31
        • 1970-01-01
        • 1970-01-01
        • 2017-02-20
        • 1970-01-01
        • 2023-03-22
        相关资源
        最近更新 更多