So I am making a Voodoo-type mobile game. To move the cannon, you have to drag across the screen. This is simple, and I have made a system where I can move the coordinates on the x axis of the cannon. This, however, changes the velocity, and slows it down. I have linked a youtube link with the video, as well as putting in my code.

extends Node2D

var ended = false

export(Color) var lineColor = Color(255, 0, 0)
export(float) var lineWidth = 5.0
export(bool) var antialiased = false
var xAxisOnCannonAtStart = 0
var position_start := Vector2.ZERO
var touch_down := false
var position_end := Vector2.ZERO
var difference = 0
func _on_input_event(_viewport, event, _shape_idx) -> void:
	
	if event.is_action_pressed("ui_touch"):
		touch_down = true
		position_start = event.position

func _input(event) -> void:
	
	if not touch_down:
		return
	
	if event is InputEventMouseMotion:
		if Input.is_action_pressed("ui_touch"):
			if ended == true:
				ended = false
			else:
				ended = false
				position_end = event.position
				update()
				print("position_end = ",event.position.x)
				difference = (-(position_start.x - event.position.x))/100
				print("The direction of movement is ",difference," in the x axis")
				print(self.get_parent().get_node("Cannon").transform.origin)
				var zAxisOnCannon = self.get_parent().get_node("Cannon").transform.origin.z
				self.get_parent().get_node("Cannon").transform.origin.x = difference+xAxisOnCannonAtStart


func _process(_delta):
	update()


func _draw():
	if Input.is_action_just_pressed("ui_touch"):
		touch_down = true
		position_start = get_local_mouse_position()
		print("position_start =",get_local_mouse_position().x)
		xAxisOnCannonAtStart = self.get_parent().get_node("Cannon").transform.origin.x
	if Input.is_action_pressed("ui_touch"):
		var mouseLocalPosition = get_local_mouse_position()

		draw_line(position_start , mouseLocalPosition, lineColor, lineWidth, antialiased)
  • FluffyPancakes1
    That's where the _delta parameter to _process comes in.
    _delta is how long it's been (in seconds) since the last call to _process. If your game is running at 100fps, delta will be 0.01s.
    If you do add 10 to the transform.origin.z, it would jump 10 units. The faster the fps, the faster the object moves.
    But if you add 10*
    delta, it becomes "10 per second". No matter the fps, it will take 1 second to travel 10 units. (Higher framerates means it takes shorter steps each frame)

    So in your _process function you could do:

    func _process(_delta):
    	self.get_parent().get_node("Cannon").transform.origin.z -= 10.0 * _delta
    	update()

    That should move at the same speed as you had with the linear_velocity.

