Sphere not moving in Unity - c#

I'm stuck with this one for quite some time now. I am trying to create spheres via script and update their position based on the position of points. Their position is updating on the Debug.Log() but they are not moving in Game View.
Here is my code:
void createSpheres(int objCount, float xPointsPos, float yPointsPos){
var sphereCreator = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphereCreator.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
sphereCreator.transform.position = new Vector3(xPointsPos, yPointsPos, 0);
sphereCreator.AddComponent<Rigidbody>();
sphereCreator.GetComponent<Rigidbody>().useGravity = false;
sphereCreator.AddComponent<SphereCollider>();
//ADD THE SPHERES TO THE SPHERELIST
sphereList = new List<Sphere>();
for(int loop = 0; loop < objCount-1; loop++){
Sphere temp = new Sphere();
temp.sphereName = "sphere"+sphereNameCount;
temp.sphereObj = sphereCreator;
temp.sphereXPos = xPointsPos;
temp.sphereYPos = yPointsPos;
sphereList.Add(temp);
}
sphereNameCount++;
}
void UpdateSpheres()
{
for(int i = 0; i < sphereList.Count - 1; i++){
sphereList[i].sphereXPos = points[i].position.x;
sphereList[i].sphereYPos = points[i].position.y;
Debug.Log($"{sphereList[i].sphereXPos}" + " -- " + $"{points[i].position.x}");
}
}
public class Sphere{
public string sphereName;
public float sphereXPos;
public float sphereYPos;
public GameObject sphereObj;
}
The createSpheres() method is called inside a loop containing how many points are spawned to match it.
I also tried checking if the ArrayList is empty or not using Debug.Log() and it returned all the Sphere gameObjects that I added.
Any help or hint will be highly appreciated. Thanks!

You do not create a number of spheres according to the code. You create just a single sphere and assign it to all your Sphere instances. To create and move your spheres:
create GameObject object for every object instead of assigning the same object for each Sphere class instance
use .transform.position of the created object, assigned to Sphere class instance to move the corresponding GameObject instance

Related

Unity: Get the position of the last cloned instantiated object

I'm trying to create an infinite ground for Android using Unity. Trying to use object pooling to achieve the ground repeating but is proving a bit tricky.
I can get my ground to Instantiate and create the clones along x axis.
What I am trying to achieve is to get the position of the last cloned object and set that as the new position of and create new object in the new position and instantiate again.
Do I need to work with the transform parent?
Am I going the right way about this?
Code below.
public class InfiniteGround : MonoBehaviour
{
public Transform ground1Obj;
private int count;
private Vector3 lastPosition;
void Start()
{
count = 0;
for (int i = 0; i < 10; i++)
{
Instantiate(ground1Obj, new Vector3(i * 100f, 0, 0), Quaternion.identity);
count++;
if (count == 10)
{
lastPosition = ground1Obj.position;
Debug.Log("Last Position: " + lastPosition);
}
}
}
}
For the Instantiating it should work, but not the way you intend to. If you want to have infinite ground you should add ground depending on the player position
If the player moves forward instantiate new ground before him and
destroy the old ground behind him.
If the player moves backward instantiate new ground behind him and
destroy the old ground before him
If you wanted to change your code. I would:
Change the functionname for example (InstantiateFloor), because you want to call it more than once at the start
Call the function depending on the player position (as described above)
Just instantiate 1 big floor piece (instead of 10 smaller ones) and take the position of that
Why not using the Gameobject returned by the Instantiation?
GameObject newObject = Instantiate(ground1Obj, new Vector3(i * 100f, 0, 0), Quaternion.identity);
count++;
if (count == 10)
{
lastPosition = newObject .position;
Debug.Log("Last Position: " + lastPosition);
}

Compare size of current object pulled from pool, with last object pulled from pool

