i would like to learn this : i have a script attached to a button which has a public array field. by drag and drop from hierarchy, i assigned 9 gameobjects to this array field in the inspector . now i need to click on this button and access this array gameobjects component called "Fill Amount" and change that to a new value. though, in the script , i could not write the correct code. any idea ? thanks. Code (CSharp): public class Boosttimes : MonoBehaviour { private float nums = 1; public GameObject[] AllObjstimes; public void Start() { } public void FullFillAmounts() { Debug.Log ("refill items time!"); } }
Do you have UI button in the scene? If not you’ll need one. The ui button has an OnClick listener. And in the onclick listener you point it to the FullFillAmounts function
i have already done that. what i need actually is how to access those draged gameobjects component called Fill Amount. maybe i asked my question not clearly enough!
UI Image has a property called Fill Amount . this property is needed to be referenced . you can learn about it in unity references. so in this script i need to reference it .
ok, know i understand. So when you press the button. you want to change the UI gameobject fillamount to a new value. I'll slap some code together for you to look at and study!
nice! i searched alot , but it is not directly addressed how to be implemented. assigning a gameobject to a public field is easy , but how can you after that , access its components? this is what i needed to learn more.anyway thanks,
here is a simple script. it will change the fill about to a different % every time you click the button. Code (CSharp): using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Boosttimes : MonoBehaviour { private float nums = 1; public GameObject[] AllObjstimes; public Image imageWithAutofill; void Start() { } public void FullFillAmounts() { Debug.Log("refill items time!"); float randomFill = Random.Range(0,1); Debug.Log("Fill amount is " + randomFill); imageWithAutofill.fillAmount = randomFill; //1 is %100 filled } }
From your last post. I'm thinking you want to change the fill amount on every GameObject that's in the array. Is this correct?
but i dont need a public image there , i need to address that image from code. i have already an array that reference to those gameobjects which each one has ui image in it. in void start() i need to access them through some syntax like findby tag or . . this is what i am looking to lean^^
lets see if this is what you're after Code (CSharp): using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; class Boosttimes : MonoBehaviour { private float nums = 1; public GameObject[] AllObjstimes; void Start() { } public void FullFillAmounts() { Debug.Log("refill items time!"); //this is a loop that looks at evey GameObject in the array for (int i = 0; i < AllObjstimes.Length; i++) { //now try and find all images that are subobjects from the main object. Image[] childImages = AllObjstimes[i].GetComponentsInChildren<Image>(); if (childImages.Length > 0) { //we found more then 1 Image gameObject, lets change each ones fill amount for (int k = 0; k < childImages.Length; k++) { float randomFill = Random.Range(0, 1); childImages[k].fillAmount = randomFill; } } } } }
if the script doesn't work, can you post a screen shot of the UI hierarchy, so I can understand the setup a bit better.
so first thanks for your helping .this is not working correctly . i need to give you more information . this array gameobjects have a child . in this child , is fill amount . now no errors in console . however the image from child of array gameobject need to be accesses. can you change the code please?^^
the idea is to get some coins from player and refill their items timer to maximum . i mean when you start the game , items from array start to count down . but this button will take some coins from player and give to their items again maximum time.
Looks like you have some compiler errors. It's helpful if you post those and the line(s) of code to which they refer when you're discussing an issue in the thread. The code provided looks good. Though, I don't think you need to check if it's greater than zero before looping, since the loop would do that anyways, but that doesn't matter.
ok, I see two things. you have an error on line 25. I don't get this error in my unity. second, it may be the source the error. "Image BG" looks to be disabled. it's grayed out.
hello sir. this code does not change fill amount to a new value . what is wrong? i fixed those errors .
they are fixed. https://imgur.com/a/pSXxCHm you know , those image are located in array member as child. that is why code does not correctly . how will you though reference that child instead of array member ? how will you access array member child fill amount? ^^
it will be active as soon as each item from array is thrown to the yard. i need as soon as item is thrown away bg be active and boost time works!
found my mistake, forgot the f for the float Code (CSharp): using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; class Boosttimes : MonoBehaviour { private float nums = 1; public GameObject[] AllObjstimes; void Start() { } public void FullFillAmounts() { Debug.Log("refill items time!"); //this is a loop that looks at evey GameObject in the array for (int i = 0; i < AllObjstimes.Length; i++) { Debug.Log("AllObjstimes " + i + " " + AllObjstimes[i].name); //now try and find all images that are subobjects from the main object. Image[] childImages = AllObjstimes[i].GetComponentsInChildren<Image>(); Debug.Log("found " + childImages.Length + " child Objects"); if (childImages.Length > 0) { //we found more then 1 Image gameObject, lets change each ones fill amount for (int k = 0; k < childImages.Length; k++) { Debug.Log("childImages " + k + " " + childImages[k].name); float randomFill = Random.Range(0, 1f); Debug.Log("change fill to " + randomFill); childImages[k].fillAmount = randomFill; } } } } }
for me , in the console it is changed to new value, but each item image fill amount does not get updated! what can be wrong ? i think my array is not addressed correctly
console shows item names . but fill amount is in the item child .how will you access child of those items instead of them? i mean one level deeper , and access children ?
can you screen shoot me the debug output. I want to see how many children it finds. Mine finds 1 found 1 child Objects
Line 24 Image[] childImages = AllObjstimes.GetComponentsInChildren<Image>(); this looks at all children, even grandchildren and great grandchildren.
https://imgur.com/a/8WqxMo0 when i click on boost button , the button which run that method , in console fill amount is 1 but in action , each item child image fill amount dont get 1 . where is problem?
Do you have any other scripts that are changing the fill amount? you said yesterday that the fill amount slowly depletes. I can only assume that the other script is keeping it 0. Can you post that script?
Code (CSharp): public bool isUsed; private bool EnableFill; public bool CanBeUsed; public float countertimes; private float FillAmount; Animator anim; private Transform Chield; void Start() { CanBeUsed = false; isUsed = false; FillAmount = 1f; anim = GetComponent<Animator> (); Chield = transform.GetChild (0); Chield.gameObject.SetActive (false); } void Update() { if (EnableFill) { FillAmount -= Time.deltaTime / countertimes; Chield.transform.GetChild(0).GetComponent<Image> ().fillAmount = FillAmount; if (FillAmount <= 0) { FillAmount = 0; GameController c = GameObject.FindObjectOfType<GameController> (); c.lives--; c.livesText.text = c.lives.ToString(); c.livesimage.gameObject.GetComponent<Animator>().SetBool("ToLivesIcon",true); anim.SetBool ("returning", true); anim.SetBool ("Smashing", false); isUsed = false; ShowBar (false); Invoke ("ResestHeart", 1f); CanBeUsed = false; } } else FillAmount = 1f; } public void ChangeState(bool state) { anim.SetBool ("Smashing",state); anim.SetBool ("returning", false); } public void ShowBar(bool isVisible) { Chield.gameObject.SetActive (isVisible); EnableFill = isVisible; CanBeUsed = true; } public void Test() { ShowBar (true); } void ResestHeart() { GameController c = GameObject.FindObjectOfType<GameController> (); c.livesimage.gameObject.GetComponent<Animator>().SetBool("ToLivesIcon",false); } this is attached to each of those item . one question on top of this : you start the game level . you need after let say 2 seconds , 1 item get thrown away . next 2 seconds 2 items get thrown ...next 2 seconds ...again 3 items get thrown . how will you do it with code? for this i have an invoke : void RandomTimer() { Invoke ("RandomItem", timeintervals); } but i dont know how to define items for that to be completed?
What you should do is instead of keeping track of the fill amount on your own, is read back the current fill amount before adjusting in that script. I think that will fix your issue. Currently, that script may have altered the fill amount variable (for that script, not the image) to 0, then you try to set it to full, and this script thinks it wants to use zero.
Hm, sorry.. so, I think this snippet: Code (csharp): if (EnableFill) { float fillAmount = Chield.transform.GetChild(0).GetComponent<Image>().fillAmount; fillAmount -= Time.deltaTime / countertimes; Chield.transform.GetChild(0).GetComponent<Image> ().fillAmount = fillAmount; That's what I meant. You do not need to track the fill yourself. Just look it up. I would suggest that you cache that Image variable, of course.
@codeandscripts I've been looking at the code and screen shots you've provided. I need to get a few thing confirmed I see 3 scripts, Boosttimes, GameController and anotherScriptNameUnknown is your last posted code, you say "this is attached to each of those item" where do the scripts live? UI instructor Canvas > Time Boost, has the Boosttimer script Canvas > Time Boost > Item01 Vase right > Image BG > image BG slider which one of these has the anotherScriptNameUnknown script on it? I assume it's "Item01 Vase right" If this is correct i'll see if i can get you a script to work for your setup.
possible fix Code (CSharp): using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; class Boosttimes : MonoBehaviour { private float nums = 1; public GameObject[] AllObjstimes; void Start() { } public void FullFillAmounts() { Debug.Log("refill items time!"); //this is a loop that looks at evey GameObject in the array for (int i = 0; i < AllObjstimes.Length; i++) { Debug.Log("AllObjstimes " + i + " " + AllObjstimes[i].name); //now try and find all images that are subobjects from the main object. Image[] childImages = AllObjstimes[i].GetComponentsInChildren<Image>(); Debug.Log("found " + childImages.Length + " child Objects"); if (childImages.Length > 0) { //we found more then 1 Image gameObject, lets change each ones fill amount for (int k = 0; k < childImages.Length; k++) { if (childImages[k].type == Image.Type.Filled)// this just makes sure that the image is set to Fill { Debug.Log("I found a fill image: " + childImages[k].gameObject.name); FindObjectOfType<OtherScript>().ResetFillAmount(1f); //if you have more then 1 OtherScript in the scene this may not work as intended. //if it's a child object then this can be changed } } } } } } and the otherScript Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class OtherScript : MonoBehaviour { public bool isUsed; private bool EnableFill; public bool CanBeUsed; public float countertimes; private float FillAmount; Animator anim; private Transform Chield; void Start() { CanBeUsed = false; isUsed = false; FillAmount = 1f; anim = GetComponent<Animator>(); Chield = transform.GetChild(0); Chield.gameObject.SetActive(false); } void Update() { if (EnableFill) { FillAmount -= Time.deltaTime / countertimes; Chield.transform.GetChild(0).GetComponent<Image>().fillAmount = FillAmount; if (FillAmount <= 0) { FillAmount = 0; GameController c = GameObject.FindObjectOfType<GameController>(); c.lives--; c.livesText.text = c.lives.ToString(); c.livesimage.gameObject.GetComponent<Animator>().SetBool("ToLivesIcon", true); anim.SetBool("returning", true); anim.SetBool("Smashing", false); isUsed = false; ShowBar(false); Invoke("ResestHeart", 1f); CanBeUsed = false; } } else FillAmount = 1f; } public void ChangeState(bool state) { anim.SetBool("Smashing", state); anim.SetBool("returning", false); } public void ShowBar(bool isVisible) { Chield.gameObject.SetActive(isVisible); EnableFill = isVisible; CanBeUsed = true; } public void Test() { ShowBar(true); } void ResestHeart() { GameController c = GameObject.FindObjectOfType<GameController>(); c.livesimage.gameObject.GetComponent<Animator>().SetBool("ToLivesIcon", false); } //this was added public void ResetFillAmount(float setTo) { FillAmount = setTo; } }
You also had a question about defining an Item. You will most likely need a class to define them, i would call the class Item. You need to think about what an Item is? Does an Item have health? does it have Hit points? does it cause damage? Is it usable, and that could mean many things. Do you need to pickup items? any other options you need can think of. You build a class that defines any of these values. Then in the main gameManager script. You can great a List<Item>. This stores any item in the world. and then you have a second script attached to the player to store the Items that he has picked up.