Godot 3:如何使用重力和重力方向在墙壁上行走?
我想与可以在墙壁和天花板上行走的玩家在Godot上进行3D游戏,但我试图做到这一点,但它不起作用:(
这是我的播放器第一人称控制器的代码:
extends KinematicBody
export var GravityDirection = Vector3(-9.8, 0, 0)
var held_object: Object
var velocity = Vector3.ZERO
var speed = 10
var MAX_SPEED = 30
var GravityStrength = 9.8
var throw_force: float = 200
var wall_one = Vector3(-9.8, 0, 0)
var wall_two = Vector3(0, 0, -9.8)
var wall_three = Vector3(9.8, 0, 0)
var wall_four = Vector3(0, 0, 9.8)
var ground = Vector3(0, -9.8, 0)
onready var ray = $"Camera/Hand/RayCast"
onready var hold_position = $"Camera/Hand/HoldPosition"
# Camera
onready var player_camera = $"Camera"
var spin = 0.1
export var mouse_sensitivity = 5
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _physics_process(delta):
var Gravity = GravityStrength * GravityDirection
var Velocity = Gravity * delta
move_and_collide(Velocity)
var run_once = 0
while 1:
if run_once == 0:
if GravityDirection == wall_one:
rotate_x(90)
run_once = 1
player_camera.rotation_degrees.y = 180
player_camera.rotation_degrees.z = 0
if Input.is_action_just_pressed("player_fire"):
fire()
if not is_on_floor():
Velocity.y += -GravityStrength
movement(delta)
velocity = move_and_slide(velocity, Vector3.ZERO)
if Input.is_action_just_pressed("player_pick"):
if held_object:
held_object.mode = RigidBody.MODE_RIGID
held_object.collision_mask = 1
held_object = null
else:
if ray.get_collider():
held_object = ray.get_collider()
held_object.mode = RigidBody.MODE_KINEMATIC
held_object.collision_mask = 0
if held_object:
held_object.global_transform.origin = hold_position.global_transform.origin
#_process_input()
#_process_gravity()
# Mouvement
func movement(_delta):
var dir = Vector3.ZERO
var vel_y = velocity.y
velocity = Vector3.ZERO
# Movement forward and backward
if Input.is_action_pressed("player_forward"):
dir += transform.basis.z
elif Input.is_action_pressed("player_backward"):
dir -= transform.basis.z
# Movement Left and Right
if Input.is_action_pressed("player_left"):
dir += transform.basis.x
elif Input.is_action_pressed("player_right"):
dir -= transform.basis.x
velocity = dir.normalized() * speed
velocity.y = vel_y
func _input(event):
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
rotate_y(lerp(0, -spin, event.relative.x * (mouse_sensitivity * 0.01) ))
player_camera.rotate_x(lerp(0,spin, event.relative.y * (mouse_sensitivity * 0.01)) )
#Clamp vertical rotation
var curr_rot = player_camera.rotation_degrees
curr_rot.x = clamp(curr_rot.x, -60, 60)
player_camera.rotation_degrees = curr_rot
func fire():
print("fire")
if ray.get_collider() != null and ray.get_collider().is_in_group("enemy"):
print(ray.get_collider())
ray.get_collider().hp -= 10
在代码中,您可以找到相机和重力系统的fonctions。拿起刚性的身体。 . you've understood but I don't know how to make a system like this!!!
I think there is a way to optimize the script, so, I need help :D
If you can perform my code it's nice! 有一个不错的代码!
I want to make a 3D game on Godot with the player who can walk on walls and ceiling but I've tried to make this but it didn't work :(
This is the code of my Player First Person Controller:
extends KinematicBody
export var GravityDirection = Vector3(-9.8, 0, 0)
var held_object: Object
var velocity = Vector3.ZERO
var speed = 10
var MAX_SPEED = 30
var GravityStrength = 9.8
var throw_force: float = 200
var wall_one = Vector3(-9.8, 0, 0)
var wall_two = Vector3(0, 0, -9.8)
var wall_three = Vector3(9.8, 0, 0)
var wall_four = Vector3(0, 0, 9.8)
var ground = Vector3(0, -9.8, 0)
onready var ray = quot;Camera/Hand/RayCast"
onready var hold_position = quot;Camera/Hand/HoldPosition"
# Camera
onready var player_camera = quot;Camera"
var spin = 0.1
export var mouse_sensitivity = 5
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _physics_process(delta):
var Gravity = GravityStrength * GravityDirection
var Velocity = Gravity * delta
move_and_collide(Velocity)
var run_once = 0
while 1:
if run_once == 0:
if GravityDirection == wall_one:
rotate_x(90)
run_once = 1
player_camera.rotation_degrees.y = 180
player_camera.rotation_degrees.z = 0
if Input.is_action_just_pressed("player_fire"):
fire()
if not is_on_floor():
Velocity.y += -GravityStrength
movement(delta)
velocity = move_and_slide(velocity, Vector3.ZERO)
if Input.is_action_just_pressed("player_pick"):
if held_object:
held_object.mode = RigidBody.MODE_RIGID
held_object.collision_mask = 1
held_object = null
else:
if ray.get_collider():
held_object = ray.get_collider()
held_object.mode = RigidBody.MODE_KINEMATIC
held_object.collision_mask = 0
if held_object:
held_object.global_transform.origin = hold_position.global_transform.origin
#_process_input()
#_process_gravity()
# Mouvement
func movement(_delta):
var dir = Vector3.ZERO
var vel_y = velocity.y
velocity = Vector3.ZERO
# Movement forward and backward
if Input.is_action_pressed("player_forward"):
dir += transform.basis.z
elif Input.is_action_pressed("player_backward"):
dir -= transform.basis.z
# Movement Left and Right
if Input.is_action_pressed("player_left"):
dir += transform.basis.x
elif Input.is_action_pressed("player_right"):
dir -= transform.basis.x
velocity = dir.normalized() * speed
velocity.y = vel_y
func _input(event):
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
rotate_y(lerp(0, -spin, event.relative.x * (mouse_sensitivity * 0.01) ))
player_camera.rotate_x(lerp(0,spin, event.relative.y * (mouse_sensitivity * 0.01)) )
#Clamp vertical rotation
var curr_rot = player_camera.rotation_degrees
curr_rot.x = clamp(curr_rot.x, -60, 60)
player_camera.rotation_degrees = curr_rot
func fire():
print("fire")
if ray.get_collider() != null and ray.get_collider().is_in_group("enemy"):
print(ray.get_collider())
ray.get_collider().hp -= 10
In the code, you can find fonctions for the camera and gravity system. Also, there is a fonction to pick up rigid bodies. I want to make a system where when the Gravity has a specific direction, the mesh rotate to 90°. I've made a "GlobalRay" with 6 RayCast to detect collisions (walls) and register face blablabla... you've understood but I don't know how to make a system like this!!!
I think there is a way to optimize the script, so, I need help :D
If you can perform my code it's nice! Have a nice code!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来,如果您不在地板上,则您从玩家的Y速度中减去重力弹力,而您应该将速度添加到玩家的速度中。否则,这里的这个问题非常笼统,可以通过多种方式实现。 wall_one,wall_two,wall_three等。我认为,在一个大小的情况下,更好的是,他们可以在以后的实现中使用与其他所有事物相同的重力度修饰符,但这只是我。
It looks like you're subtracting GravityStrength from the player's y velocity if they are not on the floor, while you should be adding the Velocity to the player's velocity. Otherwise, this question here is very general and could be implemented in a lot of ways. wall_one, wall_two, wall_three etc. I think would be better off with a magnitude of one so they could undergo the same GravityStrength modifier as everything else in later implementations, but that's just me.