GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 2017-04-07 00:58:53

LeeH
Member
Registered: 2017-04-07
Posts: 1

3D Custom Model Loading and 3D Collisions!

Hey folks!

So, for this class, we have to use Game Maker. And the project is a first person vehicle simulator. It doesn't necessarily have to be 3D, but that is what we have decided to try and do. I realize Game Maker is not a entirely perfect 3D program when compared with things like Unity or Unreal, but that is a requirement of this class and cannot be avoided.

With that out of the way...

The goods news (everyone!) is after some research and trial and error, I've been able to produce something decent as far as a flight simulator goes.

The game, breifly: A simple flight simulator in 3D where the player is an Apache Helicopter. The player simply has to fly their chopper through rings, which earn them points.

I have most of the game's central systems and structures together, but I have some bugs I have not been able to solve.

First, uploading and adding my own custom models into Game Maker. At the moment my artist has given me gmmod files converted from maya obj files. The object indeed appears in the game, but it doesn't look good at all. I'll provide a screenshot later, but at the moment imgur isn't cooperating. Basically the size of the terrain is way to small, and the texture used for it (currenlty 512 by 512 in size) is not sitting on the object correctly; it's town and distorted to shreds.

Important notes: I want this terrain to be as large as the room, which is massive: 8192 by 6144 (as big as i could get it without crashing memory.)

I have it being drawn by it's own object with a sprite, thinking the size might be tied to the sprite's size. That doesn't seem to be the case. Uploading a version of the model that is the size of the room hasn't been tried, but I have doubts Game Maker could handle that.

Any pointers, suggestions, or solutions for creating custom terrain?
Also, how could I do collisions with said terrain?

And there is my segway into my next issue: collisions.

They work, but not accurately. I followed this tutorial: and the following video in the series concerning switching to 3D.

The issue here is the collision is still detected even when flying a little bit above or to the side of the object, and not just when actually hitting it.  I've tried adjusting the object that represents the apache's size, as well as how the objects for collisions are drawn (x, y, z, values) as well as trying to adjust the collision box. I may not being doing it right, but I can't seem to bug.

Finally, when I want to award points for going through the rings, they add the points AS you collide, meaning as long as you make contact the points are added. I would like these points to be awarded only once. Using flags doesn't seem to help.

Here's my code for collisions. For clarity, note the obj_par_block is actually the terrain I've attempted to load, while the obj_par_ring is the ring, and the obj_par_blockTest are floating blocks I use to test collisions for crashing. I'll also post my code for how the objects that need colliding are drawn.

----------------------------------------------------------------------------------------------------------------------------

Collision Code:
///Collisions

if (!place_meeting_ext(x + x_vel, y, z, obj_par_block)) {
    x += x_vel
    } else {
        // start taking our "baby steps" one pixel at a time until we eventually collide.
        while (!place_meeting_ext(x + sign(x_vel), y, z, obj_par_block)) {
            x += sign(x_vel);
            }
        // we have broken out of the while loop so we must be at the solid. now stop.
        x_vel = 0;
        room_goto(room_boom);
}
if (!place_meeting_ext(x, y + y_vel, z, obj_par_block)) {
    y += y_vel
    } else {
      while (!place_meeting_ext(x + sign(x_vel), y, z, obj_par_block)) {
            y += sign(y_vel);
            }
        x_vel = 0;
        room_goto(room_boom);
        }
   
//Rings 
       
if (!place_meeting_ext(x + x_vel, y, z, obj_par_ring)) {
    x += x_vel
    pointAwarded = false;
    } else {
          while (!place_meeting_ext(x + sign(x_vel), y, z, obj_par_ring)) {
            x += sign(x_vel);
            }
            pointAwarded = true;
        if (pointAwarded == true)
        {
            global.score += 5;
            pointAwarded = false;
        }
        pointAwarded = false;
}
if (!place_meeting_ext(x, y + y_vel, z, obj_par_ring)) {
    y += y_vel
    pointAwarded = false;
    } else {
          while (!place_meeting_ext(x + sign(x_vel), y, z, obj_par_ring)) {
            y += sign(y_vel);
            }
            pointAwarded = true;
        if (pointAwarded == true)
        {
            global.score += 5;
            pointAwarded = false;
        }
        pointAwarded = false;
    }
       
//Test stuff
     
