How-to follow a model/object with BirdEyeView?

Nov 14, 2012 at 5:58 PM

Hey all,

I'm struggling with Engine Nine in XNA.
I followed the CreateASimple3DGame tutorial and now I've got a 'controlable' tank.
It can 'drive' forward, without collisions and such.

So now I was looking into the camera's of Engine Nine, I want the camera to stick behind it.
Therefor I was looking in the object browser and found that BirdEyeView can make use of something called 'LookAt'.

How can I use 'LookAt'? 

On a quick side note, if you add a model via XAML, how can you make it 'moveable'?
At this moment I used scene.Add() with the Tank as a model, but XAML is a bit more organized, however I haven't got the slightest clue how I can interact with it in XAML.

Regards,
Stefan 

Developer
Nov 14, 2012 at 6:20 PM
Edited Nov 14, 2012 at 6:22 PM

First Argument (Camera)

"BirdEyeCamera provides a bird-eye view of the scene. Use the right mouse button the pan the camera. Use the wheel button to zoom in and out. Hold down the mouse middle button to rotation the camera."

So it is easy to change what it looks at with the variable 'LookAt' that is an Vector3. Currently there are no features that you can disable camera movement. So personally I would recommend downloading the source or just look it up with the help of Codeplex code lookup feature. And then make a own.

 

Second Argument (Make Objects Movable)

If you download the example there are  a Component that is built in an external dll.

 

public class ExampleController : Component, Nine.IUpdateable
{
	public float Speed { get; set; }

	public void Update(TimeSpan elapsedTime)
	{
		var transform = Parent.Transform;

		var keyboardState = Keyboard.GetState();
		if (keyboardState.IsKeyDown(Keys.Left))
			transform.Translation += Speed * (float)elapsedTime.TotalSeconds * Vector3.Left;
		if (keyboardState.IsKeyDown(Keys.Right))
			transform.Translation += Speed * (float)elapsedTime.TotalSeconds * Vector3.Right;
		if (keyboardState.IsKeyDown(Keys.Down))
			transform.Translation += Speed * (float)elapsedTime.TotalSeconds * Vector3.Backward;
		if (keyboardState.IsKeyDown(Keys.Up))
			transform.Translation += Speed * (float)elapsedTime.TotalSeconds * Vector3.Forward;

		Parent.Transform = transform;
	}
}

 

This can then be imported to Xaml by adding something like this 'xmlns:my="clr-namespace:TutorialData;assembly=TutorialData"'. This should be in the '<Scene ... >'.

 

The other way is the do something like defining your object in Xaml by a Name. This make it easy to just use 'scene.FindName<T>("Name")' 

If you would go this approach I would recommend by putting the object in a parent(Group) and transform it.

 

<Group Name="Player">
// Your Stuff
<Group>

Example in Code:

Group player = scene.FindName("Player");

// Something like this then in update
player.Transform.Translation += Speed * (float)elapsedTime.TotalSeconds * Vector3.Left;

 

I hope this helped :)

 

Eric

Nov 14, 2012 at 6:52 PM

Great!
Thanks alot!

I will try and create my own 'Chasing Camera' then.

I got the 'Tank' in my case moving now, however I want to rotate it by pressing Left and Right.

In the code below I tried to rotate it, but it goes crazy and drives in these circles.
How can I rotate it around it's own axis? 

var tank = scene.FindName<Transformable>("MyTank");
            if (Keyboard.GetState().IsKeyDown(Keys.Up))
            {
                tank.Transform *= Matrix.CreateTranslation(0, 0, 0.1f);
            }
            if (Keyboard.GetState().IsKeyDown(Keys.Down))
            {
                tank.Transform *= Matrix.CreateTranslation(0, 0, -0.1f);
            }
            if (Keyboard.GetState().IsKeyDown(Keys.Right))
            {
                tank.Transform *= Matrix.CreateRotationY(MathHelper.ToRadians(1));
            }
            if (Keyboard.GetState().IsKeyDown(Keys.Left))
            {
                tank.Transform *= Matrix.CreateRotationY(MathHelper.ToRadians(-10));
            }

 

Thanks !

Developer
Nov 14, 2012 at 7:13 PM

If you go by the approach of making a group and moving the group, then your transform's should be on the group and not the model. 

Currently you have so that the group is on (0,0,0) so your rotation the model around that point.

Nov 15, 2012 at 1:59 PM

I'm still not quite getting the hang of scenes.
I've now created a class called Tank, and I'm trying to put the controls for the tank in there.

This is my Tank.cs at the moment:

    class Tank : Component, Nine.IUpdateable
    {
        public float Speed { get; set; }

        public void Update(TimeSpan elapsedTime)
        {
            Group tank = scene.FindName<Group>("Tank");

            var transform = Parent.Transform;
            var keyboardState = Keyboard.GetState();
            if (keyboardState.IsKeyDown(Keys.Left))
                transform.Translation += Speed * (float)elapsedTime.TotalSeconds * Vector3.Left;
            if (keyboardState.IsKeyDown(Keys.Right))
                transform.Translation += Speed * (float)elapsedTime.TotalSeconds * Vector3.Right;
            if (keyboardState.IsKeyDown(Keys.Down))
                transform.Translation += Speed * (float)elapsedTime.TotalSeconds * Vector3.Backward;
            if (keyboardState.IsKeyDown(Keys.Up))
                transform.Translation += Speed * (float)elapsedTime.TotalSeconds * Vector3.Forward;
            
            Parent.Transform = transform;
        }
    }
}

 

The thing is, it won't find Scene, and I have no idea how to fix this other then loading it again in the Tank class.
Also what does Parent.Transform do?
I tried using tank.Transform.Translation and I got an error regarding it doesn't return a variable, so I'm not allowed to change it.

I hope I'm on the right way, because this is all really new to me.



Stefan. 

Developer
Nov 15, 2012 at 8:11 PM
Edited Nov 15, 2012 at 8:14 PM

This should be created in a separate project that export an Dll and I am sorry the code I did provided in the Component was a WIP before 1.4 release. 

In 1.4 the update is implemented in the Component ( File Example )

Xaml Example

Coordinator
Nov 16, 2012 at 2:45 AM

There was a change in the Component class. You should not implement Nine.IUpdateable in your Tank class, instead, override the base Update method. This way, the scene will be properly initialized. See the above example file provided by ChFlashER.