|
|
|
|
Reply From: |
timothybrentwood |
Create a RayCast2D as a child of your Player KinematicBody2D and set it to cast to a teleport’s length in front of your player. This takes the place of the Teleporter KinematicBody2D that you were attempting to create.
onready var teleporting_ray_check : RayCast2D = get_node("ray_cast")
func _ready():
teleporting_ray_check.enabled = true
func _physics_process(_delta: float) -> void:
var teleporting = Input.is_action_just_pressed("ui_accept")
if not teleporting:
pass
elif teleporting_ray_check.is_colliding():
self.global_position = teleporting_ray_check.get_collision_point()
else:
self.position += teleporting_ray_check.get_cast_to()
Add a cooldown timer as you see fit.
I had to change some things around to work with how my project worked currently, which uses a state machine between movement and teleportation. I’ll put in the relevant code:
func _ready():
teleport.enabled = true
#State machine
func _physics_process(delta):
match state:
MOVE:
move_state(delta)
BLINK:
blink_state(delta)
(In MOVE state)
if Input.is_action_just_pressed("blink"):
state = BLINK
(Then)
func blink_state(delta):
if teleport.is_colliding():
self.global_position = teleport.get_collision_point()
else:
self.position += teleport.get_cast_to()
state = MOVE
In this current state, it works correctly when the raycast is colliding with a wall (albeit, with some visual jitter), however, when it isn’t, it instead teleports the player downwards into the floor. Additionally, I am attempting to rotate it in the code using rotation_degrees, which does not change it.
darkdestiny1010 | 2021-05-11 16:01
What kind of movement are you using? 2D side scroller or top down?
timothybrentwood | 2021-05-11 16:46
2D side scroller.
darkdestiny1010 | 2021-05-11 17:22
Make sure your RayCast2D
’s position is the center point of your KinematicBody2D
. You probably want to give yourself a buffer for when you’re colliding (a little over half the character sprite’s width is my suggestion). Make sure you’re changing where your RayCast2D
is casting to based on the direction your character is facing.
const BUFFER := Vector2(8,0)
const TELEPORT_LENGTH := 64
var CAST_LEFT := Vector2.LEFT * TELEPORT_LENGTH
var CAST_RIGHT: = Vector2.RIGHT * TELEPORT_LENGTH
func _physics_process(delta):
if teleport.is_colliding():
self.global_position = teleport.get_collision_point() + (sign(teleport.get_cast_to().x) * BUFFER)
...
if facing_right:
teleport.cast_to(CAST_RIGHT)
else:
teleport.cast_to(CAST_LEFT)
timothybrentwood | 2021-05-11 17:45
This seems to give me the error, “Invalid call. Non existant function ‘cast_to’ in base RayCast2d.”
darkdestiny1010 | 2021-05-11 18:03
My bad it should be set_cast_to()
not cast_to()
. cast_to
is the property.
timothybrentwood | 2021-05-11 18:57
It’s definitely now making the RayCast move and is teleporting, however it causes the raycast to go up or down, and only actually teleports when colliding. Currently it’s:
func blink_state(delta):
if teleport.is_colliding():
self.global_position = teleport.get_collision_point() + (sign(teleport.get_cast_to().x) * BUFFER)
if arm.global_position.x - get_global_mouse_position().x < 0:
teleport.set_cast_to(teleportRight)
else:
teleport.set_cast_to(teleportLeft)
state = MOVE
darkdestiny1010 | 2021-05-11 19:09
This is going to be fighting with the physics engine a bit since you change directions with your mouse.
func blink_state(delta):
if arm.global_position.x - get_global_mouse_position().x < 0:
teleport.set_cast_to(teleportRight)
else:
teleport.set_cast_to(teleportLeft)
teleport.force_raycast_update()
if teleport.is_colliding():
self.global_position = teleport.get_collision_point() + (sign(teleport.get_cast_to().x) * BUFFER)
else:
self.position += teleport.get_cast_to()
state = MOVE
timothybrentwood | 2021-05-11 19:46
“however it causes the raycast to go up or down”
That has to deal with the values of your teleportRight
and teleportLeft
- which should be treated as constants. You should never be adjusting the position
of the RayCast2D
it will follow the center of your KinematicBody2D
since the RayCast2D
is a child of it.
timothybrentwood | 2021-05-11 19:50
Works almost perfectly! The issue with the raycast pointing up and down was because I had already rotated it to face to the right, and the code made it rotate again, I’ve fixed that. The only thing that currently doesn’t work is collision, as it still teleports into walls.
darkdestiny1010 | 2021-05-11 19:53
If you’re standing next to a wall do you teleport the entire length of the RayCast2D
?
if teleport.is_colliding():
print("colliding")
self.global_position = teleport.get_collision_point() + (sign(teleport.get_cast_to().x) * BUFFER)
else:
print("not colliding")
self.position += teleport.get_cast_to()
add those print statements. If you’re hitting the “colliding” and still going into the wall it has to deal with what you’re setting your teleportLeft
and teleportRight
to , they should be set to Vector2.LEFT * some length
and Vector2.RIGHT * some length
respectively. Or your buffer is too small.
You shouldn’t be hitting the not colliding branch. If you are that’s very strange.
timothybrentwood | 2021-05-11 20:20
Ahh I finally found where it went wrong. I was setting the buffer to half the height, not half the width. Works perfectly now, thank you ever so much!
darkdestiny1010 | 2021-05-11 20:59
Hahaha I was very confused! No problem man!
timothybrentwood | 2021-05-11 21:12