简体   繁体   中英

Issue with invokerepeating function in unity

OK I have two scripts the first one is using invokerepeating to spawn obstacles at a given rate. The second script increases the speed of the obstacles every 20 seconds. My issue is that once the speed increases the gap between the obstacles increases which leads to very big gaps between each one. Any ideas on how to fix this?

using UnityEngine;
using System.Collections;

public class Generate : MonoBehaviour
{
public Vector3 startPosition;
public GameObject object1;
public GameObject object2;
public GameObject object3;
public int random;
int score = 0;
public int count = 0;
private float timeLeft = 20.0f;
private int num1 =3;
private int num2 =3;

// Use this for initialization
void Start()
{
    startPosition = new Vector3(5, 0, 0);
    random = Random.Range(1, 4);
    InvokeRepeating("CreateObstacle", num1, num2);
}

// Update is called once per frame
/*void OnGUI () 
{
    GUI.color = Color.black;
    GUILayout.Label(" Score: " + score.ToString());
}*/

void Update(){

            fast ();

    }


void CreateObstacle()
{
    if (random == 1) {  
        GameObject go = Instantiate(object1, startPosition, Quaternion.identity) as GameObject; 
        go.transform.parent = GameObject.Find("4 - Obstacles").transform;
        random = Random.Range(1, 4);
        //Destroy(gameObject, 10);

    }
    else if (random == 2) { 
        GameObject go = Instantiate(object2, startPosition, Quaternion.identity) as GameObject; 
        go.transform.parent = GameObject.Find("4 - Obstacles").transform;
        random = Random.Range(1, 4);
        //Destroy(gameObject, 10);

    }
    else if(random == 3) {  
        GameObject go = Instantiate(object3, startPosition, Quaternion.identity) as GameObject; 
        go.transform.parent = GameObject.Find("4 - Obstacles").transform;
        random = Random.Range(1, 4);
        //Destroy(gameObject, 10);

    }

}

void fast(){

    //Timer
    timeLeft -= Time .deltaTime;

    if (timeLeft <= 0.0f) {
        count ++;
        timeLeft += 20.0f;
        num1 += 1;
        num2 += 1;
    }
    if (count == 1) {
        num1 += 1;
        num2 += 1;
        count ++;
    }
    else if (count == 3) {
        num1 += 1;
        num2 += 1;
        count ++;
    }

}





void OnGUI () {
            // Make a background box
            GUI.Box (new Rect (10, 10, 100, 90), "Number" + num1);

    }

}

second script

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

/// <summary>
/// Parallax scrolling script that should be assigned to a layer
/// </summary>
public class Scrolling : MonoBehaviour
{
public int count = 0;

private float timeLeft = 20.0f;
/// <summary>
/// Scrolling speed
/// </summary>
private Vector2 speed = new Vector2(2, 2);

/// <summary>
/// Moving direction
/// </summary>
public Vector2 direction = new Vector2(-1, 0);

/// <summary>
/// Movement should be applied to camera
/// </summary>
public bool isLinkedToCamera = false;

/// <summary>
/// 1 - Background is infinite
/// </summary>
public bool isLooping = false;

/// <summary>
/// 2 - List of children with a renderer.
/// </summary>
private List<Transform> backgroundPart;

// 3 - Get all the children
void Start()
{
    // For infinite background only
    if (isLooping)
    {
        // Get all the children of the layer with a renderer
        backgroundPart = new List<Transform>();

        for (int i = 0; i < transform.childCount; i++)
        {
            Transform child = transform.GetChild(i);

            // Add only the visible children
            if (child.renderer != null)
            {
                backgroundPart.Add(child);
            }
        }

        // Sort by position.
        // Note: Get the children from left to right.
        // We would need to add a few conditions to handle
        // all the possible scrolling directions.
        backgroundPart = backgroundPart.OrderBy(
            t => t.position.x
            ).ToList();
    }
}

void Update()
{
    //InvokeRepeating("fast", 1, 1);
    fast();

    // Movement
    Vector3 movement = new Vector3(
        speed.x * direction.x,
        speed.y * direction.y,
        0);

    movement *= Time.deltaTime;
    transform.Translate(movement);

    // Move the camera
    if (isLinkedToCamera)
    {
        Camera.main.transform.Translate(movement);
    }

    // 4 - Loop
    if (isLooping)
    {
        // Get the first object.
        // The list is ordered from left (x position) to right.
        Transform firstChild = backgroundPart.FirstOrDefault();

        if (firstChild != null)
        {
            // Check if the child is already (partly) before the camera.
            // We test the position first because the IsVisibleFrom
            // method is a bit heavier to execute.
            if (firstChild.position.x < Camera.main.transform.position.x)
            {
                // If the child is already on the left of the camera,
                // we test if it's completely outside and needs to be
                // recycled.
                if (firstChild.renderer.IsVisibleFrom(Camera.main) == false)
                {
                    // Get the last child position.
                    Transform lastChild = backgroundPart.LastOrDefault();
                    Vector3 lastPosition = lastChild.transform.position;
                    Vector3 lastSize = (lastChild.renderer.bounds.max - lastChild.renderer.bounds.min);

                    // Set the position of the recyled one to be AFTER
                    // the last child.
                    // Note: Only work for horizontal scrolling currently.
                    firstChild.position = new Vector3(lastPosition.x + lastSize.x, firstChild.position.y, firstChild.position.z);

                    // Set the recycled child to the last position
                    // of the backgroundPart list.
                    backgroundPart.Remove(firstChild);
                    backgroundPart.Add(firstChild);
                }
            }
        }
    }
}

void fast(){
            //Timer
            timeLeft -= Time .deltaTime;

            if (timeLeft <= 0.0f) {
                    count ++;
                    timeLeft += 20.0f;
                    speed.x += 0.4f;
                    speed.y += 0.4f;
            }

            if (count == 1) {
                    speed.x += 0.4f;
                    speed.y += 0.4f;
                    count ++;
            }
            else if (count == 3) {
                speed.x += 0.4f;
                speed.y += 0.4f;
                count ++;
            }
        /*  else if (count == 5) {
                speed.x ++;
                speed.y ++;
                count ++;
            }*/
            else if (count == 5) {
                speed.x += 5;
                speed.y += 5;
                count ++;
            }
}

void OnGUI () 
{
    GUI.color = Color.black;
    GUILayout.Label(" Speed: " + speed.ToString() + " Count: " + count.ToString ());
    GUILayout.Label(" Time: " + timeLeft.ToString());
}
}

You will also have to reduce the time with which the obstacles are generating (which you are trying in your fast() method but it will not work). You are updating your num1 and num2 values but these values are never assigned to the InvokeRepeating .

After updating your num1 and num2 also cancel the previous invoke and create a new invoke (I believe this time you will only need num2). Add these two lines at the end of your fast() method.

CancelInvoke("CreateObstacle");
InvokeRepeating("CreateObstacle", num2, num2);

First time value in InvokeRepeating defines how long to wait before calling the method for the first. Second time value defines the duration after which method calls will be repeated. (In short first value is used only for first time and second value is used for repeated method calls).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM