#Johann Massyn, 23/06/2019 #Godot (3.1) 3D Player movement script #Atatch script to 3d node with following structure #Kinematic body: Player # - CollisionShape: CollisionShape # - Camera: Camera extends KinematicBody export (bool) var can_move = true #Alow player to input movment. export (bool) var can_sprint = true #Alow player to toggle sprint movment. export (float) var move_speed = 8 #Players movement speed export (float) var move_speed_sprint = 16#16 #Players sprint movement speed export (bool) var move_sprint = false #Player sprinting toggle export (float) var move_speed_max = 200 #Player maximum velocity export (float) var move_acceleration = 7 #Players acceleration to movment speed export (float) var move_deacceleration = 10 #Players deacceleration from movment speed export (bool) var mouse_captured = true #Toggles mouse captured mode export (float) var mouse_sensitivity_x = 0.3 #Mouse sensitivity X axis export (float) var mouse_sensitivity_y = 0.3 #Mouse sensitivity Y axis export (float) var mouse_max_up = 45 #Mouse max look angle up export (float) var mouse_max_down = -50 #Mouse max look angle down export (float) var jump_speed = 6 #Players jumps speed export (float) var jump_speed_sprint = 12 #Players jumps speed export (bool) var allow_fall_input = true #Alow player to input movment when falling export (bool) var stop_on_slope = false #Toggle sliding on slopes export (float) var max_slides = 4 #Maximum of slides export (float) var floor_max_angle = 60 #Maximum slop angle player can traverse export (bool) var infinite_inertia = false #Toggle infinite inertia export (float) var gravaty = 1.625 #9.81 #Gravaty acceleration #export (Vector3) var gravaty_vector = Vector3(0, -1, 0) #Gravaty normal direction vector #export (Vector3) var floor_normal = Vector3(0, 1, 0) #Floor normal direction vector #export (Vector3) var jump_vector = Vector3(0, 1, 0) #Jump normal direction vector export (Vector3) var velocity = Vector3(0, 0, 0) #Initial velocity onready var up = global_transform.origin.normalized() onready var forward = global_transform.basis.y onready var right = forward.cross(up).normalized() var maxheight = 10.783 var minheight = -8.719 var radius = 1737.4 export (int) var move_mode = 0 enum moveMode {MODE_NORMAL, MODE_HOVER, MODE_FLY} var height_over_ground = 0 func _ready(): if mouse_captured: Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) pass func moveTo(pos = Vector3()): if pos.z == 0: pos.z = radius move_and_slide(Common.latLonToGlobal(Vector3(pos.x,pos.y,pos.z)), Vector3.UP) func getSpos(): var sPos = Common.globalToLatLon(self.global_transform.origin) sPos.y = Common.relativeToAbsolute(sPos.y) return sPos func _process(delta): var pos = self.global_transform.origin .get_parent().get_node("UI/1").text="x:%s y:%s z:%s" %[pos.x, pos.y, pos.z] .get_parent().get_node("UI/2").text="latlonhight: "+str(getSpos())+","+str(pos.length()) .get_parent().get_node("UI/3").text="vel: %s" % velocity .get_parent().get_node("UI/4").text="mode: %s" % move_mode height_over_ground = pos.length() - radius*1000 #floor_normal = pos.normalized() #gravaty_vector = floor_normal * -1 #self.transform.basis.y = floor_normal #rotation_degrees.x = 90 func _physics_process(delta): up = global_transform.origin.normalized() right = forward.cross(up).normalized() forward = up.cross(right).normalized() transform.basis = Basis(right, up, -forward) # we differentialte the y portion to apply a different speed (jump_speed) var horDir = Vector3() var vertDir = Vector3() match move_mode: moveMode.MODE_FLY: horDir = forward moveMode.MODE_HOVER: horDir = -velocity * 0.1 if can_move and (is_on_floor() or allow_fall_input): #Left if Input.is_action_pressed("move_left"): horDir -= right #Right if Input.is_action_pressed("move_right"): horDir += right #Forward if Input.is_action_pressed("move_forward"): horDir += forward #Backwards if Input.is_action_pressed("move_backward"): horDir -= forward # Jump #if is_on_floor(): #if Input.is_action_pressed("move_up"): # dir += up if Input.is_action_pressed("move_down"): vertDir -= up #Jump if Input.is_action_pressed("move_up"):# and is_on_floor(): vertDir += up #Sprint toggle if can_sprint and Input.is_action_just_pressed("move_sprint"): #and is_on_floor(): move_sprint = true if can_sprint and not Input.is_action_pressed("move_sprint"): #and is_on_floor(): move_sprint = false if move_sprint: move_speed_max = 600 + 2000 * inverse_lerp(minheight*1000, maxheight*1000, height_over_ground) else: move_speed_max = 200 + 800 * inverse_lerp(minheight*1000, maxheight*1000, height_over_ground)# height_over_ground * 100 + 400 #Hover toggle if Input.is_action_just_pressed("hover_mode"): if move_mode != moveMode.MODE_HOVER: move_mode = moveMode.MODE_HOVER else: move_mode = moveMode.MODE_NORMAL #Fly toggle if Input.is_action_just_pressed("fly_mode"): if move_mode != moveMode.MODE_FLY: move_mode = moveMode.MODE_FLY else: move_mode = moveMode.MODE_NORMAL if move_mode == moveMode.MODE_NORMAL and horDir+vertDir == Vector3(0, 0, 0): # in NORMAL MODE velocity stays unchanged without input pass else: #velocity = velocity.linear_interpolate(horDir * (move_speed_sprint if move_sprint else move_speed) # + vertDir * (jump_speed_sprint if move_sprint else jump_speed), move_acceleration * delta) velocity += (horDir * (move_speed_sprint if move_sprint else move_speed) + vertDir * (jump_speed_sprint if move_sprint else jump_speed)) * move_acceleration * delta #velocity = velocity.linear_interpolate(vertDir * (jump_speed_sprint if move_sprint else jump_speed), move_acceleration * delta) #if !is_on_floor(): #velocity -= up * gravaty # limit Speed if velocity.length() > move_speed_max: velocity = velocity.normalized() * move_speed_max move_and_slide(velocity, up) #var collide = move_and_collide(velocity, true, true, true) #if collide: # velocity = Vector3() #else: # transform.origin += velocity #Smooth movement #dir = transform.basis.xform(dir.normalized()) * (move_speed_sprint if move_sprint else move_speed) #if is_on_floor() or dir != Vector3(0, 0, 0): # var acceleration = move_acceleration if dir.dot(velocity) else move_deacceleration # var vp = gravaty_vector.normalized() * velocity.dot(gravaty_vector) # velocity = (velocity - vp).linear_interpolate(dir, acceleration * delta) + vp #Gravaty #if !is_on_floor(): # velocity += gravaty_vector * gravaty * delta #Player move #move_and_slide(velocity, floor_normal, stop_on_slope, max_slides, deg2rad(floor_max_angle), infinite_inertia) #Player orientation #var spos = Common.globalToLatLon(self.global_transform.origin) #global_rotate(Vector3(1,0,0), deg2rad(spos.x)) #global_rotate(Vector3(0,1,0), deg2rad(spos.y)) func _input(event): #Mouse movement if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED: #rotate_y(deg2rad(-event.relative.x * mouse_sensitivity_x)) forward = forward.rotated(up, deg2rad(-event.relative.x * mouse_sensitivity_x)) #rotate_y(deg2rad(-event.relative.x * mouse_sensitivity_x)) #self.rotation_degrees.y += -event.relative.x * mouse_sensitivity_x $Camera.rotation_degrees.x = clamp($Camera.rotation_degrees.x + -event.relative.y * mouse_sensitivity_y, mouse_max_down, mouse_max_up) pass