0
\$\begingroup\$

So I have a pointer script I attach to a Canvas, which is used to create a simple sprite cursor for selecting menu items (similar to old RPGs). It works great in my Main Menu, but it's invisible in all the other menus it's attached to.

The pointer object exists for the other Canvases it's attached to - I can see it in the hierarchy - and it's responding to controller input and moving around according to its rect transform, but I can't see it in the Game view.

I've also found that if I create a new GameObject, give it an Image component, give the Image component a sprite, and add it to a Canvas, it also won't display. And yet that's exactly what I do for the pointer, and it works at least once - on my main menu. When I select an option on the main menu, it hides the current canvas and enables another canvas, which is appearing and functioning, but with the pointer not rendering.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.Events;


// This component is added to a Canvas to provide it with a pointer
public class Pointer : MonoBehaviour
{
// Public variables
public bool pointerEnabled;
public bool isometric;
public Sprite pointerSprite;
public int columns;
public int columnDistance;
public int rows;
public int rowDistance;
public Vector2 canvasStartingPosition;
public Vector2 currentIndexPosition;
public bool horizontalWrap;
public bool verticalWrap;

// Private variables
private GameObject pointerObject;
private Image pointerImage;
private RectTransform pointerTransform;


private float previousInputTime = 0f;       // Time that the last executed input happened
private float inputDelay = 0.5f;            // Delay between inputs if stick or D-pad is held down
private bool pointerDelay;                  // Pointer is currently delayed

private string eventAButton;
private string eventBButton;

private bool pointerAButton;
private bool pointerBButton;

private UnityAction listenerPointerEnable;
private UnityAction listenerPointerDisable;


// Use this for initialization
void Awake()
{
    pointerObject = new GameObject();
    pointerImage = pointerObject.AddComponent<Image>();
    pointerTransform = pointerObject.GetComponent<RectTransform>();
    pointerObject.GetComponent<Transform>().SetParent(gameObject.transform);
    pointerImage.sprite = pointerSprite;

    pointerTransform.sizeDelta = new Vector2(pointerSprite.bounds.size.x * pointerSprite.pixelsPerUnit, pointerSprite.bounds.size.y * pointerSprite.pixelsPerUnit);

    if (isometric)
    {
        pointerTransform.anchoredPosition = new Vector2(canvasStartingPosition.x + ((currentIndexPosition.x - currentIndexPosition.y) * rowDistance), canvasStartingPosition.y + ((currentIndexPosition.x + currentIndexPosition.y) * -columnDistance));
    }
    else
    {
        pointerTransform.anchoredPosition = new Vector2(canvasStartingPosition.x + (currentIndexPosition.x * columnDistance), canvasStartingPosition.y + (-currentIndexPosition.y * rowDistance));
    }

    pointerDelay = false;

    EventManager.StartListening("PointerEnable", enablePointer);
    EventManager.StartListening("PointerDisable", disablePointer);

    if (pointerEnabled)
    {
        enablePointer();
    }
}

public void enablePointer()
{
    pointerEnabled = true;
    pointerImage.enabled = true;
}

public void disablePointer()
{
    pointerEnabled = false;
    pointerImage.enabled = false;
}

public void setEventAButton (string eventName)
{
    eventAButton = eventName;
}

public void setEventBButton(string eventName)
{
    eventBButton = eventName;
}







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

    //Is the pointer enabled?
    if (pointerEnabled)
    {
        // Handle the delay mechanics of the pointer
        if (pointerDelay)
        {
            // User let go of controller? We can take an input again
            if (Mathf.Abs(Input.GetAxis("Horizontal")) < 0.1f && Mathf.Abs(Input.GetAxis("Vertical")) < 0.1f)
            {
                pointerDelay = false;
            }

            // Check if the input delay has passed, and we can register an input
            if (Time.realtimeSinceStartup - previousInputTime > inputDelay)
            {
                pointerDelay = false;
            }
        }

        // Pointer is not delayed? Check for input
        if (pointerDelay == false)
        {


            if ((int)Input.GetAxis("Horizontal") != 0 || (int)Input.GetAxis("Vertical") != 0)
            {

                    int pointerXInput = (int)Input.GetAxis("Horizontal");
                    int pointerYInput = (int)Input.GetAxis("Vertical");

                    currentIndexPosition.x += pointerXInput;
                    currentIndexPosition.y -= pointerYInput;



                if (currentIndexPosition.x < 0 && horizontalWrap) currentIndexPosition.x = columns - 1;
                if (currentIndexPosition.x < 0 && horizontalWrap == false) currentIndexPosition.x = 0;

                if (currentIndexPosition.x >= columns && horizontalWrap) currentIndexPosition.x = 0;
                if (currentIndexPosition.x >= columns && horizontalWrap == false) currentIndexPosition.x = columns - 1;

                if (currentIndexPosition.y < 0 && verticalWrap) currentIndexPosition.y = rows - 1;
                if (currentIndexPosition.y < 0 && verticalWrap == false) currentIndexPosition.y = 0;

                if (currentIndexPosition.y >= rows && verticalWrap) currentIndexPosition.y = 0;
                if (currentIndexPosition.y >= rows && verticalWrap == false) currentIndexPosition.y = rows - 1;

                if (isometric)
                {
                    pointerTransform.anchoredPosition = new Vector2(canvasStartingPosition.x + ((currentIndexPosition.x - currentIndexPosition.y) * columnDistance), canvasStartingPosition.y + ((currentIndexPosition.x + currentIndexPosition.y) * -rowDistance));
                }
                else
                {
                    pointerTransform.anchoredPosition = new Vector2(canvasStartingPosition.x + (currentIndexPosition.x * columnDistance), canvasStartingPosition.y + (-currentIndexPosition.y * rowDistance));
                }


                pointerDelay = true;
                previousInputTime = Time.realtimeSinceStartup;
            }
        }

        pointerAButton = Input.GetKeyDown("joystick 1 button 0");
        pointerBButton = Input.GetKeyDown("joystick 1 button 1");

        if (pointerAButton)
        {
            EventManager.TriggerEvent(eventAButton);
        }
        else if (pointerBButton)
        {
            EventManager.TriggerEvent(eventBButton);
        }


    }
}

}

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

So I found the problem, and it had nothing to do with the pointer itself.

Since I use multiple Canvases - one per menu screen - I was enabled and disabling them, but this was messing up the pointer script. I'm now instead setting the sorting order of the Canvases to -1 when I'm not needing them.

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