In godot i have ParallaxLayer
extends ParallaxLayer
var motion = Vector2(-50, 0)
var start_pos = Vector2()
var speed = -50
# Called when the node enters the scene tree for the first time.
func _ready():
set_mirroring(motion)
pass
func _process(delta):
speed -= 5
set_motion_offset(motion+Vector2(speed,0))
this code make the background scroll but not infinite
I dont know what to do when scrolling to end
the official document say i should use set_mirroring
can somebody tell me how to use this function?
or where should i go for more information?
Mirroring expects a Vector2 value, which is the XY coordinates of the "offset" of the mirror. Typically this value would be the height or width of the image you are using as a background (which usually corresponds with the window size), depending on what direction you want to mirror. The example code below assumes a window size of 1080x1920, with the ParallaxLayer being mirrored on the Y axis.
extends ParallaxLayer
func _ready():
set_mirroring(motion_mirroring)
func _process(delta):
motion_mirroring = Vector2(0,1920)
Related
The enemy in my game will not move towards the left when player is on the left but will move to the right. Then when the player is on the right the enemy will move to the player.
code for enemy:
extends KinematicBody2D
var run_speed = 100
var velocity = Vector2.ZERO
var collider = null
func _physics_process(delta):
velocity = Vector2.ZERO
if collider:
velocity = position.direction_to(collider.position) * run_speed
velocity = move_and_slide(velocity)
func _on_DetectRadius_body_entered(body):
collider = body
func _on_DetectRadius_body_exited(body):
collider = null
I suspect you are using an Area2D and it is detecting something other than the player character. I remind you can use collision_mask and collision_layer to narrow what objects are detected. For example, are you sure the Area2D is not detecting the enemy itself? For a quick check you can have Godot print the collider to double check it is what you expect.
Furthermore, notice that wen an object leaves the Area2D it will set collider to null regardless if there is still some object inside the Area2D or not. I remind you that an alternative approach is using get_overlapping_bodies.
And, of course, you can query each body you get to see if it is the player character (for example by checking its node group, name, class, etc...). I go over filtering in more detail in another answer.
If you are getting the player character, there is another possible source of problems: position vs global_position. The code you have like this:
position.direction_to(collider.position)
Is correct if both the enemy and the collider it got have the same parent. In that case their positions are in the same space. Otherwise, you may want to either work on global coordinates:
global_position.direction_to(collider.global_position)
Or you can bring the collider position to local coordinates:
position.direction_to(to_local(collider.global_position))
And of course, double check that the Area2D is positioned correctly. You can enable "Visible Collision Shapes" on the "Debug" menu, which will show it when running the game from the editor.
I want to move my kinematic body horizontally by just setting the velocity but I'm keep on getting some error on this program. I'm using godot software to do this. Need a hand to help me. Below I have attached my code:
extends KinematicBody
var KinematicBodyWidth: int
var KinematicBodyHeight: int
var velocity: float
func _enter_tree():
setupVelocity()
setupKinematicBody()
positionLeftCenter()
func _physics_process(_delta):
move_and_slide(delta)
func move_and_slide(delta: float)-> void:
position.x += delta * velocity
func setupVelocity():
velocity = 100.0
Thanks and regards,
Abhi
If you put that code on a KinematicBody it will give you the following error:
Parser Error: The function signature doesn't match the parent. Parent signature is: "Vector3 move_and_slide(Vector3, Vector3=default, bool, int, float, bool)".
That is because KinematicBody defines a move_and_slide. And no, you can't have an overload. GDScript does not support that. Instead creating a method with the same name is taken as an attempt to override it, which is failing when it checks if the parameters match. The method move_and_slide is not virtual anyway.
I also want to mention that the slide part of the name of move_and_slide refers to how it interacts with ramps. That is, if the KinematicBody collides with a surface that it considers a ramp, it will slide on it.
Now, you could put the code directly on _physics_process, like this:
func _physics_process(delta):
position.x += delta * velocity
Notice I renamed the parameter from _delta to delta. You were passing delta into your move_and_slide method, but the parameter name was _delta.
Except - wait - there is no position in KinematicBody (there is in KinematicBody2D), if you want to change the position you can write the origin of the transform:
func _physics_process(delta):
transform.origin.x += delta * velocity
And you need to be aware that that is a teleport. It would not be checking for collisions. Use move_and_slide (or if you don't want the slide part, use move_and_collide) that comes defined in the KinematicBody class. That way, it does not only moves the KinematicBody but also takes into account collisions.
By the way, I would argue the variable is a speed (scalar) not a velocity (vector). Yet, I'm keeping the way you named it.
Given that you have unused KinematicBodyWidth and KinematicBodyHeight I suspect you don't want to use Godot physic objects. If that is the case, you can use a regular Spatial node, and use physics queries to detect collisions.
I have an explanation from the basics of setting up Godot physics to how to use physic queries elsewhere. Either if you want to use Godot physic objects and don't know how, or if you don't want to use them and use physics queries instead, I think that would help you.
The next errors are that setupKinematicBody and positionLeftCenter are not defined. Either define the methods, or remove the calls. I can't help further with those.
By the way, are you sure you want to use _enter_tree instead of _ready? And are you sure you don't want to initialize velocity with the value you want (var velocity: float = 100.0), or you can export it so it is easy to set from the inspector panel (export var velocity: float = 100.0).
Your code could be just this:
extends KinematicBody
export var speed := 100.0
func _physics_process(delta):
transform.origin.x += delta * speed
Or this:
extends KinematicBody
export var velocity := Vector3(100.0, 0.0, 0.0)
func _physics_process(_delta):
move_and_slide(velocity)
I have a trouble with a 2D Godot Project.
I wrote the following code in the KinematicBody2D script:
extends KinematicBody2D
export var speed = 250
var motion = Vector2()
func _physics_process(delta):
motion = Vector2.ZERO
if Input.is_action_just_pressed("ui_left"):
motion.x = -speed
if Input.is_action_just_pressed("ui_right"):
motion.x = speed
if Input.is_action_just_pressed("ui_up"):
motion.y = -speed
if Input.is_action_just_pressed("ui_down"):
motion.y = speed
motion = move_and_slide(motion)
pass # Replace with function body.
The problem is that my player is only moving a few pixels and stops while I'm pressing the W, A, S, D or the arrow keys.
What I've done wrong?
Thank you all!
The function is_action_just_pressed tells you if the named action※ was just pressed. It will not continue returning true if the action is held.
This, combined with the fact that you are erasing motion each physic frame motion = Vector2.ZERO, result in the object moving one physics frame and then it stops.
If you want to know if the action is currently pressed - independently of when it began being pressed - use is_action_pressed instead.
※: The actions you can use with these functions are configured in the Project Settings. You will find them on the "Input Map" tab.
I'm new to godot and I was trying to make a asteriods type game. But i'm having trouble getting my space ship to shoot.
The issue is that I can't get the bullet to fire in direction of the ship. I set an 'angle' variable in the ship and assign it to the bullet once it has been instanced, but i'm not sure how to use it in the bullet. The bullet will just move right no matter the angle of the ship.
Ship Firing Code:
func _process(_delta):
if Input.is_action_just_pressed("action_fire"):
var Bullet_Instance = Bullet.instance()
Bullet_Instance.angle = angle
owner.add_child(Bullet_Instance)
Bullet Code:
extends KinematicBody2D
var angle = 0
var direction = Vector2(cos(angle), sin(angle))
func _physics_process(_delta):
move_and_slide(direction*500)
I'm pretty sure that the angle variable is being reset to 0 in the bullet code after it has been set in the ship code, but i'm not sure how to fix this. Thanks.
The angle variable is not being reset. The direction variable is not being updated when you set angle.
When the scene is instanced, here:
var Bullet_Instance = Bullet.instance()
These variables get their value:
var angle = 0
var direction = Vector2(cos(angle), sin(angle))
Then you set angle, here:
Bullet_Instance.angle = angle
But you don't use angle anymore, instead, you use direction:
func _physics_process(_delta):
move_and_slide(direction*500)
I'll give a few ways to solve this:
If you want direction to update every time you set angle, you could make a setter with setget. Like this:
var angle = 0 setget set_angle
func set_angle(new_value) -> void:
angle = new_value
direction = Vector2(cos(angle), sin(angle))
You could write direction directly from your other script, and not have the angle variable at all. In fact, you could set a velocity, and save tha multiplication by 500 every time.
You could compute the vector on _physics_process (you are already doing a vector scaling operation anyway):
func _physics_process(_delta):
move_and_slide(Vector2(cos(angle)*500, sin(angle)*500))
There likely are more ways to go about it. It is up to you.
Please provide minimal code example of Sprite following the mouse in Godot. There are complex and big sample projects, but I didn't found nothing small and clear.
Put the Sprite node in the scene, and attach the following script to it.
const SPEED = 500
func _process(delta):
var vec = get_viewport().get_mouse_position() - self.position # getting the vector from self to the mouse
vec = vec.normalized() * delta * SPEED # normalize it and multiply by time and speed
position += vec # move by that vector