Game Development Community

NullReferenceException on loading level

by Levi Putna · in Torque X Platformer Kit · 01/05/2009 (10:23 pm) · 10 replies

I recently implemented my menu system, however when I try and load the game via the "New Game" menu button I get an NullReferenceException on
float distance = Vector2.Distance((_actorComponent.SceneObject.SceneGraph.Camera as T2DSceneCamera).Position, _actorComponent._animatedSprite.Position);
in protected virtual void _playAnimation(T2DAnimationData animation, uint frameIndex) method in ActorAnimationManager.cs

The Exception Message
System.NullReferenceException was unhandled
  Message="Object reference not set to an instance of an object."
  Source="PlatformerFramework"
  StackTrace:
at GarageGames.Torque.PlatformerFramework.ActorComponent.ActorAnimationManager._playAnimation(T2DAnimationData animation, UInt32 frameIndex) in C:\Users\Levi Putna\Documents\Visual Studio 2005\Projects\thepagemaster\thepagemaster\PlatformerFramework\ActorAnimationManager.cs:line 440
       
[...]

I have modified my BeginRun() method in game.cs removing the load game section and replacing it with its own method RunLevel().

BeginRun()
protected override void BeginRun()
        {
            base.BeginRun();

            // load splash screen
            SplashScreen splashScreen = new SplashScreen();
            GUIStyle splashStyle = new GUIStyle();
            GUISceneview splash = new GUISceneview();
            splash.Style = splashStyle;
            GUICanvas.Instance.SetContentControl("SplashScreen");

            // register sound groups
            ...

            // grab the sound categories
            ...

            // start music loop
            ...
        }

RunLevel()
public void RunLevel(int level)
        {
            
            switch (level)
            {
                case 0:
                    SceneLoader.Load(@"data\levels\level_template.txscene");
                    break;
                case 1:
                    SceneLoader.Load(@"data\levels\level_template.txscene");
                    break;
                default:
                    SceneLoader.Load(@"data\levels\level_template.txscene");
                    break;
            }

            // set the parallax manager's target object
            camera = TorqueObjectDatabase.Instance.FindObject<T2DSceneCamera>("Camera");
            ParallaxManager.Instance.ParallaxTarget = camera;
            _sceneGraph = camera.SceneGraph as T2DSceneGraph;

            //create game gui
            GUIStyle playStyle = new GUIStyle();
            GUISceneview play = new GUISceneview();
            play.Name = "PlayScreen";
            play.Style = playStyle;
            play.Camera = camera;

            GUICanvas.Instance.SetContentControl(play);
            PlatformerDemoGUI.Instance.GUI.Folder = GUICanvas.Instance;
            

            // game start
            _gameStart = Time;

            //Play Background music
            _music = SoundManager.Instance.PlaySound(_musicSoundGroup, _outdoorMusic);

            // play the dragon's startup sound for the first time
            SoundManager.Instance.PlaySound("grass", "startup");
        }

I am not sure what is causing this error therefore am not sure how to resolve it.

If anyone has any suggestions it would be much appreciated.

Thanks,
Levi

#1
01/06/2009 (11:36 am)
Can I ask which variable is null?
#2
01/06/2009 (8:18 pm)
The Exception is on (_actorComponent.SceneObject.SceneGraph.Camera as T2DSceneCamera).Position

If I comment this line out the exception will be thrown on the next reference to Camera.

If I call RunLevel() from the splash screen and not the menu it works fine, however it I hit space while the splash screen is active I get the same exception.

very confusing.
#3
01/07/2009 (5:11 am)
If the camera is null then maybe the menu code is clearing the camera that you have setup in the "RunLevel()". Is the SceneGraph losing the camera that was attached to it?
#4
01/07/2009 (6:31 am)
That was my thinking at first, I don't know a great deal about the camera system but to my understanding I am setting up the camera in the RunLevel() method (see above). RunLevel() is called by the menu, after it is all finished with any code that could possibly effect the camera.

From my understanding this code is all that is needed to initalize the camera and set it to follow the player.

// set the parallax manager's target object
            camera = TorqueObjectDatabase.Instance.FindObject<T2DSceneCamera>("Camera");
            ParallaxManager.Instance.ParallaxTarget = camera;
            _sceneGraph = camera.SceneGraph as T2DSceneGraph;

            //create game gui
            GUIStyle playStyle = new GUIStyle();
            GUISceneview play = new GUISceneview();
            play.Name = "PlayScreen";
            play.Style = playStyle;
            play.Camera = camera;

            GUICanvas.Instance.SetContentControl(play);
            PlatformerDemoGUI.Instance.GUI.Folder = GUICanvas.Instance;
