It's quite difficult to properly get the whole picture of you project without seeing on which gameobject is what script. But this is be the way I would create a system like this.
Instead of only loading the image, create a prefab with the image as a component. This gameobject will have a script which will deal with the highlighting.
Also, if you overlay the RawImage with another Image, you can just change the color and alpha value of this image to highlight/grey it out.
The ImageObject.cs:
using UnityEngine;
using UnityEngine.UI;
public class ImageObject : MonoBehaviour {
[SerializeField] private RawImage rawImage;
[SerializeField] private Image overlayImage;
private SavedGameSlots savedGameSlots;
public void Initialize(Texture2D texture, SavedGameSlots sgs) {
rawImage.texture = texture;
savedGameSlots = sgs;
}
void OnMouseEnter() {
ChangeOverlayImageAlpha(0f);
savedGameSlots.SetCurrentlyHoveredImageObject(this);
}
void OnMouseExit() {
ChangeOverlayImageAlpha(1f);
savedGameSlots.SetCurrentlyHoveredImageObject(null);
}
private void ChangeOverlayImageAlpha(float alpha) {
var tmpColor = overlayImage.color;
tmpColor.a = alpha;
overlayImage.color = tmpColor;
}
}
The Prefab will be the RawImage with another another image, the overlayImage on top. Just set the references in the inspector and give it the ImageObject script as a component. Also to detect the OnMouseEnter you have to add a collider component to the prefab.
I assume you use a grid layout in your "Save Games Canvas"?
In your SavedGameSlots:Start you instantiate those ImageObject-GameObjects.
Insead of loading them from your resource folder, jsut give it the reference in the inspector.
SavedGamesSlots.cs:
public class SavedGamesSlots : MonoBehaviour
{
public GameObject imageObjectPrefab;
public GameObject imageObjectCanvas;
Texture2D thisTexture;
byte[] bytes;
string fileName;
public GameObject[] ImageHolder = new GameObject[1];
private ImageObject currentlyHoveredImageObject;
// Start is called before the first frame update
void Start()
{
var imagesToLoad = Directory.GetFiles(Application.dataPath + "/screenshots", "*.png");
for (int i = 0; i < imagesToLoad.Length; i++)
{
thisTexture = new Texture2D(100, 100);
fileName = imagesToLoad[i];
bytes = File.ReadAllBytes(fileName);
thisTexture.LoadImage(bytes);
thisTexture.name = fileName;
ImageHolder[i] = Instantiate<GameObject>(imageObjectPrefab, imageObjectCanvas.transform)
ImageHolder[i].GetComponent<ImageObject>().Initialize(thisTexture, this);
}
}
public void SetCurrentyHoveredGameObject(ImageObject imageObject) {
currentlyHoveredImageObject = imageObject;
}
}
If you want to set the images in the inspector, just remove the instantiating part and set the references in the inspector:
savedGameSlots:Start():
// Start is called before the first frame update
void Start()
{
var imagesToLoad = Directory.GetFiles(Application.dataPath + "/screenshots", "*.png");
for (int i = 0; i < imagesToLoad.Length; i++)
{
thisTexture = new Texture2D(100, 100);
fileName = imagesToLoad[i];
bytes = File.ReadAllBytes(fileName);
thisTexture.LoadImage(bytes);
thisTexture.name = fileName;
ImageHolder[i].GetComponent<ImageObject>().Initialize(thisTexture, this);
}
}
The currentlyHoveredImageObject will be the image you're hovering. When it's null, nothing is hovered. It you don't want to handle the ImageObject as currentlyHoveredObject, you can also pass an index:
// Start is called before the first frame update
void Start()
{
var imagesToLoad = Directory.GetFiles(Application.dataPath + "/screenshots", "*.png");
for (int i = 0; i < imagesToLoad.Length; i++)
{
thisTexture = new Texture2D(100, 100);
fileName = imagesToLoad[i];
bytes = File.ReadAllBytes(fileName);
thisTexture.LoadImage(bytes);
thisTexture.name = fileName;
int a = i;
ImageHolder[i].GetComponent<ImageObject>().Initialize(thisTexture, a);
}
}
Just change ImageObject:Initialize to accept an int instead of the SavedGameSlots, as well as SavedGameSlots:SetCurrentlyHoveredImage and pass the index value.