KeldorKatarn
Topic Author
Posts: 86
Joined: 30 May 2014, 10:26

Re: Question about workflow

01 Feb 2017, 00:44

You guys really should get into contact with units. If people could use your GUI to actually extend the EDITOR that would be amazing. The current API for Unity editor extension is a nightmare.
 
User avatar
jsantos
Site Admin
Posts: 2904
Joined: 20 Jan 2012, 17:18
Contact:

Re: Question about workflow

01 Feb 2017, 19:33

You guys really should get into contact with units. If people could use your GUI to actually extend the EDITOR that would be amazing. The current API for Unity editor extension is a nightmare.
They are so in love with their IMGUI approach that I doubt anything like that would happen. : )
 
KeldorKatarn
Topic Author
Posts: 86
Joined: 30 May 2014, 10:26

Re: Question about workflow

02 Feb 2017, 04:58

I have another question about the workflow. People have mentioned earlier that they use a separate WPF Application Solution to create and design and test the GUI and simply move the XAMLs to the assets folder or link them from there.

However since the x:class attribute needs to be removed, I cannot see how this works. Without the x:class attribute, how do I even add the user control to a window or any other parent control? There is no way to reference it is there? I mean usually you do <local:MyUserControl /> or something like that but I need a namespace to let WPF know where to find it. How do I define a namespace for the control without the x:class attribute?
And how do I reference controls with eachother in Noesis style XAML if I cannot declare classes for the controls? How do I add them as tags in the XAML then, i.e. to nest user controls?

Maybe I'm too stupid and this can be done in WPF also. I've never worked with XAML that didn't have the x:class attribute in each control.

Sorry if this is a stupid question but none of the

Have I completely missunderstood the necessity of the x:class attribute removal? That DOES have to be removed for XAML to work in Noesis right?

Also.. is there a recommended root element for Noesis XAML? A user control? A grid? What root element do people generally use since from the sample it seems it can be just about anything?

I'm trying to use a user control as a root so I can add it to the main window in my WPF test application, so I can test the GUI outside of Unity.
 
Etana
Posts: 17
Joined: 21 Aug 2016, 13:14

Re: Question about workflow

02 Feb 2017, 11:46

Hello,
I'll share how we at Dreamloop handle our workflow with Noesis and Unity.
We use Blend to only edit .xaml files and Visual Studio to edit .cs files.

First we obviously in Blend make a new project. We put this new project to root of unity project folder, same location where "assets" folder is located. Disable "create directory for solution"
Image

When new project is made, we cut everything from this new Blend project folder to the root of Unity project folder. so for example in above image, new folder names GameUI will be made at root of Unity project folder, cut everything from there and paste to the root of your Unity project folder. Open Blend and open GameUI project.

Now we have Blend project with access to all of our Unity project files if we want so.

Click Show All Files in blend solution explorer to see Assets folder. There you can see all of your Unity files and add them to your Blend project by right clicking and choosing "Include in Project"


Now example from our real project.
We already used Strange IoC in our project, so it was quite simple to add MVVM architecture on top of that. Here is a graph of how our hybrid MVVM-MVCS. We use MVVM for all UI related.
Image

UIView our .xaml files.
UICode is the code behind, .xaml.cs files.
ManagedView is our StrangeIoC View which communicates with all Strange IoC related code.
XamlHelper (at the right side of that image) is our all kind of xaml stuff and often used UI interactions for example window dragging with mouse, invokes, converters etc.

Here I will show you part of one of our .xaml.cs code of one UserControl, our ArenaModeWindow UI.
#if UNITY_STANDALONE || UNITY_ANDROID || UNITY_IOS || UNITY_WINRT_8_1
#define UNITY
#endif

#if UNITY
using Assets.GloryAssets.Cok_Xaml.Editors.Views;
using Assets.GloryAssets.Scripts.Xaml.Commands;
using Noesis;
using System.Collections;
using UnityEngine;
using System;
using System.Windows.Input;
using Assets.GloryAssets.Scripts.GUI.XamlHelpers;
using Assets.GloryAssets.Scripts.Arenamode.Views;

#else
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
#endif

namespace Assets.GloryAssets.Scripts.GUI.UserControls

{
    /// <summary>
    /// Interaction logic for ArenaModeWindow.xaml
    /// </summary>

#if UNITY
    [UserControlSource("Assets/GloryAssets/Cok_Xaml/Arena/ArenaModeWindow.xaml")]
#endif
    public partial class ArenaModeWindow : UserControl
    {
#if UNITY

        FrameworkElement _root;
        ArenaModeView _view;
        FrameworkElement _Bar;

        public DelegateCommand ActionButtonClickedCommand { get; private set; }
        public DelegateCommand NextTargetButtonClickedCommand { get; private set; }
        public DelegateCommand PreviousTargetButtonClickedCommand { get; private set; }
        public DelegateCommand DebugLocationCommand { get; private set; }

        public DelegateCommand ContinueButtonClickedCommand { get; private set; }

