railgun
							parent
							
								
									23e93eb674
								
							
						
					
					
						commit
						bcd84e8f39
					
				
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								| After Width: | Height: | Size: 233 B | 
|  | @ -0,0 +1,34 @@ | |||
| [remap] | ||||
| 
 | ||||
| importer="texture" | ||||
| type="CompressedTexture2D" | ||||
| uid="uid://bdidfdee6rhv4" | ||||
| path="res://.godot/imported/railgun.png-ea880f6d75ff5c52f6ef9b2f35ca009e.ctex" | ||||
| metadata={ | ||||
| "vram_texture": false | ||||
| } | ||||
| 
 | ||||
| [deps] | ||||
| 
 | ||||
| source_file="res://Assets/Sprites/railgun.png" | ||||
| dest_files=["res://.godot/imported/railgun.png-ea880f6d75ff5c52f6ef9b2f35ca009e.ctex"] | ||||
| 
 | ||||
| [params] | ||||
| 
 | ||||
| compress/mode=0 | ||||
| compress/high_quality=false | ||||
| compress/lossy_quality=0.7 | ||||
| compress/hdr_compression=1 | ||||
| compress/normal_map=0 | ||||
| compress/channel_pack=0 | ||||
| mipmaps/generate=false | ||||
| mipmaps/limit=-1 | ||||
| roughness/mode=0 | ||||
| roughness/src_normal="" | ||||
| process/fix_alpha_border=true | ||||
| process/premult_alpha=false | ||||
| process/normal_map_invert_y=false | ||||
| process/hdr_as_srgb=false | ||||
| process/hdr_clamp_exposure=false | ||||
| process/size_limit=0 | ||||
| detect_3d/compress_to=1 | ||||
|  | @ -1,5 +1,4 @@ | |||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using Godot; | ||||
| using SupaLidlGame.Characters; | ||||
| using SupaLidlGame.Items; | ||||
|  | @ -81,6 +80,7 @@ namespace SupaLidlGame.BoundingBoxes | |||
|         { | ||||
|             if (area is BoundingBox box) | ||||
|             { | ||||
|                 GD.Print("hit"); | ||||
|                 // we don't want to hurt teammates | ||||
|                 if (Faction != box.Faction) | ||||
|                 { | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ | |||
| [ext_resource type="Script" path="res://State/Character/NPCMoveState.cs" id="6_73mr6"] | ||||
| [ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="6_jo0cg"] | ||||
| [ext_resource type="Script" path="res://Items/Inventory.cs" id="7_43gq8"] | ||||
| [ext_resource type="PackedScene" uid="uid://d72ehtv1ks0e" path="res://Items/Weapons/Sword.tscn" id="8_s3c8r"] | ||||
| [ext_resource type="PackedScene" uid="uid://dvqap2uhcah63" path="res://Items/Weapons/Sword.tscn" id="8_s3c8r"] | ||||
| [ext_resource type="AudioStream" uid="uid://njun3e6v4854" path="res://Assets/Sounds/hurt.wav" id="10_n1e64"] | ||||
| 
 | ||||
| [sub_resource type="ShaderMaterial" id="ShaderMaterial_ms3xg"] | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| [ext_resource type="PackedScene" uid="uid://cl56eadpklnbo" path="res://Utils/PlayerCamera.tscn" id="4_ym125"] | ||||
| [ext_resource type="Script" path="res://State/Character/CharacterStateMachine.cs" id="5_rgckv"] | ||||
| [ext_resource type="Script" path="res://State/Character/PlayerIdleState.cs" id="6_wkfdm"] | ||||
| [ext_resource type="PackedScene" uid="uid://d72ehtv1ks0e" path="res://Items/Weapons/Sword.tscn" id="7_4rxuv"] | ||||
| [ext_resource type="PackedScene" uid="uid://dvqap2uhcah63" path="res://Items/Weapons/Sword.tscn" id="7_4rxuv"] | ||||
| [ext_resource type="Script" path="res://State/Character/PlayerMoveState.cs" id="7_dfqd8"] | ||||
| [ext_resource type="Script" path="res://Items/Inventory.cs" id="7_xyenu"] | ||||
| [ext_resource type="Script" path="res://State/Character/PlayerRollState.cs" id="8_fy0v5"] | ||||
|  | @ -208,8 +208,7 @@ InventoryMap = { | |||
| "equip_2": 1 | ||||
| } | ||||
| 
 | ||||
| [node name="Sword" parent="Inventory" instance=ExtResource("7_4rxuv")] | ||||
| position = Vector2(0, 2) | ||||
| [node name="Node2D" parent="Inventory" instance=ExtResource("7_4rxuv")] | ||||
| 
 | ||||
| [node name="Hurtbox" parent="." instance=ExtResource("9_avyu4")] | ||||
| Faction = 1 | ||||
|  |  | |||
|  | @ -1,8 +1,41 @@ | |||
| using Godot; | ||||
| using SupaLidlGame.Characters; | ||||
| using SupaLidlGame.BoundingBoxes; | ||||
| 
 | ||||
| namespace SupaLidlGame.Entities | ||||
| { | ||||
|     public abstract partial class Projectile : RigidBody2D | ||||
|     public partial class Projectile : RigidBody2D | ||||
|     { | ||||
|         public Vector2 Velocity => Direction * Speed; | ||||
| 
 | ||||
|         [Export] | ||||
|         public float Speed { get; set; } | ||||
| 
 | ||||
|         [Export] | ||||
|         public Vector2 Direction { get; set; } | ||||
| 
 | ||||
|         [Export] | ||||
|         public Hitbox Hitbox { get; set; } | ||||
| 
 | ||||
|         public Character Character { get; set; } | ||||
| 
 | ||||
|         public override void _PhysicsProcess(double delta) | ||||
|         { | ||||
|             Vector2 velocity = Velocity; | ||||
|             MoveAndCollide(velocity * (float)delta); | ||||
|         } | ||||
| 
 | ||||
|         public void _on_hitbox_hit(BoundingBox box) | ||||
|         { | ||||
|             if (box is Hurtbox hurtbox) | ||||
|             { | ||||
|                 hurtbox.InflictDamage( | ||||
|                     Hitbox.Damage, | ||||
|                     Character, | ||||
|                     Hitbox.Knockback, | ||||
|                     knockbackVector: Direction | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,32 @@ | |||
| [gd_scene load_steps=5 format=3 uid="uid://bqvseo3sbs1aj"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://Entities/Projectile.cs" id="1_hhb4t"] | ||||
| [ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="2_pcf4i"] | ||||
| 
 | ||||
| [sub_resource type="CanvasTexture" id="CanvasTexture_cc88g"] | ||||
| 
 | ||||
| [sub_resource type="RectangleShape2D" id="RectangleShape2D_j0tne"] | ||||
| size = Vector2(16, 4) | ||||
| 
 | ||||
| [node name="RailBeam" type="RigidBody2D" node_paths=PackedStringArray("Hitbox")] | ||||
| script = ExtResource("1_hhb4t") | ||||
| Speed = 512.0 | ||||
| Direction = Vector2(1, 0) | ||||
| Hitbox = NodePath("Hitbox") | ||||
| 
 | ||||
| [node name="Sprite2D" type="Sprite2D" parent="."] | ||||
| modulate = Color(1.4, 0, 1.2, 1) | ||||
| self_modulate = Color(2, 2, 2, 1) | ||||
| scale = Vector2(8, 4) | ||||
| texture = SubResource("CanvasTexture_cc88g") | ||||
| 
 | ||||
| [node name="Hitbox" parent="." instance=ExtResource("2_pcf4i")] | ||||
| Damage = 25.0 | ||||
| Knockback = 256.0 | ||||
| 
 | ||||
| [node name="CollisionShape2D" parent="Hitbox" index="0"] | ||||
| shape = SubResource("RectangleShape2D_j0tne") | ||||
| 
 | ||||
| [connection signal="Hit" from="Hitbox" to="." method="_on_hitbox_hit"] | ||||
| 
 | ||||
| [editable path="Hitbox"] | ||||
|  | @ -47,18 +47,17 @@ namespace SupaLidlGame.Items | |||
|         [Export] | ||||
|         public float MaxDistanceHint { get; set; } | ||||
| 
 | ||||
|         [Export] | ||||
|         public Node2D Anchor { get; set; } | ||||
| 
 | ||||
|         public override bool StacksWith(Item item) => false; | ||||
| 
 | ||||
|         public override void Equip(Character character) | ||||
|         { | ||||
|             Visible = true; | ||||
|             Character = character; | ||||
|         } | ||||
| 
 | ||||
|         public override void Unequip(Character character) | ||||
|         { | ||||
|             Visible = false; | ||||
|             Character = null; | ||||
|         } | ||||
| 
 | ||||
|  | @ -78,7 +77,7 @@ namespace SupaLidlGame.Items | |||
|             { | ||||
|                 if ((RemainingUseTime -= delta) <= 0) | ||||
|                 { | ||||
|                     Deuse(); | ||||
|                     //Deuse(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -1,10 +0,0 @@ | |||
| namespace SupaLidlGame.Items.Weapons | ||||
| { | ||||
|     public partial class HitscanRanged : Ranged | ||||
|     { | ||||
|         public override void Attack() | ||||
|         { | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,22 @@ | |||
| using Godot; | ||||
| using SupaLidlGame.Extensions; | ||||
| 
 | ||||
| namespace SupaLidlGame.Items.Weapons | ||||
| { | ||||
|     public partial class Railgun : Ranged | ||||
|     { | ||||
|         public override void Attack() | ||||
|         { | ||||
|             // create projectile | ||||
|             PackedScene scene = GD.Load<PackedScene>("res://Entities/RailBeam.tscn"); | ||||
|             GD.Print("lol"); | ||||
|             var projectile = scene.Instantiate<Entities.Projectile>(); | ||||
|             projectile.Hitbox.Faction = Character.Faction; | ||||
|             projectile.Direction = Character.Target; | ||||
|             projectile.GlobalPosition = GlobalPosition; | ||||
|             projectile.GlobalRotation = projectile.Direction.Angle(); | ||||
|             this.GetAncestor<SupaLidlGame.Scenes.Map>() | ||||
|                 .Entities.AddChild(projectile); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,42 @@ | |||
| [gd_scene load_steps=7 format=3 uid="uid://g7wfcubs6bdd"] | ||||
| 
 | ||||
| [ext_resource type="Texture2D" uid="uid://bdidfdee6rhv4" path="res://Assets/Sprites/railgun.png" id="1_4lqn3"] | ||||
| [ext_resource type="Script" path="res://Items/Weapons/Railgun.cs" id="1_pami3"] | ||||
| [ext_resource type="Script" path="res://State/Weapon/WeaponStateMachine.cs" id="1_xynim"] | ||||
| [ext_resource type="Script" path="res://State/Weapon/RangedIdleState.cs" id="2_a4hhy"] | ||||
| [ext_resource type="Script" path="res://State/Weapon/RangedFireState.cs" id="3_dcbnq"] | ||||
| 
 | ||||
| [sub_resource type="SpriteFrames" id="SpriteFrames_wjqqh"] | ||||
| animations = [{ | ||||
| "frames": [{ | ||||
| "duration": 1.0, | ||||
| "texture": ExtResource("1_4lqn3") | ||||
| }], | ||||
| "loop": true, | ||||
| "name": &"default", | ||||
| "speed": 5.0 | ||||
| }] | ||||
| 
 | ||||
| [node name="Railgun" type="Node2D" node_paths=PackedStringArray("StateMachine")] | ||||
| script = ExtResource("1_pami3") | ||||
| StateMachine = NodePath("State") | ||||
| Damage = 50.0 | ||||
| UseTime = 1.0 | ||||
| 
 | ||||
| [node name="State" type="Node" parent="." node_paths=PackedStringArray("InitialState")] | ||||
| script = ExtResource("1_xynim") | ||||
| InitialState = NodePath("Idle") | ||||
| 
 | ||||
| [node name="Idle" type="Node" parent="State" node_paths=PackedStringArray("FireState")] | ||||
| script = ExtResource("2_a4hhy") | ||||
| FireState = NodePath("../Fire") | ||||
| 
 | ||||
| [node name="Fire" type="Node" parent="State" node_paths=PackedStringArray("Weapon", "IdleState")] | ||||
| script = ExtResource("3_dcbnq") | ||||
| Weapon = NodePath("../..") | ||||
| IdleState = NodePath("../Idle") | ||||
| 
 | ||||
| [node name="Sprite2D" type="AnimatedSprite2D" parent="."] | ||||
| texture_filter = 1 | ||||
| position = Vector2(8, 0) | ||||
| sprite_frames = SubResource("SpriteFrames_wjqqh") | ||||
|  | @ -10,49 +10,31 @@ namespace SupaLidlGame.Items.Weapons | |||
|         [Export] | ||||
|         public float ChargeTime { get; set; } | ||||
| 
 | ||||
|         public bool IsChargeable => ChargeTime > 0; | ||||
|         [Export] | ||||
|         public State.Weapon.WeaponStateMachine StateMachine { get; set; } | ||||
| 
 | ||||
|         public double ChargeProgress { get; protected set; } | ||||
|         public override bool IsUsing => StateMachine.CurrentState | ||||
|             is State.Weapon.RangedFireState; | ||||
| 
 | ||||
|         public bool IsChargeable => ChargeTime > 0; | ||||
| 
 | ||||
|         public bool IsCharging { get; protected set; } | ||||
| 
 | ||||
|         public override void Use() | ||||
|         { | ||||
|             if (RemainingUseTime > 0) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if (IsChargeable) | ||||
|             { | ||||
|                 IsCharging = true; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 Attack(); | ||||
|             } | ||||
| 
 | ||||
|             StateMachine.Use(); | ||||
|             base.Use(); | ||||
|         } | ||||
| 
 | ||||
|         public override void Deuse() | ||||
|         { | ||||
|             if (IsChargeable && IsCharging) | ||||
|             { | ||||
|                 Attack(); | ||||
|                 IsCharging = false; | ||||
|             } | ||||
| 
 | ||||
|             StateMachine.Deuse(); | ||||
|             base.Deuse(); | ||||
|         } | ||||
| 
 | ||||
|         public override void _Process(double delta) | ||||
|         { | ||||
|             if (IsCharging) | ||||
|             { | ||||
|                 ChargeProgress += delta; | ||||
|             } | ||||
| 
 | ||||
|             StateMachine.Process(delta); | ||||
|             base._Process(delta); | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -44,6 +44,9 @@ namespace SupaLidlGame.Items.Weapons | |||
|         [Export] | ||||
|         public WeaponStateMachine StateMachine { get; set; } | ||||
| 
 | ||||
|         [Export] | ||||
|         public Node2D Anchor { get; set; } | ||||
| 
 | ||||
|         public override bool IsParryable { get; protected set; } | ||||
| 
 | ||||
|         public ulong ParryTimeOrigin { get; protected set; } | ||||
|  | @ -54,14 +57,12 @@ namespace SupaLidlGame.Items.Weapons | |||
| 
 | ||||
|         public override void Equip(Character character) | ||||
|         { | ||||
|             Visible = true; | ||||
|             base.Equip(character); | ||||
|             Hitbox.Faction = character.Faction; // character is null before base | ||||
|         } | ||||
| 
 | ||||
|         public override void Unequip(Character character) | ||||
|         { | ||||
|             Visible = false; | ||||
|             base.Unequip(character); | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -342,12 +342,12 @@ AnimationTree = NodePath("AnimationTree") | |||
| AttackTime = 0.2 | ||||
| AttackAnimationDuration = 1.0 | ||||
| ParryParticles = NodePath("Anchor/Node2D/Sprite2D/ParryParticles") | ||||
| NPCAnticipateTime = 0.4 | ||||
| NPCAnticipateTime = 0.3 | ||||
| StateMachine = NodePath("State") | ||||
| Damage = 20.0 | ||||
| UseTime = 0.4 | ||||
| Knockback = 64.0 | ||||
| Anchor = NodePath("Anchor") | ||||
| Damage = 20.0 | ||||
| UseTime = 0.8 | ||||
| Knockback = 64.0 | ||||
| 
 | ||||
| [node name="State" type="Node" parent="." node_paths=PackedStringArray("InitialState")] | ||||
| script = ExtResource("2_vwirq") | ||||
|  |  | |||
|  | @ -1,8 +1,9 @@ | |||
| [gd_scene load_steps=6 format=3 uid="uid://bxtpv6jqodj4v"] | ||||
| [gd_scene load_steps=7 format=3 uid="uid://bxtpv6jqodj4v"] | ||||
| 
 | ||||
| [ext_resource type="PackedScene" uid="uid://clwv2owvk6abe" path="res://Scenes/BaseMap.tscn" id="1_vly6f"] | ||||
| [ext_resource type="Texture2D" uid="uid://dl2h266oa2x31" path="res://Assets/Sprites/night-grass.png" id="2_ote21"] | ||||
| [ext_resource type="PackedScene" uid="uid://bf55wbq7m1gpp" path="res://Characters/ExampleEnemy.tscn" id="3_hwof6"] | ||||
| [ext_resource type="PackedScene" uid="uid://bqvseo3sbs1aj" path="res://Entities/RailBeam.tscn" id="4_vxueq"] | ||||
| 
 | ||||
| [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_dvbe3"] | ||||
| texture = ExtResource("2_ote21") | ||||
|  | @ -217,3 +218,6 @@ layer_5/tile_data = PackedInt32Array(786438, 262144, 3, 720899, 262144, 3, 85197 | |||
| 
 | ||||
| [node name="ExampleEnemy" parent="Entities" index="0" instance=ExtResource("3_hwof6")] | ||||
| position = Vector2(169, 115) | ||||
| 
 | ||||
| [node name="RailBeam" parent="." index="6" instance=ExtResource("4_vxueq")] | ||||
| position = Vector2(55, 8) | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ namespace SupaLidlGame.State.Character | |||
|         public void Input(InputEvent @event) | ||||
|         { | ||||
|             var state = CurrentState.Input(@event); | ||||
|             if (state is not null) | ||||
|             if (state is CharacterState) | ||||
|             { | ||||
|                 ChangeState(state); | ||||
|             } | ||||
|  |  | |||
|  | @ -46,8 +46,14 @@ namespace SupaLidlGame.State.Character | |||
| 
 | ||||
|             if (Godot.Input.IsActionPressed("attack1")) | ||||
|             { | ||||
|                 if (Character.Inventory.SelectedItem is not null) | ||||
|                 var item = Character.Inventory.SelectedItem; | ||||
|                 if (item is not null) | ||||
|                 { | ||||
|                     if (!item.IsUsing) | ||||
|                     { | ||||
|                         Character.Target = dirToMouse; | ||||
|                     } | ||||
|                     Character.Target = dirToMouse; | ||||
|                     Character.UseCurrentItem(); | ||||
|                 } | ||||
|             } | ||||
|  |  | |||
|  | @ -0,0 +1,37 @@ | |||
| using Godot; | ||||
| 
 | ||||
| namespace SupaLidlGame.State.Weapon | ||||
| { | ||||
|     public partial class RangedFireState : WeaponState | ||||
|     { | ||||
|         [Export] | ||||
|         public Items.Weapons.Ranged Weapon { get; set; } | ||||
| 
 | ||||
|         [Export] | ||||
|         public RangedIdleState IdleState { get; set; } | ||||
| 
 | ||||
|         private double _timeLeft = 0; | ||||
| 
 | ||||
|         public override IState<WeaponState> Enter(IState<WeaponState> prev) | ||||
|         { | ||||
|             //_timeLeft | ||||
|             _timeLeft = Weapon.UseTime; | ||||
|             Weapon.Attack(); | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         public override WeaponState Process(double delta) | ||||
|         { | ||||
|             if ((_timeLeft -= delta) <= 0) | ||||
|             { | ||||
|                 return IdleState; | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         public override void Exit(IState<WeaponState> nextState) | ||||
|         { | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,22 @@ | |||
| using Godot; | ||||
| 
 | ||||
| namespace SupaLidlGame.State.Weapon | ||||
| { | ||||
|     public partial class RangedIdleState : WeaponState | ||||
|     { | ||||
|         [Export] | ||||
|         public RangedFireState FireState { get; set; } | ||||
| 
 | ||||
|         public override IState<WeaponState> Enter(IState<WeaponState> prev) => null; | ||||
| 
 | ||||
|         public override WeaponState Use() | ||||
|         { | ||||
|             return FireState; | ||||
|         } | ||||
| 
 | ||||
|         public override void Exit(IState<WeaponState> nextState) | ||||
|         { | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,5 +0,0 @@ | |||
| using Godot; | ||||
| 
 | ||||
| namespace SupaLidlGame.State.Weapon | ||||
| { | ||||
| } | ||||
|  | @ -1,27 +0,0 @@ | |||
| using Godot; | ||||
| 
 | ||||
| namespace SupaLidlGame.State.Weapon | ||||
| { | ||||
| } | ||||
| 
 | ||||
| /* | ||||
|   | ||||
|         public void Use() | ||||
|         { | ||||
|             var state = CurrentState.Use(); | ||||
|             if (state is not null) | ||||
|             { | ||||
|                 ChangeState(state); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Process(double delta) | ||||
|         { | ||||
|             var state = CurrentState.Process(delta); | ||||
|             if (state is SwordState s) | ||||
|             { | ||||
|                 ChangeState(s); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         */ | ||||
|  | @ -6,6 +6,8 @@ namespace SupaLidlGame.State.Weapon | |||
|     { | ||||
|         public virtual WeaponState Use() => null; | ||||
| 
 | ||||
|         public virtual WeaponState Deuse() => null; | ||||
| 
 | ||||
|         public abstract IState<WeaponState> Enter(IState<WeaponState> previousState); | ||||
| 
 | ||||
|         public virtual void Exit(IState<WeaponState> nextState) | ||||
|  |  | |||
|  | @ -10,7 +10,16 @@ namespace SupaLidlGame.State.Weapon | |||
|         public void Use() | ||||
|         { | ||||
|             var state = CurrentState.Use(); | ||||
|             if (state is not null) | ||||
|             if (state is WeaponState) | ||||
|             { | ||||
|                 ChangeState(state); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Deuse() | ||||
|         { | ||||
|             var state = CurrentState.Deuse(); | ||||
|             if (state is WeaponState) | ||||
|             { | ||||
|                 ChangeState(state); | ||||
|             } | ||||
|  |  | |||
|  | @ -0,0 +1,8 @@ | |||
| [gd_scene load_steps=2 format=3 uid="uid://8hqnkll3x7tr"] | ||||
| 
 | ||||
| [ext_resource type="PackedScene" uid="uid://bqvseo3sbs1aj" path="res://Entities/RailBeam.tscn" id="1_os4wy"] | ||||
| 
 | ||||
| [node name="Node2D" type="Node2D"] | ||||
| 
 | ||||
| [node name="RailBeam" parent="." instance=ExtResource("1_os4wy")] | ||||
| gravity_scale = 0.0 | ||||
		Loading…
	
		Reference in New Issue