if (!place_meeting_ext(x + x_vel, y, z, obj_blockTest)) {
    x += x_vel
    } else {
        // start taking our "baby steps" one pixel at a time until we eventually collide.
        while (!place_meeting_ext(x + sign(x_vel), y, z, obj_blockTest)) {
            x += sign(x_vel);
            }
        // we have broken out of the while loop so we must be at the solid. now stop.
        x_vel = 0;
        room_goto(room_boom);
}
if (!place_meeting_ext(x, y + y_vel, z, obj_blockTest)) {
    y += y_vel
    } else {
      while (!place_meeting_ext(x + sign(x_vel), y, z, obj_blockTest)) {
            y += sign(y_vel);
            }
        x_vel = 0;
        room_goto(room_boom);
        }
-------------------------------------------------------------------------------------------------------
Drawing the test blocks:
d3d_draw_block(x, y, z, x+32, y+32, z+32, background_get_texture(crate), 1, 1)
-----------------------------------------------------------------------------------------------------

Drawing the rings(as blocks for the moment):
d3d_draw_block(x, y, z, x+60, y+60, z+60, background_get_texture(ring), 1, 1);
----------------------------------------------------------------------------------------------------------------

Drawn projection for the obj_camera (which represents the chopper):

d3d_set_projection(x, y, z+height, x+cos(degtorad(direction)), y-sin(degtorad(direction)), z-sin(degtorad(pitch))+height, 0, 0, 1);

---------------------------------------------------------------------------------------------------------------------------

Just in case, I'm throwing in the code for movement:
window_set_cursor(cr_none);
direction -= sensitivity * (display_mouse_get_x() - display_get_width() * 0.5);
pitch += sensitivity * (display_mouse_get_y() - display_get_height() * 0.5);

//limit the pitch
pitch = clamp(pitch, -10, 20);

display_mouse_set(display_get_width()/2, display_get_height()/2);

if (keyboard_check(vk_escape))
    game_end();

var d=degtorad(direction);

xspeed = 0;
yspeed = 0;
zspeed = 0;

var fbKeys = keyboard_check(ord('W')) - keyboard_check(ord('S'));
var rlKeys = keyboard_check(ord('D')) - keyboard_check(ord('A'));
var udKeys = keyboard_check(ord('X')) - keyboard_check(vk_space);

fb_vel += fbKeys * acc;
rl_vel += rlKeys * acc;
ud_vel += udKeys * acc;

//limit the speeds
fb_vel = clamp(fb_vel, -max_spd, max_spd);
rl_vel = clamp(rl_vel, -max_spd, max_spd);
ud_vel = clamp(ud_vel, -max_spd, max_spd);

//Decelerate if moving and no keys pressed

if (fbKeys == 0 && abs(fb_vel) >= acc)
{
    fb_vel -= sign(fb_vel) * acc;
}

if (rlKeys == 0 && abs(rl_vel) >= acc)
{
    rl_vel -= (sign(rl_vel) * (acc)) * 2;
}
if (udKeys == 0 && abs(ud_vel) >= acc)
{
    ud_vel -= sign(ud_vel) * acc;
}

//tilt cockpit down or up based on direction
if (keyboard_check(ord('W')) && (pitch < 20))
{
    pitch += .5;
}

if (keyboard_check(ord('S')) && (pitch > 5))
{
    pitch -= .5;
}

// Translate the velocities in terms of x and y
var x_vel = lengthdir_x(fb_vel, direction) + lengthdir_x(rl_vel, direction - 90);
var y_vel = lengthdir_y(fb_vel, direction) + lengthdir_y(rl_vel, direction - 90);
var z_vel = lengthdir_y(ud_vel, direction) + lengthdir_y(ud_vel, direction - 90);


x += x_vel;
y += y_vel;

//contollers for a more instantanous response to direction change...

switch (keyboard_key)
{
    case vk_space:
        height+=8;
        break;
    case ord('X'):
        height-=8;
        break;
}

x += xspeed;
y += yspeed;

------------------------------------------------------------------------------------------------------------------------

I've got to get this sucker nice and polished by Tuesday night, and present it in class Wednesday evening.
Any and all advice, suggestions and help will be hugely appreciated!

Please let me know if you need any more information, and I'll provide it asap.

Thanks guys!
Lee H

Last edited by LeeH (2017-04-07 01:08:23)

Offline

#2 2017-04-07 21:10:36

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

Re: 3D Custom Model Loading and 3D Collisions!

Even if you had come to me two weeks ago, I couldn't do your homework for you.

Good luck.


Abusing forum power since 1986.

Offline

Board footer

Powered by FluxBB