Скрипт таймера на C#

#c# #unity3d

#c# #unity-game-engine

Вопрос:

Мой таймер все еще запущен в обновлении, но он не остановится после столкновения. Я хочу запускать таймер при запуске игры и останавливать, когда мой игрок сталкивается с врагом.

Вот мои скрипты Timer.cs и player (корабль, cs):

Timer.cs:

 [SerializeField]
public Text scoreText;
float startTime;
public const string scorePrefix = "Timer: ";

//Timer initializer
public float elapsedSeconds = 0;

//Stop Timer initializer
bool gameTimerIsRunning = true;

// Start is called before the first frame update
void Start() {
    gameTimerIsRunning = true;
    startTime = 0;
    scoreText.text = scorePrefix   startTime.ToString();
}

// Update is called once per frame
void Update() {
    if (gameTimerIsRunning == true) {
        elapsedSeconds  = Time.deltaTime;
        int timer = (int) elapsedSeconds;
        scoreText.text = scorePrefix   timer.ToString();
        Debug.Log("YOO....");
    }
}

public void StopGameTimer() {
    gameTimerIsRunning = false;
    GetComponent < Text > ().text = "Sorry !!";

    Debug.Log("StopGameTimer Is called Succesfully.");
}
  

Ship.cs:

 HUD hud;

[SerializeField]
public GameObject prefabBullet;

Bullet script;

// thrust and rotation support
Rigidbody2D rb2D;
Vector2 thrustDirection = new Vector2(1, 0);
const float ThrustForce = 10;
const float RotateDegreesPerSecond = 180;

/// <summary>
/// Use this for initialization
/// </summary>
void Start() {
    hud = GetComponent < HUD > ();
    //  bullet = prefabBullet.GetComponent<Bullet>();
    // saved for efficiency
    rb2D = GetComponent < Rigidbody2D > ();
}

/// <summary>
/// Update is called once per frame
/// </summary>
void Update() {
    // check for rotation input
    float rotationInput = Input.GetAxis("Rotate");
    if (rotationInput != 0) {

        // calculate rotation amount and apply rotation
        float rotationAmount = RotateDegreesPerSecond * Time.deltaTime;
        if (rotationInput < 0) {
            rotationAmount *= -1;
        }
        transform.Rotate(Vector3.forward, rotationAmount);

        // change thrust direction to match ship rotation
        float zRotation = transform.eulerAngles.z * Mathf.Deg2Rad;
        thrustDirection.x = Mathf.Cos(zRotation);
        thrustDirection.y = Mathf.Sin(zRotation);
    }

    //Firing the Bullet
    if (Input.GetKeyDown(KeyCode.LeftControl)) {
        GameObject bullet = Instantiate(prefabBullet, transform.position, Quaternion.identity);
        bullet.GetComponent < Bullet > ().ApplyForce(thrustDirection);
    }
}

/// <summary>
/// FixedUpdate is called 50 times per second
/// </summary>
void FixedUpdate() {
    // thrust as appropriate
    if (Input.GetAxis("Thrust") != 0) {
        rb2D.AddForce(ThrustForce * thrustDirection, ForceMode2D.Force);
    }
}

/// <summary>
/// Destroys the ship on collision with an asteroid
/// </summary>
/// <param name="coll">collision info</param>
void OnCollisionEnter2D(Collision2D coll) {
    hud = gameObject.AddComponent < HUD > ();

    if (coll.gameObject.CompareTag("Asteroid")) {
        hud.StopGameTimer();
        Destroy(gameObject);
    }
}
  

Я прикрепил свой скрипт таймера к холсту Hud и скрипт отправки к объекту ship game.

Комментарии:

1. запускается ли OnCollisionEnter2D при возникновении столкновения? как насчет условия if в нем?

2. Это условие if предполагает, что если произойдет столкновение черно-белого корабля и врага, оно уничтожит и вызовет функцию StopGameTimer().

Ответ №1:

Сначала вы должны получить ссылку на игровой объект HUD canvas:

