Godot 3:如何使用重力和重力方向在墙壁上行走?

发布于 2025-01-26 07:50:45 字数 3603 浏览 3 评论 0原文

我想与可以在墙壁和天花板上行走的玩家在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

Nodes Configuration

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清引 2025-02-02 07:50:45

看起来,如果您不在地板上,则您从玩家的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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文