- Home /
Problem with instantiate script
Hello!
I've got a problem with my spawn script which i just cant figure out. The point of the script is to spawn platforms aligned perfectly next to each other, without any gap between. The "SpawnDistance" variable sets the distance on how often the platforms should spawn, for example if its set to 20, then they will spawn every 20 position. And the platforms have to be 20 units wide to be aligned. The script is attached to an empty game object that get its position from the player which is constantly moving with use of:
transform.Translate(Vector2.right * speed * Time.deltaTime);
Now on to the problem.. On lower speeds this is working perfectly and they align like they should, but when you go a bit faster, then the errors start to appear. I Made a debug to get the positions on where they actually spawn at, as you can see on the image: imgur this sometimes happens. The extra number added to some of the positions. The frequency of this happening depends on the players speed, at some speeds this doesnt happen at all. And i just dont know why this happens.. It doesnt seem to be a rounding problem.
Any ideas?
var obj : GameObject[];
var player : Transform;
private var xmin = 0;
var SpawnDistance = 20;
function Spawn() {
var temp = Mathf.FloorToInt(player.position.x/SpawnDistance);
transform.position.x = Mathf.FloorToInt(transform.position.x);
if (temp > xmin){
for(var i = xmin; i < temp; i++){
Instantiate (obj [Random.Range (0, obj.Length)], transform.position, Quaternion.identity);
}
xmin = temp;
Debug.Log(transform.position.x);
}
}
can you stick the debug statement that generated the image output,in your code, pls? The issue, is that the output showed, a number(361) that was not an even multiple of 20, right?
The debug statement im using is this to get the spawners position (pasted it in the main code as well):
Debug.Log(transform.position.x);
Yeah, the problem is that it's supposed to instantiate every 20 position. Which means it should be 360, not 361. And i don't understand why that is happening.. with decimals it would be something like 361.00324. Which means its not rounding from 360 to 361.
At the player speed of 55 which im using on the image, the first error is ALWAYS at 361 and second 581. So its somehow related to the speed.
How exactly do you get that debug from that script?
How is Spawn called?
I think your rounding logic could be to blame here.
Sorry, the spawn is called with fixedUpdate() like this:
function FixedUpdate () {
Spawn();
}
Not sure if its the rounding causing it, seems to be something else. But i could be wrong. I really haven no clue right now :'/
Using your script all the spheres (is what I used) get thrown out at the same spot the player is standing in. Is this what you wanted?
Answer by Baste · Mar 04, 2015 at 03:24 PM
I'm not quite seeing why the spawner needs to move - why not just use the player's position to spawn the... whatever you're spawning?
Anyways, With a speed of 55, you're moving 55 units every second. With fixed timestep set to the default (.02), you're running FixedUpdate 50 times each second. This means that for every FixedUpdate, you move the player 1.1 units. Thus, every tenth fixedUpdate, the floor of the current position will be two more than the floor of the last position. That means that at some regular intervals, you'll skip over a "whole" 20.
To fix this, instead of spawning the thing you're spawning at the rounded player position when the player has moved spawndistance, spawn it at a point that's exactly 20 away from the last spawn point, in the direction of the player.
Thanks for your reply Baste. Things are bit more clear to me now.
When I made it, I thought it would be easier having a separate spawner to handle the spawning. So I easily can place it where I want it on the scene, and also so I could put it outside the camera range to not show when the actual spawning occurs. But I'm kinda new to this, so it might not be the best approach.
I see, so basically if i change the timestep to allow a higher fps it should work at this speed?
Also I'm not quite sure on how to make one platform spawn exactly 20 positions away from the previous one, without making it stuck in an infinite loop.. How can I make it know when to spawn the next one?
$$anonymous$$y email notifications went awol, so I didn't see your comment, sorry about that!
Changing the timestep does not allow a higher fps - the physics timestep and fps are separate, to allow for accurate physics calculation. Increasing the frequency of the timestep would work, but it'd also mean that your physics would run more often, which would have it take up more cpu cyles. The end result would actually be a lower fps.
If you want to spawn 20 away from the last one, just store the last position, get the vector from that to this one, and scale it appropriately. Something like:
var lastSpawnPos : float;
function Start() {
lastSpawnPos = transform.position;
}
function Spawn() {
var pos = transform.position;
var distance = Vector3.Distance(lastSpawnPos, pos);
if (distance > 20){
var toPos = pos - lastSpawnPos;
var spawnPos = lastSpawnPos + (toPos.normalized * 20);
Instantiate (obj [Random.Range (0, obj.Length)], spawnPos, Quaternion.identity);
lastSpawnPos = spawnPos;
}
}
I don't really write UnityScript much, so that might not be 100% correct (ie. it might not compile), but you should get the idea.
I see, thanks! This makes sense. although I haven't really used normalized before, does it always return 1?
You should really check out the docs for that kind of questions! It always returns a Vector of length one. So (10, 0, 0) would turn into (1, 0, 0), as would (0.3, 0, 0). On the other hand, (1, 0, 1) would turn into approximately (0.7, 0, 0.7).