Изменения в Ship.cs:

 void OnCollisionEnter2D(Collision2D coll) {
    hud = GameObject.Find("HudCanvas").GetComponent < HUD > ();
  

Предполагается, что имя игрового объекта hud canvas равно «HudCanvas»

Ответ №2:

 public float saveTime = 0;
void Update()
{
    if (gameTimerIsRunning == true)
    {
        if(saveTime == 0) //don't have savetime
        {
            elapsedSeconds  = Time.deltaTime;
            int timer = (int)elapsedSeconds;
            scoreText.text = scorePrefix   timer.ToString();
            Debug.Log("YOO....");
        }
        else //have savetime like pause system
        {
            elapsedSeconds = saveTime;
            saveTime = 0;
            int timer = (int)elapsedSeconds;
            scoreText.text = scorePrefix   timer.ToString();
        }
    }
    else if(gameTimerIsRunning == false) //don't Timer running
    {
        saveTime = elapsedSeconds;    //current time save
        int timer = (int)elapsedSeconds;
        scoreText.text = scorePrefix   timer.ToString();
    }
}
  

Комментарии:

1. Это выдает мне ошибку исключения NullReference. А также как бы я вызвал функцию StopGameTimer () из скрипта отправки при возникновении коллизии?

Ответ №3:

hud = gameObject.AddComponent < HUD > ();

Зачем написана эта строка?

Пожалуйста, удалите его, потому что у вас уже есть hud в методе Start:

 void Start() {
    hud = GetComponent < HUD > ();
}
  

Комментарии:

1. Я не думаю, что, делая это, я получаю так много исключений NullReference. Кстати, спасибо, что уделили мне свое время.

Ответ №4:

Итак, окончательный ответ таков: HUD.cs:

 [SerializeField]
public Text scoreText;
//float startTime;
public const string scorePrefix = "Timer: ";

//Timer initializer
float  elapsedSeconds=0;

//Stop Timer initializer
bool gameTimerIsRunning;

// Start is called before the first frame update
void Start()
{


    gameTimerIsRunning = true;

    scoreText.text = scorePrefix   "0";
}

// Update is called once per frame
void Update()
{
    if (gameTimerIsRunning)
    {
        elapsedSeconds  = Time.deltaTime;
        int timer = (int)elapsedSeconds;
        scoreText.text = scorePrefix   timer.ToString();
        Debug.Log("YOO....");
    }
    else

    {  }

}

public void StopGameTimer()
{
      gameTimerIsRunning = false;
        elapsedSeconds = 0;
    Debug.Log("Timer Stops.");
 }
  

Ship.cs

  [SerializeField]
public HUD hud;

[SerializeField]
public GameObject prefabBullet;

Bullet script;

// thrust and rotation support
Rigidbody2D rb2D;
Vector2 thrustDirection = new Vector2(1, 0);
const float ThrustForce = 10;
const float RotateDegreesPerSecond = 180;

/// <summary>
/// Use this for initialization
/// </summary>
void Start()
{
      hud = GetComponent<HUD>();
  //  bullet = prefabBullet.GetComponent<Bullet>();
    // saved for efficiency
    rb2D = GetComponent<Rigidbody2D>();
}

/// <summary>
/// Update is called once per frame
/// </summary>
void Update()
{
    // check for rotation input
    float rotationInput = Input.GetAxis("Rotate");
    if (rotationInput != 0)
    {

        // calculate rotation amount and apply rotation
        float rotationAmount = RotateDegreesPerSecond * Time.deltaTime;
        if (rotationInput < 0)
        {
            rotationAmount *= -1;
        }
        transform.Rotate(Vector3.forward, rotationAmount);

        // change thrust direction to match ship rotation
        float zRotation = transform.eulerAngles.z * Mathf.Deg2Rad;
        thrustDirection.x = Mathf.Cos(zRotation);
        thrustDirection.y = Mathf.Sin(zRotation);
    }

    //Firing the Bullet

    if (Input.GetKeyDown(KeyCode.LeftControl))

    {

       GameObject bullet =  Instantiate(prefabBullet, transform.position, Quaternion.identity) ;
        bullet.GetComponent<Bullet>().ApplyForce(thrustDirection);

        AudioManager.Play(AudioClipName.PlayerShot);
    }




}

/// <summary>
/// FixedUpdate is called 50 times per second
/// </summary>
void FixedUpdate()
{
    // thrust as appropriate
    if (Input.GetAxis("Thrust") != 0)
    {
        rb2D.AddForce(ThrustForce * thrustDirection,ForceMode2D.Force);
    }
}

/// <summary>
/// Destroys the ship on collision with an asteroid
/// </summary>
/// <param name="coll">collision info</param>
void OnCollisionEnter2D(Collision2D coll)
{
    hud = GameObject.Find("HUD").GetComponent<HUD>();

    AudioManager.Play(AudioClipName.PlayerDeath);

    if (coll.gameObject.CompareTag("Asteroid"))
    {
        hud.StopGameTimer();
        gameObject.SetActive(false);
       // Destroy(gameObject);

    }
}
  

P.S: Это окончательное решение для этой проблемы.