        public ICommand EnterCommand { get; private set; }
        public ICommand ExitCommand { get; private set; }

        public ArenaModeWindow()
        {
            ActionButtonClickedCommand = new DelegateCommand(OnActionButtonClicked);
            NextTargetButtonClickedCommand = new DelegateCommand(OnNextTargetButtonClicked);
            PreviousTargetButtonClickedCommand = new DelegateCommand(OnPreviousTargetButtonClicked);
            ContinueButtonClickedCommand = new DelegateCommand(OnContinueButtonClickedCommand);

            DebugLocationCommand = new DelegateCommand(debugLocation);

            EnterCommand = new DelegateCommand(OnEnter);
            ExitCommand = new DelegateCommand(OnExit);

            this.Initialized += OnInitialized;
            this.InitializeComponent();
        }

        private void OnContinueButtonClickedCommand(object o)
        {
            _view.OnContinueButtonClicked();
        }

        private void OnEnter(object o)
        {
            _view.OnMouseOverTurnTrackerElement((int)o);           
        }

        private void OnExit(object o)
        {
            _view.OnMouseExitTurnTrackerElement((int)o);
        }

        private void OnActionButtonClicked(object obj)
        {
            _view.ActionButtonClicked((int)obj);
        }

        private void OnNextTargetButtonClicked(object obj)
        {
            _view.NextTargetButtonPressed();
        }

        private void OnPreviousTargetButtonClicked(object obj)
        {
            _view.PreviousTargetButtonPressed();
        }

        private void debugLocation(object obj)
        {
            FrameworkElement element = (FrameworkElement)obj;
            Debug.Log(Noesis.Canvas.GetLeft(element));
        }

        private void OnInitialized(object sender, Noesis.EventArgs e)
        {
            _view = Camera.main.GetComponent<ArenaModeView>();
            _root = (UserControl)FindName("root");

            _root.DataContext = _view;
            _view.root = _root;
        }

#endif
    }
 
As you can see, Blend will only see lines which defines our Class and some includes. All other code is completely out of Blend's reach. We only want Blend to be able to build solution without errors so this enables us to do that.

At initialization we set our Xaml's datacontext to our StrangeIoC View.

We are quite happy with this workflow.
 
User avatar
ai_enabled
Posts: 221
Joined: 18 Jul 2013, 05:28
Contact:

Re: Question about workflow

03 Feb 2017, 15:07

While developing VoidExpanse we've used similar workflow to described above by @Etana, except we copy .XAML files without .XAML.CS and simply created new corresponding .XAML.CS files at the Unity project. So we didn't wrote these horrible #if sections. And we can run WPF application presenting the UI for testing/prototyping separately from the game (so WPF application contains some simulation/fake logic to properly test the UI separately).
Thought this approach still requires writing a lot of extra code and we've switched on the new approach which I've described in the beginning of this topic. With the new approach we're sharing 99% of the UI code (including markup and C# code). We could easily switch off some (rare) sections of code which could be run only by the game - with simple logical checks - if (IsDesignTime) { return; } --- and IsDesignTime is a constant which is set to true in case of WPF.
Other code (including usings for namespaces, locating controls using FindName<Type>("name"), etc) is 100% shared between WPF and the game, but it requires some smart preprocessing of the UI C# code (with Roslyn) to make it compatible with NoesisGUI before compiling it. Thought this is not a problem in our case as our game itself uses Roslyn for dynamic compilation, so it could preprocess the code before compiling it.

I hope someday we will cooperate to make an opensource framework for NoesisGUI making that workflow accessible for everybody.

Regards!
AtomicTorch Studio Pte. Ltd. http://atomictorch.com
 
User avatar
jsantos
Site Admin
Posts: 2904
Joined: 20 Jan 2012, 17:18
Contact:

Re: Question about workflow

03 Feb 2017, 21:54

#if UNITY
    [UserControlSource("Assets/GloryAssets/Cok_Xaml/Arena/ArenaModeWindow.xaml")]
#endif
That attribute is deprecated in v1.3. Now, it must be done exactly as in WPF:
class ArenaModeWindow : public UserControl
{
public:
    ArenaModeWindow ()
    {
        InitializeComponent();
    }

private:
    void InitializeComponent()
    {
        GUI::LoadComponent(this, "Assets/GloryAssets/Cok_Xaml/Arena/ArenaModeWindow.xaml");
    }
}
There is another important change in Unity. Now, each XAML is preprocessed into a first citizen Unity asset (.asset extension). This means that XAMLs will have their own inspector window, preview, thumbnail icon and the same rules that Unity applies for all the assets: if you need to use an asset you need to have a reference to that asset in a public property of a MonoBehaviour or it must be located in a /Resources/ folder.

This has implications for the above code, because the XAML associated to User Controls must be located under a /Resources/ folder or stored in a global list under some global GameObject or something similar.

What do you think about it? Feedback is very welcome at this point because we are almost ready to release the Unity plugin for v1.3.

Who is online

Users browsing this forum: No registered users and 1 guest