Teleportation / vectors don't match each other

newMorningKingdoMnewMorningKingdoM Posts: 54Member
edited February 22 in Programming

this is player movment code, gets value from joystic:

var accel = 40
var speed = 70
var vel = Vector3()
var rotate_speed = 10

var target_position_3d


func _physics_process(delta):


    var target_dir = joistic.get_value()
    var target_dir_3d = Vector3(target_dir.x, 0, target_dir.y)
    target_position_3d = global_transform.origin + (target_dir_3d * 2)
    look_at(target_position_3d, Vector3.UP)


    target_dir = target_dir.normalized()

    vel.x = lerp(vel.x, target_dir.x * speed , accel * delta)
    vel.z = lerp(vel.z, target_dir.y * speed , accel * delta)

    move_and_slide(vel, Vector3(0,1,0))

this is teleportation script:
when player double tab;

extends Node2D

const double_tab_time_out = 0.5
const max_tab = 1

var total_tab = 2
var time_out_check_delta = 0

## player node ##
onready var player_old_position = get_parent().get_parent().get_parent().get_parent().get_node("karakter")

func _input(event):
    if not event is InputEventScreenTouch:
        return
    if event.pressed:
        if time_out_check_delta > double_tab_time_out:
            total_tab = 0

        if total_tab > max_tab:

            print ("double tab")


            player_old_position.translation.x = event.position.x
            player_old_position.translation.z = event.position.y
            player_old_position.translation.y = player_old_position.translation.y


            print(player_old_position.target_position_3d)
            print (player_old_position.translation)
            print (event.position)

        time_out_check_delta = 0
        total_tab = 2

func _process(delta):
    time_out_check_delta += delta

this is output :
https://streamable.com/eept24

nodes:

why is this happening?

