built single-resource based script for weapons, most are broken right now

This commit is contained in:
derek
2025-03-03 15:33:59 -06:00
parent 3e6ad2a56d
commit 15f32eff61
16 changed files with 1566 additions and 191 deletions

File diff suppressed because one or more lines are too long

274
assets/mac9508.tmp Normal file

File diff suppressed because one or more lines are too long

772
assets/mac_10_uber.tscn Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="bullet_resource" load_steps=4 format=3 uid="uid://covnkagmv8b1x"]
[ext_resource type="PackedScene" uid="uid://dqhltdnqyg8ni" path="res://assets/bullet.tscn" id="1_d24o1"]
[ext_resource type="PackedScene" uid="uid://crvohhc6kgshn" path="res://assets/bullet_hole.tscn" id="2_qickn"]
[ext_resource type="Script" path="res://scripts/bullet_resource.gd" id="3_0h3h3"]
[resource]
script = ExtResource("3_0h3h3")
asset = ExtResource("1_d24o1")
ammo_type = 0
bullet_hole = ExtResource("2_qickn")

View File

@@ -0,0 +1,27 @@
[gd_resource type="Resource" script_class="weapon_resource" load_steps=6 format=3 uid="uid://byimj60rup3an"]
[ext_resource type="Resource" uid="uid://covnkagmv8b1x" path="res://assets/weaponresources/light_ammo.tres" id="1_y4ehq"]
[ext_resource type="PackedScene" uid="uid://c1gdehrsytlkk" path="res://assets/casing.tscn" id="2_7wxcs"]
[ext_resource type="Texture2D" uid="uid://gx3iw54iemho" path="res://assets/Textures/ObjectTextures/mac10.png" id="2_a3oyj"]
[ext_resource type="Script" path="res://scripts/weapon_resource.gd" id="3_10fhq"]
[ext_resource type="PackedScene" uid="uid://cp8563f0oxvff" path="res://assets/mag1.tscn" id="4_fiujt"]
[resource]
script = ExtResource("3_10fhq")
gun_name = "Mac 10"
gun_icon = ExtResource("2_a3oyj")
bullet = ExtResource("1_y4ehq")
fire_mode = 0
fov_zoom_amt = 0.98
ads = false
recoil_amount = Vector3(0.1, 0.05, 0.05)
kick_amount = 0.1
max_ammo = 20
start_mags = 3
bullet_damage = 1
smoke_enabled = false
bullet_force_mod = 5.0
bullet_speed = 600
casing = ExtResource("2_7wxcs")
casing_array = Array[NodePath]([])
mag = ExtResource("4_fiujt")

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=21 format=3 uid="uid://jdwpc622vmok"]
[gd_scene load_steps=22 format=3 uid="uid://jdwpc622vmok"]
[ext_resource type="Script" path="res://scripts/LevelManager.gd" id="1_1bnbi"]
[ext_resource type="Resource" uid="uid://bxcxqt7rmfvdw" path="res://GameModes/hubworld.tres" id="2_62iy8"]
@@ -17,6 +17,7 @@
[ext_resource type="PackedScene" uid="uid://bji3bukudxlhm" path="res://assets/health_dispenser.tscn" id="13_h5xga"]
[ext_resource type="PackedScene" uid="uid://d4suhr3allsj" path="res://assets/revolver2_pickup.tscn" id="14_ak7yq"]
[ext_resource type="PackedScene" uid="uid://dyu46bns8mesv" path="res://assets/mac10_pickup.tscn" id="17_u30rd"]
[ext_resource type="PackedScene" uid="uid://3hvtwn2qotle" path="res://assets/mac10_UBER_pickup.tscn" id="18_1idjd"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_s7e4t"]
sky_top_color = Color(0.623488, 0.812575, 0.900791, 1)
@@ -260,3 +261,6 @@ transform = Transform3D(-0.00572468, 0, -0.999984, 0, 1, 0, 0.999984, 0, -0.0057
item = ExtResource("17_u30rd")
item_name = "Mac 10"
item_price = 100
[node name="mac10_pickup" parent="." instance=ExtResource("18_1idjd")]
transform = Transform3D(0.533245, 0.845961, 0, -0.845961, 0.533245, 0, 0, 0, 1, 4.67892, 2.14044, 7.83235)

View File

@@ -1,15 +1,12 @@
extends RigidBody3D
var bullet_speed
var bullet_drop
var random_spread_amt
var bullet_damage
var instance_bullethole
var bullet_force_mod = 1.0
var distance_from_player
var player_position
var player_velocity
var bullet_active = true
var bullet_damage
var instance_bullethole
var bullet_force_mod
var bullet_speed
@onready var mesh = $Cylinder
@onready var particles = $GPUParticles3D
@@ -29,7 +26,7 @@ func _physics_process(delta):
angular_velocity = Vector3(0,0,0)
distance_from_player = abs(self.global_position - player_position)
var distance_from_player = abs(self.global_position - player_position)
if distance_from_player.length() > 2:
visible = true

View File

@@ -0,0 +1,6 @@
extends Resource
class_name bullet_resource
@export var asset : Resource
@export_enum("Light", "Medium", "Heavy", "Shotgun", "Rocket") var ammo_type: int
@export var bullet_hole : Resource

View File

@@ -1,153 +0,0 @@
extends Node3D
@export_group("Gun Feel")
@export var gun_name : String
@export_enum("Auto", "Single", "Burst") var fire_mode: int
@export var fov_zoom_amt = .98
@export var recoil_amount : Vector3 = Vector3(.2,.05,.05)
@export var max_ammo = 15
@export var start_mags = 3
@export var bullet_damage = 1
@export var bullet_force_mod = 5.0
@export var bullet_speed = 150
@export var bullet_drop = .3
@export var random_spread_amt = 1.0
@export var fire_pitch_scale_amt = .2
@export_group("Gun Assets")
@export_subgroup("Main Assets")
@export var flare_light : Node
@export var bullet : Resource
@export var bullethole : Resource
@export var casing : Resource
@export var mag : Resource
@export_subgroup("Raycast Nodes")
@export var anim_player : Node
@export var barrel_raycast : Node
@export var casing_ejector : Node
@export var mag_ejector : Node
@export_subgroup("Audio Clips")
@export var audio_fire : Node
@export var audio_empty : Node
@export var audio_reload : Node
@onready var player = get_tree().current_scene.player
@onready var level_control = get_tree().current_scene
@onready var ammo_current
var start_position
var start_rotation
var random_spread_start
var cycle_count_start
var cycle_count
var rng = RandomNumberGenerator.new()
var gun_index
#var ammo_current
var ammo_reserve
# Called when the node enters the scene tree for the first time.
func _ready():
random_spread_start = random_spread_amt
ammo_current = level_control.ammo_current[gun_index]
ammo_reserve = level_control.ammo_reserve[gun_index]
if fire_mode == 0:
cycle_count = 1
cycle_count_start = 1
elif fire_mode == 1:
cycle_count = 1
cycle_count_start = 1
elif fire_mode == 2:
cycle_count = 3
cycle_count_start = 3
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
pass
func reload_finished():
if level_control.ammo_reserve[gun_index] >= max_ammo:
level_control.ammo_current[gun_index] += max_ammo
level_control.ammo_reserve[gun_index] -= max_ammo
else:
level_control.ammo_current[gun_index] += level_control.ammo_reserve[gun_index]
level_control.ammo_reserve[gun_index] -= level_control.ammo_reserve[gun_index]
func shoot(delta):
if level_control.ammo_current[gun_index] > 0 and cycle_count > 0:
if !anim_player.is_playing():
#Audio and Animations
level_control.ammo_current[gun_index] -= 1
audio_fire.pitch_scale = 1 + rng.randf_range(-fire_pitch_scale_amt,fire_pitch_scale_amt)
audio_fire.play()
anim_player.play("shoot")
# instance fake bullet
bullet_fire()
# Fire hitscan
if player.gun_folded == false:
player.bullet_ray.hitscan_fire(bullet_damage,bullet_force_mod,bullethole)
else:
barrel_raycast.hitscan_fire(bullet_damage,bullet_force_mod,bullethole)
spawn_casing()
if fire_mode != 0:
cycle_count -= 1
elif !anim_player.is_playing() and cycle_count != 0:
anim_player.play("empty")
audio_empty.play()
func reload(delta):
if level_control.ammo_current[gun_index] < max_ammo and player.gun.anim_player.get_current_animation() != "reload" and level_control.ammo_reserve[gun_index] > 0:
#player.reloading = true
anim_player.play("reload")
audio_reload.play()
if anim_player.is_playing() and anim_player.current_animation == "reload":
if level_control.ammo_current[gun_index] == 0:
level_control.ammo_current[gun_index] = 0
else:
level_control.ammo_current[gun_index] = 1
func spawn_mag():
var instance_mag = mag.instantiate()
instance_mag.position = mag_ejector.global_position
instance_mag.transform.basis = mag_ejector.global_transform.basis
get_tree().get_root().add_child(instance_mag)
func swapped_out():
queue_free()
func bullet_fire():
var instance_bullet = bullet.instantiate()
instance_bullet.position = player.bullet_ray.global_position
instance_bullet.bullet_speed = bullet_speed
instance_bullet.player_velocity = player.velocity
instance_bullet.bullet_drop = bullet_drop
instance_bullet.random_spread_amt = random_spread_amt
instance_bullet.bullet_damage = bullet_damage
instance_bullet.bullet_force_mod = bullet_force_mod
instance_bullet.instance_bullethole = bullethole.instantiate()
instance_bullet.player_position = player.global_position
#shoot bullet from real gun if gun is folded up
if player.gun_folded == false:
instance_bullet.transform.basis = player.bullet_ray.global_transform.basis
else:
instance_bullet.transform.basis = barrel_raycast.global_transform.basis
get_tree().current_scene.add_child(instance_bullet)
func spawn_casing():
# Casing transform
var instance_casing = casing.instantiate()
instance_casing.position = casing_ejector.global_position
instance_casing.transform.basis = casing_ejector.global_transform.basis
get_tree().get_root().add_child(instance_casing)
player.recoil.add_recoil(recoil_amount,10,10)

View File

@@ -114,15 +114,15 @@ func _process(delta: float) -> void:
current_stam_bar.value = player.remaining_stamina
if player.gun != null:
if GameGlobals.gun_ammo.has(player.gun.gun_name) and GameGlobals.gun_ammo[player.gun.gun_name] != null:
if GameGlobals.gun_ammo.has(player.gun.weapon_info.gun_name) and GameGlobals.gun_ammo[player.gun.weapon_info.gun_name] != null:
ammo_counter.visible = true
ammo_current.text = str(GameGlobals.gun_ammo[player.gun.gun_name]).pad_zeros(2)
lerp_color(ammo_current,RED_COLOR,FULL_WHITE,GameGlobals.gun_ammo[player.gun.gun_name],player.gun.max_ammo,.5)
ammo_current.text = str(GameGlobals.gun_ammo[player.gun.weapon_info.gun_name]).pad_zeros(2)
lerp_color(ammo_current,RED_COLOR,FULL_WHITE,GameGlobals.gun_ammo[player.gun.weapon_info.gun_name],player.gun.weapon_info.max_ammo,.5)
else:
ammo_counter.visible = false
if GameGlobals.ammo_reserve.has(str(player.gun.ammo_type)):
ammo_reserve.text = str(GameGlobals.ammo_reserve[str(player.gun.ammo_type)]).pad_zeros(3)
lerp_color(ammo_reserve,RED_COLOR,FULL_WHITE,GameGlobals.ammo_reserve[str(player.gun.ammo_type)],player.gun.max_ammo*2,.5)
if GameGlobals.ammo_reserve.has(str(player.gun.weapon_info.bullet.ammo_type)):
ammo_reserve.text = str(GameGlobals.ammo_reserve[str(player.gun.weapon_info.bullet.ammo_type)]).pad_zeros(3)
lerp_color(ammo_reserve,RED_COLOR,FULL_WHITE,GameGlobals.ammo_reserve[str(player.gun.weapon_info.bullet.ammo_type)],player.gun.weapon_info.max_ammo*2,.5)
else:
ammo_reserve.text = "-"
else:
@@ -130,7 +130,7 @@ func _process(delta: float) -> void:
fade_in_out(ammo_reserve,1,false,10,delta)
fade_in_out(crosshair,1,false,10,delta)
if player.gun != null:
gun_name.text = player.gun.gun_name
gun_name.text = player.gun.weapon_info.gun_name
gun_name.visible = true
else:
gun_name.visible = false
@@ -159,7 +159,7 @@ func _process(delta: float) -> void:
if player.ads:
if player.gun != null:
if player.gun.ads:
if player.gun.weapon_info.ads:
fade_in_out(crosshair,1,false,5,delta)
fade_in_out(current_stam_bar,.001,true,5,delta)
else:

View File

@@ -347,7 +347,6 @@ func _physics_process(delta):
ads = true
if !gamespeed_controlled:
Engine.time_scale = lerp(Engine.time_scale, level_control.gamemode.time_slowed_speed, (delta * 50) / Engine.time_scale)
#gun.random_spread_amt = 0
AudioServer.set_bus_effect_enabled(0,0,true)
clock_sound.play()
if sensitivity_shift == true:
@@ -358,7 +357,6 @@ func _physics_process(delta):
ads = false
if !gamespeed_controlled:
Engine.time_scale = lerp(Engine.time_scale, 1.0, (delta * 50)/Engine.time_scale)
#gun.random_spread_amt = gun.random_spread_start
clock_sound.stop()
AudioServer.set_bus_effect_enabled(0,0,false)
SENSITIVITY = start_sensitivity
@@ -596,13 +594,13 @@ func flashlight_toggle():
func aim_down_sights(delta):
if gun != null:
if ads:
if gun.ads == true:
camera.fov = lerp(camera.fov,BASE_FOV - float(gun.fov_zoom_amt),(delta * 5)/Engine.time_scale)
if gun.weapon_info.ads == true:
camera.fov = lerp(camera.fov,BASE_FOV - float(gun.weapon_info.fov_zoom_amt),(delta * 5)/Engine.time_scale)
gun.position = lerp(gun.position,ADS_POS,delta * 10 / Engine.time_scale)
else:
weapon_holder.rotation = lerp(weapon_holder.rotation,Vector3(0,0,0),(delta * 10)/Engine.time_scale)
gun.position = lerp(gun.position, weapon_start_pos,(delta * 4)/Engine.time_scale)
camera.fov = lerp(camera.fov,BASE_FOV - float(gun.fov_zoom_amt),(delta * 5)/Engine.time_scale)
camera.fov = lerp(camera.fov,BASE_FOV - float(gun.weapon_info.fov_zoom_amt),(delta * 5)/Engine.time_scale)
else:
gun.position = lerp(gun.position, weapon_start_pos,(delta * 100)/Engine.time_scale)
@@ -750,12 +748,12 @@ func weapon_sway(delta):
weapon_holder.rotation.y = lerp(weapon_holder.rotation.y, (mouse_input.x + joy_input.x) * weapon_sway_amount, 5 * delta)
else:
if gun != null:
if gun.ads == true:
if gun.weapon_info.ads == true:
weapon_holder.rotation = Vector3.ZERO
func weapon_bob(vel : float, delta):
if weapon_holder:
if gun != null and !ads and !gun.ads:
if gun != null and !ads and !gun.weapon_info.ads:
weapon_holder.global_position.y += -clamp(velocity.y * .15,-1,1) * delta
if vel > 2 and is_on_floor():
var speed_adjust = speed/level_control.gamemode.walk_speed

View File

@@ -83,7 +83,6 @@ func shoot(delta):
if !anim_player.is_playing():
GameGlobals.gun_ammo[gun_name] -= 1
#RECOIL --- fix later to happen over a period of time
#(ADD PLAYER KICK HERE. RELATIVE TO GUN POSITION)
audio_fire.pitch_scale = 1 + rng.randf_range(-fire_pitch_scale_amt,fire_pitch_scale_amt)
audio_fire.play()
anim_player.play("shoot")

View File

@@ -109,7 +109,6 @@ func shoot(delta):
if tracker != null and !check_track:
fire()
func fire():
if GameGlobals.gun_ammo[gun_name] > 0 and cycle_count > 0:
if !anim_player.is_playing():
@@ -209,7 +208,6 @@ func bullet_fire():
instance_bullet.player_position = player.global_position
get_tree().get_root().add_child(instance_bullet)
func swapped_out():
tracker_check_mesh.visible = false
queue_free()

View File

@@ -23,8 +23,8 @@ func picked_up():
gun_already_held = true
if !gun_already_held:
var gun_info = gun_resource.instantiate()
level_control.player.add_ammo(true,gun_info.gun_name,gun_info.ammo_type,gun_info.max_ammo,gun_info.start_mags)
var spawn_gun = gun_resource.instantiate()
level_control.player.add_ammo(true,spawn_gun.weapon_info.gun_name,spawn_gun.weapon_info.bullet_info.ammo_type,spawn_gun.weapon_info.max_ammo,spawn_gun.weapon_info.start_mags)
GameGlobals.held_guns.append(gun_resource)
var instance_gun = gun_resource.instantiate()
var weapon_id = GameGlobals.held_guns.size() - 1

View File

@@ -1,11 +1,25 @@
extends Node
extends Resource
class_name weapon_resource
@export_group("Gun Feel")
@export var gun_name : String
@export var gun_icon : Texture2D
@export var bullet : bullet_resource
@export_enum("Auto", "Single", "Burst") var fire_mode: int
@export var fov_zoom_amt = .98
@export var ads : bool = false
@export var recoil_amount : Vector3 = Vector3(.2,.05,.05)
@export var kick_amount : float = .1
@export var max_ammo = 15
@export var start_mags = 3
@export var bullet_damage = 1
@export var smoke_enabled : bool = false
@export var bullet_force_mod = 5.0
@export var bullet_speed = 600
@export_group("Gun Assets")
@export var casing : Resource
@export_subgroup("Revolver")
@export var casing_array : Array[NodePath]
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
@export var mag : Resource

View File

@@ -0,0 +1,154 @@
extends Node3D
@export var weapon_info : weapon_resource
@export var casing_ejector : Node
@export var mag_ejector : Node
@export var barrel_ray : Node
@export var anim_player : AnimationPlayer
@export var audio_fire : AudioStreamPlayer3D
@export var audio_empty : AudioStreamPlayer3D
@export var audio_reload : AudioStreamPlayer3D
@onready var player = get_tree().current_scene.player
var start_position
var start_rotation
var cycle_count_start
var cycle_count
var rng = RandomNumberGenerator.new()
var gun_index
# Called when the node enters the scene tree for the first time.
func _ready():
if weapon_info.fire_mode == 0:
cycle_count = 1
cycle_count_start = 1
elif weapon_info.fire_mode == 1:
cycle_count = 1
cycle_count_start = 1
elif weapon_info.fire_mode == 2:
cycle_count = 3
cycle_count_start = 3
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
pass
func reload_finished():
if GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)] >= weapon_info.max_ammo:
GameGlobals.gun_ammo[weapon_info.gun_name] += weapon_info.max_ammo
GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)] -= weapon_info.max_ammo
else:
GameGlobals.gun_ammo[weapon_info.gun_name] += GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)]
GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)] -= GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)]
func shoot(delta):
if GameGlobals.gun_ammo[weapon_info.gun_name] > 0 and cycle_count > 0:
if !anim_player.is_playing():
GameGlobals.gun_ammo[weapon_info.gun_name] -= 1
#audio and anims
audio_fire.play()
anim_player.play("shoot")
vibration()
bullet_fire()
spawn_casing()
if weapon_info.smoke_enabled:
spawn_muzzle_smoke()
player.recoil.add_recoil(Vector3(0,weapon_info.recoil_amount.y,weapon_info.recoil_amount.z),10,10)
player.recoil.add_gun_recoil(weapon_info.recoil_amount.x)
#player.velocity += player.bullet_ray.global_basis * Vector3(0,0, kick_amount)
SignalBus.emit_signal("shot_fired")
if weapon_info.fire_mode != 0:
cycle_count -= 1
elif !anim_player.is_playing() and cycle_count != 0:
anim_player.play("empty")
audio_empty.play()
func reload():
if GameGlobals.gun_ammo[weapon_info.gun_name] < weapon_info.max_ammo and player.gun.anim_player.get_current_animation() != "reload" and GameGlobals.ammo_reserve[str(weapon_info.bullet.ammo_type)] > 0:
#player.reloading = true
anim_player.play("reload")
audio_reload.play()
if anim_player.is_playing() and anim_player.current_animation == "reload":
if GameGlobals.gun_ammo[weapon_info.gun_name] == 0:
GameGlobals.gun_ammo[weapon_info.gun_name] = 0
else:
GameGlobals.gun_ammo[weapon_info.gun_name] = 1
func spawn_mag():
var instance_mag =weapon_info.mag.instantiate()
instance_mag.position = mag_ejector.global_position
instance_mag.transform.basis = mag_ejector.global_transform.basis
instance_mag.linear_velocity += transform.basis * Vector3(0, -20, 0) + player.velocity
get_tree().get_root().add_child(instance_mag)
func spawn_casing():
# Casing transform
var instance_casing = weapon_info.casing.instantiate()
instance_casing.position = casing_ejector.global_position
instance_casing.transform.basis = casing_ejector.global_transform.basis
instance_casing.player_velocity = player.velocity * transform.basis
get_tree().get_root().add_child(instance_casing)
func spawn_revolver_casings():
if weapon_info.casing_array.size() > 0:
pass
#for i in weapon_info.casing_array:
#i.visible = false
#if weapon_info.casings_chamber_last > 0:
#var instance_casing = weapon_info.spawn_casing.instantiate()
#instance_casing.position = i.global_position
#instance_casing.random_rotation = false
#instance_casing.transform.basis = i.global_transform.basis
#instance_casing.player_velocity = player.velocity * transform.basis
#instance_casing.rotation.x += deg_to_rad(90)
#instance_casing.linear_velocity.y = -(8 + rng.randf_range(0,3))
#get_tree().get_root().add_child(instance_casing)
#weapon_info.casings_chamber_last -= 1
func shotgun_pellet_spawn():
var pellets_remaining = weapon_info.pellets_per_shot
while pellets_remaining > 0:
var lv_x = rng.randf_range(-weapon_info.shotgun_spread.x,weapon_info.shotgun_spread.x)
var lv_y = rng.randf_range(-weapon_info.shotgun_spread.y,weapon_info.shotgun_spread.y)
# instance bullet
var instance_bullet = weapon_info.bullet.instantiate()
instance_bullet.position = player.bullet_ray.global_position
instance_bullet.transform.basis = player.bullet_ray.global_transform.basis
instance_bullet.linear_velocity += instance_bullet.transform.basis * Vector3(lv_x, lv_y, -weapon_info.bullet_speed) + player.velocity
instance_bullet.player_position = player.global_position
get_tree().get_root().add_child(instance_bullet)
pellets_remaining -= 1
func spawn_muzzle_smoke():
var instance_smoke = weapon_info.muzzle_smoke.instantiate()
instance_smoke.global_transform.basis = barrel_ray.global_transform.basis
add_child(instance_smoke)
func bullet_fire():
var instance_bullet = weapon_info.bullet.asset.instantiate()
instance_bullet.position = player.bullet_ray.global_position
#shoot bullet from real gun if gun is folded up
if player.gun_folded == false:
instance_bullet.transform.basis = player.bullet_ray.global_transform.basis
else:
instance_bullet.transform.basis = barrel_ray.global_transform.basis
instance_bullet.bullet_speed = weapon_info.bullet_speed
instance_bullet.player_velocity = player.velocity * transform.basis
instance_bullet.bullet_damage = weapon_info.bullet_damage
instance_bullet.bullet_force_mod = weapon_info.bullet_force_mod
instance_bullet.instance_bullethole = weapon_info.bullet.bullet_hole.instantiate()
instance_bullet.player_position = player.global_position
get_tree().current_scene.add_child(instance_bullet)
func swapped_out():
queue_free()
func vibration():
Input.start_joy_vibration(0,.1,.5,.1)