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

3d characters should have easier implementation. #11050

Closed
toger5 opened this issue Sep 7, 2017 · 16 comments
Closed

3d characters should have easier implementation. #11050

toger5 opened this issue Sep 7, 2017 · 16 comments

Comments

@toger5
Copy link
Contributor

toger5 commented Sep 7, 2017

Currently it is some work to make a 3d character work!

Basics:

there are two option:

  • rigid body with character mode
  • kinematic body

Both modes don't allow for rotation on the y axis which makes them hard to use.

this would be the idea character gdscript I could imagine:
(this example is for rigid body in character mode)

export var speed = 0.5

_ready():
   Input.set_mouse_mode(MOUSE_MODE_CAPTURED)

_process_input(ev):
   if ev is InputEventMouseMotion:
      $Camera.rotate_x(ev.relative.y / 100)
      rotate_y(ev.relavtive.x / 100)

_process(delta):
   var dir = Vector3()
   if is_action_pressed("forward"):
      dir += Vector3(1,0,0)
   if is_action_pressed("backwards"):
      dir += Vector3(-1,0,0)
   if is_action_pressed("left"):
      dir += Vector3(0,0,-1)
   if is_action_pressed("right"):
      dir += Vector3(0,0,1)
   set_linear_velocity(dir * speed * delta)

that would be just great since it would be super easy to understand and super short.

the issues

Since rotate_y does not work for rigidBody (in character mode) it is much harder. (need to do math in which direction the camera looks and than modify the direction based on that...)

The issue with kinematic body is:
move_and_slide is global.. that means you have to do a vector transformation to get the vector pointing forward in global space.

I think kinematic body is the better character anyways since it allows for really simple jumping and move and slide is pretty nice too.

It seems like they were inspired by their 2d counterparts. that explains why character mode has NO rotation at all (for rigidbody)
and why move and slide uses global axis.

So for 3.0 the api for those bodies should be adapted for 3d.

what I actually propose:

option one (kinematic body):

  • add a function move_and_slide_global
  • add a function move_global
  • make move_and_slide, move use local vectors.
    OR
  • add a param for local movement to both functions:
    • move_and_collide( Vector3 rel_vec, local=true )
    • move_and_slide( Vector3 linear_velocity, local=true, Vector3 floor_normal=Vector3( 0, 0, 0 ), float slope_stop_min_velocity=0.05, int max_slides=4, float floor_max_angle=0.785398 )

option two (rigidBody, in character mode)

  • allow rotation on the y axis (keep rotation on x + z disabled)

I think even implementing both is a really good idea since I don't see a reason why there should not be the option for rotating on the y axis or why there should be no local axis move and slice

@novemberist
Copy link

I don't know if I understand you correctly, but KinematicBody2D's move() and move_and_slide() also move the body on the global axes (i.e. without any regard for its rotation).

I also found it very inconvenient to use a KinematicBody as an fps controller since move() is not easily usable (without doing rotation calculations) and translate, which does respect rotation, doesn't work well for collision detection.

@toger5
Copy link
Contributor Author

toger5 commented Sep 7, 2017

@novemberist yea the 2d one use global axis. which makes a lot of sense since top down usually uses global input (when keyboard is used) and with mouse controls you also have a global vector.
when doing jump and run style 2d global input is also easier since jump and run characters don't rotate anyways so it makes not difference.

But it is good to know that I'm not the only one who was bothered by the 3d physics bodies.

@novemberist
Copy link

novemberist commented Sep 7, 2017

If the idea is to make move() more versatile (by being able to decide between local/global axis movement), I don't think that we should make a difference between 2D and 3D though. I can also think of a couple examples where it would make sense to be able to move locally, even in 2D. Think of a game like e.g. Hotline Miami, or a top-down racing game, where movement direction is always dependent on the players rotation.

btw. are you sure about not being able to rotate a RigidBody in character mode? I'm could swear this worked at some point...

@toger5
Copy link
Contributor Author

toger5 commented Sep 7, 2017

just tried yea. no rotation...
also the docs say so:

This behaves like a rigidBody but cannot rotate

@novemberist but you are right adding a param local = true also to the 2d functions would make a lot of sense. (for consistency and in some cases you actually want to rotate in 2d and not be bothered by making the rotation vector math)

@HummusSamurai
Copy link
Contributor

HummusSamurai commented Sep 8, 2017

KinematicBody will always be the better character controller than RigidBody.

I think it makes sense to add another variant for move_and_slide() with one being for global and another for local axes, as that would help reduce the most common code by a few lines.

@kubecz3k
Copy link
Contributor

kubecz3k commented Sep 8, 2017

I was y rotating 3d character bodies without problems in 2.x with look_at method (however the shape was uniform so at that time I would have the same effect if I would only rotate asset model)

@toger5
Copy link
Contributor Author

toger5 commented Sep 8, 2017

@kubecz3k which charcter body?
Rigid body in character mode or kinematic body?
Kinematic body can rotate but that sadly does not chnage how the coordinate system for move.

@toger5
Copy link
Contributor Author

toger5 commented Sep 8, 2017

@HummusSamurai I dont like kinematicBody that much since it has no grvavity support out of the box. And i havent gotten good results with simple implementations like always applying down movement (in the move_and_slide function) yet...
Rigid bodies are great for just a out of the box working solution. Of course, as soon as you get more advanced and add things like: wall jumps, climbing, rolling to dodge you should use a kinematic body.

@kubecz3k
Copy link
Contributor

kubecz3k commented Sep 8, 2017

@toger5 rigid body in character mode

@toger5
Copy link
Contributor Author

toger5 commented Sep 8, 2017

@kubecz3k are u sure? If you can reproduce it would be great. I tried with almost all versions i could get my hands on... (not really true... But i tried with 2. And 3) and i could not rotate...
Although therewere some really wired things happening. That it worked sometimes. But i think in those cases i put it into rigid body mode...
So if you can show me a situation where ot works wpuld be great!

@kubecz3k
Copy link
Contributor

kubecz3k commented Sep 8, 2017

@toger5 well all characters in my previous project were working like that, so I'm sure it's the case for 1.x and 2.x Haven't ported those to 3.x yet however but I would be very surprised if it's not working like that anymore.

@HummusSamurai
Copy link
Contributor

@toger5 Have you tried using move_and_slide() like in the 3D platformer demo, where gravity is passed as a second argument?

I haven't had problems with that.

@toger5
Copy link
Contributor Author

toger5 commented Sep 8, 2017

oh the floor part is for gravity... I was just applying movement down. which was lagging on the ground. I think I just have to try more. But I believe you guys that kinematic body is the better option. So a move_and_slide function with a local coordiatne option would be more important I guess

@toger5
Copy link
Contributor Author

toger5 commented Sep 8, 2017

@HummusSamurai just tried the gravity for kinematic body. I can get it to work to calculate my own velocity based on a accelaration... But if I pass a second param. for p_floor_direction I don't get any gravity. would u mind making an example?

@toger5
Copy link
Contributor Author

toger5 commented Sep 9, 2017

I again did some testing and research how a 3d character is done in the demos. I'm still not satisfied with the results...

  • can't get is_on_floor working. (so I cannot reset the velocity.y value when touching the ground to 0)
  • need to calculate gravity myself. which is kind of okay... (not a real issue)
  • body does not detect when leaving a collision plane. although the velocity.y value decreases all the time, It does not fall when leaving the coalition plane...

@Calinou
Copy link
Member

Calinou commented Aug 28, 2020

Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine.

The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker.

If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance!

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

No branches or pull requests

5 participants