This is a follow-up for a different question I posted earlier. The solution found there led to a new problem I will describe here.
Having objects spawn, with random size within set range, with equal distance between them regardless of framerate
I am trying to create the effect of several buildings in different sizes moving from left to right at a constant speed regardless of framerate. I want the spacing between the buildings to be the same no matter the size, and each building's size is randomized within a range.
I solved this by comparing the size of the last building with the current and dividing it by their speed, which worked initially, but was very heavy on performance due to Instantiating prefabs constantly. This is the original code from my ScrollingCity script.
if(Time.time > nextBuilding)
{
spawningRatio = ((randomSize / 2) + (buildingPrefab.transform.localScale.x / 2) + distanceBetween) / (speed);
nextBuilding = Time.time + spawningRatio;
buildingPrefab.transform.localScale = new Vector3(randomSize, randomSize, randomSize);
Instantiate(buildingPrefab, spawnPoint.transform.position, Quaternion.identity);
randomSize = Random.Range(ranMin, ranMax);
}
In the linked thread I was advised to use pooling for my objects, to reduce the load, and I was able to make it work with the use of some tutorials. However, I now don't know how to compare the sizes of the last to objects pulled from the pool, to ensure that they all have the same spacing between them.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPooler : MonoBehaviour
{
[System.Serializable]
public class Pool
{
public string tag;
public GameObject prefab;
public int size;
}
#region Singleton
public static ObjectPooler Instance;
private void Awake()
{
Instance = this;
}
#endregion
public List<Pool> pools;
public Dictionary<string, Queue<GameObject>> poolDictionary;
private void Start()
{
poolDictionary = new Dictionary<string, Queue<GameObject>>();
foreach (Pool pool in pools)
{
Queue<GameObject> objectPool = new Queue<GameObject>();
for (int i = 0; i < pool.size; i++)
{
GameObject obj = Instantiate(pool.prefab);
obj.SetActive(false);
objectPool.Enqueue(obj);
}
poolDictionary.Add(pool.tag, objectPool);
}
}
public GameObject SpawnFromPool (string tag, Vector3 position, Quaternion rotation)
{
if (!poolDictionary.ContainsKey(tag))
{
Debug.LogWarning("Tag doesn't exist");
return null;
}
GameObject objectToSpawn = poolDictionary[tag].Dequeue();
objectToSpawn.SetActive(true);
objectToSpawn.transform.position = position;
objectToSpawn.transform.rotation = rotation;
poolDictionary[tag].Enqueue(objectToSpawn);
return objectToSpawn;
}
}
This is the script for my Object Pooler, learned from a tutorial.
I then call the function in my ScrollingCity Script, where I try to get the transform value of the latest object created so I can compare them with the current object, but I can only get the transform of the first object pulled, until it reaches the end of the Queue.
if(Time.time > nextBuilding)
{
nextBuilding = Time.time + spawningRatio;
objectPooler.SpawnFromPool("Build", transform.position, Quaternion.identity);
lastBuilding = objectPooler.SpawnFromPool("Build", transform.position, Quaternion.identity);
Debug.Log(lastBuilding.transform.localScale);
}
And it only returns the transform of the first object in the log:
So my Question is how can I access the scale of the last object in the Queue, and compare it with the current to control the frequency with which they are created, and effectively keep the distance between each object the same regardless of scale?

