Getting error with creating objects in Unity - c#

I have an error in the script. At first, when the program starts, everything is fine, all InputFields have coordinates Y -200. But when I delete objects, and then re-create already the Y coordinate -800.
Where is the error?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SpawnText : MonoBehaviour
{
public int text_number = 20;
public GameObject TextPanel;
public GameObject toggle;
public GameObject ct;
private int k;
public GameObject[] obj;
public GameObject[] obj1;
public GameObject textTime;
public GameObject textPrice;
public GameObject InputFieldTime;
public GameObject InputFieldPrice;
private RectTransform rt;
private bool isSettings = false;
// Start is called before the first frame update
void Start()
{
CreateProgram();
}
// Update is called once per frame
//Клик на кнопку настроек
public void SettingsOnClick()
{
switch (isSettings)
{
case false:
isSettings = true;
textTime.SetActive(false);
textPrice.SetActive(false);
InputFieldTime.SetActive(false);
InputFieldPrice.SetActive(false);
for(int i = 0;i < text_number; i++)
{
Destroy(obj[i]);
Destroy(obj1[i]);
}
break;
case true:
isSettings = false;
textTime.SetActive(true);
textPrice.SetActive(true);
InputFieldTime.SetActive(true);
InputFieldPrice.SetActive(true);
CreateProgram();
break;
}
}
private void CreateProgram()
{
rt = ct.GetComponent<RectTransform>();
int height;
k = -60;
height = text_number * 72;
rt.sizeDelta = new Vector2(0, height);
for (int i = 0; i < text_number; i++)
{
obj[i] = Instantiate(TextPanel, new Vector2(0, 0), Quaternion.identity) as GameObject;
obj1[i] = Instantiate(toggle, new Vector2(0, 0), Quaternion.identity) as GameObject;
obj[i].transform.SetParent(ct.transform);
obj1[i].transform.SetParent(ct.transform);
obj[i].transform.localPosition = new Vector2(-200, k);
obj1[i].transform.localPosition = new Vector2(-420, k);
k -= 70;
obj[i].transform.localScale = new Vector2(1, 1);
obj1[i].transform.localScale = new Vector2(1, 1);
obj1[i].GetComponentInChildren<Text>().text = (i + 1).ToString();
}
}
}
When program starts
When delete and create objects

It is not Y but X actually
But note that the RectTransform is not the same as Transform.
What you see there in the Inspector is afaik the RectTransform.anchoredPosition not the transform.localPosition!
Not 100% sure but you should try and use
obj[i].GetComponent<RectTransform>().anchoredPosition = new Vector2(-200, k);
obj1[i].GetComponent<RectTransform>().anchoredPosition = new Vector2(-420, k);

Related

How can I put all the linerenderer test function under a gameobject parent?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DrawLines : MonoBehaviour
{
public LineRenderer lineRenderer;
public GameObject dotPrefab;
public string numbers;
private Vector3[] Positions;
// Start is called before the first frame update
void Start()
{
DrawNumber(0);
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown("0"))
{
DrawNumber(0);
numbers = "0";
}
}
void DrawNumber(int number)
{
if (number == 0)
{
Zero();
}
}
private void Zero()
{
Positions = new Vector3[7] { new Vector3(0, 0, 0),
new Vector3(1, 0, 0),
new Vector3(1, -1, 0),
new Vector3(1,-2,0),
new Vector3(0,-2,0),
new Vector3(0,-1,0),
new Vector3(0,0,0)};
lineRenderer.positionCount = 7;
lineRenderer.SetPositions(Positions);
for (int i = 0; i < Positions.Length; i++)
{
var dot = Instantiate(dotPrefab);
dot.transform.position = Positions[i];
}
}
}
Each time I press on the key 0 it's creating another Zero but the first problem is that the new zero is on the same positions of the first zero so I want to put all the Zeros under a parent so each time I press on 0 it will create a new Zero gameobject child and also the new child will be in a bit different position.
I think thats what you'r looking for.
private const float LETTER_WIDTH = 2f;
public LineRenderer lineRenderer;
public GameObject dotPrefab;
public string numbers;
public Transform WordAnchor;//parent object to set all the letters under
private int currentLetterIndex = 0;
private Vector3[] Positions;
// Start is called before the first frame update
void Start()
{
DrawNumber(0);
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown("0"))
{
DrawNumber(0);
numbers = "0";
}
}
void DrawNumber(int number)
{
if (number == 0)
{
Zero();
}
}
private void Zero()
{
Positions = new Vector3[7] { new Vector3(0, 0, 0),
new Vector3(1, 0, 0),
new Vector3(1, -1, 0),
new Vector3(1,-2,0),
new Vector3(0,-2,0),
new Vector3(0,-1,0),
new Vector3(0,0,0)};
//Create a gameobject to parent the dots under
GameObject letter = new GameObject(currentLetterIndex.ToString() );
letter.transform.parent = WordAnchor;//parent the letter under the word
letter.transform.localPosition = new Vector3(currentLetterIndex * LETTER_WIDTH, 0f, 0f);//move an offset base on the index
LineRenderer lineRendererInstance = letter.AddComponent<LineRenderer>();
lineRendererInstance.positionCount = 7;
lineRendererInstance.SetPositions(Positions);
lineRendererInstance.useWorldSpace = false;
for (int i = 0; i < Positions.Length; i++)
{
var dot = Instantiate(dotPrefab, letter.transform);//parent the dot under the letter.
dot.transform.localPosition = Positions[i];//set the relative position.
}
++currentLetterIndex;
}

Why does the script ignore the part after the first WaitForSeconds()?

I am trying to use WaitForSeconds() in my game to perform a scene.
I would love to here improvements and answers to the not working WaitForSeconds() (Its just ignores the part after I start to use WaitForSeconds())
The script:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FoodManager : MonoBehaviour
{
public bool[] isFull;
public GameObject[] slots;
public GameObject[] itemNames;
public GameObject[] itemImages;
public GameObject[] itemAmounts;
public GameObject foodObject;
public GameObject mainPanel;
public string[] foodNames;
public Sprite[] foodImages;
public Sprite[] foodHalfImages;
public GameObject foodPanel;
public GameObject bird;
private int _lastFood;
private int _hunger;
void Update()
{
_hunger = PlayerPrefs.GetInt("_hunger");
for(int i = 0; i < 6; i++)
{
if (isFull[i] == true)
slots[i].SetActive(true);
if (isFull[i] == false)
slots[i].SetActive(false);
}
}
private void addItem(int max, string itemName, GameObject itemImage, int addingAmount)
{
for (int j = 0; j < max; j++)
{
if (isFull[j] == true && itemNames[j].GetComponent<Text>().text == itemName)
{
itemAmounts[j].GetComponent<Text>().text = (int.Parse(itemAmounts[j].GetComponent<Text>().text) + addingAmount).ToString();
_lastFood = j;
return;
}
if (isFull[j] == false)
{
isFull[j] = true;
itemNames[j].GetComponent<Text>().text = itemName;
itemAmounts[j].GetComponent<Text>().text = addingAmount.ToString();
itemImages[j].GetComponent<Image>().sprite = foodImages[j];
_lastFood = j;
return;
}
if (isFull[j] == true && int.Parse(itemAmounts[j].GetComponent<Text>().text) == 0)
{
isFull[j] = false;
return;
}
}
}
public void foodButtonsBehavior(int a)
{
if(a >= 0 && a <= 5)
{
StartCoroutine(foodEat(slots[a]));
}
if (a == 7) //add food button
{
addItem(7, "Special Seeds", itemImages[1], 2);
}
}
public void closeFoodMenu()
{
foodPanel.SetActive(false);
}
public IEnumerator foodEat(GameObject slot)
{
mainPanel.SetActive(false);
foodPanel.SetActive(false); // Start Of Animation
itemAmounts[_lastFood].GetComponent<Text>().text = (int.Parse(itemAmounts[_lastFood].GetComponent<Text>().text) - 1).ToString();
moveFood(-1f, -1f); // Resetting Position for the food
foodObject.GetComponent<SpriteRenderer>().sprite = foodImages[_lastFood];
yield return new WaitForSeconds(1.1f);
print("Continuing");
foodObject.SetActive(true);
//bird.transform.Rotate(0, 0, 0);
bird.transform.position = new Vector2(0, -2.4f);
yield return new WaitForSeconds(0.7f);
moveFood(-1f, -2f);
bird.transform.Rotate(0, 0, 0);
bird.transform.position = new Vector2(0, -2.4f);
yield return new WaitForSeconds(0.7f);
moveFood(-1f, -2.7f);
bird.transform.Rotate(0, 0, 0);
bird.transform.position = new Vector2(0, -2.4f);
yield return new WaitForSeconds(0.4f);
foodObject.GetComponent<SpriteRenderer>().sprite = foodHalfImages[_lastFood];
bird.transform.Rotate(0, 0, 0);
bird.transform.position = new Vector2(0, -2.4f);
yield return new WaitForSeconds(0.4f);
foodObject.SetActive(false);
bird.transform.Rotate(0, 0, 0);
bird.transform.position = new Vector2(0, -2.4f);
yield return new WaitForSeconds(0.8f);
PlayerPrefs.SetInt("_hunger", _hunger + 24);
foodPanel.SetActive(true); // End Of Animation
mainPanel.SetActive(true);
}
private void moveFood(float x, float y)
{
foodObject.transform.position = new Vector2(x, y);
}
public void changeBird(GameObject x)
{
bird = x;
}
}
I would love to get some help here, as this is critical for my game and I couldn't find my answer online, so I would appreciate if someone decides to help with the problem. (Srry stackOverFlow wouldn't let me post without the last lines.)
Something important to note is that Coroutines only run when the the gameobject it is attached to remains active. From the Coroutine documentation:
A coroutines also stops when the GameObject
it is attached to is disabled with SetActive(false)
This behaviour is consistent with the error you are seeing, albeit a little confusing because the code appears to continue running after you disable the object. There's a very nuanced explanation, but for a simplified version: SetActive(false) waits until the end of the frame to stop MonoBehaviours running on the gameobject.

