- Rocko Bonaparte
- Posts: 39
- Joined:
Properly showing/hiding a view in Unity with state changes
I am having some goofy problems reusing my main menu view. The first problem I think was that I was recreating it each time I was trying to show it. So now I'm preserving the setup and just enabling and disabling it. However, there's a second layer to the problem where it looks like button enable states aren't propagating or something that's going to be a hard problem to show in detail and will take some effort to simplify and see what could be wrong. But for now, I was hoping somebody could check my work for showing and hiding a main menu:
The button enable/disable logic is trickier because that goes between multiple files, involves the view model, and property change notifications. It works in a standalone test but doesn't in Unity. Is the a gotcha with affecting a viewmodel while the view is disabled or something?
Code: Select all
private NoesisXaml mainMenuXaml;
private NoesisView mainMenuView;
public void Show()
{
if (mainMenuView == null)
{
mainMenuView = GlobalState.Instance.MainCamera.gameObject.GetComponent<NoesisView>();
mainMenuXaml = (NoesisXaml)UnityEngine.Resources.Load(MainMenuXamlPath, typeof(NoesisXaml));
// I'm keeping this canary here in case something screws up with loading the main menu later. At least
// this will point to the crux of the problem.
if (mainMenuXaml == null)
{
Debug.LogError("Could not load the main menu XAML from " + MainMenuXamlPath);
}
mainMenuView.Xaml = mainMenuXaml;
mainMenuView.LoadXaml(true);
}
else
{
mainMenuView.enabled = true;
}
}
public void Hide()
{
mainMenuView.enabled = false;
}
- Rocko Bonaparte
- Posts: 39
- Joined:
Re: Properly showing/hiding a view in Unity with state changes
I'm concluding I have that part down well enough. The bulk of my problem had to do with RelayCommand implementation, per viewtopic.php?f=3&t=2169&p=12273#p12273
- Rocko Bonaparte
- Posts: 39
- Joined:
Re: Properly showing/hiding a view in Unity with state changes
I'm now stuck on a new problem. It looks like if I disable the view, it still gets events. So if I opt for a new game, this will disable the view and start the game. However, if I hit enter on the keyboard, it'll start a new game again despite having disabled the main menu. It's not showing that menu at all.
I also disabled keyboard, mouse, and gamepad, but that doesn't seem to do anything:
I considered it more of a hack regardless, but I'm still left wondering what I really should be doing.
I also disabled keyboard, mouse, and gamepad, but that doesn't seem to do anything:
Code: Select all
mainMenuView.enabled = false;
mainMenuView.EnableGamepad = false;
mainMenuView.EnableMouse = false;
mainMenuView.EnableKeyboard = false;
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: Properly showing/hiding a view in Unity with state changes
Hi Rocko,
I don't know if I'm following your setup, but if I understood correctly you are creating a new NoesisView component for each xaml you want to load, is that right?
What is the purpose of that? Do you need to render them to different cameras?
If you just want to load different xamls into the same scene I recommend using a single NoesisView component with a root xaml:
Each view (MainMenu, Settings, HUD,...) can just be a new xaml that you load into that root Grid.
The loading can be done manually:
Or it can be data driven using MVVM:
Where that ViewModel is set in root xaml DataContext, and each view is a UserControl that loads its associated xaml.
Does any of this helps?
I don't know if I'm following your setup, but if I understood correctly you are creating a new NoesisView component for each xaml you want to load, is that right?
What is the purpose of that? Do you need to render them to different cameras?
If you just want to load different xamls into the same scene I recommend using a single NoesisView component with a root xaml:
Code: Select all
<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- you can place here everything you need -->
</Grid>
The loading can be done manually:
Code: Select all
NoesisView view = GetComponent<NoesisView>();
var xaml = Noesis.GUI.LoadXaml("Assets/Path/To/MainMenu.xaml");
var grid = (Grid)view.Content;
grid.Children.Add(xaml);
Code: Select all
<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyTests">
<Grid.Resources>
<DataTemplate DataType="{x:Type local:MainMenuVM}">
<local:MainMenu/>
</DataTemplate>
<!-- and the rest of views -->
</Grid.Resources>
<ContentControl Content="{Binding ActiveView}"/>
</Grid>
Code: Select all
public class ViewModel: INotifyPropertyChanged
{
private object _activeView;
public object ActiveView
{
get { return _activeView; }
set
{
if (_activeView != value)
{
_activeView = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ActiveView");
}
}
...
}
Does any of this helps?
Who is online
Users browsing this forum: Google [Bot], Semrush [Bot] and 9 guests