Adding GUI Tutorial
This tutorial shows how to add a GUI interface using C# to a currently existing scene. This tutorial follows the “Getting Started with Visual3d” tutorial. and adds code the following demo: MyDemoScene.cs.
To do this tutorial, create MyDemoScene.cs by doing the “Getting Started with Visual3d” tutorial.
1. Add the following to the top of the code to let the routine know where to find the GUI includes.
using Visual3D.UI;
using Visual3D.UI.Controls;
using Visual3D.UI.CommonForms;
2. Add the following to the end of the following routine OnStarted()
MyDemoGui Gui = new MyDemoGui();
Gui.Initialize(this);
Gui.Show();
3. Add the following statement after the “}” of routine OnStarted()
public MyDemoGui Gui;
4. Add the following to OnLoadStaticContent()
MyDemoGui gui = ((MyDemoScene)Scene).Gui;
5. Add the following class after the “}” of // end public class MyDemoRegion : BaseDemoRegion
[Serializable]
public class MyDemoGui : GuiForm
{//I'm not 100% on this, however each interface that I've seen always has this
//The reasoning behind this seems to be if you dive through the other interfaces
//they seem to pull other UIs, this method allows them to all open the same window
//Without pointers I imagine I'd do the same thing... but I'd go through a lot of
//trial and error before realizing it.
public MyDemoGui()
: base(GuiIds.New("FantasyGuiDemoMenu"), false, ScreenRectangle.FullSize)
{
}
static public MyDemoGui _instance;
public static MyDemoGui Instance
{
get
{
if (_instance != null)
return _instance;
else
{
MyDemoGui custom = new MyDemoGui();
custom.PrepareForUse();
return custom;
}
}
}
//destructor
protected override void OnDispose(bool isDisposing)
{
base.OnDispose(isDisposing);
_instance = null;
}
//declare any other consoles you want to be able to pull from here... this includes every form item so add em
protected Label _avatarName;//we'll show them their name.
protected ProgressBar _healthBar;//and I think that we'll show them their health, that should be enough for now.
protected override void OnActivated()
{
base.OnActivated();//I'm guessing that this calls the BuildGui function.
}
protected override void BuildGui()
{
if (_healthBar != null)//not entirely certain on this one... seems like redundant error checking, but whatever.
return;
float ScreenWidth = World.GuiRenderer.Width;
float ScreenHeight = World.GuiRenderer.Height;
int barWidth = 100;
//public Label AddText(string name, float posX, float posY, float width, float height, string text);
//is what you pull up if you look at it in metadata. So basically, it does what it says.
//I wonder about that last string though. The next few lines are ripped straight from CharacterStatsConsole.cs
_avatarName = (Label)this.AddText("AvatarName", 10, 65, barWidth, 20, "");
//I'm going to guess that the first bit is just to reference, the second and third is the same as above
//the barwidth.... I have no clue why its not just an int but its nice to know what that field does.
//and the next few I do not know.
_healthBar = (ProgressBar)this.AddColorProgressBar(
"HealthBar", 10, 90, barWidth, 20, 0, 100, 100,
ProgressBarConfig.Orientation.Horizontal);//can I call diagonal?
//thats kindof a nifty feature though.
_healthBar.Prefix = "H:";
//Not sure on this one but guessing where the thing appears?
this.TopSheet.ThemeFileName = SkinIDs.Fantasy;
}
public void UpdateBeforeRender()
{//I think this is on the todo list, so put it here to be safe.
}
public void UpdateStats()
{//ripped from their files, is obvious.
if (!this.IsActive || !this.IsShowing)
return; // not active!
Avatar avatar = World.Selections.FocusedObject as Avatar;
//need a reference on who to get the health on.
if (avatar != null)
{
_avatarName.Text = avatar.Name;
// We have a player, update his stats
_healthBar.MaxRange = avatar.MaxHitPoints;
_healthBar.Progress = avatar.HitPoints;
}
return;
}
} // end public class MyDemoGui : GuiForm
6. Build and Run, See green status bar with the hit points.
7. Double left click on the avatar, then do some single right clicks and watch the health bar go down.
In case you made some mistake along the way. You can cut and paste the complete code should look like the following:
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Visual3D.Terrains;
using Visual3D.Terrains.Topography;
using Visual3D.Terrains.GIS2;
using Visual3D.Demo.Actors;
using Visual3D.UI;
using Visual3D.UI.Controls;
using Visual3D.UI.CommonForms;
namespace Visual3D.Demo.Scenes
{
[Serializable]
public class MyDemoScene : BaseDemoScene
{
public MyDemoScene()
{
InitialAmbientLight = new Color(128, 128, 128);
InitialSkyDefinitionName = "Afternoon.sky.xml";
InitialCameraPosition = new Vector3(-10f, 3f, -10f);
InitialCameraFocusPoint = new Vector3(70f, 30f, 100f);
} // end public MyDemoScene()
protected override void OnStarted()
{
SceneRootNode = new MyDemoRegion();
base.OnStarted();
MyDemoGui Gui = new MyDemoGui();
Gui.Initialize(this);
Gui.Show();
} // end protected override void OnStarted()
public MyDemoGui Gui;
} // end public class MyDemoScene : BaseDemoScene
public class MyDemoRegion : BaseDemoRegion
{
private Terrains.InfiniteTerrain _terrain;
public MyDemoRegion()
{
} // end public MyDemoRegion()
protected override void OnLoadStaticContent()
{
// Infinite terrain:
_terrain = Terrains.InfiniteTerrain.SetSceneTerrain("GrassyFlat.InfiniteTerrain.xml");
_terrain.Node.ShadowSettings.IsShadowReceiver = true;
Actor tree = new Actor("tree", "bigtree1.mesh", 1f);
tree.Spatial.RelativePosition = new Vector3(20, 0f, 20);
tree.ShadowSettings.IsShadowCaster = true;
Spatial.AddChild(tree);
Actor woman = new CasualHumanFemaleAvatar("woman", 5f, 1f);
woman.Spatial.RelativePosition = new Vector3(0f, 0, 0f);
woman.ShadowSettings.IsShadowCaster = true;
Spatial.AddChild(woman);
MyDemoGui gui = ((MyDemoScene)Scene).Gui;
base.OnLoadStaticContent();
} // end protected override void OnLoadStaticContent()
} // end public class MyDemoRegion : BaseDemoRegion
[Serializable]
public class MyDemoGui : GuiForm
{//I'm not 100% on this, however each interface that I've seen always has this
//The reasoning behind this seems to be if you dive through the other interfaces
//they seem to pull other UIs, this method allows them to all open the same window
//Without pointers I imagine I'd do the same thing... but I'd go through a lot of
//trial and error before realizing it.
public MyDemoGui()
: base(GuiIds.New("FantasyGuiDemoMenu"), false, ScreenRectangle.FullSize)
{
}
static public MyDemoGui _instance;
public static MyDemoGui Instance
{
get
{
if (_instance != null)
return _instance;
else
{
MyDemoGui custom = new MyDemoGui();
custom.PrepareForUse();
return custom;
}
}
}
//destructor
protected override void OnDispose(bool isDisposing)
{
base.OnDispose(isDisposing);
_instance = null;
}
//declare any other consoles you want to be able to pull from here... this includes every form item so add em
protected Label _avatarName;//we'll show them their name.
protected ProgressBar _healthBar;//and I think that we'll show them their health, that should be enough for now.
protected override void OnActivated()
{
base.OnActivated();//I'm guessing that this calls the BuildGui function.
}
protected override void BuildGui()
{
if (_healthBar != null)//not entirely certain on this one... seems like redundant error checking, but whatever.
return;
float ScreenWidth = World.GuiRenderer.Width;
float ScreenHeight = World.GuiRenderer.Height;
int barWidth = 100;
//public Label AddText(string name, float posX, float posY, float width, float height, string text);
//is what you pull up if you look at it in metadata. So basically, it does what it says.
//I wonder about that last string though. The next few lines are ripped straight from CharacterStatsConsole.cs
_avatarName = (Label)this.AddText("AvatarName", 10, 65, barWidth, 20, "");
//I'm going to guess that the first bit is just to reference, the second and third is the same as above
//the barwidth.... I have no clue why its not just an int but its nice to know what that field does.
//and the next few I do not know.
_healthBar = (ProgressBar)this.AddColorProgressBar(
"HealthBar", 10, 90, barWidth, 20, 0, 100, 100,
ProgressBarConfig.Orientation.Horizontal);//can I call diagonal?
//thats kindof a nifty feature though.
_healthBar.Prefix = "H:";
//Not sure on this one but guessing where the thing appears?
this.TopSheet.ThemeFileName = SkinIDs.Fantasy;
}
public void UpdateBeforeRender()
{//I think this is on the todo list, so put it here to be safe.
}
public void UpdateStats()
{//ripped from their files, is obvious.
if (!this.IsActive || !this.IsShowing)
return; // not active!
Avatar avatar = World.Selections.FocusedObject as Avatar;
//need a reference on who to get the health on.
if (avatar != null)
{
_avatarName.Text = avatar.Name;
// We have a player, update his stats
_healthBar.MaxRange = avatar.MaxHitPoints;
_healthBar.Progress = avatar.HitPoints;
}
return;
}
} // end public class MyDemoGui : GuiForm
} // end namespace Visual3D.Demo.Scenes
Sources:
http://game-engine.visual3d.net/forum/showthread.php?t=778 Cullen Ogilvie, Tashi Duane, Chris Bossardet