Hello all, Godot beginner here. I ran into an issue yesterday or so that I am utterly confused on how to solve. Here it is:
I'm using Godot 3.5.1 (stable), linux edition. I am trying to complete the "Your first 3D game" tutorial on the Godot docs using C++ (GDNative) only. Upon completing the "Spawning monsters" section however, my game would crash whenever the onMobTimertimeout() method was called. After various tests, I learned that, for some reason, it was because none of my member variables (random, velocity, minspeed, and maxspeed) could be accessed within my _initialize method, and if I were to remove them (define a local _random inside the method, make _velocity a property and use get("velocity") and set("velocity, ...), and replace minspeed and max_speed with constants [10 and 18]), then the program would not only not crash, but would run like clockwork. Today I did further testing and generated this when I ran Godot from the terminal:
Running: /app/bin/godot-bin --path /home/x/Projects/Godot%20Projects/squashthecreeps/project --remote-debug 127.0.0.1:6007 --allowfocussteal_pid 37 --position 600,270
Godot Engine v3.5.1.stable.flathub.6fed1ffa3 - https://godotengine.org
libGL error: failed to create dri screen
libGL error: failed to load driver: nouveau
OpenGL ES 2.0 Renderer: Mesa Intel(R) UHD Graphics (CML GT2)
ERROR: NativeScriptInstance detected crash on method: onMobTimer_timeout
at: notification (modules/gdnative/nativescript/nativescript.cpp:758)
================================================================
handlecrash: Program crashed with signal 11
Engine version: Godot Engine v3.5.1.stable.flathub (6fed1ffa313c6760fa88b368ae580378daaef0f0)
Dumping the backtrace. Please include this when reporting the bug on: https://github.com/godotengine/godot/issues
[1] /usr/lib/x8664-linux-gnu/libc.so.6(+0x39510) [0x7f15459e8510] ()
[2] godot::RandomNumberGenerator::randfrange(float, float) ()
[3] Mob::initialize(godot::Vector3, godot::Vector3) ()
[4] Main::onMobTimertimeout() ()
[5] godotvariant godot::wrappedmethod<Main, void>(void*, void*, void*, int, godotvariant**) ()
[6] /app/bin/godot-bin() [0xef3e2a] ()
[7] /app/bin/godot-bin() [0x2e60e5e] ()
[8] /app/bin/godot-bin() [0x2e6bad1] ()
[9] /app/bin/godot-bin() [0x2e6c8a3] ()
[10] /app/bin/godot-bin() [0x1faff72] ()
[11] /app/bin/godot-bin() [0x1f562c6] ()
[12] /app/bin/godot-bin() [0x1f6bdfe] ()
[13] /app/bin/godot-bin() [0xaa227a] ()
[14] /app/bin/godot-bin() [0xa10c05] ()
[15] /usr/lib/x86_64-linux-gnu/libc.so.6(libcstart_main+0xf0) [0x7f15459d2b80] ()
[16] /app/bin/godot-bin() [0xa23d6e] ()
-- END OF BACKTRACE --
With all that said, I've tried all I could fathom and I'm still stumped, so maybe some Godot experts can solve my conundrum? My basic questions are as follows:
1. Why did this happen?
2. How do I prevent this from happening in the future?
3. Is this a bug that I should report?
Thanks in advance for any answers all :)
Files:
Mob.hpp:
#ifndef MOB_H
#define MOB_H
#include <Godot.hpp>
#include <KinematicBody.hpp>
#include <RandomNumberGenerator.hpp>
class Mob : public godot::KinematicBody
{
GODOT_CLASS(Mob, godot::KinematicBody)
godot::Vector3 _velocity;
godot::Ref<godot::RandomNumberGenerator> _random;
public:
int min_speed;
int max_speed;
Mob();
~Mob() {}
void _init() {}
void initialize(godot::Vector3, godot::Vector3);
void _on_VisibilityNotifier_screen_exited();
void _physics_process(float);
static void _register_methods();
};
#endif
Mob.cpp:
#include "mob.hpp"
Mob::Mob()
{
_random = (godot::Ref<godot::RandomNumberGenerator>)godot::RandomNumberGenerator::_new();
_random->randomize();
min_speed = 10;
max_speed = 18;
_velocity = godot::Vector3::ZERO;
}
void Mob::_physics_process(float delta)
{
move_and_slide(_velocity);
return;
}
void Mob::initialize(godot::Vector3 start_position, godot::Vector3 player_position)
{
look_at_from_position(start_position, player_position, godot::Vector3::UP);
rotate_y(_random->randf_range(-3.14f / 4, 3.14f / 4));
float random_speed = (float)_random->randf_range(min_speed, max_speed);
_velocity = godot::Vector3::FORWARD * random_speed;
_velocity = _velocity.rotated(godot::Vector3::UP, get_rotation().y);
return;
}
void Mob::_on_VisibilityNotifier_screen_exited()
{
queue_free();
return;
}
void Mob::_register_methods()
{
godot::register_method("_physics_process", &Mob::_physics_process);
godot::register_method("_on_VisibilityNotifier_screen_exited", &Mob::_on_VisibilityNotifier_screen_exited);
godot::register_property("min_speed", &Mob::min_speed, 10);
godot::register_property("max_speed", &Mob::max_speed, 18);
return;
}
Main.hpp:
#ifndef MAIN_H
#define MAIN_H
#include <Godot.hpp>
#include <Node.hpp>
#include <PackedScene.hpp>
#include <RandomNumberGenerator.hpp>
#include <PathFollow.hpp>
#include "player.hpp"
#include "mob.hpp"
class Main : public godot::Node
{
GODOT_CLASS(Main, godot::Node)
godot::Ref<godot::RandomNumberGenerator> _random;
Player * _player;
public:
godot::Ref<godot::PackedScene> mob_scene;
void _init() {}
void _ready();
void _on_MobTimer_timeout();
static void _register_methods();
};
#endif
Main.cpp:
#include "main.hpp"
void Main::_ready()
{
_random = (godot::Ref<godot::RandomNumberGenerator>)godot::RandomNumberGenerator::_new();
_random->randomize();
_player = get_node<Player>("Player");
return;
}
void Main::_on_MobTimer_timeout()
{
// Create new instance of the mob
Mob * mob = static_cast<Mob*>(mob_scene->instance());
// Choose random location on spawn path
godot::PathFollow * mob_spawn_location = get_node<godot::PathFollow>("SpawnPath/SpawnLocation");
// Give spawn location a random offset
mob_spawn_location->set_unit_offset(_random->randf());
godot::Vector3 player_position = _player->get_transform().origin;
mob->initialize(mob_spawn_location->get_translation(), player_position);
add_child(mob);
return;
}
void Main::_register_methods()
{
godot::register_method("_ready", &Main::_ready);
godot::register_method("_on_MobTimer_timeout", &Main::_on_MobTimer_timeout);
godot::register_property("mob_scene", &Main::mob_scene, (godot::Ref<godot::PackedScene>)nullptr);
return;
}