Skip to main content
added a possible solution
Source Link

To elaborate on the workaround I suggested in the end, I have now implemented it like this:

Right below my main scene root, I have added a Node2D and attached InputControl.cs to it. On that node, I have added a metadata value named PlayerNode of type NodePath and assigned my Spaceship node from the same scene to it.

Node2D
 |- Spaceship + (whatever script is attached in the scene)
     |- RemoteTransform2D
 |- Node2D + InputControl.cs

The InputControl class now inherits from Node2D and has a Player property of type RigidBody2D that is used as the target of my calls to ship movement methods. I initialize the object as follows:

public override void _Ready()
{
    var player = GetNode(GetMeta("PlayerNode").AsNodePath()) as RigidBody2D;
    if (player == null)
    {
        throw new InvalidOperationException("Player object not found.");
    }

    Player = player;
}

This works, is easy to implement (once you know what API methods to use) and it's easy to understand, still - being a total beginner in Godot - I wonder whether this is the way we're supposed to use Godot?


To elaborate on the workaround I suggested in the end, I have now implemented it like this:

Right below my main scene root, I have added a Node2D and attached InputControl.cs to it. On that node, I have added a metadata value named PlayerNode of type NodePath and assigned my Spaceship node from the same scene to it.

Node2D
 |- Spaceship + (whatever script is attached in the scene)
     |- RemoteTransform2D
 |- Node2D + InputControl.cs

The InputControl class now inherits from Node2D and has a Player property of type RigidBody2D that is used as the target of my calls to ship movement methods. I initialize the object as follows:

public override void _Ready()
{
    var player = GetNode(GetMeta("PlayerNode").AsNodePath()) as RigidBody2D;
    if (player == null)
    {
        throw new InvalidOperationException("Player object not found.");
    }

    Player = player;
}

This works, is easy to implement (once you know what API methods to use) and it's easy to understand, still - being a total beginner in Godot - I wonder whether this is the way we're supposed to use Godot?

added 328 characters in body
Source Link

But then, it seems that it would be my Spaceship scene flying around in this wrapping node rather than in the global space. That doesn't seem right. Or, looking at it differently, that would mean I could just as well handle input in a script on the main scene's root node (or anywhere else in the scene) and just notify the player object about the input. This will work, but is it the intended way to use Godot?

But then, it seems that it would be my Spaceship scene flying around in this wrapping node rather than in the global space. That doesn't seem right. Or, looking at it differently, that would mean I could just as well handle input in a script on the main scene's root node (or anywhere else in the scene) and just notify the player object about the input. This will work, but is it the intended way to use Godot?

added 447 characters in body
Source Link

What node types How to use for astructure my composite (player) object with regard to attaching scripts?

While learning about the Godot engine, I am trying to write a simple spaceships game.

A spaceship, as I have found out, can be defined as a scene of its own, with the following internal structure:

RigidBody2D            // the root of the scene
 |- Sprite2D           // the image representing the spaceship
 |- CollisionPolygon2D // the collision shape

Now, I can add this "Spaceship" scene into my main game scene, which then looks like this:

Node2D
 |- Spaceship             // instance of the above scene
     |- RemoteTransform2D // makes the camera follow the ship

In here, I have attached a C# script on the Spaceship node that does a simple check for input and calls methods like AddConstantCentralForce and AddConstantTorque n its _Process method to move the ship according to player input.:

Node2D
 |- Spaceship + InputControl.cs
     |- RemoteTransform2D

So far, this works fine.

Problem: I also need (?) to attach a script to the root node of my Spaceship scene. That is because I want to dynamically add some additional nodes in there, depending on what is happening in the game, and I think the root object of the scene would be the appropriate place to handle this logic.:

RigidBody2D + ManageShip.cs
 |- Sprite2D
 |- CollisionPolygon2D

But if I do this, it has no effect - the script on the root node of the Spaceship scene is replaced by the script on the Spaceship node in my main scene.

Possible alternatives:

  • I do not want to integrate the input control script into the Spaceship scene, because only the player ship should be controlled like this, whereas I want to reuse the Spaceship scene also for enemy ships.
  • I have tried to wrap the Spaceship node in a Node2D node in my main scene, but then I cannot attach my input control script because Node2D does not have the methods like AddConstantCentralForce.:
    Node2D
     |- Node2D + InputControl.cs
         |- Spaceship
             |- RemoteTransform2D
    
  • I have tried to wrap the Spaceship node in a RigidBody2D node instead, but then, my input seems to have no effect because that RigidBody2D itself has no mass and/or shape (as is also pointed out by the Godot IDE with a warning symbol).:
    Node2D
     |- RigidBody2D + InputControl.cs
         |- Spaceship
             |- RemoteTransform2D
    