Can't move Instatiated Object from queue, changes transform of prefab instead

I'm trying to make a "Mania" style game(like guitar hero). But i can't seem to get the Movement of the "notes" to work, I keep the notes in a queue and I dequeue the last note and change it's position to the top again. But for some reason it doesen't work with my "goodcubes". only the normal ones
The problem seems to be that the instead of moving the "goodCube" to the correct position it instead changes the transform of the prefab.
All "notes" are referred to as "Cubes" in script
for (int i = 0; i < backlog; i++)//how many rows to spawn
{
goodCubes.Enqueue(Instantiate(goodcube));
for (int j = 0; j < columns - 1; j++)
{
badCubes.Enqueue(Instantiate(cube));
}
}
//I check the player input and if it corresponds with a note in the correct row
//I have tested so both true and false option gets called
if (i == position)
{
GameObject good = goodCubes.Dequeue();
good.transform.position = spawnPoint;
spawnPoint += new Vector2(1 * rowOffset, 0);
goodCubes.Enqueue(goodcube);
}
else
{
GameObject badCube = badCubes.Dequeue();
badCube.transform.position = spawnPoint;`enter code here`
spawnPoint += new Vector2(1 * rowOffset, 0);
badCubes.Enqueue(badCube);
}
The full script
public int columus;
public GameObject cube;
public GameObject goodcube;
public event Action moveCubes;
[SerializeField] private int score = 0;
[SerializeField] private float rowOffset = 1;
[SerializeField] private float heightDifference = 1;
[SerializeField] private int backlog = 4;
private float SpawnHeight;
Queue<int> positions = new Queue<int>();
Queue<GameObject> badCubes = new Queue<GameObject>();
Queue<GameObject> goodCubes = new Queue<GameObject>();
private void Start()
{
for (int i = 0; i < backlog; i++)
{
goodCubes.Enqueue(Instantiate(goodcube));
for (int j = 0; j < columus - 1; j++)
{
badCubes.Enqueue(Instantiate(cube));
}
}
for (int i = 0; i < backlog; i++)
{
positions.Enqueue(SpawnRow(i * heightDifference));
}
}
int SpawnRow(float y)
{
int position = UnityEngine.Random.Range(0, columus);
Vector2 spawnPoint = new Vector2(-columus * rowOffset / 2f, y);
for (int i = 0; i < columus; i++)
{
if (i == position)
{
GameObject goodCube = goodCubes.Dequeue();
goodCube.transform.position = spawnPoint;
spawnPoint += new Vector2(1 * rowOffset, 0);
goodCubes.Enqueue(goodcube);
}
else
{
GameObject badCube = badCubes.Dequeue();
badCube.transform.position = spawnPoint;
spawnPoint += new Vector2(1 * rowOffset, 0);
badCubes.Enqueue(badCube);
}
}
return position;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.D))
{
UpdateScore(0);
}
else if (Input.GetKeyDown(KeyCode.F))
{
UpdateScore(1);
}
else if (Input.GetKeyDown(KeyCode.J))
{
UpdateScore(2);
}
else if (Input.GetKeyDown(KeyCode.K))
{
UpdateScore(3);
}
} //inputcheck
private void UpdateScore(int input)
{
if (positions.Dequeue() == input)
{
moveCubes?.Invoke();
positions.Enqueue(SpawnRow(backlog * heightDifference + 1 * heightDifference));
score++;
}
else
{
moveCubes?.Invoke();
positions.Enqueue(SpawnRow(backlog * heightDifference + 1 * heightDifference));
score--;
}
}
I truly believe your issue is a typo in your code. That usually happens when you have variables with the same name. Your issue is that you are enqueuing the prefab goodcube and not the goodCube object:
GameObject goodCube = goodCubes.Dequeue();
goodCube.transform.position = spawnPoint;
spawnPoint += new Vector2(1 * rowOffset, 0);
//******HERE YOU ARE ENQUEUEING THE PREFAB goodcube AND NOT goodCube as your variable name suggests two lines above this line*****
goodCubes.Enqueue(goodCube);//INSTEAD OF goodCubes.Enqueue(goodcube);

