Hi,
After seeing some problems similar to mine on the web, I decided to create my first post on this forum !
Here is a sum up of my problem :
- I have script (A) drawing a GUI on my screen
- I have a script (B) that manage the LClick mouse event. ( Raycast on the scene → Object selection )
- When I click on my GUI, I don’t want (B) to trigger itself.
- What (A) is drawing directly depends of the current selection ( → defined by the last time (B) was triggered )
So what I thought was :
- I record when I click on a GUI : AECore.GUIClicked = true;
- During the update loop, I check if the GUI was clicked : if( AECore.GUIClicked ) …
- If it is, I don’t trigger the selection change
- At the end of the update loopm I reset GUICliked : AECore.GUIClicked = false;
But my problem is as follow :
I assume that the Update() method is called before the OnGUI( ) during a loop.
So, in my case, this is what happens :
- Left click on my GUI Button
- (B) is called. → The raycast has no hit
- No object is selected
- (A) don’t build the GUI
- The button is not seen as clicked. ( Since he is not present )
I think I can solve my problem if I can find a method that is called after the OnGUI one.
Thanks in advance !
PS : I’m new to this engine, so there may be some trivial solutions I havn’t seen.
It’s me again.
Looks like one night helped me to think.
I didn’t understand my problem correctly :
The problem wasn’t that the Update( ) method was called before the OnGUI( ) method.
It was that :
Here is a solution for my problem :
- Input.GetButton(“LClick”) is triggered when the mouse button is clicked
- GUI.Button( … ) == true when the mouse boutton is released
So I did something like that to solve my problem :
#region Static vars
/// <summary>
/// Capturing events on GUI before changing selection
/// </summary>
private static bool _guiClicked = false;
/// <summary>
/// The method called by the GUI to let this class know that the imput was consumed by the GUI
/// </summary>
public static void ClickOnGUI() { _guiClicked = true; }
#endregion
#region Vars for clicks
/// <summary>
/// A mouse click is treated on the first frame it appears.
/// After that, it is ignored
/// </summary>
private bool _LClickOnLastFrame = false;
/// <summary>
/// The current control selection
/// </summary>
private GameObject _currentControl = null;
/// <summary>
/// The next control selection.
/// When a click is done, we want a little time so that the GUI can days if the click was consumed by them
/// </summary>
private GameObject _nextControl = null;
/// <summary>
/// The IControlDisplayer component corresponding to the current selection
/// </summary>
private IControlDisplayer _controlDisplayer = null;
/// <summary>
/// Update called once per frame
/// Capture mouse click on treat them
/// </summary>
void Update ()
{
// Manage LClick
bool tmp = Input.GetButton("LClick");
if( tmp != _LClickOnLastFrame )
{
if( ! _LClickOnLastFrame )
ManageLClick();
else
UpdateSelection();
}
_LClickOnLastFrame = tmp;
}
/// <summary>
/// GUI method
/// Display the _controlDisplayer and the _targetDisplayer if they exist
/// </summary>
void OnGUI()
{
if( _controlDisplayer != null )
_controlDisplayer.DisplayControl( );
}
/// <summary>
/// Manage Left click button
/// </summary>
private void ManageLClick()
{
int layerMask = ( 1 << AELayers.CONTROLLABLES );
Ray ray = Camera.main.ScreenPointToRay( Input.mousePosition );
RaycastHit hit;
// Selecting a new controller
if( Physics.Raycast( ray, out hit, Mathf.Infinity, layerMask ) )
{
GameObject gameObj = hit.collider.gameObject;
_nextControl = gameObj;
}
// Unselect controller
else
_nextControl = null;
}
/// <summary>
/// When a left click is done, this method wait for button click before changing selection
/// </summary>
/// <returns></returns>
void UpdateSelection()
{
// Update displayers :
// The controller change are delayed until the button is released.
// Tha way, we can wait for GUI interception
//---------------------
if( ! _guiClicked )
{
// Control displayer
if( _nextControl != _currentControl )
{
_currentControl = _nextControl;
Component comp;
if( _currentControl == null || ! _currentControl.TryGetIComponent<IControlDisplayer>( out comp ) )
_controlDisplayer = null;
else
{
_controlDisplayer = (IControlDisplayer) comp;
_controlDisplayer.InitControlDisplay( );
}
}
}
// The update is done
//----------------------------
_guiClicked = false;
_nextControl = _currentControl;
}
And on my GUI buttons :
if( GUI.Button( ... ) )
{
InputManagement.ClickOnGUI();
[...]
}
Hope it will helps some other people 