How to create a character3d base class

Godot Version

4.4.1

Question

I have been programming for decades now, but just started with godot and game developent. So I hope this is some simple task, where I just miss a setting.

I have created a simple game with a player (new scene character3d) that always moves forward and can only move up or down. It can collide with a floor, trees and other objects because of the collisionshapes I added.

This is working as it should and all movement logic has been built in an attached script on the player.

But now I want to have a character selection, where you can be either a male or female, with different dimensions, but the same movement.

So I made a new player_wrapper scene (character3d) and added all the movement there. Then I added the old player to this scene as a child. The old player has collision boxes, the wrapper doesnt (because they change based on the player).

Visually it works and movement works at first, but not when there is a collision.

When colliding the player_wrapper doesnt hit anything and keeps moving forward, and inside the wrapper the actual player is stuck behind the object and moves.

Basically the player starts at 0,0 in the wrapper and after a collision the player moves to e.g. -50,0 and after that things become strange obviously, because rotation is skewed.

Is there anyway to uses the players collisionboxes on the wrapper as well?

Somebody suggested changing the player to a collisionshape3d instead of character3d, but that didnt add collision to the wrapper. Maybe it need something else?

Or I could update player position in pshysics bacl to 0,0 but that feels a little hackish.

What would be the proper way to have one movement object and different objects inside? Let’s say a base car class with logic and then a Ferrari, Lamborgini and Hummer scene inside.

What you describe sounds like a very normal use of a base/extended class that shouldn’t present any issues, are you also using inherited scenes?

Can you share a screenshot of your scene trees? You should be able to use the same script for objects with different collision shapes. Did you extend the base player script for different hit boxes?

It;s not an extended class of the script, it’s a script on a character3d scene and inside is another character3d without a script, but with collisions.

wrapper-tree:
The CSGbox isn’t required, but is just an added visual to show what is happening.

wrapper-tree-2

The player will be added by code to the player-wrapper with a simple preload and add_child.

player-tree:
The attached script is not doing anything for the forward movement

When colliding the player is stuck, but the player-wrapper still moves forward

Result on collision:

Having a CharacterBody as a child of another CharacterBody is very strange, as the parent moves the child will not obey physics; maybe you would be better off using an inherited scene from your cartoon_plane, and/or extending that script?

So a CharacterBody3D only collides based on what its direct descendent CollisionShape3Ds looks like, and its own CollisionObject3D settings (in the Inspector). It doesn’t care what collisions its children are having. So you probably want a structure more like this:

In this case the Rig (called Mage Rig) stores all the information about what the Character looks like, as well as the animations. The CharacterBody3D (Player in this example) handles collisions, as well as calling animations, and player input. When you want different appearances, you swap out the Rig.

If you want different collision shapes for your different Rigs, then you’d need a way to get that information from the Rig and apply it to your CharacterBody3D’s CollisionShape3d(s). If you’re getting really complex, then it becomes more complicated.

Let’s say you want a every part of the character to have it’s own CollisionShape3D so you can tell when an arm, leg, head, etc has been hit, and you want the shapes to move with the parts of the body. You’ll have to create PhysicalBone3D nodes for each one, tie them to existing bones, and then have an Area3D hanging off each bone, with the correct CollisionObject3D settings, and a CollisionShape3D hanging off each Area3D. Then you have to have all the signals for the Area3Ds going somewhere.

So you can put all of those on the Rig, then filter what got hit to either a signal or function that the CharacterBody3D gets and filter those collisions up.

1 Like

I have removed the double character3d scenes and have just created a separate player class with all the logic and extend the visual scene with that class. It’s not exactly what I was hoping for, but it works.

What is an “inherited scene” and how would that behave any different then a parent/child structure?

They don’t behave differently.

If you take a look at the screen shot I posted, there are 3 inherited scenes in it. Cameras, StateMachine and Mage Rig. Each of these is its own scene that I have instantiated in my Player scene. You can tell that’s what they are because of the little movie slate icons next to them. Clicking that icon takes you to the original scene, which you can then edit.

You’ll notice all the nodes under Mage Rig are yellow. This is because I have checked Editable Children. This allows me to see and change what’s inside an inherited scene. The yellow tells me that if I change it here, I am changing an instance of the scene, and not the base scene itself.

So with your multiple rigs, you can just have a scene for each, add the one you want when you need it in code, or you can hang them all there and turn them on and off. (Though that will make memory bloat because it still has to be in memory even if it’s not doing anything.)

These are instantiated scenes; you can only inherit from one scene by right-clicking the .tscn file and selecting “New Inherited Scene” which allows you to build on, and keep all of the children and properties of the inherited scene (in yellow), much like instantiated scenes with editable children selected. If you want to build on a physics body a new inherited scene will let you work on one CharacterBody node with different children including collision shapes.

Oh poop, @gertkeno is right. I blame lack of coffee. Thanks @gertkeno!

Honestly, I recommend staying away from inherited scenes. I find them a huge pain in the tuckas. What I prefer to do is create something with a class_name, and then create a new version of it as its own node and then edit that further. Doesn’t work with complex nodes.

Godot prefers composition over inheritance.

Thanks all! Inherited scenes are even more of a hassle for this use case. I’ll stick to the base class and use it as extend.