- Edited
I was working on a project of my own and decided to redo some of the player code, this time by use of two separate Vectors: spd_vec (Player Speed) and grv_vec (Player Gravity). Because I found out that you can add the two vectors together in move_and_slide_with_snap(), but however the problem I ran into is that the Y-Axis isn't colliding/snapping with the slopes (Shown in link/video)
The two vectors work by use of global_transform.basis[2] (Z-Axis / Speed) and global_transform.basis[1] (Y-Axis / Gravity) so then I can make the player fall in a different direction for gravity modification. This is the code I used for the player:
extends KinematicBody
var movedir = Vector3(0,0,0)
var velocity = Vector3()
var spd_vel = Vector3()
var grv_vel = Vector3()
var gravity = -35
var camera
var character
const SPEED = 12
const ACCELERATION = 5
const DECELERATION = 10
const JUMP_HEIGHT = 10
var is_moving = false
var can_jump = false
var rot_speed = 0
var mov_speed = 0
var camrot_h = 0
var camrot_v = 0
var floored = false
var ang_grav = false
var ang_gate = false
func _ready():
character = get_node(".")
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
$CamRoot.set_as_toplevel(true)
func _input(event):
if event is InputEventMouseMotion:
camrot_h += -event.relative.x
camrot_v += event.relative.y
pass
pass
func _physics_process(delta):
# Rotating our camera by mouse controls (press Alt+ f4 to quit, just in case)
camera = get_node("CamRoot/H/V/Camera").get_global_transform()
$CamRoot.global_transform.origin = self.global_transform.origin
$CamRoot/H.rotation_degrees = Vector3(0,(camrot_h*(delta*10)),0)
$CamRoot/H/V.rotation_degrees = Vector3((camrot_v*(delta*10)),0,0)
# Speed Movement and Jump
if Input.is_action_pressed("left"):
rot_speed = lerp(rot_speed, 5, .1)
pass
elif Input.is_action_pressed("right"):
rot_speed = lerp(rot_speed, -5, .1)
else:
rot_speed = lerp(rot_speed, 0, .1)
#rotation += (global_transform.basis[1] * delta) * rot_speed
if Input.is_action_pressed("up"):
mov_speed = lerp(mov_speed, 400, .1)
is_moving = true
elif Input.is_action_pressed("down"):
mov_speed = lerp(mov_speed, -400, .1)
is_moving = true
else:
mov_speed = lerp(mov_speed, 0, .1)
is_moving = false
var ground = get_node("FloorCast").get_collision_normal()
spd_vel = (global_transform.basis[2].normalized() * delta) * mov_speed
if Input.is_action_just_pressed("jump"):
grv_vel = (global_transform.basis[1].normalized() * delta) * 1000
else:
grv_vel += (global_transform.basis[1].normalized() * delta) * gravity
if is_on_floor() or is_on_wall():
if ang_gate == false:
gravity = 0
else:
gravity = -35
else:
gravity = -35
# Moving our character (Also used to determine ground collision)
var slides = move_and_slide_with_snap(spd_vel + grv_vel, ground, Vector3(0,1,0), true)
# Player origin base (Feet)
var down = -global_transform.basis.y
# Freezes player rotation while moving
if is_moving && !Input.is_key_pressed(KEY_SHIFT):
set_rotation($CamRoot/H.global_transform.basis.get_euler())
# Alternate character collison detection
var tilt = move_and_collide(global_transform.origin,true,true,true)
### OLD Ignore this ###
# if ang_grav == true:
# if is_moving == false and (is_on_floor() or is_on_wall()):
# spd_vel = Vector3.ZERO
# grv_vel = Vector3.ZERO
# elif ang_grav == false:
# if is_moving == false:
# spd_vel = Vector3.ZERO
# if (is_on_floor() or is_on_wall()):
# grv_vel = Vector3.ZERO
# Modify gravity based on slopes and wheter on floor or not
if ang_grav == true:
if is_moving == false and (is_on_floor() or is_on_wall()):
spd_vel = Vector3.ZERO
if ang_gate == true:
pass
else:
grv_vel = Vector3.ZERO
elif ang_grav == false:
if is_moving == false:
spd_vel = Vector3.ZERO
if (is_on_floor()):
grv_vel = Vector3.ZERO
pass
# Used to determine if on a slope or not (Slopes / Part 2)
if test_move(global_transform,down,true):
#print("Ground!")
var n = get_node("FloorCast").get_collision_normal()
#var floor_angle = rad2deg(acos(n.dot(Vector3(0,1,0))))
var floor_angle = rad2deg(acos(n.dot(global_transform.basis.y)))
#print(floor_angle)
if floor_angle > 0:
ang_grav = true
if floor_angle > 60:
$CollisionShape3.shape.slips_on_slope = true
ang_gate = true
else:
$CollisionShape3.shape.slips_on_slope = false
ang_gate = false
pass
else:
ang_grav = false
else:
pass
#print(-global_transform.basis.y)
# if tilt is colliding
if tilt:
pass
# if move_and_slide detects a collision
if get_slide_count() > 0:
for i in get_slide_count():
print(get_slide_collision(i).normal)
pass
else:
if is_moving == true:
pass
else:
pass
pass
global_transform = global_transform.orthonormalized()
I organized the lines of code based on which part does for ease of taking a look at the code. I honestly have no Idea how to get the collision to stay/snapped to the slope. Any help is appreciated!
If you need the demo project for a more better Idea I'm running into, let me know and I'll upload it.