I have a Canvas object in my scene and when I click a button on the controller, a script adds a "IgnorePointer" tag to the canvas and disables the renderer. The code is pretty simple:
GameObject UI = GameObject.Find("UI Canvas");
UI.tag = "IgnorePointer";
GameObject conceptMenu = GameObject.Find("UI Canvas");
Canvas conceptCanvas = conceptMenu.GetComponent<Canvas>();
conceptCanvas.enabled = false;
When the button is clicked, the canvas disappears and the tag is correctly added, but if you activate the pointer and aim it where the canvas was, the ray-cast still collides with the invisible canvas. Is this a bug or am I going about this operation incorrectly?
Edit: I should clarify that if you manually add the tag in the editor instead of from script, that the ray-cast performs as expected and passes through the canvas.
What happens if you call SetWorldCanvas on your UI pointer passing the canvas you want to ignore (after you set the ignore tag)?
Does it work then?
I tidied up my code to make it clearer and added your suggestion, however the problem still persists.
GameObject menu = GameObject.Find("Menu");
menu.tag = "IgnorePointer";
Canvas menuCanvas= menu.GetComponent<Canvas>();
GetComponent<VRTK_UIPointer>().SetWorldCanvas(menuCanvas);
menuCanvas.enabled = false;
Can you confirm if I am invoking 'SetWorldCanvas' correctly?
Yeah looks correct. I'll attempt to recreate your issue in the example scene and investigate further
Don't know if this helps, but if you enable 'togglePointerOnHit' on the controller, after you add the tag from script, the ray-cast does indeed stop appearing when you point it at where the canvas was. The issue arises again when you manually activate the pointer and it collides with the invisible canvas again.
Right I think I misread the original question, I thought you were talking about the Ignore Canvas With Tag Or Class setting.
Instead of just setting the canvas to enabled = false try disabling the GameObject the canvas is on.
The Raycast stuff will still be emitted even if the canvas is turned off because that's a separate script.
(you could disable VRTK_UIGraphicRaycaster on the canvas that would probably also work)
No, you didn't misread the question. I was talking about the 'Ignore Canvas With Tag Or Class' setting.
If I disable the GameObject the canvas is on, that does work, but the problem is trying to enable it again because I cannot locate a disabled GameObject with GameObject .Find()
I already tried to disable 'VRTK_UIGraphicRaycaster' by doing the following...
GameObject UI = GameObject.Find("Concept Canvas");
UI.GetComponent<VRTK_UIGraphicRaycaster>().enabled = false;
UI.GetComponent<Canvas>().enabled = false;
...but the ray-cast still collided with the invisible canvas when the pointer was manually activated.
Were you able to recreate the issue in your own example?
Ok, so just so I understand it, is this correct? :)
Ignore Tag Or Canvas string to IgnorePointerIgnorePointerExpected:
UI Pointer should not be able to access the canvas
Actual:
UI Pointer can still interact with the canvas
Yes, that is it exactly.
Does it work as intended for you?
Not tried yet,
I'm about to, I'll let you know how I get on
Ok so adding the exclude tag at runtime prevents me from using the UI canvas, but the simple pointer still collides with the canvas.
Is that what you experience?
Ok I know what the problem is.
Because the canvas is generated at start up as a UI Pointer canvas, when you disable it at runtime, it's still considered a UI pointer canvas.
I think what needs to happen is:
Ignore Canvas with tag or class is set toSetWorldCanvas(x) passing the canvas objectThen at this point, the SetWorldCanvas method should check to see if the given canvas should be ignored (which it does now) but instead of just returning (as it does now) it should then check to see if the canvas was previously set up as a UI Pointer canvas and it should clean it so it's no longer a UI Pointer canvas.
Then if you want to re-enable it in the future, you'd remove it's tag and call SetWorldCanvas again.
Okay, so if I understand you correctly, on my vive controller script I should have something like...
void Start () {
GameObject UI = GameObject.Find("Concept Canvas");
UI.tag = "IgnorePointer";
GetComponent<VRTK_UIPointer>().SetWorldCanvas(UI.GetComponent<Canvas>());
GetComponent<VRTK_ControllerEvents>().ApplicationMenuPressed += new ControllerInteractionEventHandler(DoApplicationMenuPressed);
}
private void DoApplicationMenuPressed(object sender, ControllerInteractionEventArgs e)
{
GameObject UI = GameObject.Find("Concept Canvas");
if (UI.tag == "Untagged")
{
UI.tag = "IgnorePointer";
}
else
{
UI.tag = "Untagged";
}
GetComponent<VRTK_UIPointer>().SetWorldCanvas(UI.GetComponent<Canvas>());
}
This actually worked so far as at startup the canvas was ignored by the pointer. Then I pressed the script button and the pointer started interacting with the canvas. However, once I clicked the button again (and I can confirm I can see the tag is removed in the editor) the pointer continues to collide with the canvas.
Did I implement your suggestion correctly?
Don't worry I'm implementing the fix right now :)
Oh, is it actually a bug? I was still convinced I was just being stupid somewhere :P
No it's a bug :)
I actually feel a lot better knowing that. Been pulling my hair out for the past 2 days!