• 3D
  • How move forward when you look at a specific object?

Hello world, hm, i try to make an application for Android. The export work and i can move my head to look around me. But i can't "move forward" in my map.

It's for my smartphone, and i have "only" my phone (no joystick or something else). So, i thought "ok it will be cool if in my map i had a "special object", and it "tract me" if i look a this object. I thought use a Raycast to do it. My player is so :

Player +-- Head +-- ARVROrigin +-- ARVRCamera +-- deFrag(Raycast)

On PC : when i move my mouse and there a collision with the wall or orange box or floor, i move forward. When i look at the sky, i stop.

On my smartphone, when i change the angle of my smartphone and i look at the wall, or orange box or floor, i move... to the right. When i look at the sky, i stop.

It's in progress but, i am blocked to this problem. I would like to move "only" when i look at the orange box, and go "to" the orange box. And stop when i look at another thing... (and so, with a lot of orangebox, i could move everywhere in the map ;D)

Have you any idea please? Maybe i can use "look_at" but i don't understand to do it... x/

Thanks for your advice :)

ps: here is a picture of the map, and the player.gd

` extends KinematicBody

var speed
var default_move_speed = 1.5
var acceleration = 20
var gravity = 0.2
var mouse_sensivity = 0.1
var direction = Vector3()
var velocity = Vector3()
var fall = Vector3()
onready var head = $Head
onready var anim_play = $Head/HB
onready var raycast_pk = $"Head/ARVROrigin/ARVRCamera/deFrag"

func _ready():
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _input(event):
	if event is InputEventMouseMotion:
		rotate_y(deg2rad(-event.relative.x * mouse_sensivity))
		head.rotate_x(deg2rad(-event.relative.y * mouse_sensivity))
		head.rotation.x = clamp(head.rotation.x, deg2rad(-90), deg2rad(90))

func _process(delta):

	speed = default_move_speed
	direction = Vector3()
	if raycast_pk.is_colliding():
		direction -= transform.basis.z
		direction = direction.normalized()
		velocity = velocity.linear_interpolate(direction * speed, acceleration * delta)
		velocity = move_and_slide(velocity, Vector3.UP)



	if not is_on_floor():
		fall.y -= gravity + delta

	if direction != Vector3():
		anim_play.play("HB_marche")
		$"Pas/Bruit2pas".play("marche")

	move_and_slide(fall, Vector3.UP)

func _on_Bruit2pas_finished(anim_name):
	if is_on_floor():
		var aupif = str(randi() % 3)
		if aupif == String("0"):
			$"Pas/pl_step1".play()
		if aupif == String("1"):
			$"Pas/pl_step2".play()
		if aupif == String("2"):
			$"Pas/pl_step3".play()
		if aupif == String("3"):
			$"Pas/pl_step4".play()

`

Have you tried using collision layers/masks? If you put the orange box on its own collision layer and mask that only it’s on, and have the Raycast also on the same collision layer/mask as the orange box. If only the orange box (or boxes) are on the collision layer and nothing else is, then a raycast also on the same layer should only detect just the orange box, which I think will give you the desired outcome :smile:

Yeah, thank you TwistedTwigleg, your solution with mask is cool and it work ; i didn't think about it ;)

So, it works correctly on my PC, but the direction is always "strange" on my smartphone

I use this :

direction -= transform.basis.z ("z" is the axis where à go... x/ not the cube position)

And on PC it work, so... i don't understand, hm... 8/

Maybe it should be something like this (sorry for the "false synthaxe", it's just to show my idea" x)):

	
if raycast_pk.is_colliding():
	if its the orange_cube_1:
		direction -= transform.basis.orange_cube_1.position3D
	if its the orange_cube_2:
		direction -= transform.basis.orange_cube_2.position3D

or something like that x)

After a few research on google to find the name of the object when there is collision, i find the second part of the anwser x)

I made variables with 4 oranges cubes and i use "get_collider". When the player's raycast is colliding with cube name "zecible1", the player move to the position -17,4,-6. etc, etc...

It's not perfect-perfect but it works ;)

Yeaaaah

Here is the apk for this final test (i have a samsung Galaxy J6+ with Android 8.1.0)

You might not want to be hard-coding those values. Maybe it is okay if you only have 4 objects in the whole game, but once you add more levels or expand the number of objects it won't be maintainable. Instead you can get the collision point and do some math there, you should be able to make it more dynamic.

Hello, so cybereality, I replace the references of the cube by a "collision point" and it works x). I don't need to put the name of all of cubes and it's ok. It's not perfect too, but it's better xD In fact there's another pb (sorry). hm... - When the coordinates 0, 0, 0, are between me and the cube i go to it. - When the coordinates 0, 0, 0, aren't between me and the cube, my direction deviates. It's not dramatic for my project. And i'm on another project in the same time so... i take a pause with vr 8) a few days...

Thanks for your advices

Try something like this for getting the direction:

direction = global_transform.origin.direction_to(raycast_pk.get_collision_point())

get_collision_point returns the position of the Raycast in world space, or in other words, the position where the raycast collided. To get a direction from it, you'll need to get your current position (global_transform.origin) and then get the direction from that point to the raycast collision point.