Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vector3.ZERO stops being constant and returns wrong values. #345

Open
MarioMey opened this issue Jul 12, 2022 · 3 comments
Open

Vector3.ZERO stops being constant and returns wrong values. #345

MarioMey opened this issue Jul 12, 2022 · 3 comments

Comments

@MarioMey
Copy link

Transporting "Your first 3D game" to python, I found something weird. Simplified code:

from godot import Vector3, KinematicBody
class Player(KinematicBody):
    def _ready(self):
        print(Vector3.ZERO)

Returns:

<Vector3(x=0.0, y=0.0, z=0.0)>

And this:

    def _physics_process(self, delta):
        print(Vector3.ZERO)

Returns:

<Vector3(x=0.0, y=-1.2500001192092896, z=0.0)>
<Vector3(x=0.0, y=-1.2500001192092896, z=0.0)>
<Vector3(x=0.0, y=-1.2500001192092896, z=0.0)>
...

If I do the same with GDScript, Vector3.ZERO returns always (0.0, 0.0, 0.0) (inside _ready() and _physics_process(delta)).

So, why it is returning wrong values?

...

The full code is here, but game is not completely transported.

from godot import exposed, export, signal, Vector3, InputEventKey, KinematicBody
from godot import KEY_RIGHT, KEY_LEFT, KEY_UP, KEY_DOWN, KEY_SPACE
import math

@exposed
class Player(KinematicBody):

	hit = signal()

	speed = export(int, default=14)
	jump_impulse = export(int, default=20)
	bounce_impulse = export(int, default=16)
	fall_acceleration = export(int, default=75)

	velocity = Vector3.ZERO
	direction = Vector3.ZERO
	direction_real = Vector3.ZERO
	
	space_pressed = False
	
	def _ready(self):
		pass
	
	def _unhandled_input(self, event):
		if type(event) is InputEventKey:
			if event.pressed and event.scancode == KEY_RIGHT and not event.echo:
				self.direction.x += 1
			if event.pressed and event.scancode == KEY_LEFT and not event.echo:
				self.direction.x -= 1
			if not event.pressed and event.scancode in [KEY_RIGHT, KEY_LEFT]:
				self.direction.x = 0
			
			if event.pressed and event.scancode == KEY_DOWN and not event.echo:
				self.direction.z += 1
			if event.pressed and event.scancode == KEY_UP and not event.echo:
				self.direction.z -= 1
			if not event.pressed and event.scancode in [KEY_UP, KEY_DOWN]:
				self.direction.z = 0
			
			if event.pressed and event.scancode == KEY_SPACE and not event.echo:
				self.space_pressed = True
			if not event.pressed and event.scancode == KEY_SPACE:
				self.space_pressed = False
			
		self.velocity.x = self.direction.x * self.speed
		self.velocity.z = self.direction.z * self.speed
		
	def _physics_process(self, delta):
		#print(Vector3.ZERO)
		
		if self.direction != Vector3.ZERO:
			self.direction_real = self.direction.normalized()
			self.get_node("Pivot").look_at(self.translation + self.direction_real, Vector3.UP)
			self.get_node("AnimationPlayer").playback_speed = 4
		else:
			self.get_node("AnimationPlayer").playback_speed = 1

		if self.is_on_floor() and self.space_pressed:
			self.velocity.y += self.jump_impulse

		self.velocity.y -= self.fall_acceleration * delta
		self.velocity = self.move_and_slide(self.velocity, Vector3.UP)

		for index in range(self.get_slide_count()):
			collision = self.get_slide_collision(index)
			if collision.collider.is_in_group("mob"):
				mob = collision.collider
				if Vector3.UP.dot(collision.normal) > 0.1:
					mob.squash()
					self.velocity.y = self.bounce_impulse

		# This makes the character follow a nice arc when jumping
		self.get_node("Pivot").rotation.x = math.pi / 6 * self.velocity.y / self.jump_impulse


	def die(self):
		self.call("emit_signal", "hit")
		self.queue_free()


	def _on_MobDetector_body_entered(self, _body):
		self.die()
@MarioMey
Copy link
Author

After some tests, I discovered some stuff:

The line that ruins everything

This is the line that makes Vector3.ZERO turns to that value:

self.velocity.y -= self.fall_acceleration * delta

... if I comment this line, Vector3.ZERO is always (0,0,0). Weeeirrrddd....

The guess

Someone from GODOT Español (Telegram group) told me that gravity Vector3(0,-1.25,0) is added to Vector3.ZERO. But this is a wrong behavior, because Vector3.ZERO must be always (0,0,0).

Another test: printing some constants:

    Vector3.AXIS_X = DOESN'T EXIST
    Vector3.AXIS_Y = DOESN'T EXIST
    Vector3.AXIS_Z = DOESN'T EXIST
    Vector3.ZERO <Vector3(x=0.0, y=-1.2500001192092896, z=0.0)>
    Vector3.ONE <Vector3(x=1.0, y=1.0, z=1.0)>
    Vector3.INF <Vector3(x=inf, y=inf, z=inf)>
    Vector3.LEFT <Vector3(x=-1.0, y=0.0, z=0.0)>
    Vector3.RIGHT <Vector3(x=1.0, y=0.0, z=0.0)>
    Vector3.UP <Vector3(x=0.0, y=1.0, z=0.0)>
    Vector3.DOWN <Vector3(x=0.0, y=-1.0, z=0.0)>
    Vector3.FORWARD <Vector3(x=0.0, y=0.0, z=-1.0)>
    Vector3.BACK <Vector3(x=0.0, y=0.0, z=1.0)>

As you can see, only Vector3.ZERO is affected

Workaround:

def _ready(self):
    self.zero = Vector3(0,0,0)
def _physics_process(self, delta):
    print(self.zero)

In this way, it always returns (0,0,0). But I don't think this is the solution.

@MarioMey
Copy link
Author

I found a solution and maybe this could be a bug.

By doing this:

velocity = Vector3.ZERO
direction = Vector3.ZERO

And then, something like:

velocity.y -= fall_acceleration * delta

Vector3.ZERO ends being (0,0,0) and it starts having the value that velocity or direction has. Vector3.ZERO is not a constant... because there is no constants in Python (someone told me this).

The solution is to do this:

velocity = Vector3(0,0,0)
direction = Vector3(0,0,0)

I keep this thread open because I don't know if it is a bug 🪲 or not 🤷.

@MarioMey MarioMey changed the title Vector3.ZERO returns wrong values. Vector3.ZERO stops being constant and returns wrong values. Jul 13, 2022
@touilleMan
Copy link
Owner

Hi @MarioMey !

Yes, Vector3.ZERO is just a plain Vector3 instance so modifying it creates this kind of surprises :'(

However your issue is a valuable input 😃 : I'm currently re-writting the project for Godot4, and will make sure the constant are real constant (by using properties, so each time you do Vector3.ZERO a new Vector3 is created !)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants