Hi. I want to make the control in the scrolling game concurrently by keyboard and mouse (click and move). But the mouse control don`t work properly. The character move to the edges (left-right) of the screen, even the mouse clicked in the same position. And don't move smoothly. Character appears in the edge of the screen. Also I need that move only by X axis. Here the code (mouse-and-click part):

func _input(event):
    if event is InputEventMouseButton:
        if event.is_action_pressed("LeftClick"):
            var target_x = get_local_mouse_position().x
            move_to_x(target_x)

func move_to_x(target_x):
    var direction = target_x

    if direction:
        velocity.x = direction * SPEED
    else:
        velocity.x = move_toward(velocity.x, 0, SPEED)
    move_and_slide()
'''
  • That's because you're always writing over velocity with your click-and-move code. Your code should be doing only one of either click-and-move or moving with keys at one time. You can use a bool to keep track of which way you're moving. I've written you an example here:

    extends CharacterBody2D
    
    const SPEED := 300.0
    const JUMP_VELOCITY := -400.0
    
    var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity")
    
    var move_to_click := false
    var target := 0.0
    
    func _input(event):
    	if event.is_action_pressed("LeftClick"):
    		target = get_global_mouse_position().x
    		move_to_click = true
    
    func _physics_process(delta: float) -> void:
    	if not is_on_floor():
    		velocity.y += gravity * delta
    
    	if Input.is_action_just_pressed("Jump") and is_on_floor():
    		velocity.y = JUMP_VELOCITY
    
    	var direction := Input.get_axis("Left", "Right")
    	if !is_zero_approx(direction):
    		#player wants to move with keys
    		#so let's stop moving to the mouse click if we were
    		move_to_click = false
    		velocity.x = direction * SPEED
    	elif move_to_click:
    		#player didn't press key and has a click to move to
    		var dist := target - global_position.x
    		var x:float = sign(dist) * SPEED
    		if abs(x * delta) > abs(dist): #would we overshoot?
    			x = dist / delta #get there in one physics frame
    			move_to_click = false
    		velocity.x = x
    	else:
    		velocity.x = move_toward(velocity.x, 0, SPEED)
    
    	move_and_slide()

I have a question about what you want to happen. Is it:

  1. When you click a position, the character will move until they are at that x position.
    or
  2. While you are holding the mouse down, the character will move towards that x position.

?

    award
    First variant.
    Try to add this code inside _physics_process() but the gravity not work. As well as keyboard control. Only click and move movement available

    extends CharacterBody2D
    
    
    const SPEED = 300.0
    const JUMP_VELOCITY = -400.0
    
    # Get the gravity from the project settings to be synced with RigidBody nodes.
    var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
    
    #click-and-move
    var target = position
    
    #click-and-move func1
    func _input(event):
    	if event.is_action_pressed("LeftClick"):
    		target = get_global_mouse_position()
    
    	
    func _physics_process(delta):
    	# Add the gravity.
    	if not is_on_floor():
    		velocity.y += gravity * delta
    
    	# Handle Jump.
    	if Input.is_action_just_pressed("Jump") and is_on_floor():
    		velocity.y = JUMP_VELOCITY
    
    	# Get the input direction and handle the movement/deceleration.
    	# As good practice, you should replace UI actions with custom gameplay actions.
    	var direction = Input.get_axis("Left", "Right")
    	
    	if direction:
    		velocity.x = direction * SPEED
    	else:
    		velocity.x = move_toward(velocity.x, 0, SPEED)
    	
    	#click-and-move _phisics_process.
    	velocity = position.direction_to(target) * SPEED
    	#look_at(target)
    	if position.distance_to(target) > 10:
    		move_and_slide()
    	move_and_slide()
    
    `Further question for me will the pathfinding of the character - jump over the obstacles.  I found another method move_and_collide.`

    That's because you're always writing over velocity with your click-and-move code. Your code should be doing only one of either click-and-move or moving with keys at one time. You can use a bool to keep track of which way you're moving. I've written you an example here:

    extends CharacterBody2D
    
    const SPEED := 300.0
    const JUMP_VELOCITY := -400.0
    
    var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity")
    
    var move_to_click := false
    var target := 0.0
    
    func _input(event):
    	if event.is_action_pressed("LeftClick"):
    		target = get_global_mouse_position().x
    		move_to_click = true
    
    func _physics_process(delta: float) -> void:
    	if not is_on_floor():
    		velocity.y += gravity * delta
    
    	if Input.is_action_just_pressed("Jump") and is_on_floor():
    		velocity.y = JUMP_VELOCITY
    
    	var direction := Input.get_axis("Left", "Right")
    	if !is_zero_approx(direction):
    		#player wants to move with keys
    		#so let's stop moving to the mouse click if we were
    		move_to_click = false
    		velocity.x = direction * SPEED
    	elif move_to_click:
    		#player didn't press key and has a click to move to
    		var dist := target - global_position.x
    		var x:float = sign(dist) * SPEED
    		if abs(x * delta) > abs(dist): #would we overshoot?
    			x = dist / delta #get there in one physics frame
    			move_to_click = false
    		velocity.x = x
    	else:
    		velocity.x = move_toward(velocity.x, 0, SPEED)
    
    	move_and_slide()
      6 days later