Player doesnt collide with the box and can walk through it or past it as this is a platformer.
Trying to achieve: When the player is next to the left or right edge of the box and holds down the action key for a set peroid of time, the player will move the box depending on which directional key is also pressed.
Current:
area2d(leftsideedge) collision box setup from the edge and extrudes out left and is connected to a signal on_body_entered and exited. This has a print statement stating entered and exited. (working)
area2d(rightsideedge) collision box setup from the edge and extrudes out right and is connected to a signal on_body_entered and exited. This has a print statement stating entered and exited. (working)
I have a input action timer also which is as follows,
elif Input.is_action_pressed(“action_key”):
action_hold_time += _delta
if action_hold_time >= HOLD_ACTION_THRESHOLD and action_can_move:
action_is_moving = true
else:
action_is_moving = false
(working)
I currently have this in the box node script, should this be in the player or should it not matter?
As the player needs to walk past the box the collision on the rigidbody2d is not set to interact with the player by default so this will need to be changed when the action key is held down. Perhaps changing the layer and mask on action then revert back to default setting? Is this logical?
I have seen a number of videos on pushing objects but i cant seem to connect the while holding button move the direction your movement keys are going.
Would i be better using a KinematicBody2D vs RigidBody2D?
I don’t know what you meant by “push and pull object”, did you mean applying forces to a `RigidBody2D? I have several questions.
Did you successfully connect the area_entered signal on your Area2D?
Do your input map working well?
Does the code successfully handle keyboard inputs?
Don’t worry about these if you get lost, you can always use the print() function to test whether it works or not. Lastly, we can keep working on this issue together.
About the question:
We usually use KinematicBody2D for character controls, and RigidBody2D for others, like your boxes.
Push and Pull: The idea is to press the E key (player_action) and hold it down to activate the next stages of input. So as an example my player is facing the left edge of the box within the area2d collision box and holding down the player_action key.
Once this is achieved move the box by pulling it or pushing it with the directional keys.
End Goal
player_action held down and also holding the right movement button to push the box right.
Answers:
I have placed print signals with in the enter and exit and the collision mask is set to detect the player. These are successful.
directional input does work with movement going left or right and jump. These are successful.
I have code that places items in and removes them from the box. When holding down the player_action key it will hit the 1.0 sec limit and print true when past it. also prints when i have let go. These are successful.
I did try using a characterbody2d but changed back to the rigidbody2d as you have also suggested.
Hope this is enough to go on and cheers for the help.
It shouldn’t have any problems anymore, as your code is all good. So, I’ll try posting the code that I’ll write:
# As always, I explicitly write the types of variables, parameters, and return values.
const BOX_MOVE_FORCE: float = 100
var is_player_inside: bool = false
func _on_area2d_entered(area: Area2D) -> void:
if area is Player: # I assume your player is of the "Player" class
is_player_inside = true
func _on_area2d_exited(area: Area2D) -> void:
if area is Player:
is_player_inside = false
func _physics_process(delta: float) -> void:
if is_player_inside:
# I assume "move_left" is your left movement action, and the same as "move_right"
var direction := Input.get_axis("move_left", "move_right")
if direction != 0:
# I don't know how to get the box, but this should be your RigidBody2D box
box.apply_force(direction * BOX_MOVE_FORCE * delta)
I can provide more precise assistance with the code if you can provide your scene tree and the code of the boxes and the areas within it.
You can set all properties of the box RigidBody2D back to default, print out the force variable which is passed to apply_force(), and test if these if statements could be reached.
print("var direction: ",direction)
works shows -1 , 0 or 1 in float values
print("force: ", force)
works shows -3 or 3 in float values
print("apply.force: ", box.apply_force(force))
Error: Trying to get a return value of a method that returns “void”
Edit: Ah i think this is me being stupid. if i remove the print statement it stops the error. However i am wondering why its value is void?
This method doesn’t return anything as it said, void means it doesn’t return anything, calm down
Shouldn’t this be a Vector2? this looks suspicious. You might have to use strong type to handle this:
# Ensure this is a Vector2 instead of anything else.
var force: Vector2 = Vector2(direction * IMPULSE_STRENGTH * delta,0)
# Or use the type of its initial value, for we explicitly created a Vector2.
var force := Vector2(direction * IMPULSE_STRENGTH * delta,0)
It seems like you did a pretty good job on your game. You might have some older code that affects the box, such as your player script, but you haven’t noticed it.
I usually create a temporary statement in the _ready() method to test something. For example, you can test inside the box with this code:
This did nothing (-1000), however, if i apply -10000 it moves it up. I have also tested with -50000 and this makes it move.
apply_force(Vector2(0, -1000)) - does nothing
apply_force(Vector2(0, -10000)) - moves up
apply_force(Vector2(0, -50000)) - moves up a lot
Tested changing the IMPULSE_STRENGTH = 10000, didnt move the box. This is with the player layer and mask set to 8 on the box.
output
action push ready: true
var direction: -1
force: (-166.6667, 0)
So i have scripted all the code within the box. Do you think this logic should be within the player script and just looks for the on enter body signals of the box?
I have also just tried something with the layers and mask.
Current settings:
box collision set to,
player layer and mask = 8
world mask = 1
if i remove the player layer and only have the box on the follwoing:
player mask = 8
world mask = 1
I can push the box and with enough force pass through it. issue is thats just me moving with no keys pressed.
If i add the box back to the player layer = 8 and have the CURRENT settings it does not move. The player shouldnt be moving th box full stop with out holding down the action key, so im not sure whats going on there now… sigh…
The layer property defines the layer of this object, while the mask property determines the layers that this object should collide with. The issue may be stemming from this conflicting configuration.
Also, check out your box’s mass and any other properties, and try to reset them all to their default values.
Let’s pause for a moment right now to consider the desired effect rather than just the actions being taken.
Again, layer are the layers of this object, and mask are the layers this object will collide with.
So if the ground layer is 1, the player layer is 2, and the box layer is 8; then the player mask should be 1 and 8 to collide with the ground and the box, and the box mask should be 1 and 2 to collide with the ground and the player. Then we’ll have a configuration like:
How does it behave? Is it pushed by the player or sliding across a slope? It’s not affected by the box code since we know the action key checking is fine, can you post every code related to the box?
Also, let’s look at the apply_force() method. The force we applied is too small indeed, I’ve tested it, and it proved this, setting it to 1000 should take effect.