Comments

  • dotteddotted Posts: 279Member
    edited February 23

    player_old_position.translation.x = event.position.x
    player_old_position.translation.z = event.position.y <---- did you really mean this?
    player_old_position.translation.y = player_old_position.translation.y

  • newMorningKingdoMnewMorningKingdoM Posts: 54Member
    edited February 23

    Well, touchscreen double tab return a Vector2, but Player is on 3d space. So it has vector3 as a position.
    And when u think 2d plane

    vector3. Z = Vector2. Y
    vector3. X = Vector2. X

    Or did i miss something?

  • newMorningKingdoMnewMorningKingdoM Posts: 54Member
    edited February 23

    I did try a diffrent thing tonight,
    i add a toucscreen button,

    add this code on it:
    extends TouchScreenButton

            onready var target_drag_pos = get_parent().get_node("meteor_target")
            onready var meteor_magic_circle_sprite = preload("res://sahneler/magic_circle_sprite.tscn")
    
            var target
            var skill_pressed = false
    
        func _on_meteor_call_skill_pressed():
            skill_pressed = true
            target = meteor_magic_circle_sprite.instance()
            add_child(target)
            target.transform.origin = Vector3(0,1,0)
            print ("button pressed")
    

    everyting is good, i got instanced magic circle that as vector3.
    so after that i did try the get the vector2 position data from touchscreen drag script, and aply to magic circle so that when drag is happen, magic circle move with it, in the base is the same thing with teleportation code above, that is ;

    -----> i did try get the vector data from touchscreen drag event. <-----

    like this:
    func _process(delta):
        print(target_drag_pos.current_touch)
    
        if skill_pressed == true:
            if target_drag_pos.current_touch:
                target.global_transform.origin.x = target_drag_pos.current_touch.x
                target.global_transform.origin.y = 1
                target.global_transform.origin.z = target_drag_pos.current_touch.y
    

    its summon it, but same thing happen again, vectors do not mach eachother.

    this is dragevent code:

    extends Node2D
    var touch_position = Vector2()
    var current_touch = Vector2()
    
    
    func _ready():
        set_as_toplevel(true)
    
    func _input(event):
    
        if event is InputEventScreenTouch and event.is_pressed():
            touch_position = event.get_position()
    
    
        if event is InputEventScreenDrag:
            current_touch = event.get_position()
    

    output:
    https://streamable.com/mu1edt

    i dont understand where and what i did was wrong?

    can some one pls help me ?

  • newMorningKingdoMnewMorningKingdoM Posts: 54Member
    edited February 23

    i think drag event position and 3dspace i mean camera position do not match each other, but how can i get ofset of it.
    of cource if it is true ? not sure.

  • TwistedTwiglegTwistedTwigleg Posts: 4,604Admin

    Are you teleporting to a 3D position? If so, you probably want to send a raycast from the double touch position, and then teleport the player to the collision position of the raycast. Something like this (untested, semi-pseudo code):

    var do_teleport_raycast = false
    var teleport_touch_position = Vector2.zero
    const TELEPORT_RAY_LENGTH = 100
    
    # For the sake of this example, we'll just use a single touch to teleport
    func _input(event):
        if event is InputEventScreenTouch and event.is_pressed():
            teleport_touch_position = event.get_position()
            do_teleport_raycast = true
    
    func _physics_process():
        if (do_teleport_raycast == true):
            do_teleport_raycast = false
            var camera = $Camera
    
            var ray_from = camera.project_ray_origin(teleport_touch_position)
            var ray_to = ray_from + camera.project_ray_normal(teleport_touch_position) * TELEPORT_RAY_LENGTH
    
            var space_state = get_world().direct_space_state
            var result = space_state.intersect_ray(ray_from, ray_to)
            if (result.empty() == false):
                # Teleport to the collision point
                global_transform.origin = result["position"]
    

    You can read more about raycasting and see some example code here on the documentation.

    For this solution to work, you will need to make sure that there is collision geometry wherever you want to teleport, but outside of that it should work. You can also use collision layers if you want to only teleport to certain areas by passing the collision mask to the intersect_ray function.

    Also, one thing to remember that may be helpful when dealing with touch input: It's always relative to the screen in 2D, not the view in 3D. I do not remember right off, but touch input may also be unaffected by Camera2D movement, so you may need to account for that if you are using a 2D camera as well.

    Hopefully this helps! I tried to look through the posts to figure out what is going on and not working, but it's possible I misinterpreted the issue, in which case let me know and I'll see if I can take another look.

  • newMorningKingdoMnewMorningKingdoM Posts: 54Member
    edited February 26

    Thank you for answer.

    i got a error.
    when double tab :

    this is the script, bdw, insteed of get_world, i did use get_world_2d , cause godot didn't let me use, and i think because of this script on a node2d.

    extends Node2D
    
    const double_tab_time_out = 0.5
    const max_tab = 1
    
    var total_tab = 2
    var time_out_check_delta = 0
    
    var do_teleport_raycast = false
    var teleport_touch_position = Vector2.ZERO
    const TELEPORT_RAY_LENGTH = 100
    
    
    onready var player_old_position = get_parent().get_parent().get_parent().get_parent().get_node("karakter")
    onready var camera_node = get_parent().get_parent().get_parent().get_parent().get_node("Camera")
    
    
    func _input(event):
        if not event is InputEventScreenTouch:
            return
        if event.pressed:
            if time_out_check_delta > double_tab_time_out:
                total_tab = 0
    
            if total_tab > max_tab:
                print ("double tab")
                teleport_touch_position = event.get_position()
                do_teleport_raycast = true
    
    
    
    
            time_out_check_delta = 0
            total_tab = 2
    
    func _process(delta):
        time_out_check_delta += delta
    
    
        if (do_teleport_raycast == true):
            do_teleport_raycast = false
            var camera = camera_node
    
            var ray_from = camera.project_ray_origin(teleport_touch_position)
            var ray_to = ray_from + camera.project_ray_normal(teleport_touch_position) * TELEPORT_RAY_LENGTH
    
            var space_state = get_world_2d().direct_space_state
            var result = space_state.intersect_ray(ray_from, ray_to)
    
            if (result.empty() == false):
                # Teleport to the collision point
                global_transform.origin = result["position"]
    

    ps: what following player is a an emty spatial, camera is use lerp to catch emty spatial. and there are no 2d camera on game, just one 3d camera.

  • TwistedTwiglegTwistedTwigleg Posts: 4,604Admin

    Is this a 2D game or a 3D game? If its 3D, you will need to use the 3D physics engine if you want to teleport to a position in 3D. If its a 2D game, then you will need to use 2D raycasting (examples in the documentation link in last post).

    For getting the world, I think you can use camera.get_world instead of get_world if the game is 3D.

  • newMorningKingdoMnewMorningKingdoM Posts: 54Member

    Thank you, well its topdown game, :P its work now.

    Can i also get the collision_point for everyframe with this ?
    i wanna use drag event for draging an instanced sprite while raycast collision happening ?

  • TwistedTwiglegTwistedTwigleg Posts: 4,604Admin

    Sure, you should be able to get a collision point every frame without any issues. You can send quite a few raycasts per physics frame (_physics_process) without slow downs on most modern machines. The exact number depends on the hardware you are targeting, but even with constrained hardware (like mobile) I've found I can send about 12-24 a physics frame without any issues.

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file