【问题标题】:Time.Timescale is not pausing the gameTime.Timescale 没有暂停游戏
【发布时间】:2020-07-23 19:19:40
【问题描述】:

这是我正在制作的球类游戏的脚本。 游戏应该在点击Time.timescale 后暂停,但它没有。

我需要知道我做错了什么以及我需要在这里改变什么。

我是 Unity 和 C# 的初学者,所以我可能把一切都搞砸了。

如果有任何其他方法可以暂停游戏而不是使用Time.timescale,我也想知道。

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

public class PauseScript : MonoBehaviour
{
    public bool paused = false;
    void Start()
    {
        paused = false;
        Time.timeScale = 1;
    }

    // Update is called once per frame
    public void Pause()
    {
        if (Input.GetKeyDown("p") && paused == false)
        {
            Time.timeScale = 0;
            paused = true;
        }
        if (Input.GetKeyDown("p") && paused == true)
        {
            Time.timeScale = 1;
            paused = false;
        }
    }
}

Ball.cs

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

public class Ball : MonoBehaviour
{  
    
    //configuration parameter
    [SerializeField] Paddle paddleInitial;
    [SerializeField] float horizontalPush = 2f;
    [SerializeField] float verticalPush = 15f;
    [SerializeField] AudioClip[] ballSounds; 

    //state parameter
    Vector2 paddleToBallVector;
    bool mouseButtonClicked = false;

    //Cached COmponent References
    AudioSource myAudioSource;

    // Start is called before the first frame update
    void Start()
    {
        paddleToBallVector = transform.position - paddleInitial.transform.position;
        myAudioSource = GetComponent<AudioSource>();
    }

    // Update is called once per frame
    void Update()
    {
        if (mouseButtonClicked == false)
        {
            stickBallToPaddle();
            launchOnMouseClick();
        }
        if (Input.GetMouseButtonDown(1))
        {
            GetComponent<Rigidbody2D>().velocity = new Vector2(horizontalPush,verticalPush);
        }
    }

    private void launchOnMouseClick()
    {
        if (Input.GetMouseButtonDown(0))
        {
            mouseButtonClicked = true;
            GetComponent<Rigidbody2D>().velocity = new Vector2(horizontalPush, verticalPush);
        }
    }

    private void stickBallToPaddle()
    {
        Vector2 paddlePosition = new Vector2(paddleInitial.transform.position.x, paddleInitial.transform.position.y);
        transform.position = paddlePosition + paddleToBallVector;
    }

    //audio settings
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (mouseButtonClicked)
        {
            AudioClip clip = ballSounds[UnityEngine.Random.Range(0, ballSounds.Length)];
           myAudioSource.PlayOneShot(clip);
        }
    }
}

【问题讨论】:

  • 您在该代码中没有任何时候更改时间刻度,所以...我们如何告诉您为什么没有给您带来麻烦的代码它无法工作?
  • 问题需要包含minimal reproducible example

标签: c# unity3d game-development


【解决方案1】:

有几个潜在的问题。

  1. 你的函数应该被称为Update,否则它不会每帧运行一次
  2. Input.GetKeyDown 返回是否开始按下某个键,但这会持续存在于当前帧上(它只会在下一次 Update 调用之前重置,因此每次在同一个 Update 函数块中调用它时它都会返回 true)

当您按下 P 时,您检查键是否按下然后设置暂停标志/时间刻度,但如果检查执行相反操作的更新方法,则执行另一个操作。

    // Update is called once per frame
    public void Pause()
    {
        // The p key is down and the game isn't paused, set timescale to 0 and paused to true...
        if (Input.GetKeyDown("p") && paused == false)
        {
            Time.timeScale = 0;
            paused = true;
        }

        // The p key is still down since we are on the same frame and paused flag is set so here we set timescale to 1 and paused to false...
        if (Input.GetKeyDown("p") && paused == true)
        {
            Time.timeScale = 1;
            paused = false;
        }
    }

您可能希望确保每次更新仅运行这些条件之一,并确保调用该函数 Update 否则它不会每帧运行一次

    // Update is called once per frame
    public void Update()
    {
        if (Input.GetKeyDown("p") && paused == false)
        {
            Time.timeScale = 0;
            paused = true;
        }
        // Use else to make sure this block only gets executed if the above doesn't
        else if (Input.GetKeyDown("p") && paused == true)
        {
            Time.timeScale = 1;
            paused = false;
        }
    }

可以这么说,给猫剥皮的方法有很多种;替代代码可能如下所示:

public void Update()
{
    if(Input.GetKeyDown("p"))
    {
        // Toggle paused
        paused != paused;
        // Use ternary operator to save lines because making code harder to read is fun
        Time.timeScale = paused ? 0 : 1;
    }
}

-- 编辑:

还要确保将运动等的任何矢量乘以每帧deltaTime - 否则您的模拟将继续。

您可能还需要为其他方面(例如动画等)显式处理暂停 - 这取决于它们是如何实现的,但只要他们逐帧考虑增量,他们就会在 timeScale 设置为 0 时做出反应预计。

【讨论】:

  • 我按照你的建议做了,但没有奏效。脚本运行良好,但游戏不会暂停。 link。 @Charleh
  • 您是否考虑过您可能没有使用使用增量时间移动对象的方法,因此时间尺度不会影响您的模拟?
  • 您需要确保在物理模拟过程中将向量(例如速度)乘以增量时间,您还需要明确检查游戏是否在某些地方暂停以防止某些游戏功能从跑步开始(例如,如果游戏暂停,您不想让用户得分或移动,听起来您正在制作一个突围风格的游戏,并且桨随鼠标移动)
  • yaa 我想这就是问题所在,因为我没有使用增量时间来定义运动,而是使用了一些固定值。@Charleh
猜你喜欢
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-09
  • 2015-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多