#5
01/07/2009 (7:33 am)
This is a copy of my menu code, I removed a bit of the duplicated button code to keep the character count under the forum max. If you can see anything that would effect the camera system please let me know.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using GarageGames.Torque.Platform;
using GarageGames.Torque.Core;
using GarageGames.Torque.Core.Xml;
using GarageGames.Torque.Sim;
using GarageGames.Torque.GUI;
using GarageGames.Torque.MathUtil;
using GarageGames.Torque.T2D;

using GarageGames.Torque.PlatformerFramework;

namespace GarageGames.Torque.PlatformerDemo
{
    class GuiStartMenu
    {

        public GuiStartMenu()
        {
            _createStartMenuGUI();
        }

        public void ToggleMenu()
        {
            if (_root == null)
                return;

            if (_root.Folder == GUICanvas.Instance)
            {
                GUICanvas.Instance.PopDialogControl(_root);
            }
            else
            {
                GUICanvas.Instance.PushDialogControl(_root, 50);
                _currentSelection = 0;
                _button1.Visible = true;
            }
        }

        public void MoveDown()
        {
            _buttonModeList[_currentSelection].Visible = false;
            _currentSelection = _currentSelection < (_buttonModeList.Length - 1) ? _currentSelection + 1 : (_buttonModeList.Length - 1);
            _buttonModeList[_currentSelection].Visible = true;
        }

        public void MoveUp()
        {
            _buttonModeList[_currentSelection].Visible = false;
            _currentSelection = _currentSelection > 0 ? _currentSelection - 1 : 0;
            _buttonModeList[_currentSelection].Visible = true;
        }

        public void SELECT()
        {
            ToggleMenu();

            switch (_currentSelection)
            {
                case 0:
                    GarageGames.Torque.PlatformerDemo.Game.Instance.RunLevel(0);
                    break;
                case 2:
                    GuiStartMenu _StartMenu = new GuiStartMenu();
                    GUICanvas.Instance.SetContentControl("OptionsMenu");
                    break;
                case 3:
                    GarageGames.Torque.PlatformerDemo.Game.Instance.Exit();
                    break;
            }
        }
        private void _createStartMenuGUI()
        {

            #region background
            GUIStyle baseStyle = new GUIStyle();
            baseStyle.Focusable = true;
            GUIBitmapStyle bitmapStyle = new GUIBitmapStyle();
            bitmapStyle.SizeToBitmap = true;

            _root = new GUIControl();
            _root.Style = baseStyle;
            _root.Layer = 50;
            _root.FocusOnWake = true;
            _root.Visible = true;
            _root.Name = "StartMenu";

            GUIBitmap baseFrame = new GUIBitmap();
            baseFrame.Style = bitmapStyle;
            baseFrame.HorizSizing = HorizSizing.Center;
            baseFrame.VertSizing = VertSizing.Center;
            baseFrame.Bitmap = @"data\images\gui\mainMenu_back";
            baseFrame.Size = new Vector2(Game.Instance.Window.ClientBounds.Width, Game.Instance.Window.ClientBounds.Height); //*1.5
            baseFrame.Visible = true;
            baseFrame.Folder = _root;

            Vector2 btnPosition = new Vector2(560, 100);
            switch (Game.Instance.Window.ClientBounds.Height)
            {
                case 1080:
                    btnPosition = new Vector2(btnPosition.X * 1.5f, btnPosition.Y * 1.5f);
                    break;
                case 720:
                    // btnPosition = btnPosition; //1
                    break;
                case 480:
                    btnPosition = new Vector2(btnPosition.X / 1.77f, btnPosition.Y / 1.77f);
                    break;
            }

            GUIBitmap button1 = new GUIBitmap();
            button1.Style = bitmapStyle;
            button1.Bitmap = @"data\images\gui\mainMenu_newGame_normal";
            button1.Position = btnPosition;
            button1.Visible = true;
            switch (Game.Instance.Window.ClientBounds.Height)
            {
                case 1080:
                    button1.Size = new Vector2(button1.Size.X * 1.5f, button1.Size.X * 1.5f);
                    break;
                case 720:
                    //Do nothing
                    break;
                case 480:
                    button1.Size = new Vector2(button1.Size.X / 1.77f, button1.Size.X / 1.77f);
                    break;
            }

            button1.Folder = baseFrame;


            _button1 = new GUIBitmap();
            _button1.Style = bitmapStyle;
            _button1.Bitmap = @"data\images\gui\mainMenu_newGame_hover";
            _button1.Position = btnPosition;
            _button1.Visible = false;
            button1.Visible = true;
            switch (Game.Instance.Window.ClientBounds.Height)
            {
                case 1080:
                    _button1.Size = new Vector2(_button1.Size.X * 1.5f, _button1.Size.X * 1.5f);
                    break;
                case 720:
                    //Do nothing
                    break;
                case 480:
                    _button1.Size = new Vector2(_button1.Size.X / 1.77f, _button1.Size.X / 1.77f);
                    break;
            }
            _button1.Folder = baseFrame;

            _buttonModeList[0] = _button1;

            
           //...

           //Button 2, 3, 4
           //same code as button one but with different image

          //...

            _InitInputMap();

            ToggleMenu();
        }

