UI Button reference not visible in the inspector - c#

I declared my Button[] public so i can reference it from my inspector
but it does not appear in my inspector. Please help!!!
I tried restarting the C# as well as re-importing everything in unity....
public rocket rocket;
public Button[] levelButtons;
void Start()
{
for(int i=1 ; i<levelButtons.Length ; i++)
{
// if(i + 1 > rocket.level)
levelButtons[i].SetEnabled(false);
}
}

Button actually is GameObject include Component Button. And you should init size for Array you want to create before using it. I had edited code for example:
//Your array
public GameObject[] levelButtons;
//Object to attach Button
public GameObject panelShow;
//Size for Array
public int sizeArrayButton = 5;
void Awake()
{
//Init size for Array
levelButtons = new GameObject[sizeArrayButton];
for (int i = 0; i < levelButtons.Length; i++)
{
//Create new Object and random for position of Gameobject
GameObject button = new GameObject();
button.transform.parent = panelShow.transform;
button.AddComponent<RectTransform>();
button.AddComponent<Button>();
button.transform.position = new Vector3(Random.Range(100, 50), Random.Range(100, 26), Random.Range(-25, 26));
button.AddComponent<Image>();
button.GetComponent<Button>().onClick.AddListener(() => { Debug.Log($"Button: +{i}+ was clicked"});
levelButtons[i] = button;
}
}
And in Unity, you also make it by using List and Prefabs.

so the issue is solved...so basically what i did was just update my unity version and then it allowed me to use UnityEngine.UI and the issue is now fixed...
Thank you everyone for your time...much apppreciated

Related

How delete clone GameObjects in Unity

So I didn't find something useful, to solve my problem. My script is downloading an JSON Array from my Server and fills some text with that informations.
Thats the part of code:
void DrawUI()
{
GameObject buttonObj = transform.GetChild (0).gameObject; //Gets button to clone it
GameObject g;
int N = allCars.Length;
for (int i = 0; i < N; i++)
{
g = Instantiate(buttonObj, transform);
g.transform.Find("name").GetComponent<Text>().text = allCars[i].carName;
g.transform.Find("type").GetComponent<Text>().text = allCars[i].type;
g.transform.Find("price").GetComponent<Text>().text = allCars[i].price+ "€";
if(balance < int.Parse(allCars[i].price))
{
g.transform.Find("price").GetComponent<Text>().color = Color.red;
} else if (balance >= int.Parse(allCars[i].price))
{
g.transform.Find("price").GetComponent<Text>().color = new Color32(53, 140, 3, 255);
}
g.GetComponent<Button>().AddEventListener(i, OpenBuyDialog);
itemIndex = i;
}
Destroy(prefab);
}
This code loops and creates clones of my buttons, all fine. When user confirms the Buy Dialog, it should reload/refresh the list, but for that I have to delete the old clones. I can't find how to do that properly.
Assume the transform has only one child (buttonObj) at the beginning, then you can delete the clones with this code.
var count = transform.childCount;
for (var i = 1; i != count; ++i)
Destroy(transform.GetChild(i).gameObject);
Add your instantiates objects to a member:
private List<GameObject> buttons;
On refresh, iterate through buttons and call Destroy on each GameObject.
Since you said:
g = Instantiate(buttonObj, transform);
Your clone object is = g.
So you can basically say:
Destroy(g.gameObject);

My event trigger is not working and I don't know what is effecting it

What im trying to do is make ActiveFrame
public int activeFrame;
Update every time a Click on a new ItemFrame.
I Have my ActiveFrame linked to a int
public void Awake()
{
im = GameObject.Find("FrameList").GetComponent<InventoryMenu>();
}
public void ActivateFrame()
{
im.activeFrame = index;
//im.PreviewNewItem(item.ModelPath);
}
And I Have it attached to a EventTrigger
But everytime i Click on the "ItemFrame" it doesn't work and activeFrame just stays at 0 (Each ItemFrame index is not zero)
Heres the Draw Method
void DrawItem(Item it)
{
tmp = GameObject.Instantiate(ItemFrame);
tmp.transform.SetParent(gameObject.transform);
tmpRT = tmp.GetComponent<RectTransform>();
tmpRT.localScale = ItemFrameRT.localScale;
tmpRT.anchoredPosition = ItemFrameRT.anchoredPosition;
tmpRT.anchoredPosition += new Vector2(0, ItemFrameRT.rect.height + 1.5f) * -RectSize;
tmpIf = tmp.GetComponent<ItemFrameScript>();
tmpIf.index = itemframes.Count;
itemframes.Add(tmpIf);
tmpIf.SetValues(it);
RectSize++;
}
I Solved It!
All I did was turn off the Raycast Target On The Child Text
(Can't Approve This Until 2 Days)

How to instantiate next prefab in array on click on button?

I want to instantiate new prefab in array and delete the old one when user click on the next button or on previous button.
I have the array of gameobject prefab something like this:
public GameObject[] prefabMoles = new GameObject[3];
GameObject[] moles = new GameObject[3];
void Start () {
for(int i = 0; i < prefabMoles.Length; i++)
{
moles[i] = (GameObject) GameObject.Instantiate(prefabMoles[i], new Vector3((i-1)*5, 0, 0), Quaternion.identity);
}
}
So now I want to add button on canvas which will be next character and previous will return back one number in array.
For example:
I have Moles array and i instantiate moles[2];
On click on next button I want to destroy moles[2] and instantiate moles[3].
When we are on moles[3] and when we click previous we must destroy moles[3] and instantiate moles[2].
It would be great to have some effect of spawn new one but doesn't matter.
And then when instantiate the new the button must popup for unlock or for select if the character is unlocked.
Thank you so much community for help if that is possible.
If what you want to do is have your button create a new and destroy the old you can do this one function that can be added to the button's action.
It will look something like:
int currentIndex = 0;
GameObject currentObject;
void Start()
{
//Instantiate initial object
currentObject = Instantiate(Moles[currentIndex]);
}
public void Previous()
{
Destroy(currentObject);
currentIndex --;
currentIndex = currentIndex < 0 ? Moles.Length : currentIndex;
currentObject = Instantiate(Moles[currentIndex]);
SpawnEffects();
}
public void Next()
{
Destroy(currentObject);
currentIndex ++;
currentIndex = currentIndex > Moles.Length ? 0 : currentIndex;
currentObject = Instantiate(Moles[currentIndex]);
SpawnEffects();
}
void SpawnEffects()
{
//put your desired Effects
}
Essentially you are keeping track of what has been created and what is the next item that you want to make.

Unity - How can i make a function fire only when player clicked on it 3 times?

I have a hint button on my game, but it fires up everytime you click on it. I need for it to fire only once every 3 clicks
i've tried adding a loadCount = 0 and an if statement
if (loadCount % 3 == 0) { }
but it dosen't seem to work
image for reference : https://ibb.co/L9LnNDw
Here is the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class HintScript : MonoBehaviour
{
LineRenderer line;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
line = GetComponent<LineRenderer>();
line.positionCount = transform.childCount;
for (int i = 0; i<transform.childCount; i++)
{
line.SetPosition(i, transform.GetChild(i).position);
}
}
// This is called from onClick of the Button
public void Hint()
{
FindObjectOfType<AdMobManager>().Hint = true;
FindObjectOfType<AdMobManager>().showInterstitial();
}
}
You should use a simply counter.
I also changed and commented other "issues" in your code:
public class HintScript : MonoBehaviour
{
// by adding SerializeField you can already set those references
// directly in the Unity Editor. This is better than getting them at runtime.
[SerializeField] private LineRenderer line;
[SerializeField] private AdMobManager adMobManager;
// you can still change the required clicks in the inspector
// Note: afterwards changing it here will have no effect!
[SerializeField] private int requiredClicks = 3;
// counter for your clicks
private int counter;
// Use this for initialization
void Start ()
{
// you should do this only once
line = GetComponent<LineRenderer>();
// you should also this only do once
adMobManager = FindObjectOfType<AdMobManager>();
// If instead you would drag those references directly into the now
// serialized fields you wouldn't have to get them on runtime at all.
}
// Update is called once per frame
void Update ()
{
line.positionCount = transform.childCount;
var positions = new Vector3[transform.childCount];
for (var i = 0; i < transform.childCount; i++)
{
position[i] = transform.GetChild(i).position;
}
// it is more efficient to call this only once
// see https://docs.unity3d.com/ScriptReference/LineRenderer.SetPositions.html
line.SetPositions(positions);
}
// This is called from onClick of the Button
public void Hint()
{
counter++;
if(counter < requiredClicks) return;
// Or using your solution should actually also work
if(counter % requiredClicks != 0) return;
adMobManager.Hint = true;
adMobManager.showInterstitial();
// reset the counter
counter = 0;
}
}
You can have a counter to keep track of how many times the player has clicked. Then fire when that counter is at 3.
int amountOfClicks = 0;
void clickme(){
amountOfClicks++;
if(amountOfClicks == 3){
amountOfClicks = 0;
YourFunction();
}
}
void YourFunction(){
// do something...
}
1.Keep a static/global variable.
2.You can't stop event notifications so, please add condition(if condition) upon code block inside the event handler code.

how GetComponentInChildren in unity

I have a problem:
How to assign [] status to rend[]
public GameObject[] Obj;
private bool[] Status;
private MeshRenderer[] rend;
private void Start ()
{
for (int i = 0; i < Obj.Length; i++)
{
rend[i] = GetComponentInChildren<MeshRenderer>();
Status[i] = rend[i];
}
}
Accorting to Object.bool you can try this way:
public GameObject[] Obj ;
private bool[] Status;
private MeshRenderer[] rend;
void Start () {
for (int i = 0; i < Obj.Length; i++)
{
rend[i] = Obj[i].GetComponentInChildren<MeshRenderer>();
Status[i] = rend[i] != null;
}
}
Your question is very unclear so I can just guess what you are trying to archieve:
I'ld say you want to find the first MeshRenderer under your GameObjects in Obj and get an array Status saying whether they are enabled or not.
You are currently allways searching for MeshRenderer in the GameObject this script is attached to instead of looking in the Obj GameObjects. You have to get it using
Obj[i].GetComponentInChildren<MeshRenderer>();
you probably don't initailize your arrays -> you cannot just assign values using Status[i] = and rend[i] = if the arrays were never initialized using new. You can either do that in start once you have the size of Obj
public GameObject[] Obj;
private bool[] Status;
private MeshRenderer[] rend;
private void start()
{
Status = new bool[Obj.Length];
rend = new MeshRenderer[Obj.Length];
// ...
}
but I would prefer using a List<bool> and List<MeshRenderer> instead so you can simply add and remove values later (while an array has a fixed length).
Finally I guess you want to know whether the component MeshRenderer is enabled so you can assign rend[i].enabled
all together
something like
public GameObject[] Obj ;
// Using List here you can already initialize it here
// which would be possible using an array
private List<bool> Status = new List<bool>();
private List<MeshRenderer> rend = new List<MeshRenderer>();
private void Start(){
for (int i = 0; i < Obj.Length; i++)
{
rend.Add(Obj[i].GetComponentInChildren<MeshRenderer>());
bool existsAndEnabled = rend[i] != null && rend[i].enabled;
Status.Add(existsAndEnabled);
}
}
Note that it is still possible that for one of the GameObjects in Obj there is no MeshRenderer found so I say Status shall also be false if there was none.

Categories

Resources