Instantiating problems

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 () {
width = 2f;
timer.Duration = 3;
timer.Run();

}
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 () {
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);
}
else
{
moveleft = new Vector2(-4 * Time.deltaTime, 0);
}
}
}


• 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? Sep 9, 2018 at 0:54
• 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. Sep 9, 2018 at 9:48

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;
}

• 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 Sep 9, 2018 at 12:53
• 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. Sep 9, 2018 at 14:07
• 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 ! Sep 9, 2018 at 14:32
• 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. Sep 9, 2018 at 14:44
• 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 Sep 9, 2018 at 15:04