        protected void _InitInputMap()
        {
            InputMap input = new InputMap();
            for (int i = 0; i < 4; i++)
            {
                int gamepadId = InputManager.Instance.FindDevice("gamepad" + i);
                if (gamepadId >= 0)
                {
                    input.BindCommand(gamepadId, (int)XGamePadDevice.GamePadObjects.Back, ToggleMenu, null);
                    input.BindCommand(gamepadId, (int)XGamePadDevice.GamePadObjects.Up, MoveUp, null);
                    input.BindCommand(gamepadId, (int)XGamePadDevice.GamePadObjects.Down, MoveDown, null);
                    input.BindCommand(gamepadId, (int)XGamePadDevice.GamePadObjects.A, SELECT, null);
                }
            }

            int keyboardId = InputManager.Instance.FindDevice("keyboard");
            input.BindCommand(keyboardId, (int)Microsoft.Xna.Framework.Input.Keys.S, MoveDown, null);
            input.BindCommand(keyboardId, (int)Microsoft.Xna.Framework.Input.Keys.W, MoveUp, null);
            input.BindCommand(keyboardId, (int)Microsoft.Xna.Framework.Input.Keys.Space, SELECT, null);

            input.BindCommand(keyboardId, (int)Microsoft.Xna.Framework.Input.Keys.Escape, ToggleMenu, null);

            _root.InputMap = input;
        }

        GUIControl _root;
        GUIBitmap _button1;
        GUIBitmap _button2;
        GUIBitmap _button3;
        GUIBitmap _button4;
        GUIBitmap[] _buttonModeList = new GUIBitmap[4];
        int _currentSelection;
    }
            #endregion
}
#6
01/07/2009 (5:14 pm)
Ok I have tracked the problem down to this line

T2DSceneCamera camera = TorqueObjectDatabase.Instance.FindObject("Camera");

TorqueObjectDatabase.Instance.FindObject("Camera"); doesn't seem to be assigning any value to the camera, and only on the levels I have created.

All levels I have created have the same reference to Camera as the template levels.

<Camera2D name="Camera">
			<CenterPosition>
				<X>-1825.125244</X>
				<Y>-231.530167</Y>
			</CenterPosition>
			<Extent>
				<X>100.000000</X>
				<Y>75.000000</Y>
			</Extent>
			<ResizeToDisplayAspectRatioWithFixedWidth>true</ResizeToDisplayAspectRatioWithFixedWidth>
			<UseCameraWorldLimits>false</UseCameraWorldLimits>
		</Camera2D>

Is there the object the camera code above is looking for? do I need to check for anything else in the level?
#7
01/08/2009 (5:14 am)
In the level's that came with the kit, there is some kind of reference to the word "Camera"

camera = TorqueObjectDatabase.Instance.FindObject<T2DSceneCamera>("Camera");

That might be written in the xml file somewhere. It's not in the xml code above.
#8
01/08/2009 (3:04 pm)
Got It...

After many many many hours if digging, I discovered that the probe was caused by my player. I had replaced the tutorial player character with my own flowing the steps in the documentation, however the documentation character has no mention of Animation Transitions. My character doesn't need them however if I added some very quick transitions in the problem was resolved.

I don't know why Animation Transitions only effected the game after I added a menu, my guess is that it had something to do with the key press.
#9
01/08/2009 (6:03 pm)
Rrrrr,

Ok I am getting the same error when I create my own enemy (following the tutorial instructions, with Animation Transitions).

I still don't understand why this is effecting the camera.
#10
01/20/2009 (1:21 am)
This is a problem that I and others have been having. As yet I haven't seen any postings where someone has got this to work.

Have a look here

If anyone has managed to load new levels in the PSK please put us all out of our misery.