3D [solved] GMS2 How to move towards z angle

T

trentallain

Guest
Wish there was some from of point_direction_3d(x1,y1,z1,x2,y2,z2), but that wouldn't work. But anyway, I'm trying to somewhat replicate star wars battlefront's spaceship combat (like this:
but not so HD and only with 2 ships, more just gameplay etc) but I am very new to 3D (I pretty much started 2 days ago). I have the camera and model set up, as well as left and right steering.

What I need to add next is vertical movement but I'm not sure what I need to do in order to do that. I have tried:
Code:
//Step (this is all the code in step)
direction = global.pan
speed = -10
z -= lengthdir_y(speed,global.tilt)
z -= lengthdir_y(1, global.tilt+25) * speed
(global.pan is the horizontal camera angle and tilt is the vertical camera angle)

In case it might help I'll also add my other code:
Code:
///Create
format = vertex_format_create_simple(true,true,true)
model = model_load("xwinggms2.dat",format)
texture = sprite_get_texture(spr_texture1,0)
xangle = 0
yangle = 0//180
zangle = 0
draw_set_lighting(true)
draw_light_enable(0,true)
draw_light_define_point(0, x, y, -100, 500, c_white)
z = 0

//3D camera
camera = camera_create()
gpu_set_zwriteenable(true)
gpu_set_ztestenable(true)
projection_matrix = matrix_build_projection_perspective_fov(-60, -view_get_wport(0)/view_get_hport(0), 32, 32000)
camera_set_proj_mat(camera, projection_matrix)
view_set_camera(0, camera)
camera_set_update_script(view_camera[0], camera_update_script)
global.xmove = 0
//
global.pan = 0
global.tilt = 45
global.distance = 1000
global.camerax = lengthdir_x(lengthdir_x(1, global.pan), global.tilt)
global.cameray = lengthdir_x(lengthdir_y(1, global.pan), global.tilt)
global.cameraz = lengthdir_y(1, global.tilt)
Code:
//Draw
draw_light_define_point(0, x, y, -1000, 2000, c_white)
//
matrix_set(matrix_world, matrix_build(x, y, z, global.tilt-180, -yangle, global.pan+90, scale, scale, scale))
vertex_submit(model, pr_trianglelist, texture)
matrix_set(matrix_world, matrix_build(0, 0, 0, 0, 0, 0, 1, 1, 1))
//
Code:
///camera_update_script
if keyboard_check(vk_right)
{
    if global.pan < 360 { global.pan += 1 }
    else { global.pan = 1 }
}

if keyboard_check(vk_left)
{
    if global.pan > 0 { global.pan -= 1 }
    else { global.pan = 359 }
}


if keyboard_check(vk_up)
{
    if global.tilt < 360 {global.tilt += 1 }
    else { global.tilt = 1 }
}

if keyboard_check(vk_down)
{
    if global.tilt > 0 { global.tilt -= 1 }
    else { global.tilt = 359 }
}

global.camerax = lengthdir_x(lengthdir_x(1, global.pan), global.tilt+25)
global.cameray = lengthdir_x(lengthdir_y(1, global.pan), global.tilt+25)
global.cameraz = lengthdir_y(1, global.tilt+25)

up_x = -dsin(global.tilt + 25)*dcos(global.pan);
up_y = dsin(global.tilt + 25)*dsin(global.pan);
up_z = -dcos(global.tilt + 25);

matrixlookat = matrix_build_lookat(obj_xwing.x + global.camerax * global.distance,obj_xwing.y + global.cameray * global.distance,obj_xwing.z + global.cameraz * global.distance,obj_xwing.x,obj_xwing.y,obj_xwing.z, up_x,up_y,up_z)

camera_set_view_mat(view_camera[0], matrixlookat)
So what I'm basically aiming for is to move in the 3D direction I am looking at with the camera.

Also as a side thing, how do I find the position of the laser shooters to shoot the laser at the correct position?
 
Last edited:
K

Kobold

Guest
You know, GameMaker is designed for 2D games.
Its main focus is 2D but you can create pretty amazing 3D games with it. You just need to think outside the box, haha.
Besides that.... I think this: "Game Maker is made for 2D only"-attitude is just an excuse for people who can't stand that you can create more than just a 2D pixel-art game.
Cheers!
 
O

orSQUADstra

Guest
Its main focus is 2D but you can create pretty amazing 3D games with it. You just need to think outside the box, haha.
Besides that.... I think this: "Game Maker is made for 2D only"-attitude is just an excuse for people who can't stand that you can create more than just a 2D pixel-art game.
Cheers!
I can stand it, but only if they would add z, zspeed, lengthdir_z, and such things into gamemaker then it wouldn't be a pain in the A to make a 3D game with it.
 
