0
\$\begingroup\$

This is a screenshot showing two small images on the panel and I want that when the mouse cursor is over the image/s to highlight the current image the mouse is over.

On the right the canvas settings and the rawimages.

Canvas and raw images

This script is attached to the canvas :

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class SavedGamesSlots : MonoBehaviour
{
    Texture2D thisTexture;
    byte[] bytes;
    string fileName;
    public GameObject[] ImageHolder = new GameObject[1];

    // 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<RawImage>().texture = thisTexture;

        }
    }

    // Update is called once per frame
    void Update()
    {

    }

    public void OnHover()
    {
        Debug.Log("Enter");

    }

    public void OnHoverExit()
    {
        Debug.Log("Exit");
    }
}

I have two problems :

How to know what image the mouse is over now ?

How to highlight the current image the mouse is over ?

I also created Trigger Event component on each RawImage then calling this two functions OnHover and OnHoverExit :

Trigger Event

And this is when I tried to make one of the rawimages the left one brighter changed it's color to white but still the image is too dark :

Rawimage too dark

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.