Unity - how do i move the pencil higher then the mouse

The problem is that the pencil it's way too close to the mousePosition. i want to put the pencil higher than the mousePosition.
here is an image as reference : https://ibb.co/s6v25t9
The thing i want to achieve, it's the pencil to be higher than the line drawn
This is taken from a project. it's not my own code but i am trying to figure out how to fix some bugs and this one i cant really figure out how to fix
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using System.IO;
public class GameManager : MonoBehaviour
{
[Tooltip("The color of the drawn lines")]
public Color lineColor;
public Material lineMaterial;
public Transform Pencil;
public Sprite SurpriseGlass;
public Sprite HappyGlass;
public Sprite SadGlass;
public Slider PenCapacity;
public Text PenPercent;
[HideInInspector]
public GameObject[] Hint;
public Image Star1;
public Image Star2;
public Image Star3;
public GameObject LevComp;
private GameObject[] Obs;
private List<GameObject> listLine = new List<GameObject>();
public List<Vector2> listPoint = new List<Vector2>();
private GameObject currentLine;
public GameObject currentColliderObject;
private GameObject hintTemp;
private GameObject[] waterTap;
private GameObject Glass;
private Vector3 LastMosPos;
private BoxCollider2D currentBoxCollider2D;
private LineRenderer lines;
private LineRenderer currentLineRenderer;
private bool stopHolding;
private bool allowDrawing = true;
[HideInInspector]
public bool completed;
int clickCont;
private List<Rigidbody2D> listObstacleNonKinematic = new List<Rigidbody2D>();
private GameObject[] obstacles;
float mosDis;
bool canCreate;
RaycastHit2D hit_1;
RaycastHit2D hit_2;
RaycastHit2D hit_3;
GameObject TemLine;
void Start()
{
Pencil.gameObject.SetActive(false);
waterTap = GameObject.FindGameObjectsWithTag("Interactive");
Glass = GameObject.FindGameObjectWithTag("GlassParent");
Glass.GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Static;
Hint = GameObject.FindGameObjectsWithTag("Hint");
for (int i = 0; i < Hint.Length; i++)
{
Hint[i].SetActive(false);
}
lineMaterial.SetColor("_Color", lineColor);
Obs = GameObject.FindGameObjectsWithTag("Obstacle");
for (int i = 0; i < Obs.Length; i++)
{
Obs[i].GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Static;
}
}
void Update()
{
if (PenCapacity.value <= 0.01f || !Input.GetMouseButton(0))
{
Pencil.gameObject.SetActive(false);
}
if (Input.GetMouseButtonDown(0))
{
GameObject thisButton = UnityEngine.EventSystems.EventSystem.current.currentSelectedGameObject; //Get the button on click
if (thisButton != null) //Is click on button
{
allowDrawing = false;
print("cant drwa");
}
else //Not click on button
{
allowDrawing = true;
stopHolding = false;
listPoint.Clear();
CreateLine(Input.mousePosition);
print("draw");
}
}
else if (Input.GetMouseButton(0) && !stopHolding && allowDrawing && PenCapacity.value > 0)
{
RaycastHit2D rayHit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if (LastMosPos != Camera.main.ScreenToWorldPoint(Input.mousePosition))
{
if (rayHit.collider == null)
{
Pencil.gameObject.SetActive(true);
Pencil.position = new Vector3(LastMosPos.x, LastMosPos.y, 0);
if (canCreate == false)
{
float dist = Vector3.Distance(LastMosPos, Camera.main.ScreenToWorldPoint(Input.mousePosition));
Pencil.GetComponent<TrignometricRotation>().enabled = true;
PenCapacity.value = PenCapacity.value - dist / 25;
PenPercent.text = Mathf.FloorToInt(PenCapacity.value * 100).ToString() + " %";
if (Mathf.FloorToInt(PenCapacity.value * 100) < 75)
{
Star3.gameObject.SetActive(false);
}
if (Mathf.FloorToInt(PenCapacity.value * 100) < 50)
{
Star2.gameObject.SetActive(false);
}
if (Mathf.FloorToInt(PenCapacity.value * 100) < 25)
{
Star1.gameObject.SetActive(false);
}
}
}
}
else
{
Pencil.GetComponent<TrignometricRotation>().enabled = false;
}
Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
float ab = Vector2.Distance(LastMosPos, mousePos);
mosDis = mosDis + ab;
if (!listPoint.Contains(mousePos) && mosDis > .02f)
{
mosDis = 0;
//Add mouse pos, set vertex and position for line renderer
if (canCreate == false)
{
if (rayHit.collider == null)
{
listPoint.Add(mousePos);
}
In the code you posted the value of LastMosPos is never changed so I can't say where you get it from.
However instead of the line
Pencil.position = new Vector3(LastMosPos.x, LastMosPos.y, 0);
you probably could simply add a certain offset like e.g.
Pencil.position = new Vector3(LastMosPos.x, LastMosPos.y + 20f, 0);
to make the pencil appear 20 Unity units (in a Screenspace Overlay canvas this euqals 20 Pixels) above the LastMosPos.

Unity what's wrong with my instantiating algorithm?

I dont know if I can call this algorithm. But I am working on a game in which player will move in a circular path.
As you can see in the picture player is suppose to orbit the circle. And obstacle shall be instantiated in the circle.I am trying to first create the obstacle in first half(left to the long cube) and then in the second half. But things are getting created in the next half too when code is not supposed to do that. Also, it is showing argument exception error. Please have a look at my code and tell me whether my method is wrong or my formulas are wrong or anything else.
public class ObjectInstantiater : MonoBehaviour {
DataHolder dataholder;
GameObject Obstacle;
LevelData leveldata;
private int currentlevel=0; // default level starts from 0
private List<GameObject> Inactivegameobject = new List<GameObject>(); // this object can be used
private List<GameObject> Activegameobject = new List<GameObject>();
private int totalgameobjects;
private int firsthalfgameobjects, secondhalfgameobjects;
public float outerradius;
public float innerradius;
private bool shallspawnouterradiues = true;
// Use this for initialization
void Awake () {
dataholder = (Object)GameObject.FindObjectOfType<DataHolder>() as DataHolder;
Obstacle = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
leveldata = dataholder.Leveldata[0];
}
void Start()
{
Updateleveldata();
FirstHalf();
}
public int Currentlevel
{
get { return currentlevel; }
set { currentlevel = value;
leveldata = dataholder.Leveldata[currentlevel];//sets the level data
}
}
private void Updateleveldata() // this function gets called after a round
{
totalgameobjects = Random.Range(leveldata.MinimumObstacle, leveldata.MaximumObstacle);
firsthalfgameobjects = Mathf.RoundToInt(totalgameobjects / 2);
secondhalfgameobjects = totalgameobjects - firsthalfgameobjects;
}
private void FirstHalf()
{
Debug.Log(firsthalfgameobjects);
Vector3 pos;
if (Inactivegameobject.Count < firsthalfgameobjects)
{
for (int x = 0; x <= (firsthalfgameobjects - Inactivegameobject.Count); x++)
{
GameObject obs = Instantiate(Obstacle) as GameObject;
obs.SetActive(false);
Inactivegameobject.Add(obs);
}
}
float spawnangledivision = 180 / firsthalfgameobjects;
float spawnangle = 180f;
for(int x = 0; x < firsthalfgameobjects; x++)
{
float proceduralRandomangle = spawnangle;
proceduralRandomangle = Random.Range(proceduralRandomangle , proceduralRandomangle + 2f);
if (shallspawnouterradiues)
{
pos = new Vector3(outerradius * Mathf.Cos(spawnangle), outerradius * Mathf.Sin(spawnangle), 0f);
shallspawnouterradiues = false;
}else
{
pos = new Vector3(innerradius * Mathf.Cos(spawnangle), innerradius * Mathf.Sin(spawnangle), 0f);
shallspawnouterradiues = true;
}
spawnangle += spawnangledivision;
Inactivegameobject[0].SetActive(true); // set it to 0
Inactivegameobject[0].transform.position = pos;
Activegameobject.Add(Inactivegameobject[0]);
Inactivegameobject.RemoveAt(0);
}
}
private void SecondHalf()// No need to check this
{
if (Inactivegameobject.Count < firsthalfgameobjects)
{
GameObject obs = Instantiate(Obstacle) as GameObject;
obs.SetActive(false);
Inactivegameobject.Add(obs);
}
}
}

Categories