- Home /
Why does my method "Vector2 SpawnPosition()" cause erratic behavior?
So I have an infinite spawner based on distance that spawns an object every time the previous object is 10 units away, but this only works for the X spacing and does not allow me to alter the Y spacing, therefore I have to alter it afterwards. It will all make sense once you read the code.
What happens is that when I use SpawnedObject.transform.position = transform.position;, the spacing is all fine and dandy, but when I use SpawnedObject.transform.position = SpawnPosition(-10, 10);, the position.x starts to get crazy and erratic. Meaning it will spawn like 2 units away, or sometimes 6 and so on.
Why is it doing this and how can I fix it?
Here is a picture of the problem http://imgur.com/YIXSK8X The logs are supposed to be separated by 1 square which is 10 units.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
// This script creates a list of type objects and allows you to use the objects in that list.
public class ObjectPool : MonoBehaviour
{
//when using this for other GameObjects, just change the class name to _w/e.
public static ObjectPool instance;
public GameObject _object;
public int poolAmount = 20;
public bool willGrow = true;
public float newSpeed;
public List<GameObject> pooledObjects;
public float distance;
public int ObjectSpacing;
private GameObject SpawnedObject;
private float randomXPosition;
private float randomYPosition;
void Awake()
{
instance = this;
}
// Use this for initialization
void Start()
{
pooledObjects = new List<GameObject>(); //create object pool
for (int i = 0; i < poolAmount; i++)
{
var obj = (GameObject)Instantiate(_object);
obj.SetActive(false);
pooledObjects.Add(obj);
}
SpawnNextObject(); //Spawn first object
}
void Update()
{
distance = Vector2.SqrMagnitude(SpawnedObject.transform.position - transform.position); //calculate distance between this object and objectpool start position
if (distance > (ObjectSpacing*ObjectSpacing))
{
SpawnNextObject();
}
}
public GameObject GetPooledObject()
{
for (int i = 0; i < pooledObjects.Count; i++)
{
if (!pooledObjects[i].activeInHierarchy)
{
return pooledObjects[i];
}
}
if (willGrow)
{
GameObject obj = (GameObject)Instantiate(_object);
pooledObjects.Add(obj);
return obj;
}
return null;
}
private void SpawnNextObject()
{
SpawnedObject = GetPooledObject();
//SpawnedObject.transform.position = transform.position;
SpawnedObject.transform.position = SpawnPosition(-10, 10);
SpawnedObject.SetActive(true);
}
Vector2 SpawnPosition(float minY, float maxY)
{
if (minY != maxY)
{
randomYPosition = Random.Range(minY, maxY);
}
else
{
randomYPosition = minY;
}
var obstaclePos = new Vector2(transform.position.x, randomYPosition);
return obstaclePos;
}
}
So okay, even without the SpawnPosition() method, but by placing
SpawnedObject.transform.position = new Vector2(transform.position.x, Random.Range(-10, 10));
into line 79, it still causes the same erratic behavior to occur.
i'm not by my devbox (so can't test it) but just a thought - is it definitely the x component that's acting up? you're setting position to a Vector2, so maybe the z is having some impact.
Okay I tried SpawnedObject.transform.position = new Vector3(transform.position.x, Random.Range(-10, 10), transform.position.z);
, but the same thing still occurs.
Even when z is 0, still occurs. =\
Why not put in a Debug.Log after that statement?
Debug.Log("Base position: " + transform.position.ToString() + ", result position: " + SpawnedObject.transform.position.ToString());
This should give you a much better idea of what's going on internally.
Speaking of which, are your Sprites rotated at all?
Your passing a Vector2 value to a Vector3, what do you think happens to the missing value? Vector3 = (x,y,z) and Vector2(x,y)
You want:
SpawnedObject.transform.position = new Vector3(transform.position.x, Random.Range(-10, 10), 0);
Z has to be set 0. Hope that helps.
Answer by Pyrian · Jul 17, 2014 at 11:19 PM
Hi Kamuzai, I can't seem to see the rest of the comments, have you made any progress?
@Pyrian, nothing else is there. Only 2 scripts are in the scene, $$anonymous$$ove.cs on each prefab and ObjectPool.cs is the only one that is in the scene before I hit play. I have no idea what to do now. Do you think there is another way to deal with this problem?
2 hours agokamuzai1226
Okay, I think I found the problem. What happens is that float distance is not going back to 0 every time SpawnNextObject() is called. I found this out by stepping through each frame in Unity that sometimes when the next object is spawned at x = 25, distance = 50. I am going to test to see if setting distance = 0 in SpawnNextObject() works.
Edit: This did not work.
I am out of ideas on what to do right now =.
Oh, you're using the X AND Y to calculate distance, but you only want the distance in X! Try replacing your sqr$$anonymous$$agnitude with a simple X-value difference:
distance = $$anonymous$$athf.Abs(SpawnedObject.transform.position.x - transform.position.x);
Of course, this isn't squared, so compare the result directly to ObjectSpacing, ins$$anonymous$$d of to ObjectSpacing*ObjectSpacing.
Yes it worked!
And I completely understand now about the Sqr$$anonymous$$agnitued comparing X AND Y, ins$$anonymous$$d of just X.
Thanks!