Unity 2D (C#) - More objects in same position

I have some 2D objects in same transform position. How can I find out how many objects are in one same position and which objects are they?
EDIT:
Here is my code:
I want save all object on transform.position - new Vector3(speed, 0, 0)
GameObject go = GetObjectAt(transform.position - new Vector3(speed, 0, 0));
public GameObject GetObjectAt(Vector3 position)
{
string pos = position.x + "_" + position.y + "_";
if (obstacleDictionary.ContainsKey(pos + "BigRed"))
{
return obstacleDictionary[pos + "BigRed"];
}
else if (obstacleDictionary.ContainsKey(pos + "SmallRed"))
{
return obstacleDictionary[pos + "SmallRed"];
}
else return null;
}
I think you can use List<SomeModel> for keep object and postion.
Add your object to list when the object created
then find same postion object used by LINQ
CodeSample
Public class ObjectListener
{
public string ObjectName {get; set;}
public Vector2 ObjectVector {get; set;}
}
public class CreateObject : MonoBehaviour
{
List<ObjectListener> _gameObjectListener = new List<ObjectListener>();
void Update()
{
private GameObject _gameObject ; // you must create _gameObject
// and set tranform.Postion maybe you
// can use a method returned gameObject
Instantiate(_gameObject, _gameObject.transform.position, Quaternion.identity);
_gameObjectListener.Add(new ObjectListener
{
ObjectName = _gameObject.Name,
ObjectVector = _gameObject.transform.postion
});
}
}
I'm not sure that's the right way, but you can keep all created object name and postion in list object. So you can find how many object are in same object or not
Assuming all of the objects have a Collider2D on them, you just need to call Physics2D.BoxCastAll( and it will return a array of RaycastHit2D which you can call hitItems[i].collider.gameObject on to get the object.
RaycastHit2D[] hitItems = Physics2D.BoxCastAll(origin, size, angle, direction);
for(int i = 0; i < hitItems.Length; i++)
{
GameObject hitObject = hitItems[i].collider.gameObject;
//Do something with the hit object.
}
One method is mentioned in the below article
http://answers.unity3d.com/questions/638319/getting-a-list-of-colliders-inside-a-trigger.html
The basics of the above article
Make sure everything has a collider
Make sure at least one thing has a trigger
User "TriggerList" to get all items with a collider within the trigger.
This article is a second option
http://answers.unity3d.com/questions/532746/finding-gameobjects-within-a-radius.html
The basics
Get a position/transform
Get all colliders within a sphere
iterate through the list.

Randomise Prefab Position Unity

im creating a game where the player needs to find and pick up a certain number of keys. Currently ive got a spawn container that generates 5 keys in given locations. I want to be able to generate the 5 keys in 5 random locations. So lets say i have 10 spawn points, i want it to randomly pick any of the 5 points and place a key there.
I have the following code so far
using UnityEngine;
using System.Collections;
public class KeySpawnManager : MonoBehaviour
{
// array to store spawnpoints
private Transform[] spawnTransformList;
// integer to store number of spawnpoints
private int numberOfSpawnpoints;
// the prefab we're going to spawn
public GameObject prefab;
private int collectedCount = 0;
private int currentTime = 0;
// Singleton Instance
public static KeySpawnManager Instance { get; private set; }
// AWAKE Function - fired on initialization
void Awake ()
{
if (Instance == null) Instance = this;
else Destroy( gameObject );
numberOfSpawnpoints = transform.childCount;
spawnTransformList = new Transform[numberOfSpawnpoints];
for (int i = 0; i < numberOfSpawnpoints; i++)
{
// add the spawn to the array
spawnTransformList[i] = transform.GetChild(i); // return transform Component of each child object
}
for (int j = 0; j < numberOfSpawnpoints; j++)
{
GameObject newPrefab = (GameObject) Instantiate(prefab, spawnTransformList[j].position, spawnTransformList[j].rotation);
newPrefab.transform.parent = transform.position;
}
}
}
Any ideas on how to do this?
thanks
create your ten empty gameobject in a list then shuffle the list using Fisher-Yates shuffle then use the first five elements of the list and spawn keys in them
Here is the implementation of a Fisher-Yates shuffle in c#
Create a random method using random class that you can pass in the total number of spawn points. Have it return then index for your spawn location.

adding GameObject at runtime

This may seem like a stupid question but I'm stuck with it. I have GameObjects in a list (List<GameObject>) and I want to add them on the scene runtime, prefarbly on predefined places (like placeholders or something). What would be a good way to do it? I've been searching the net but can't really find anything that would solve this. This is my code so far:
public static List<GameObject> imglist = new List<GameObject>();
private Vector3 newposition;
public static GameObject firstGO;
public GameObject frame1;//added line
void Start (){
newposition = transform.position;
firstGO = GameObject.Find ("pic1");
frame1 = GameObject.Find ("Placeholder1");//added line
//this happens when a button is pressed
imglist.Add(firstGO);
foreach(GameObject gos in imglist ){
if(gos != null){
print("List: " + gos.name);
try{
//Vector3 temp = new Vector3 (0f, 0f, -5f);
Vector3 temp = new Vector3( frame1.transform.position.x, frame1.transform.position.y, -1f);//added line
newposition = temp;
gos.transform.position += newposition;
print ("position: " + gos.transform.position);
}catch(System.NullReferenceException e){}
}
}
}
How can I place the pics (5) on the predefined spots?
//----------------
EDIT: Now I can place 1 image to a placeholder (transparent png). For some reason z-value goes all over the place so it needs to be forced to -1f but that's OK. I add the images to the list from other scenes and there can be 1-5 of them. Do I need to put the placeholders in another list or array? I'm a bit lost here.
If you've already created 5 new objects you can just do like they do here:
http://unity3d.com/learn/tutorials/modules/beginner/scripting/invoke under the InvokeScript
foreach(GameObject gos in imglist)
{
Instantiate(gos, new Vector3(0, 2, 0), Quaternion.identity);
}
I don't really understand what you're trying to do, but if I'm correct and you have a list of objects, and you know where you want to move them at runtime, just make two lists,
one containing the objects and
one containing transforms of empty game-objects in the scene placed at those predefined positions, and match them at runtime.
Populate both lists from the inspector.
public List<GameObject> imglist = new List<GameObject>();
public List<Transform> imgPositions = new List<Transform>();
void Start()
{
for(var i = 0 i < imglist.Count; ++i)
{
imglist[i].transform.position = imgPositions[i].position
}
}
The general best way is to create prefabs for your objects, passing them as a parameter and instantiate when needed (Start in your case). That's the common case, but maybe yours is slightly different.
This is an example of passing a prefabs array and to instantiate one object for each one in the array:
public GameObject prefabs[];
List<GameObject> objects = new List<GameObject>();
void Start() {
for(GameObject prefab in prefabs) {
GameObject go = Instantiate(prefab, Vector3.zero, Quaternion.identity) as GameObject; // Replace Vector3.zero by actual position
objects.Add(go); // Store objects to access them later: total enemies count, restart game, etc.
}
}
In case you need several instances for the same prefab (multiple enemies or items, for instance) just adapt code above.

Categories

Resources