Last edited:

Nux

GameMaker Staff
GameMaker Dev.
I'm not sure if the view matrices in gamemaker follow this convention, but if you use camera_get_view_mat(my_camera) to get the look-at matrix of your view, you can obtain the camera's "forward" vector. This can be used to move your object in the direction the camera is facing.
To get the forward vector, the x y and z components should be located at indexes 2, 6, and 10 respectively. This is because matrices are stored as single dimension arrays (as described here)
For example:
Code:
var lookat = camera_get_view_mat(my_camera);
var dx = lookat[2];
var dy = lookat[6];
var dz = lookat[10];
x += dx*speed;
y += dy*speed;
z += dz*speed;
Have a look at this resource for more information: https://www.3dgep.com/understanding-the-view-matrix/
 
T

trentallain

Guest
I'm not sure if the view matrices in gamemaker follow this convention, but if you use camera_get_view_mat(my_camera) to get the look-at matrix of your view, you can obtain the camera's "forward" vector. This can be used to move your object in the direction the camera is facing.
To get the forward vector, the x y and z components should be located at indexes 2, 6, and 10 respectively. This is because matrices are stored as single dimension arrays (as described here)
For example:
Code:
var lookat = camera_get_view_mat(my_camera);
var dx = lookat[2];
var dy = lookat[6];
var dz = lookat[10];
x += dx*speed;
y += dy*speed;
z += dz*speed;
Have a look at this resource for more information: https://www.3dgep.com/understanding-the-view-matrix/
Thank you this should help heaps!
Edit: what does dx dy dz look like? Is it an angle because I have a camera vertical angle of +25 to appear slightly more above the ship and changing it dz to take 25 just made it shoot up into the sky hahahaha

Edit: just released its between -1 and 1
Edit 2: I tried dz = lookat[10]-((25/360*100)*sign(lookat[10])) but it didn't work
Edit 3: matrix_direction[10]-degtorad(25) worked, thanks
 
Last edited:
T

trentallain

Guest
but if I were you, I would have the ship's movement and orientation be totally independent from the camera.
I can always experiment a bit. At least now I know how to get the direction the camera is facing, as well as how to move the ship in a 3D direction. Would I build another matrix/invisible camera for the ship or just change dx dy dz? What I'm generally trying to do is the same movement as in the video, so I'll have a little window thing and the ship steers towards it.
 
Last edited:
T

trentallain

Guest
The best option depends on how your ship is able to maneuver. I would use a matrix or quaternion to hold the present orientation of the ship. I tend to find matrices easier to use.
I'm using this in the step event (and the ships x angle also = matrix_direction[10]-degtorad(25)):
Code:
var matrix_direction = camera_get_view_mat(camera)
var dx = matrix_direction[2]
var dy = matrix_direction[6]
var dz = matrix_direction[10]-degtorad(25)

switch (state)
{
    case "move":   
        x += dx*-movespeed
        y += dy*-movespeed
        z += dz*-movespeed       
        break;
        
    case "dodge":
        if dodge_timer > 0
        {
            dodge_timer -= 1
            rotation += 6
        }
        else
        {
            state = "move"
            dodge_timer = 60
            rotation = 0
        }
        break;
}
But if I hold down up/down (which is in the camera_update_script in the first post), the camera doesn't stick to the ship past a certain point and eventually allows me to rotate vertically around the whole ship, when it should be constantly locked at the 25 degree offset. Could you help me find why please?
 

Nux

GameMaker Staff
GameMaker Dev.
Are you able to post some screenshots/̶c̶o̶d̶e̶ ̶o̶f̶ ̶y̶o̶u̶r̶ ̶u̶p̶d̶a̶t̶e̶ ̶s̶c̶r̶i̶p̶t̶? (Sorry I saw your post)
 
Last edited:
T

trentallain

Guest
Are you able to post some screenshots/̶c̶o̶d̶e̶ ̶o̶f̶ ̶y̶o̶u̶r̶ ̶u̶p̶d̶a̶t̶e̶ ̶s̶c̶r̶i̶p̶t̶? (Sorry I saw your post)
It's not really something that can be shown with screenshots because it's a moving thing
 
T

trentallain

Guest
Basically what happens is when traveling horizontally (along x or y, -z is up), the flight is normal, but as soon as it starts going up until its nearly going up vertically, the camera loses control of it and the ship continues its rotation without the camera following it at the correct angle.
 
Top