What node type should I use instead? Is there a scene design guideline by Godot for this?

Is the solution maybe to wrap Spaceship in just a Node2D and rewrite the input control script to find the nested RigidBody2D and call the methods on that instance?

What node types to use for a composite object with regard to attaching scripts?

While learning about the Godot engine, I am trying to write a simple spaceships game.

A spaceship, as I have found out, can be defined as a scene of its own, with the following internal structure:

RigidBody2D            // the root of the scene
 |- Sprite2D           // the image representing the spaceship
 |- CollisionPolygon2D // the collision shape

Now, I can add this "Spaceship" scene into my main game scene, which then looks like this:

Node2D
 |- Spaceship
     |- RemoteTransform2D // makes the camera follow the ship

In here, I have attached a C# script on the Spaceship node that does a simple check for input and calls methods like AddConstantCentralForce and AddConstantTorque n its _Process method to move the ship according to player input.

So far, this works fine.

Problem: I also need (?) to attach a script to the root node of my Spaceship scene. That is because I want to dynamically add some additional nodes in there, depending on what is happening in the game, and I think the root object of the scene would be the appropriate place to handle this logic.

But if I do this, it has no effect - the script on the root node of the Spaceship scene is replaced by the script on the Spaceship node in my main scene.

Possible alternatives:

  • I do not want to integrate the input control script into the Spaceship scene, because only the player ship should be controlled like this, whereas I want to reuse the Spaceship scene also for enemy ships.
  • I have tried to wrap the Spaceship node in a Node2D node in my main scene, but then I cannot attach my input control script because Node2D does not have the methods like AddConstantCentralForce.
  • I have tried to wrap the Spaceship node in a RigidBody2D node instead, but then, my input seems to have no effect because that RigidBody2D itself has no mass and/or shape (as is also pointed out by the Godot IDE with a warning symbol).

What node type should I use instead? Is there a scene design guideline by Godot for this?

Is the solution maybe to wrap Spaceship in just a Node2D and rewrite the input control script to find the nested RigidBody2D and call the methods on that instance?

How to structure my composite (player) object?

While learning about the Godot engine, I am trying to write a simple spaceships game.

A spaceship, as I have found out, can be defined as a scene of its own, with the following internal structure:

RigidBody2D            // the root of the scene
 |- Sprite2D           // the image representing the spaceship
 |- CollisionPolygon2D // the collision shape

Now, I can add this "Spaceship" scene into my main game scene, which then looks like this:

Node2D
 |- Spaceship             // instance of the above scene
     |- RemoteTransform2D // makes the camera follow the ship

In here, I have attached a C# script on the Spaceship node that does a simple check for input and calls methods like AddConstantCentralForce and AddConstantTorque n its _Process method to move the ship according to player input:

Node2D
 |- Spaceship + InputControl.cs
     |- RemoteTransform2D

So far, this works fine.

Problem: I also need (?) to attach a script to the root node of my Spaceship scene. That is because I want to dynamically add some additional nodes in there, depending on what is happening in the game, and I think the root object of the scene would be the appropriate place to handle this logic:

RigidBody2D + ManageShip.cs
 |- Sprite2D
 |- CollisionPolygon2D

But if I do this, it has no effect - the script on the root node of the Spaceship scene is replaced by the script on the Spaceship node in my main scene.

Possible alternatives:

  • I do not want to integrate the input control script into the Spaceship scene, because only the player ship should be controlled like this, whereas I want to reuse the Spaceship scene also for enemy ships.
  • I have tried to wrap the Spaceship node in a Node2D node in my main scene, but then I cannot attach my input control script because Node2D does not have the methods like AddConstantCentralForce:
    Node2D
     |- Node2D + InputControl.cs
         |- Spaceship
             |- RemoteTransform2D
    
  • I have tried to wrap the Spaceship node in a RigidBody2D node instead, but then, my input seems to have no effect because that RigidBody2D itself has no mass and/or shape (as is also pointed out by the Godot IDE with a warning symbol):
    Node2D
     |- RigidBody2D + InputControl.cs
         |- Spaceship
             |- RemoteTransform2D
    

What node type should I use instead? Is there a scene design guideline by Godot for this?

Is the solution maybe to wrap Spaceship in just a Node2D and rewrite the input control script to find the nested RigidBody2D and call the methods on that instance?

Source Link
Loading