extends KinematicBody # export variables export(NodePath) var body_nodepath export(NodePath) var lookingAt_nodepath export(NodePath) var animation_nodepath export(NodePath) var ui_interact_nodepath export(int) var keycard_lvl export(Array) var key_chain # const const GRAVITY = -24.8 const JUMP_SPEED = 8 const MOVE_SPEED = 6 const SPRINT_SPEED = 10 const ACCEL = 15.0 const MAX_SLOPE_ANGLE = 40 const MOUSE_SENSITIVITY = 0.05 const INTERACT_DISTANCE = 4 # private members var _body: Spatial var _camera: Camera var _lookCast: RayCast var _animation: AnimationPlayer var _dir = Vector3(); var _vel = Vector3(); var _is_sprinting; var _prev_look; # TODO: move to global var _inventory: Control func _ready(): # Assign child node variables _body = get_node(body_nodepath) as Spatial # = $Body assert(null != _body) _camera = $Body/Camera assert(null != _camera) _animation = get_node(animation_nodepath) as AnimationPlayer assert(null != _animation) # Setup mouse look Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) _lookCast = get_node(lookingAt_nodepath) as RayCast _lookCast.cast_to = Vector3(0, 0, INTERACT_DISTANCE) _inventory = get_node("HUD") func _physics_process(delta): process_input() process_movement(delta) func _process(delta): check_interact() process_animations() func process_input(): # Walking var input_movement_vector = Vector2() if Input.is_action_pressed("move_fwrd"): input_movement_vector.y += 1 if Input.is_action_pressed("move_back"): input_movement_vector.y -= 1 if Input.is_action_pressed("move_left"): input_movement_vector.x -= 1 if Input.is_action_pressed("move_right"): input_movement_vector.x += 1 # look around with mouse _dir = Vector3() var camera_transform = _camera.get_global_transform() _dir += -camera_transform.basis.z * input_movement_vector.y _dir += camera_transform.basis.x * input_movement_vector.x # jumping if Input.is_action_just_pressed("move_jump") and is_on_floor(): _vel.y = JUMP_SPEED # sprinting _is_sprinting = Input.is_action_pressed("move_sprint") # Taking a pill # TODO: Should be moved to a different component which only handles pills - this script should only do movement # Only here for testing purposes! if Input.is_action_just_pressed("take_pill"): Pills.take_pill() Logger.info("Player took a pill; new level: %s" % [Pills.get_round_level()]) func process_movement(delta): _vel.y += delta * GRAVITY # set movement speed var target = _dir if _is_sprinting: target *= SPRINT_SPEED else: target *= MOVE_SPEED var hvel = _vel hvel = hvel.linear_interpolate(target, ACCEL * delta) _vel.x = hvel.x _vel.z = hvel.z _vel = move_and_slide(_vel, Vector3(0, 1, 0), 0.05, 4, deg2rad(MAX_SLOPE_ANGLE)) func process_animations(): _animation.playback_speed = _vel.length() / MOVE_SPEED func check_interact(): if _lookCast.is_colliding(): var collider = _lookCast.get_collider() if collider.is_in_group("Touchables"): #show interact tooltip get_node(ui_interact_nodepath).show() #enable outline of seen object collider.get_node(collider.outline_path).show() if _prev_look != null and is_instance_valid(_prev_look): if _prev_look != collider: _prev_look.get_node(_prev_look.outline_path).hide() _prev_look = collider #do interaction if Input.is_action_just_pressed("interact"): collider.do_interact(self) _inventory.add_item(collider.name) else: #stop showing interact tooltip get_node(ui_interact_nodepath).hide() elif _prev_look != null and is_instance_valid(_prev_look): #disable outline of last seen object _prev_look.get_node(_prev_look.outline_path).hide() _prev_look = null #stop showing interact tooltip get_node(ui_interact_nodepath).hide() func _input(event): # capture mouse movement if event is InputEventMouseMotion: _camera.rotate_x(deg2rad(event.relative.y * MOUSE_SENSITIVITY * -1)) self.rotate_y(deg2rad(event.relative.x * MOUSE_SENSITIVITY * -1)) # Prevent player from doing a purzelbaum _camera.rotation_degrees.x = clamp(_camera.rotation_degrees.x, -70, 70)