Hi! I’m new here and I just started learning Godot coming from the Unreal Engine.
I’m currently stuck trying to figure out how to override functions. In my current example, I’m trying to override get_gravity() in a script that extends CharacterBody3D:
class_name Player
extends CharacterBody3D
@onready var gravity_component: GravityComponent = %GravityComponent
func get_gravity() -> Vector3:
var gravity:= Vector3(10, 50, 0) # Random value to test function
print("get_gravity Called")
# my initial code below, currently replaced by the above line for simple testing purpose:
#if gravity_component == null:
#gravity = super.get_gravity()
#else:
#gravity = gravity_component.get_gravity()
return gravity
func _physics_process(delta: float) -> void:
print(get_gravity())
It seems my function is simply being ignored.
What am I doing wrong? Are there functions that can’t be overriden? If so, how to know which are these functions?
The core engine C++ only recognizes overridden functions if they are marked as virtual in the docs. From your tests I’m surprised that there at least isn’t a warning or error.
As an example these top three methods will be called from C++ if overriden
As gertkeno pointed out, only virtual functions can be overriden.
As a general rule, there are also rather few virtual functions in Godot. Generally the design principle is to provide a signal over a virtual function (e.g., pressed signal, not on_pressed virtual function).
This is the type of error/warning you should have recieved:
Error at (4, 1): The method “get_collision_exceptions()” overrides a method from native class “PhysicsBody3D”. This won’t be called by the engine and may not work as expected. (Warning treated as error.)
From an optimization standpoint, I hope you can understand there is a huge difference between a virtual function which may be implemented outside of C++, and a raw C++ function.
Here is an excerpt from the docs, providing some context:
CharacterBody2D bodies detect collisions with other bodies, but are not affected by physics properties like gravity or friction. Instead, they must be controlled by the user via code. The physics engine will not move a character body.
Essentially, you should think of get_gravity as a function you can call, in order to gather gravity information from all sources. Gravity can be effected from a few locations, so this is just the engines way of adding them up for you.
The actual movement code for CharacterBody3D is done via the function move_and_slide and move_and_collide, as well as the setup of the component itself (e.g., floating movement vs. grounded).
Put another way: CharacterBody3D is a pre-configured character controller for you to configure. Some people like that (easy to use), but it’s not infinitely configurable. You have other options at your disposal (e.g., creating a rigid body based controller).
The core engine C++ only recognizes overridden functions if they are marked as virtual in the docs. From your tests I’m surprised that there at least isn’t a warning or error.
From an optimization standpoint, I hope you can understand there is a huge difference between a virtual function which may be implemented outside of C++, and a raw C++ function.
I’m self-thaught (mostly using Unreal blueprint visual scripting, that might have prevented me from doing such errors), initially not a programmer, but I think I get what you mean, that was something I was suspecting. I think I still lack some concepts and vocabulary to easily find what I need.
However, I didn’t get any error/warning.
So, I guess that for my current example, I have to build a parallel gravity system instead of trying to inject my data into the built-in one.
I’m also considering RigidBody, but haven’t tried it yet. I’m still in early investigation on how to handle my character.
Have you tried just… defining the gravity that you need?
You haven’t explained what you need, but Godot offers a bunch of ways of effecting gravity. For example you can change default gravity under project settings. Or you can define an Area3D with it’s own gravity field.
I’ll simply need volumes to locally override gravity. At least these 3 types:
local directional gravity
planet gravity , with a gradient effect
centrifuge (within a cylinder) gravity, with a gradient effect
For now, I have built a “component” that apply gravity on its owner. It’s working well on my character (CharacterBody3D), but I would like to make it compatible for use on other “actors” types that needs gravity (physics objects,…).
It is currently based on the built-in get_gravity() function, so I already have project defaut gravity and planet gravity using Area3D point gravity override. But I’ll have to extend it to include the “centrifuge” gravity type (and gradient effect option), and for this, I feel I have to build my own get_gravity function. Or is there a way to extend on Area3D gravity override?
In Unreal Engine, I already built a gravity system, using component that actually disable the engine built-in gravity and apply my own gravity system gathered from specific volumes (the 3 types: planet gravity, centrifuge (cylinder) gravity, directional gravity). It works fine, but I felt it was a bit hacky to have built it that way (“against” the engine).
It seems Godot provides a more in depth control of everything (at least, it has less assumptions in a blank project), so I initially thought I could extend on the built-in gravity.
But now that I’m learning more about godot, it seems there aren’t nodes that are affected by gravity out of the box (like it is in Unreal Engine), you have to apply it yourself. From there, I feel it is totally ok to build it my way and dismiss the built-in get_gravity() function, if it isn’t already called anywhere.
Still haven’t checked how to build physics object, though.