I don't see any problem in the video. You are moving the mouse in a circle, which is not linear.

    cybereality it slows down the velocity
    You do not need to worry about anything else, as it is not the problem. It slows down on the y-axis when i move on the x axis

    EDIT:
    Also, I use this code to make the cannon move forward forever:

    func _button_pressed():
    		self.visible = false
    		self.get_parent().get_node("Cannon").gravity_scale = 0
    		self.get_parent().get_node("Cannon").linear_damp = 0
    		self.get_parent().get_node("Cannon").friction = 0
    		self.get_parent().get_node("Cannon").linear_velocity = Vector3(0,0,-10)
    		self.get_parent().get_node("Cannon").axis_lock_angular_x = true
    		self.get_parent().get_node("Cannon").axis_lock_angular_y = true
    		self.get_parent().get_node("Cannon").axis_lock_angular_z = true

    As far as I can tell, there is no y-axis movement, but the video is short and the mouse is moving fast. I'm not even sure what I'm looking it.

      cybereality

      The movement going forward is on the y axis, and when I move on the x axis, it stops/slows down movement on the y axis. I want the y axis to have a constant velocity and not change because of other movements. I have attatched all the information I believe is needed to figure out what is wrong. I could have this fixed in 1 of 2 ways, figure out how to make a constant velocity on the y axis which never changes, or the x axis velocity not effect the y axis velocity.

      FluffyPancakes1 I'm pretty sure that's an optical illusion. What you can do is measure the time, in delta of when the bullet hits an object from when it is fired. By moving it back and forth, you get a different viewing angle. If it's slows down it's more than likely your graphics card is just working harder showing the different angles. That would cause a stuttering effect, it should still take the same amount of time if it's in physics process.

        Oh, you're talking about the projectile ball? It would have helped if you mentioned that. I still don't see anything wrong. However, feel free to put print statements tracing the x and y values and see if you notice anything.

          FluffyPancakes1 Does moving in one axis effect the velocity of other axis?

          If it is so programmed ...

          The object stops moving forward when you want to change its direction, right? Then it is necessary to calculate the direction in which the cannon is pointing independently from the forward movement.

          Also, is the there a reason why you use Node2D in the 3D scene ? The object is a billboard I recon, but still it is oriented in 3D space, if I am not mistaken.

            fire7side
            It is not any of those, look:

            cybereality
            I never mentioned anything about the oranges. The problem is the cannon, and it is clearer in the video I have linked

            Pixophir
            I do not understand what you mean.
            Also, I am using a Node2D so that I can take the x axis and move the cannon accordingly

            Okay, let's start from the top. What is it you expect to happen and what is it you think is happening? I just don't understand what I'm supposed to be looking at in that video.

            When the transform of a rigid body is changed, the physics integration of that frame is lost. Even just changing the origin's x value will lose the y and z velocity for the frame.

            In the docs, it says:

            If you only need to place a rigid body once, for example to set its initial location, you can use the methods provided by the Spatial node, such as set_global_transform() or look_at(). However, these methods cannot be called every frame or the physics engine will not be able to correctly simulate the body's state.

            Changing one part of the transform is effectively the same as set_global_transform() being called (from what I can tell), so has the same issue.
            (I tried debugging into the code to see where that happens, but scons is damn annoying)

            One fix is to store the desired x position in a class variable instead of setting the transform directly in the event code. Then add this function:

            func _integrate_forces(state):
            	state.transform.origin.x = mx

            where mx is the variable with the mouse x pos. In my tests, that lets the linear_velocity continue working as normal.

            Although I don't know if that's going to get the right node, I don't know your hierarchy. But doing that to a simple test fixed the issue for me.

              FluffyPancakes1
              _integrate_forces is a built in callback that lets you intercept the physics processing and do your own stuff in there. The state parameter to it is the internal physics state of whatever node (I assume needs to be a physics node like rigidbody) you put the _integrate_forces function on.
              If you put it in a script on the rigid body (if that's your cannon) then every time the physics tries to update it will call _integrate_forces and you can manipulate the physics there.

              Basically I made a rigid body node and put this script on it:

              extends RigidBody
              
              var mx = 0
              
              func _ready():
              	gravity_scale = 0
              	linear_velocity = Vector3(0,0,-10)
              
              func _input(event) -> void:
              	if event is InputEventMouseMotion:
              		mx = event.position.x/100.0
              
              func _integrate_forces(state):
              	state.transform.origin.x = mx

              The rigid body moves forward along Z and tracks the mouse on X.

              If you need precise movement like this (and aren't really using the physics engine, like to bounce on stuff), then you are probably better off just writing the movement by hand.

              For some reason, the cannon now doesn't move on the x axis. Here is my code:

              extends Node2D
              
              var ended = false
              
              export(Color) var lineColor = Color(255, 0, 0)
              export(float) var lineWidth = 5.0
              export(bool) var antialiased = false
              var change = 0
              var xAxisOnCannonAtStart = 0
              var position_start := Vector2.ZERO
              var touch_down := false
              var position_end := Vector2.ZERO
              var difference = 0
              func _on_input_event(_viewport, event, _shape_idx) -> void:
              	
              	if event.is_action_pressed("ui_touch"):
              		touch_down = true
              		position_start = event.position
              
              func _input(event) -> void:
              	
              	if not touch_down:
              		return
              	
              	if event is InputEventMouseMotion:
              		if get_parent().get_node("Button").visible == false:
              			if Input.is_action_pressed("ui_touch"):
              				if ended == true:
              					ended = false
              				else:
              					ended = false
              					position_end = event.position
              					update()
              					#print("position_end = ",event.position.x)
              					difference = (-(position_start.x - event.position.x))/100
              					print("The direction of movement is ",difference," in the x axis")
              					#print(self.get_parent().get_node("Cannon").transform.origin)
              					var _zAxisOnCannon = self.get_parent().get_node("Cannon").transform.origin.z
              					change = difference+xAxisOnCannonAtStart
              
              func _integrate_forces(state):
              	self.get_parent().get_node("Cannon").transform.origin.x = change
              
              func _process(_delta):
              	update()
              
              
              func _draw():
              	if get_parent().get_node("Button").visible == false:
              		if Input.is_action_just_pressed("ui_touch"):
              			touch_down = true
              			position_start = get_local_mouse_position()
              			#print("position_start =",get_local_mouse_position().x)
              			xAxisOnCannonAtStart = self.get_parent().get_node("Cannon").transform.origin.x
              		if Input.is_action_pressed("ui_touch"):
              			var mouseLocalPosition = get_local_mouse_position()
              
              			draw_line(position_start , mouseLocalPosition, lineColor, lineWidth, antialiased)

              here is the hierarchy:

              The _integrate_forces function needs to be in a script on the Cannon node, and you need to use the state variable to access the physics state transform (not the transform of a node from get_node())

              Although as Cyber said, you might want to do the moving manually. Rigid bodies really don't want you to teleport them around, they want to move using velocity and force so they can bounce off of things. The code would be smaller too.

                FluffyPancakes1
                The physics-functions get passed a variable deltatime that has the time passed since the last frame. That is used to equalize the effects of different performances etc.

                FluffyPancakes1
                That's where the _delta parameter to _process comes in.
                _delta is how long it's been (in seconds) since the last call to _process. If your game is running at 100fps, delta will be 0.01s.
                If you do add 10 to the transform.origin.z, it would jump 10 units. The faster the fps, the faster the object moves.
                But if you add 10*
                delta, it becomes "10 per second". No matter the fps, it will take 1 second to travel 10 units. (Higher framerates means it takes shorter steps each frame)

                So in your _process function you could do:

                func _process(_delta):
                	self.get_parent().get_node("Cannon").transform.origin.z -= 10.0 * _delta
                	update()

                That should move at the same speed as you had with the linear_velocity.