Hello Unity Community, I’ve been looking everywhere for an answer to this but I can not find it. basically my betweenTiles grabs all the sprites I need and adds them to its list. Now the problem occurs when I want to change every sprite renderer in betweenTiles to a certain sprite. I’m going to list the code below, and I can provide my full scripts for clarification if needed. Thank you!
Here is what is declared:
csharp* *public List<GameObject> betweenTiles; public Sprite Foundation;* *
And here is the code sample which is called in a void.
@fire7side , Yes however, from looking at that it seems like it is for changing a single sprite and being able to change it to multiple different sprites. What I am trying to do is change all my sprites in a list, and change them to a sprite I have declared. My current code will only change the first sprite in the list, interestingly.
I don’t know what happened because I could only get it to work by instantiating, I tried it about 3 times. Now I opened up the same thing, it works fine with one sprite. Maybe I’m just losing it. It’s just weird though, I only used 2 sprites, but one would change and the other wouldn’t. Then I just instantiated the second one and they both changed. Maybe I was hallucinating or something.
Yeah. I think something was out of sync because when I tried to save the file with the little save icon, it didn’t save. I had to use save all files. Now I can just click on the icon and it saves.
This first script detects a click on an existing sprite.
using UnityEngine;
using UnityEngine.EventSystems;
public class TileData : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler
{
public void OnPointerClick(PointerEventData eventData)
{
TileManager tm = GameObject.Find("GameMaster").GetComponent<TileManager>();
//Accessing the 'AddSprite' function of the 'TileManager' to add the selected object.
tm.AddTile(eventData.pointerPress.gameObject);
}
public void OnPointerDown(PointerEventData eventData)
{
}
public void OnPointerUp(PointerEventData eventData)
{
}
}
This second script compiles it, and will then change all the sprites within the list it has created between two points:
using System.Collections.Generic;
using UnityEngine;
public class TileManager : MonoBehaviour
{
// A list of the two selected tiles
public List<GameObject> selected;
// A list of all the tiles
public List<GameObject> allTiles;
// A list of the tiles in-between the two selection points
public List<GameObject> betweenTiles;
// Other variables
public Sprite Foundation;
public List<GameObject> renTiles;
public bool pickedFoundation = false;
int i;
private void Start()
{
// Creates an array of every tile and adds it to the 'allTiles' array.
GameObject[] tile = GameObject.FindGameObjectsWithTag("Tile");
for (int i = 0; i < tile.Length; i++)
{
allTiles.Add(tile[i]);
}
}
// This function that adds the tiles within the selection
// points to the 'betweenTiles' list.
public void AddTile(GameObject tile)
{
selected.Add(tile);
// When the selected points is = 2
if (selected.Count == 2)
{
// Calculate the minimum coordinate
Vector2 minCoord = new Vector2(Mathf.Min(selected[0].transform.localPosition.x, selected[1].transform.localPosition.x), Mathf.Min(selected[0].transform.localPosition.y, selected[1].transform.localPosition.y));
// Calculate the maximum coordinate
Vector2 maxCoord = new Vector2(Mathf.Max(selected[0].transform.localPosition.x, selected[1].transform.localPosition.x), Mathf.Max(selected[0].transform.localPosition.y, selected[1].transform.localPosition.y));
// Loop through each tile in 'allTiles' and see if the tile is = or
// within the minCoord and maxCoord.
for (i = 0; i < allTiles.Count; i++)
{
if (allTiles[i].transform.localPosition.x >= minCoord.x && allTiles[i].transform.localPosition.x <= maxCoord.x && allTiles[i].transform.localPosition.y >= minCoord.y && allTiles[i].transform.localPosition.y <= maxCoord.y)
{
// Adds to the 'betweenTiles' list
betweenTiles.Add(allTiles[i]);
Debug.Log("Bet with All: " + betweenTiles.Count);
// Problem right below here.
betweenTiles[i].GetComponent<SpriteRenderer>().sprite = Foundation;
//BuildFoundation();
}
}
}
}
// -------------------------------------------------------- //
public void PickFoundation()
{
}
public void BuildFoundation()
{
Debug.Log("Bet with All: " + betweenTiles.Count);
selected[i].GetComponent<SpriteRenderer>().sprite = Foundation;
// It only will grab the first sprite
betweenTiles[i].GetComponent<SpriteRenderer>().sprite = Foundation;
Debug.Log("It worked");
}
}
for (i = 0; i < allTiles.Count; i++)
{
if (allTiles[i].transform.localPosition.x >= minCoord.x && allTiles[i].transform.localPosition.x <= maxCoord.x && allTiles[i].transform.localPosition.y >= minCoord.y && allTiles[i].transform.localPosition.y <= maxCoord.y)
{
// Adds to the 'betweenTiles' list
betweenTiles.Add(allTiles[i]);
Debug.Log("Bet with All: " + betweenTiles.Count);
// Problem right below here.
betweenTiles[i].GetComponent<SpriteRenderer>().sprite = Foundation;
//BuildFoundation();
}
}
This creates issues. You’re looping through allTiles. Now, let’s say your first tile matches and is added to betweenTiles. Ok, no issues there.
But then if your second tile doesn’t match, it isn’t added. But if your third tile is added, oops. Issue. At this point i =2. but betweenTiles only has 2 entries in it, which means at most i can only be 1 or else you’ll get an error.
So, if you plan to keep it this way, you either should change allTiles[ i ] instead of betweenTiles[ i ] or you need to access the last index of betweenTiles.
I was going to write more, but…
Does betweenTiles ever get cleared?
I really think you shouldn’t use the ‘i’ variable there for betweenTiles, as the loop counter may be different than the betweenTiles index.
You did add the other point I forgot to add, which is how does betweenTiles get cleared or selected for that fact.
@OP, what you could do is populate betweenTiles first, then after that is done, loop through it and switch all the sprites in it instead of trying to do it all in one pass. Just another possible option.
But some of this depends on your mechanics to if you want to clear the list or not.
This sounds about right, considering that one sprite does change, and an error is thrown. For betweenTiles[betweenTiles.Count -1], is that being replaced with the allTiles.Count? Because betweenTiles is empty at that point?
If your if statement is always false, you’ll never access betweenTiles. But once you add 1 item to it, betweenTiles.Count is 1. Then you need to subtract 1 to get the last index available. (in this example, index 0). Because you are adding to the list before changing it’s last objects sprite, Count will always go up by 1 and you’ll always access the last index of the list.
I’m not sure what you mean by it being replaced by allTiles.Count.
Also since you mentioned clearing the list, you could just as easily loop through betweenTiles in a different method and change the sprites there as per my other suggestion.