How to instantiate next prefab in array on click on button? - c#

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.

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)

UI Button reference not visible in the inspector

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

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.

Check integer value in Unity for player turn

I am trying to prevent a click if a move is invalid based on an the int lastClickedValuex and o respectively
Not sure how to do the check. Last thing I have to do before my code is complete and driving me insane.
Basically
if (lastclickedvaluex >= boardsquarevalue || boardsquarevalue == 0){
allow move;
} else {
dont show the sprite;
dont switch turns;
restart the players turn;
dont change the value of lastclickedvaluex;
make like player never clicked I suppose;
}
Im at hour 20 so its probably something immensely stupid.
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour
{
public int playerTurn; //0 = X && 1 = O
public int turnCountX; //Tally Player X Turns
public int turnCountO; //Tally Player O Turns
public GameObject[] bigTurnIcons; //Player Icons Array
public Sprite[] playerGamePieces; //GamePieces Array
public Button[] gameBoardSquares; //GameBoard Array
public int lastPlayedSquareValueX; //Store Value of Last Clicked Square
public int lastPlayedSquareValueO; // ""
public bool gameOver; // End Game
public bool isValidMove; // Check For Valid Move
public int boardSquareValue; //Value of Each Square from Value Script
public int[] markedSquare; //Win Check Array
void Awake()
{
GameSetup();
}
public void GameSetup()
{
isValidMove = true;
playerTurn = 0; //Set Player Turn To X Goes First
turnCountX = 0; //Set X Turn Count to 0
turnCountO = 0; //Set O Turn COunt to 0
bigTurnIcons[0].SetActive(true); //Set X Turn Icon to Active
bigTurnIcons[1].SetActive(false); //Set O Turn Icon to Inactive
for (int i = 0; i < gameBoardSquares.Length; i++) //Initialize Squares (GameBoard) Array
{
gameBoardSquares[i].interactable = true; //Make All Squares Clickable
gameBoardSquares[i].GetComponent<Image>().sprite = null; //Set TurnIcons To Off
}
for (int j = 0; j < markedSquare.Length; j++) //Initialize MarkedSquare Array
{
markedSquare[j] = -100; //Set Value To Wacky Number So It Doesn't Interfere With Formula FOr Win Check
}
}
public void PlaySquareButton(int WhichNumber) //OnClick Function
{
markedSquare[WhichNumber] = playerTurn + 1; //OnClick Store Which PLayer Clicked Which Square
gameBoardSquares[WhichNumber].image.sprite = playerGamePieces[playerTurn]; //OnClick Check To Place Correct Symbol (GamePiece)
gameBoardSquares[WhichNumber].interactable = false; //OnClick Set Button.Interactable To False So It Cannot Be CLicked Again
boardSquareValue = gameBoardSquares[WhichNumber].GetComponent<Value>().boardSquareValue; //OnClick Set The Square's Value To The BoardSquareValue Variable in the Value Script
if (turnCountO > 3 || turnCountX > 3) //Check For Wins After 3 Turns
{
CheckForWinner(); //Iterate Through The MarkedSpaces Array To Check For A Winner
}
if (playerTurn == 0)
{
playerTurn = 1; //Player O Turn
bigTurnIcons[0].SetActive(false);
bigTurnIcons[1].SetActive(true);
Debug.Log(boardSquareValue); //Show Value of Clicked Square in Console
lastPlayedSquareValueX = boardSquareValue; //Set Last CLicked Value to Current Clicked Square
turnCountX++; //Increment Player Turn Count
}
else
{
playerTurn = 0;
bigTurnIcons[0].SetActive(true);
bigTurnIcons[1].SetActive(false);
Debug.Log(boardSquareValue);
lastPlayedSquareValueO = boardSquareValue;
turnCountO++;
}
}
Thank you for any help
GameBoard
As per your comments, you may be missing:
public PlaySquareButton(int WhichNumber){
if(playerTurn)
{
if(WhichNumber > lastPlayedSquareValueX){
markedSquare[WhichNumber] = playerTurn + 1; //OnClick Store Which PLayer Clicked Which Square
gameBoardSquares[WhichNumber].image.sprite = playerGamePieces[playerTurn]; //OnClick Check To Place Correct Symbol (GamePiece)
gameBoardSquares[WhichNumber].interactable = false; //OnClick Set Button.Interactable To False So It Cannot Be CLicked Again
...
}
}else{
if(WhichNumber > lastPlayedSquareValueO){
markedSquare[WhichNumber] = playerTurn + 1; //OnClick Store Which PLayer Clicked Which Square
gameBoardSquares[WhichNumber].image.sprite = playerGamePieces[playerTurn]; //OnClick Check To Place Correct Symbol (GamePiece)
gameBoardSquares[WhichNumber].interactable = false; //OnClick Set Button.Interactable To False So It Cannot Be CLicked Again
...
}
}
}
Basically before you start your functionality you check if the WhichNumber, that I guess comes from the square once clicked, is greater than the lastPlayedSquareValueX

Categories

Resources