Search Unity

Problems with spawning prefabs due to framerate

Discussion in 'Scripting' started by UDN_49c94242-0e41-4453-bd8b-fa2de5d6450e, Jun 20, 2019.

  1. UDN_49c94242-0e41-4453-bd8b-fa2de5d6450e

    UDN_49c94242-0e41-4453-bd8b-fa2de5d6450e

    Joined:
    Jun 20, 2019
    Posts:
    3
    Hi all! So I have just finished making my endless (runner? ball-roller?) game where the platforms spawning are supposed to be flush to each other, creating an illusion of an endless platform. The problem is that by switching monitors, (of which i have two) I have noticed that the platfroms spawn at different times, allowing for gaps inbetween the prefabs, which I suspect is due to framerate (one monitor is 120Hz and the other is 60Hz). My question is, how do I make the platform spawning independent from the framerate? I tried using deltatime but then the platforms start spawing inside each other.

    Just to let y'all know, I have EXTREMELY limited knowledge of C# and have done most of the coding by frankensteining different tutorials together.
     
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    We'd have to see the code you're using to decide to spawn a new prefab. If you're getting gaps between objects, it sounds like you're spawning a new platform based on a certain number of frames passing? That kind of approach won't work well, given that if things slow down for any reason (the computer gets busy), it will break your game.

    Also, just consider gameplay possibilities, like something intentionally stopping the player for a second (they slip on a banana peel...), where you'd want to stop spawning prefabs until the player starts moving again.

    A better, general approach, to spawning platforms is to make it time independent, and just spawn a new platform at a predetermined position once the player has gone a certain distance. Maybe every 10 units the player moves along the Z axis, you spawn another prefab. There's no need to keep track of time, in that case, just distance traveled.

    Anyway, show some code.
     
  3. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    I can't say what's your problem is without looking at code. But probably you should define a connection point on your platforms and put next platform exactly to that point when it's created.
     
  4. UDN_49c94242-0e41-4453-bd8b-fa2de5d6450e

    UDN_49c94242-0e41-4453-bd8b-fa2de5d6450e

    Joined:
    Jun 20, 2019
    Posts:
    3
    Here is the code. Sorry for not including it beforehand:

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

    public class Spawner : MonoBehaviour
    {
    public GameObject prefab1, prefab2, prefab3, prefab4, prefab5, prefab6, prefab7;

    public float spawnRate = 2f;

    float nextSpawn = 0f;

    int whatToSpawn;

    void Start()
    {


    void FixedUpdate()
    {
    if (Time.time > nextSpawn) {
    whatToSpawn = Random.Range (1,8);
    Debug.Log(whatToSpawn);
    switch (whatToSpawn) {
    case 1:
    Instantiate (prefab1, transform.position, Quaternion.identity);
    break;
    case 2:
    Instantiate (prefab2, transform.position, Quaternion.identity);
    break;
    case 3:
    Instantiate (prefab3, transform.position, Quaternion.identity);
    break;
    case 4:
    Instantiate (prefab4, transform.position, Quaternion.identity);
    break;
    case 5:
    Instantiate (prefab5, transform.position, Quaternion.identity);
    break;
    case 6:
    Instantiate (prefab6, transform.position, Quaternion.identity);
    break;
    case 7:
    Instantiate (prefab7, transform.position, Quaternion.identity);
    break;
    }
    nextSpawn = Time.fixedDeltaTime + spawnRate;
    }
    }
    }
     
  5. Zalosath

    Zalosath

    Joined:
    Sep 13, 2014
    Posts:
    688
    Seems like you're indefinitely increasing a float, whilst generating a random number, whilst using a switch statement to pick a prefab.

    I would go about it a different way,

    Your
    Code (CSharp):
    1. public GameObject prefab1, prefab2...
    Can be condensed into
    Code (CSharp):
    1. public GameObject[] prefabs
    And your switch statement can be totally removed and changed to
    Code (CSharp):
    1. Instantiate(prefabs[randomNumber], transform.position, Quaternion.identity)
    This completely removes the selection process, and also the unnecessary initialisation of 6 un-needed variables.

    Put this inside of either a Repeating Coroutine, with a two second delay

    Or:

    create a variable named currentTime and a variable named timeToReach, or something like that, in FixedUpdate increase currentTime by Time.deltaTime, check if currentTime >= timeToReach, if it is, set currentTime to 0 and Instantiate an object.
     
  6. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    First, this https://forum.unity.com/threads/using-code-tags-properly.143875/
    Second, the problem is here because you're using transform.position for spawning new objects. I guess it is moving over frames so you can't guarantee the objects will overlap. Instead of using transform.position try to calculate where you want to place new platform based on last placed platform position and bounds.
     
  7. UDN_49c94242-0e41-4453-bd8b-fa2de5d6450e

    UDN_49c94242-0e41-4453-bd8b-fa2de5d6450e

    Joined:
    Jun 20, 2019
    Posts:
    3
    Ok, so I have found a solution, even though it might be less than ideal. Instead of using Update() and Time.time I have switched to FixedUpdate() and Time.fixedTime seemed to fix the problem and no there isnt any difference between my two monitors. I will test further though and I will try to implement some of the things you guys have posted here :)
     
  8. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    This will work until first physics lag.