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 Answer 1

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .