1
\$\begingroup\$

I'm beginner here, I'm trying to instantiate a single object every specific duration, either form the left of the screen or from the the right, at the same time I want this object to move to the other side of the screen

So the troubles I'm facing here are:

  1. sometimes 2 objects are being instantiated at the same time.
  2. the objects move in the direction that are defined in the first if statement (both objects on the left and the right move in one direction)

the part where I instantiate objects is in the script(smallFishes) that's attached to an empty gameobject is :

void Start () {
    timer = gameObject.AddComponent<Timer>();
    width = 2f;
    timer.Duration = 3;
    timer.Run();
    left = Resources.Load("Left") as GameObject;
    right = Resources.Load("Right") as GameObject;

}
void Update () {

    if (timer.Finished)
    {
        lr = Random.Range(1, 3);
        if (lr == 1)
        {
            var generetx = -8.8f - width / 2;
            Instantiate(left, new Vector2(generetx, Random.Range(-4.8f,4.8f)), Quaternion.identity);
        }
        else
        {
            var generetx = +8.8f + width / 2;
            Instantiate(right, new Vector2(generetx, Random.Range(-4.8f, 4.8f)), Quaternion.identity);
        }
        timer.Duration = 3;
        timer.Run();
    }

}
public int state
{
    get { return lr; }
}

the part where I make the object move from the script that's attached to the object prefab:

void Start () {
    small = gameObject.AddComponent<smallFishes>();
    rb2d = gameObject.GetComponent<Rigidbody2D>();
}

void Update()
{
    var fishes = GameObject.FindGameObjectsWithTag("small");
    if (fishes!=null)
    {
        if (small.state == 1)
        {
            moveright = new Vector2(4 * Time.deltaTime, 0);
            rb2d.AddForce(moveright, ForceMode2D.Impulse);
        }
        else
        {
            moveleft = new Vector2(-4 * Time.deltaTime, 0);
            rb2d.AddForce(moveleft, ForceMode2D.Impulse);
        }
    }
}

Thanks in advance.

\$\endgroup\$
  • \$\begingroup\$ Your code snippets are missing a few crucial details. What kind of object is timer? What is small.state and where does it come from? \$\endgroup\$ – Philipp Sep 9 '18 at 0:54
  • \$\begingroup\$ Oh right! the timer is a class provided by Dr.Tim, the professor at Coursera, I could test if it finished directly, change its duration and start it again(it's perfectly working). Small is a reference to the script I'm Instantiating in, and state refers to the variable lr. \$\endgroup\$ – Abeer Sep 9 '18 at 9:48
1
\$\begingroup\$

It's quite likely that if (timer.Finished) is satisfied twice. As Update is called once for each frame it seams that timer.Finished is true for two frames in a raw.

Possible solutions:
Falsifying timer.Finished as soon as it's true value is consumed can be a solution.
Or detecting change of timer.Finished from false to true and executing code on that event also can be a solution.

Or just detecting the change not only true value:

bool timerFinishedPrevious = false;
void Update () {

    var timerFinishedToTrue = timerFinishedPrevious == false && (timerFinishedPrevious != timer.Finished);

    if (timerFinishedToTrue)
    {
        lr = Random.Range(1, 3);
        if (lr == 1)
        {
            var generetx = -8.8f - width / 2;
            Instantiate(left, new Vector2(generetx, Random.Range(-4.8f,4.8f)), Quaternion.identity);
        }
        else
        {
            var generetx = +8.8f + width / 2;
            Instantiate(right, new Vector2(generetx, Random.Range(-4.8f, 4.8f)), Quaternion.identity);
        }
        timer.Duration = 3;
        timer.Run();
    }

    timerFinishedPrevious = timer.Finished;
}
\$\endgroup\$
  • \$\begingroup\$ I tried it and it didn't work ,even though you're right , when I'm printing the time in the console ,it's satisfied twice, I'm printing timerFinishedToTrue too, and sometimes it's Instantiating even when it's false ,that's when I got two objects \$\endgroup\$ – Abeer Sep 9 '18 at 12:53
  • \$\begingroup\$ Without seeing the project files I'd speculate that there might following reasons to look out for: 1) It might be so that smallFishes itself is created twice (so there is duplication); 2) It might be so that there is another point where instantiation happens (hidden state/side effects). It's interesting to see what would happen if console print was put inside smallFishes's Start method. \$\endgroup\$ – ivane Sep 9 '18 at 14:07
  • \$\begingroup\$ I'm sorry ,I didn't quite understand what you mean by printing was put inside smallFishes's Start method, I tried decreasing the duration and I can see more objects being Instantiated at the same time(like 6 instead of 2), and by increasing it I no longer see that ! \$\endgroup\$ – Abeer Sep 9 '18 at 14:32
  • \$\begingroup\$ I meant adding Start method to smallFishes with Debug.Log message in it so that if smallFishes itself is created (maybe cause of faulty setup) twice you could see that in Unity console. void Start () {Debug.Log("smallFishes created"); } Hope expressed myself clearer. Also it's interesting to see what happens after you call Timer.Run() particularly how does timer.Finished behave at that point. \$\endgroup\$ – ivane Sep 9 '18 at 14:44
  • \$\begingroup\$ Oh my mistake ! I was adding the smallFishes script instead of getting it, that's why there was a duplication, thank you for your help \$\endgroup\$ – Abeer Sep 9 '18 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.