├── .gitignore
├── images
├── .gdignore
├── mannequin-v0.1.png
├── mannequiny-0.2.png
└── mannequin-v0.1.png.import
├── godot
├── icon.png
├── assets
│ ├── 2d
│ │ ├── reticle.png
│ │ └── reticle.png.import
│ ├── theme
│ │ ├── gdquest.theme
│ │ ├── empty.stylebox
│ │ ├── button
│ │ │ ├── hover.stylebox
│ │ │ ├── focused.stylebox
│ │ │ ├── normal.stylebox
│ │ │ ├── pressed.stylebox
│ │ │ └── disabled.stylebox
│ │ ├── panel
│ │ │ └── panel.stylebox
│ │ ├── slider
│ │ │ ├── slider.stylebox
│ │ │ └── grabber_area.stylebox
│ │ ├── fonts
│ │ │ ├── montserrat
│ │ │ │ ├── Montserrat-Bold.ttf
│ │ │ │ ├── Montserrat-Black.ttf
│ │ │ │ └── Montserrat-Medium.ttf
│ │ │ ├── source_code_pro
│ │ │ │ └── SourceCodePro-Medium.otf
│ │ │ ├── default_font.tres
│ │ │ ├── font_title.tres
│ │ │ ├── default_font_bold.tres
│ │ │ └── default_font_code.tres
│ │ ├── separator
│ │ │ └── line.tres
│ │ └── icons
│ │ │ ├── chevron-up.svg
│ │ │ ├── chevron-right.svg
│ │ │ ├── chevron-up.svg.import
│ │ │ └── chevron-right.svg.import
│ └── 3d
│ │ ├── level
│ │ ├── playground.glb
│ │ ├── Material.material
│ │ ├── level_environment.tres
│ │ └── playground.glb.import
│ │ ├── mannequiny
│ │ ├── Azul.material
│ │ ├── Blanco.material
│ │ ├── Negro.material
│ │ └── mannequiny-0.3.0.glb
│ │ └── materials
│ │ ├── floor.tres
│ │ └── obstacle.tres
├── src
│ ├── Player
│ │ ├── States
│ │ │ ├── Extensions
│ │ │ │ ├── Hang.gd
│ │ │ │ └── Zip.gd
│ │ │ ├── Air.gd
│ │ │ ├── Run.gd
│ │ │ ├── Idle.gd
│ │ │ └── Move.gd
│ │ ├── Camera
│ │ │ ├── CameraState.gd
│ │ │ ├── States
│ │ │ │ ├── Default.gd
│ │ │ │ ├── Aim.gd
│ │ │ │ └── Camera.gd
│ │ │ ├── AimTarget.gd
│ │ │ ├── SpringArm.gd
│ │ │ ├── CameraRig.gd
│ │ │ └── CameraRig.tscn
│ │ ├── PlayerState.gd
│ │ ├── Player.gd
│ │ ├── Mannequiny.gd
│ │ └── Player.tscn
│ ├── Debug
│ │ ├── DebugDock.gd
│ │ ├── DebugPanel.tscn
│ │ └── DebugPanel.gd
│ ├── Main
│ │ ├── Game.gd
│ │ ├── StateMachine
│ │ │ ├── State.gd
│ │ │ └── StateMachine.gd
│ │ └── Game.tscn
│ └── Level
│ │ └── Playground.tscn
├── icon.png.import
├── default_env.tres
└── project.godot
├── godot-csharp
├── icon.png
├── assets
│ ├── 2d
│ │ ├── reticle.png
│ │ ├── icons
│ │ │ ├── state.svg.import
│ │ │ ├── state_machine.svg.import
│ │ │ ├── state_machine.svg
│ │ │ └── state.svg
│ │ └── reticle.png.import
│ ├── 3d
│ │ ├── level
│ │ │ ├── playground.glb
│ │ │ ├── Material.material
│ │ │ ├── level_environment.tres
│ │ │ └── playground.glb.import
│ │ ├── mannequiny
│ │ │ ├── Azul.material
│ │ │ ├── Blanco.material
│ │ │ ├── Negro.material
│ │ │ └── mannequiny-0.3.0.glb
│ │ └── materials
│ │ │ ├── floor.tres
│ │ │ └── obstacle.tres
│ └── fonts
│ │ └── Montserrat-Bold.ttf
├── .gitignore
├── src
│ ├── Camera
│ │ ├── CameraState.cs
│ │ ├── States
│ │ │ ├── Default.cs
│ │ │ ├── Aim.cs
│ │ │ └── Camera.cs
│ │ ├── AimTarget.cs
│ │ ├── SpringArm.cs
│ │ ├── CameraRig.cs
│ │ └── CameraRig.tscn
│ ├── Main
│ │ ├── Label.cs
│ │ ├── Game.cs
│ │ ├── Game.tscn
│ │ └── StateMachine
│ │ │ ├── State.cs
│ │ │ └── StateMachine.cs
│ ├── Player
│ │ ├── Player.cs
│ │ ├── PlayerState.cs
│ │ ├── States
│ │ │ ├── Idle.cs
│ │ │ ├── Run.cs
│ │ │ ├── Air.cs
│ │ │ └── Move.cs
│ │ ├── Player.tscn
│ │ └── Mannequiny.cs
│ └── Level
│ │ └── Playground.tscn
├── icon.png.import
├── default_env.tres
├── Properties
│ └── AssemblyInfo.cs
├── Learn to Code a Pro 3D Character with Godot (start).sln
├── Learn to Code a Pro 3D Character with Godot (start).csproj
└── project.godot
├── LICENSE
├── CHANGELOG.md
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .import/
--------------------------------------------------------------------------------
/images/.gdignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/godot/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/icon.png
--------------------------------------------------------------------------------
/godot-csharp/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot-csharp/icon.png
--------------------------------------------------------------------------------
/images/mannequin-v0.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/images/mannequin-v0.1.png
--------------------------------------------------------------------------------
/images/mannequiny-0.2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/images/mannequiny-0.2.png
--------------------------------------------------------------------------------
/godot/assets/2d/reticle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/2d/reticle.png
--------------------------------------------------------------------------------
/godot/assets/theme/gdquest.theme:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/gdquest.theme
--------------------------------------------------------------------------------
/godot-csharp/assets/2d/reticle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot-csharp/assets/2d/reticle.png
--------------------------------------------------------------------------------
/godot/assets/theme/empty.stylebox:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/empty.stylebox
--------------------------------------------------------------------------------
/godot/assets/3d/level/playground.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/3d/level/playground.glb
--------------------------------------------------------------------------------
/godot/assets/3d/level/Material.material:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/3d/level/Material.material
--------------------------------------------------------------------------------
/godot/assets/3d/mannequiny/Azul.material:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/3d/mannequiny/Azul.material
--------------------------------------------------------------------------------
/godot/assets/theme/button/hover.stylebox:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/button/hover.stylebox
--------------------------------------------------------------------------------
/godot/assets/theme/panel/panel.stylebox:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/panel/panel.stylebox
--------------------------------------------------------------------------------
/godot/assets/3d/mannequiny/Blanco.material:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/3d/mannequiny/Blanco.material
--------------------------------------------------------------------------------
/godot/assets/3d/mannequiny/Negro.material:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/3d/mannequiny/Negro.material
--------------------------------------------------------------------------------
/godot/assets/theme/button/focused.stylebox:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/button/focused.stylebox
--------------------------------------------------------------------------------
/godot/assets/theme/button/normal.stylebox:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/button/normal.stylebox
--------------------------------------------------------------------------------
/godot/assets/theme/button/pressed.stylebox:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/button/pressed.stylebox
--------------------------------------------------------------------------------
/godot/assets/theme/slider/slider.stylebox:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/slider/slider.stylebox
--------------------------------------------------------------------------------
/godot-csharp/assets/3d/level/playground.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot-csharp/assets/3d/level/playground.glb
--------------------------------------------------------------------------------
/godot-csharp/assets/fonts/Montserrat-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot-csharp/assets/fonts/Montserrat-Bold.ttf
--------------------------------------------------------------------------------
/godot/assets/theme/button/disabled.stylebox:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/button/disabled.stylebox
--------------------------------------------------------------------------------
/godot-csharp/assets/3d/level/Material.material:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot-csharp/assets/3d/level/Material.material
--------------------------------------------------------------------------------
/godot-csharp/assets/3d/mannequiny/Azul.material:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot-csharp/assets/3d/mannequiny/Azul.material
--------------------------------------------------------------------------------
/godot/assets/3d/mannequiny/mannequiny-0.3.0.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/3d/mannequiny/mannequiny-0.3.0.glb
--------------------------------------------------------------------------------
/godot/assets/theme/slider/grabber_area.stylebox:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/slider/grabber_area.stylebox
--------------------------------------------------------------------------------
/godot-csharp/assets/3d/mannequiny/Blanco.material:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot-csharp/assets/3d/mannequiny/Blanco.material
--------------------------------------------------------------------------------
/godot-csharp/assets/3d/mannequiny/Negro.material:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot-csharp/assets/3d/mannequiny/Negro.material
--------------------------------------------------------------------------------
/godot/assets/3d/materials/floor.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="SpatialMaterial" format=2]
2 |
3 | [resource]
4 | albedo_color = Color( 0.956863, 0.964706, 0.968627, 1 )
5 |
--------------------------------------------------------------------------------
/godot-csharp/assets/3d/mannequiny/mannequiny-0.3.0.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot-csharp/assets/3d/mannequiny/mannequiny-0.3.0.glb
--------------------------------------------------------------------------------
/godot-csharp/assets/3d/materials/floor.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="SpatialMaterial" format=2]
2 |
3 | [resource]
4 | albedo_color = Color( 0.956863, 0.964706, 0.968627, 1 )
5 |
--------------------------------------------------------------------------------
/godot/assets/theme/fonts/montserrat/Montserrat-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/fonts/montserrat/Montserrat-Bold.ttf
--------------------------------------------------------------------------------
/godot/assets/theme/separator/line.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="StyleBoxLine" format=2]
2 |
3 | [resource]
4 |
5 | color = Color( 1, 1, 1, 0.196078 )
6 | thickness = 2
7 |
8 |
--------------------------------------------------------------------------------
/godot/assets/theme/fonts/montserrat/Montserrat-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/fonts/montserrat/Montserrat-Black.ttf
--------------------------------------------------------------------------------
/godot/assets/theme/fonts/montserrat/Montserrat-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/fonts/montserrat/Montserrat-Medium.ttf
--------------------------------------------------------------------------------
/godot/assets/theme/fonts/source_code_pro/SourceCodePro-Medium.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ailisp/godot-3d-mannequin/master/godot/assets/theme/fonts/source_code_pro/SourceCodePro-Medium.otf
--------------------------------------------------------------------------------
/godot/assets/3d/materials/obstacle.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="SpatialMaterial" format=2]
2 |
3 | [resource]
4 | albedo_color = Color( 0.921569, 0.247059, 0.247059, 1 )
5 | metallic_specular = 0.13
6 |
--------------------------------------------------------------------------------
/godot-csharp/assets/3d/materials/obstacle.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="SpatialMaterial" format=2]
2 |
3 | [resource]
4 | albedo_color = Color( 0.921569, 0.247059, 0.247059, 1 )
5 | metallic_specular = 0.13
6 |
--------------------------------------------------------------------------------
/godot/assets/theme/fonts/default_font.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="DynamicFont" load_steps=2 format=2]
2 |
3 | [ext_resource path="res://assets/theme/fonts/montserrat/Montserrat-Medium.ttf" type="DynamicFontData" id=1]
4 |
5 | [resource]
6 | size = 20
7 | use_filter = true
8 | font_data = ExtResource( 1 )
9 |
--------------------------------------------------------------------------------
/godot/assets/theme/fonts/font_title.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="DynamicFont" load_steps=2 format=2]
2 |
3 | [ext_resource path="res://assets/theme/fonts/montserrat/Montserrat-Black.ttf" type="DynamicFontData" id=1]
4 |
5 | [resource]
6 | size = 28
7 | use_filter = true
8 | font_data = ExtResource( 1 )
9 |
--------------------------------------------------------------------------------
/godot/assets/theme/icons/chevron-up.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/godot-csharp/.gitignore:
--------------------------------------------------------------------------------
1 | # Godot-specific ignores
2 | .import/
3 | export.cfg
4 | export_presets.cfg
5 |
6 | # Mono-specific ignores
7 | .mono/
8 | data_*/
9 | mono_crash*.json
10 | *.blob
11 |
12 | # Visual studio code
13 | .vscode/
14 | .VSCodeCounter/
15 |
16 | # Godot Plugins
17 | addons/
18 |
--------------------------------------------------------------------------------
/godot/assets/theme/fonts/default_font_bold.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="DynamicFont" load_steps=2 format=2]
2 |
3 | [ext_resource path="res://assets/theme/fonts/montserrat/Montserrat-Bold.ttf" type="DynamicFontData" id=1]
4 |
5 | [resource]
6 | size = 20
7 | use_filter = true
8 | font_data = ExtResource( 1 )
9 |
--------------------------------------------------------------------------------
/godot/assets/theme/icons/chevron-right.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/godot/assets/theme/fonts/default_font_code.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="DynamicFont" load_steps=2 format=2]
2 |
3 | [ext_resource path="res://assets/theme/fonts/source_code_pro/SourceCodePro-Medium.otf" type="DynamicFontData" id=1]
4 |
5 | [resource]
6 | size = 20
7 | use_filter = true
8 | font_data = ExtResource( 1 )
9 |
--------------------------------------------------------------------------------
/godot/src/Player/States/Extensions/Hang.gd:
--------------------------------------------------------------------------------
1 | extends PlayerState
2 | # State that does not involve gravity or further movement until released.
3 |
4 |
5 | func unhandled_input(event: InputEvent) -> void:
6 | if event.is_action_released("interact"):
7 | _state_machine.transition_to("Move/Idle")
8 | _parent.unhandled_input(event)
9 |
--------------------------------------------------------------------------------
/godot/src/Player/Camera/CameraState.gd:
--------------------------------------------------------------------------------
1 | extends State
2 | class_name CameraState
3 | # Base type for the camera rig's state classes. Contains boilerplate code to
4 | # get autocompletion and type hints.
5 |
6 | var camera_rig: CameraRig
7 |
8 |
9 | func _ready() -> void:
10 | yield(owner, "ready")
11 | camera_rig = owner
12 |
--------------------------------------------------------------------------------
/godot/src/Debug/DebugDock.gd:
--------------------------------------------------------------------------------
1 | extends MarginContainer
2 | # Contains UI widgets that display debug info about the game world
3 |
4 |
5 | func _ready() -> void:
6 | visible = false
7 |
8 |
9 | func _input(event: InputEvent) -> void:
10 | if event.is_action_pressed('toggle_debug_menu'):
11 | visible = not visible
12 |
13 | accept_event()
14 |
--------------------------------------------------------------------------------
/godot/src/Player/PlayerState.gd:
--------------------------------------------------------------------------------
1 | extends State
2 | class_name PlayerState
3 | # Base type for the player's state classes. Contains boilerplate code to get
4 | # autocompletion and type hints.
5 |
6 | var player: Player
7 | var skin: Mannequiny
8 |
9 |
10 | func _ready() -> void:
11 | yield(owner, "ready")
12 | player = owner
13 | skin = owner.skin
14 |
--------------------------------------------------------------------------------
/godot/src/Player/Camera/States/Default.gd:
--------------------------------------------------------------------------------
1 | extends CameraState
2 | # Rotates the camera around the character, delegating all the work to its parent state.
3 |
4 |
5 | func unhandled_input(event: InputEvent) -> void:
6 | if event.is_action_pressed("toggle_aim"):
7 | _state_machine.transition_to("Camera/Aim")
8 | else:
9 | _parent.unhandled_input(event)
10 |
11 |
12 | func process(delta: float) -> void:
13 | _parent.process(delta)
14 |
--------------------------------------------------------------------------------
/godot-csharp/src/Camera/CameraState.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class CameraState : State
5 | {
6 | protected CameraRig cameraRig = null;
7 |
8 | public override void _Ready()
9 | {
10 | base._Ready();
11 | WaitForParentNode();
12 | cameraRig = (Owner as CameraRig);
13 | }
14 |
15 | async void WaitForParentNode() {
16 | await ToSignal(Owner, "ready");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/godot/src/Player/Player.gd:
--------------------------------------------------------------------------------
1 | tool
2 | class_name Player
3 | extends KinematicBody
4 | # Helper class for the Player scene's scripts to be able to have access to the
5 | # camera and its orientation.
6 |
7 | onready var camera: CameraRig = $CameraRig
8 | onready var skin: Mannequiny = $Mannequiny
9 | onready var state_machine: StateMachine = $StateMachine
10 |
11 |
12 | func _get_configuration_warning() -> String:
13 | return "Missing camera node" if not camera else ""
14 |
--------------------------------------------------------------------------------
/godot-csharp/src/Main/Label.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class Label : Godot.Label
5 | {
6 | StateMachine stateMachine = null;
7 |
8 | public override void _Ready() {
9 | stateMachine = GetNode("../StateMachine");
10 | if (stateMachine == null) GD.PushError("statemachine in Label null");
11 | }
12 |
13 | public void _on_StateMachine_Transitioned(NodePath statePath) {
14 | Text = statePath;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/godot/src/Player/States/Air.gd:
--------------------------------------------------------------------------------
1 | extends PlayerState
2 | # State for when the player is jumping and falling.
3 |
4 |
5 | func physics_process(delta: float) -> void:
6 | _parent.physics_process(delta)
7 |
8 | if player.is_on_floor():
9 | _state_machine.transition_to("Move/Idle")
10 | elif player.is_on_ceiling():
11 | _parent.velocity.y = 0
12 |
13 |
14 | func enter(msg: Dictionary = {}) -> void:
15 | match msg:
16 | {"velocity": var v, "jump_impulse": var ji}:
17 | _parent.velocity = v + Vector3(0, ji, 0)
18 | skin.transition_to(skin.States.AIR)
19 | _parent.enter()
20 |
21 |
22 | func exit() -> void:
23 | _parent.exit()
24 |
--------------------------------------------------------------------------------
/godot/src/Player/Camera/AimTarget.gd:
--------------------------------------------------------------------------------
1 | extends Sprite3D
2 | # Visual target shape that gets projected on the environment, to help the player aim.
3 |
4 |
5 | func _ready() -> void:
6 | set_as_toplevel(true)
7 |
8 |
9 | func update(ray: RayCast) -> void:
10 | ray.force_raycast_update()
11 | var is_colliding := ray.is_colliding()
12 | visible = is_colliding
13 | if is_colliding:
14 | var collision_point := ray.get_collision_point()
15 | var collision_normal := ray.get_collision_normal()
16 | global_transform.origin = collision_point + collision_normal * 0.01
17 | look_at(collision_point - collision_normal, global_transform.basis.y.normalized())
18 |
--------------------------------------------------------------------------------
/godot-csharp/src/Player/Player.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class Player : KinematicBody
5 | {
6 | public CameraRig camera = null;
7 | public Mannequiny skin = null;
8 | public StateMachine stateMachine = null;
9 |
10 | public override void _Ready()
11 | {
12 | camera = GetNode("CameraRig");
13 | if (camera == null) GD.PushError("CameraRig reference is null!");
14 |
15 | skin = GetNode("Mannequiny");
16 | if (skin == null) GD.PushError("Mannequiny reference is null!");
17 |
18 | stateMachine = GetNode("StateMachine");
19 | if (stateMachine == null) GD.PushError("stateMachine reference is null!");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/godot-csharp/src/Camera/States/Default.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class Default : CameraState
5 | {
6 |
7 | public override void _Ready()
8 | {
9 | base._Ready();
10 | }
11 |
12 | public override void UnhandledInput(InputEvent @event)
13 | {
14 | if (@event.IsActionPressed("toggle_aim") || @event.IsActionPressed("fire"))
15 | {
16 | (_stateMachine as StateMachine).TransitionTo("Camera/Aim");
17 | }
18 | else
19 | {
20 | _parent.UnhandledInput(@event);
21 | }
22 | }
23 |
24 | public override void Process(float delta) {
25 | _parent.Process(delta);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/godot/src/Player/States/Run.gd:
--------------------------------------------------------------------------------
1 | extends PlayerState
2 | # Basic state when the player is moving around until jumping or lack of input.
3 |
4 |
5 | func unhandled_input(event: InputEvent) -> void:
6 | _parent.unhandled_input(event)
7 |
8 |
9 | func physics_process(delta: float) -> void:
10 | _parent.physics_process(delta)
11 | if player.is_on_floor() or player.is_on_wall():
12 | if _parent.velocity.length() < 0.001:
13 | _state_machine.transition_to("Move/Idle")
14 | else:
15 | _state_machine.transition_to("Move/Air")
16 |
17 |
18 |
19 | func enter(msg: = {}) -> void:
20 | skin.transition_to(skin.States.RUN)
21 | skin.is_moving = true
22 | _parent.enter()
23 |
24 |
25 | func exit() -> void:
26 | skin.is_moving = false
27 | _parent.exit()
28 |
--------------------------------------------------------------------------------
/godot/src/Main/Game.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 |
3 |
4 | func _ready() -> void:
5 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
6 |
7 |
8 | func _input(event: InputEvent) -> void:
9 | if event.is_action_pressed("click"):
10 | if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
11 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
12 | if event.is_action_pressed("toggle_mouse_captured"):
13 | if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
14 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
15 | else:
16 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
17 | get_tree().set_input_as_handled()
18 |
19 | if event.is_action_pressed("toggle_fullscreen"):
20 | OS.window_fullscreen = not OS.window_fullscreen
21 | get_tree().set_input_as_handled()
22 |
--------------------------------------------------------------------------------
/godot/src/Player/States/Idle.gd:
--------------------------------------------------------------------------------
1 | extends PlayerState
2 | # State for when there is no movement input.
3 | # Supports triggering jump after the player started to fall.
4 |
5 |
6 | func unhandled_input(event: InputEvent) -> void:
7 | _parent.unhandled_input(event)
8 |
9 |
10 | func physics_process(delta: float) -> void:
11 | _parent.physics_process(delta)
12 | if player.is_on_floor() and _parent.velocity.length() > 0.01:
13 | _state_machine.transition_to("Move/Run")
14 | elif not player.is_on_floor():
15 | _state_machine.transition_to("Move/Air")
16 |
17 |
18 | func enter(msg: Dictionary = {}) -> void:
19 | _parent.velocity = Vector3.ZERO
20 | skin.transition_to(skin.States.IDLE)
21 | _parent.enter()
22 |
23 |
24 | func exit() -> void:
25 | _parent.exit()
26 |
--------------------------------------------------------------------------------
/godot/icon.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://icon.png"
13 | dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/godot-csharp/icon.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://icon.png"
13 | dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/godot-csharp/src/Player/PlayerState.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System.Threading.Tasks;
3 |
4 | public class PlayerState : State
5 | {
6 | protected Player _player = null;
7 | protected Mannequiny _skin = null;
8 | public override void _Ready()
9 | {
10 | base._Ready();
11 | WaitForParentNode();
12 | }
13 |
14 |
15 | // Waiting for the owner node to be ready
16 | private async void WaitForParentNode()
17 | {
18 | await ToSignal(Owner, "ready");
19 |
20 |
21 | _player = (Owner as Player);
22 |
23 | _skin = ((Owner as Player).skin);
24 |
25 | if ((_player == null)) GD.PushError("_player reference is null!");
26 | if ((_skin == null)) GD.PushError("_player.skin reference is null!");
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/godot-csharp/assets/2d/icons/state.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/state.svg-d06754b36e2c90d383239ac6f060972b.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://assets/2d/icons/state.svg"
13 | dest_files=[ "res://.import/state.svg-d06754b36e2c90d383239ac6f060972b.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/godot/src/Player/Camera/SpringArm.gd:
--------------------------------------------------------------------------------
1 | tool
2 | extends SpringArm
3 | # Control the zoom of the camera with `zoom`, a value between 0 and 1
4 |
5 | export var length_range := Vector2(3.0, 6.0) setget set_length_range
6 | export var zoom := 0.5 setget set_zoom
7 |
8 | onready var _position_start: Vector3 = translation
9 |
10 |
11 | # Ensures that each value is greater than 0, and that length_range.x <= length_range.y
12 | # Then updates the zoom
13 | func set_length_range(value: Vector2) -> void:
14 | value.x = max(value.x, 0.0)
15 | value.y = max(value.y, 0.0)
16 | length_range.x = min(value.x, value.y)
17 | length_range.y = max(value.x, value.y)
18 | self.zoom = zoom
19 |
20 |
21 | func set_zoom(value: float) -> void:
22 | assert(value >= 0.0 and value <= 1.0)
23 | zoom = value
24 | spring_length = lerp(length_range.y, length_range.x, zoom)
25 |
--------------------------------------------------------------------------------
/images/mannequin-v0.1.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/prototype-1.png-4ffdd871fc7208d257b791af640b3f66.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://assets/screenshots/prototype-1.png"
13 | dest_files=[ "res://.import/prototype-1.png-4ffdd871fc7208d257b791af640b3f66.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/godot/assets/theme/icons/chevron-up.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/chevron-up.svg-48b5b69265734774d0a7516dcc6f0863.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://assets/theme/icons/chevron-up.svg"
13 | dest_files=[ "res://.import/chevron-up.svg-48b5b69265734774d0a7516dcc6f0863.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/godot-csharp/assets/2d/icons/state_machine.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/state_machine.svg-dba8e7cdb56c0173ebd2c904fa7180e5.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://assets/2d/icons/state_machine.svg"
13 | dest_files=[ "res://.import/state_machine.svg-dba8e7cdb56c0173ebd2c904fa7180e5.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/godot/assets/theme/icons/chevron-right.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/chevron-right.svg-f77dee7a088177a2ac1d467f4c7cd3e1.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://assets/theme/icons/chevron-right.svg"
13 | dest_files=[ "res://.import/chevron-right.svg-f77dee7a088177a2ac1d467f4c7cd3e1.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/godot/assets/3d/level/level_environment.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Environment" load_steps=2 format=2]
2 |
3 | [sub_resource type="ProceduralSky" id=1]
4 | radiance_size = 1
5 | sky_top_color = Color( 0.309804, 0.694118, 0.847059, 1 )
6 | sky_horizon_color = Color( 0.882353, 0.937255, 0.980392, 1 )
7 | sky_curve = 0.11471
8 | ground_bottom_color = Color( 0.309804, 0.435294, 0.560784, 1 )
9 | ground_horizon_color = Color( 0.929412, 0.937255, 0.960784, 1 )
10 | sun_color = Color( 0.941176, 0.886275, 0.705882, 1 )
11 | sun_longitude = -147.57
12 | sun_curve = 0.0420449
13 | texture_size = 1
14 |
15 | [resource]
16 | background_mode = 2
17 | background_sky = SubResource( 1 )
18 | tonemap_mode = 3
19 | tonemap_white = 2.0
20 | ss_reflections_enabled = true
21 | ss_reflections_max_steps = 32
22 | ssao_enabled = true
23 | glow_intensity = 1.24
24 | glow_strength = 0.93
25 | adjustment_contrast = 1.1
26 |
--------------------------------------------------------------------------------
/godot-csharp/assets/3d/level/level_environment.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Environment" load_steps=2 format=2]
2 |
3 | [sub_resource type="ProceduralSky" id=1]
4 | radiance_size = 1
5 | sky_top_color = Color( 0.309804, 0.694118, 0.847059, 1 )
6 | sky_horizon_color = Color( 0.882353, 0.937255, 0.980392, 1 )
7 | sky_curve = 0.11471
8 | ground_bottom_color = Color( 0.309804, 0.435294, 0.560784, 1 )
9 | ground_horizon_color = Color( 0.929412, 0.937255, 0.960784, 1 )
10 | sun_color = Color( 0.941176, 0.886275, 0.705882, 1 )
11 | sun_longitude = -147.57
12 | sun_curve = 0.0420449
13 | texture_size = 1
14 |
15 | [resource]
16 | background_mode = 2
17 | background_sky = SubResource( 1 )
18 | tonemap_mode = 3
19 | tonemap_white = 2.0
20 | ss_reflections_enabled = true
21 | ss_reflections_max_steps = 32
22 | ssao_enabled = true
23 | glow_intensity = 1.24
24 | glow_strength = 0.93
25 | adjustment_contrast = 1.1
26 |
--------------------------------------------------------------------------------
/godot-csharp/src/Main/Game.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class Game : Node
5 | {
6 | public override void _Ready()
7 | {
8 | Input.SetMouseMode(Input.MouseMode.Captured);
9 | }
10 |
11 | public override void _Input(InputEvent @event) {
12 |
13 | // Toggle Cursor mode on click on window or escape key
14 |
15 | if (@event.IsActionPressed("click")) {
16 | if(Input.GetMouseMode() != Input.MouseMode.Captured) {
17 | Input.SetMouseMode(Input.MouseMode.Captured);
18 | }
19 | }
20 |
21 |
22 | if (@event.IsActionPressed("toggle_mouse_captured"))
23 | {
24 | if (Input.GetMouseMode() == Input.MouseMode.Captured) {
25 | Input.SetMouseMode(Input.MouseMode.Visible);
26 | } else {
27 | Input.SetMouseMode(Input.MouseMode.Captured);
28 | }
29 | // no other input function should get this
30 | GetTree().SetInputAsHandled();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/godot-csharp/src/Camera/AimTarget.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class AimTarget : Sprite3D
5 | {
6 |
7 | public override void _Ready()
8 | {
9 | SetAsToplevel(true);
10 | Visible = false;
11 | }
12 |
13 | public void Update(RayCast ray) {
14 | // update manually instead only once per frame in process
15 | ray.ForceRaycastUpdate();
16 | var isColliding = ray.IsColliding();
17 | Visible = isColliding;
18 |
19 | if (isColliding) {
20 | Vector3 collisionPoint = ray.GetCollisionPoint();
21 | Vector3 collisionNormal = ray.GetCollisionNormal();
22 |
23 | var transform = this.GlobalTransform;
24 | transform.origin = collisionPoint + collisionNormal * 0.01f;
25 | GlobalTransform = transform;
26 |
27 | LookAt(collisionPoint - collisionNormal, GlobalTransform.basis.y.Normalized());
28 | }
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/godot/default_env.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Environment" load_steps=2 format=2]
2 |
3 | [sub_resource type="ProceduralSky" id=1]
4 | radiance_size = 1
5 | sky_top_color = Color( 0.309804, 0.694118, 0.847059, 1 )
6 | sky_horizon_color = Color( 0.882353, 0.937255, 0.980392, 1 )
7 | sky_curve = 0.11471
8 | ground_bottom_color = Color( 0.309804, 0.435294, 0.560784, 1 )
9 | ground_horizon_color = Color( 0.929412, 0.937255, 0.960784, 1 )
10 | sun_color = Color( 0.941176, 0.886275, 0.705882, 1 )
11 | sun_longitude = -147.57
12 | sun_curve = 0.0420449
13 | texture_size = 1
14 |
15 | [resource]
16 | background_mode = 3
17 | background_sky = SubResource( 1 )
18 | background_color = Color( 0.215686, 0.215686, 0.215686, 1 )
19 | ambient_light_color = Color( 0.976471, 0.941176, 0.941176, 1 )
20 | ambient_light_sky_contribution = 0.72
21 | tonemap_mode = 3
22 | tonemap_white = 2.0
23 | ss_reflections_enabled = true
24 | ss_reflections_max_steps = 32
25 | glow_intensity = 1.24
26 | glow_strength = 0.93
27 | adjustment_contrast = 1.1
28 |
--------------------------------------------------------------------------------
/godot-csharp/default_env.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Environment" load_steps=2 format=2]
2 |
3 | [sub_resource type="ProceduralSky" id=1]
4 | radiance_size = 1
5 | sky_top_color = Color( 0.309804, 0.694118, 0.847059, 1 )
6 | sky_horizon_color = Color( 0.882353, 0.937255, 0.980392, 1 )
7 | sky_curve = 0.11471
8 | ground_bottom_color = Color( 0.309804, 0.435294, 0.560784, 1 )
9 | ground_horizon_color = Color( 0.929412, 0.937255, 0.960784, 1 )
10 | sun_color = Color( 0.941176, 0.886275, 0.705882, 1 )
11 | sun_longitude = -147.57
12 | sun_curve = 0.0420449
13 | texture_size = 1
14 |
15 | [resource]
16 | background_mode = 3
17 | background_sky = SubResource( 1 )
18 | background_color = Color( 0.215686, 0.215686, 0.215686, 1 )
19 | ambient_light_color = Color( 0.976471, 0.941176, 0.941176, 1 )
20 | ambient_light_sky_contribution = 0.72
21 | tonemap_mode = 3
22 | tonemap_white = 2.0
23 | ss_reflections_enabled = true
24 | ss_reflections_max_steps = 32
25 | glow_intensity = 1.24
26 | glow_strength = 0.93
27 | adjustment_contrast = 1.1
28 |
--------------------------------------------------------------------------------
/godot/src/Player/Camera/CameraRig.gd:
--------------------------------------------------------------------------------
1 | tool
2 | extends Spatial
3 | class_name CameraRig
4 | # Accessor class that gives the nodes in the scene access the player or some
5 | # frequently used nodes in the scene itself.
6 |
7 | signal aim_fired(target_position)
8 |
9 | onready var camera: InterpolatedCamera = $InterpolatedCamera
10 | onready var spring_arm: SpringArm = $SpringArm
11 | onready var aim_ray: RayCast = $InterpolatedCamera/AimRay
12 | onready var aim_target: Sprite3D = $AimTarget
13 |
14 | var player: KinematicBody
15 |
16 | var zoom := 0.5 setget set_zoom
17 |
18 | onready var _position_start: Vector3 = translation
19 |
20 |
21 | func _ready() -> void:
22 | set_as_toplevel(true)
23 | yield(owner, "ready")
24 | player = owner
25 |
26 |
27 | func _get_configuration_warning() -> String:
28 | return "Missing player node" if not player else ""
29 |
30 |
31 | func set_zoom(value: float) -> void:
32 | zoom = clamp(value, 0.0, 1.0)
33 | if not spring_arm:
34 | yield(spring_arm, "ready")
35 | spring_arm.zoom = zoom
36 |
--------------------------------------------------------------------------------
/godot/assets/2d/reticle.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path.s3tc="res://.import/reticle.png-82034ac855365a76f8f31dfc0b0190e4.s3tc.stex"
6 | path.etc2="res://.import/reticle.png-82034ac855365a76f8f31dfc0b0190e4.etc2.stex"
7 | metadata={
8 | "imported_formats": [ "s3tc", "etc2" ],
9 | "vram_texture": true
10 | }
11 |
12 | [deps]
13 |
14 | source_file="res://assets/2d/reticle.png"
15 | dest_files=[ "res://.import/reticle.png-82034ac855365a76f8f31dfc0b0190e4.s3tc.stex", "res://.import/reticle.png-82034ac855365a76f8f31dfc0b0190e4.etc2.stex" ]
16 |
17 | [params]
18 |
19 | compress/mode=2
20 | compress/lossy_quality=0.7
21 | compress/hdr_mode=0
22 | compress/bptc_ldr=0
23 | compress/normal_map=0
24 | flags/repeat=true
25 | flags/filter=true
26 | flags/mipmaps=true
27 | flags/anisotropic=false
28 | flags/srgb=2
29 | process/fix_alpha_border=true
30 | process/premult_alpha=false
31 | process/HDR_as_SRGB=false
32 | process/invert_color=false
33 | stream=false
34 | size_limit=0
35 | detect_3d=false
36 | svg/scale=1.0
37 |
--------------------------------------------------------------------------------
/godot-csharp/assets/2d/reticle.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path.s3tc="res://.import/reticle.png-82034ac855365a76f8f31dfc0b0190e4.s3tc.stex"
6 | path.etc2="res://.import/reticle.png-82034ac855365a76f8f31dfc0b0190e4.etc2.stex"
7 | metadata={
8 | "imported_formats": [ "s3tc", "etc2" ],
9 | "vram_texture": true
10 | }
11 |
12 | [deps]
13 |
14 | source_file="res://assets/2d/reticle.png"
15 | dest_files=[ "res://.import/reticle.png-82034ac855365a76f8f31dfc0b0190e4.s3tc.stex", "res://.import/reticle.png-82034ac855365a76f8f31dfc0b0190e4.etc2.stex" ]
16 |
17 | [params]
18 |
19 | compress/mode=2
20 | compress/lossy_quality=0.7
21 | compress/hdr_mode=0
22 | compress/bptc_ldr=0
23 | compress/normal_map=0
24 | flags/repeat=true
25 | flags/filter=true
26 | flags/mipmaps=true
27 | flags/anisotropic=false
28 | flags/srgb=2
29 | process/fix_alpha_border=true
30 | process/premult_alpha=false
31 | process/HDR_as_SRGB=false
32 | process/invert_color=false
33 | stream=false
34 | size_limit=0
35 | detect_3d=false
36 | svg/scale=1.0
37 |
--------------------------------------------------------------------------------
/godot-csharp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | // Information about this assembly is defined by the following attributes.
4 | // Change them to the values specific to your project.
5 |
6 | [assembly: AssemblyTitle("Learn to Code a Pro 3D Character with Godot (start)")]
7 | [assembly: AssemblyDescription("")]
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("")]
10 | [assembly: AssemblyProduct("")]
11 | [assembly: AssemblyCopyright("")]
12 | [assembly: AssemblyTrademark("")]
13 | [assembly: AssemblyCulture("")]
14 |
15 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
16 | // The form "{Major}.{Minor}.*" will automatically update the build and revision,
17 | // and "{Major}.{Minor}.{Build}.*" will update just the revision.
18 |
19 | [assembly: AssemblyVersion("1.0.*")]
20 |
21 | // The following attributes are used to specify the signing key for the assembly,
22 | // if desired. See the Mono documentation for more information about signing.
23 |
24 | //[assembly: AssemblyDelaySign(false)]
25 | //[assembly: AssemblyKeyFile("")]
26 |
--------------------------------------------------------------------------------
/godot-csharp/src/Player/States/Idle.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System.Collections.Generic;
3 |
4 | public class Idle : PlayerState
5 | {
6 | public override void _Ready()
7 | {
8 | base._Ready();
9 | }
10 |
11 | public override void UnhandledInput(InputEvent @event) {
12 | (_parent as Move).UnhandledInput(@event);
13 | }
14 | public override void PhysicsProcess(float delta) {
15 | (_parent as Move).PhysicsProcess(delta);
16 |
17 | if (_player.IsOnFloor() && (_parent as Move).velocity.Length() > 0.01) {
18 | (_stateMachine as StateMachine).TransitionTo("Move/Run");
19 | } else if (!_player.IsOnFloor()) {
20 | (_stateMachine as StateMachine).TransitionTo("Move/Air");
21 | }
22 | }
23 |
24 | public override void Enter(Dictionary msg = null) {
25 | (_parent as Move).velocity = Vector3.Zero;
26 | (_skin as Mannequiny).TransitionTo(Mannequiny.States.IDLE);
27 | _parent.Enter(msg);
28 | }
29 |
30 | public override void Exit() {
31 | (_parent as Move).Exit();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/godot-csharp/Learn to Code a Pro 3D Character with Godot (start).sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2012
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Learn to Code a Pro 3D Character with Godot (start)", "Learn to Code a Pro 3D Character with Godot (start).csproj", "{88DCB668-1E0F-40F7-BFC3-96BBEA3AA5D1}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Any CPU = Debug|Any CPU
8 | Release|Any CPU = Release|Any CPU
9 | Tools|Any CPU = Tools|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {88DCB668-1E0F-40F7-BFC3-96BBEA3AA5D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {88DCB668-1E0F-40F7-BFC3-96BBEA3AA5D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {88DCB668-1E0F-40F7-BFC3-96BBEA3AA5D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {88DCB668-1E0F-40F7-BFC3-96BBEA3AA5D1}.Release|Any CPU.Build.0 = Release|Any CPU
16 | {88DCB668-1E0F-40F7-BFC3-96BBEA3AA5D1}.Tools|Any CPU.ActiveCfg = Tools|Any CPU
17 | {88DCB668-1E0F-40F7-BFC3-96BBEA3AA5D1}.Tools|Any CPU.Build.0 = Tools|Any CPU
18 | EndGlobalSection
19 | EndGlobal
20 |
--------------------------------------------------------------------------------
/godot-csharp/src/Camera/SpringArm.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System.Diagnostics;
3 |
4 | // Control the zoom of the camera with 'zoom', a value between 0 and 1
5 | public class SpringArm : Godot.SpringArm
6 | {
7 |
8 | Vector2 lengthRange = new Vector2(3.0f, 6.0f);
9 | float zoom = 0.5f;
10 | public Vector3 _positionStart;
11 |
12 | [Export]
13 | public Vector2 LengthRange
14 | {
15 | get { return lengthRange; }
16 | set
17 | {
18 | value.x = Mathf.Max(value.x, 0.0f);
19 | value.y = Mathf.Max(value.y, 0.0f);
20 | lengthRange.x = Mathf.Min(value.x, value.y);
21 | lengthRange.y = Mathf.Min(value.x, value.y);
22 | // set zoom again
23 | this.Zoom = zoom;
24 | }
25 | }
26 |
27 | [Export]
28 | public float Zoom {
29 | get { return zoom;}
30 | set {
31 | Debug.Assert((value >= 0.0) && (value <= 1.0f));
32 | zoom = value;
33 | SpringLength = lengthRange.y + lengthRange.x - Mathf.Lerp(lengthRange.x, lengthRange.y, zoom);
34 | }
35 | }
36 |
37 | public override void _Ready()
38 | {
39 | _positionStart = Translation;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/godot/src/Main/StateMachine/State.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 | class_name State
3 | # State interface to use in Hierarchical State Machines. The lowest leaf tries
4 | # to handle callbacks, and if it can't, it delegates the work to its parent.
5 | #
6 | # It's up to the user to call the parent state's functions, e.g.
7 | # `_parent.physics_process(delta)`
8 | #
9 | # Use State as a child of a StateMachine node.
10 |
11 | onready var _state_machine := _get_state_machine(self)
12 |
13 | # Using the same class, i.e. State, as a type hint causes a memory leak in Godot
14 | # 3.2.
15 | var _parent = null
16 |
17 |
18 | func _ready() -> void:
19 | yield(owner, "ready")
20 | var parent = get_parent()
21 | if not parent.is_in_group("state_machine"):
22 | _parent = parent
23 |
24 |
25 | func unhandled_input(event: InputEvent) -> void:
26 | pass
27 |
28 |
29 | func process(delta: float) -> void:
30 | pass
31 |
32 |
33 | func physics_process(delta: float) -> void:
34 | pass
35 |
36 |
37 | func enter(msg := {}) -> void:
38 | pass
39 |
40 |
41 | func exit() -> void:
42 | pass
43 |
44 |
45 | func _get_state_machine(node: Node) -> Node:
46 | if node != null and not node.is_in_group("state_machine"):
47 | return _get_state_machine(node.get_parent())
48 | return node
49 |
--------------------------------------------------------------------------------
/godot/src/Main/StateMachine/StateMachine.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 | class_name StateMachine
3 | # Generic State Machine. Initializes states and delegates engine callbacks
4 | # (_physics_process, _unhandled_input) to the active state.
5 |
6 | signal transitioned(state_path)
7 |
8 | export var initial_state := NodePath()
9 |
10 | onready var state: State = get_node(initial_state) setget set_state
11 | onready var _state_name := state.name
12 |
13 |
14 | func _init() -> void:
15 | add_to_group("state_machine")
16 |
17 |
18 | func _ready() -> void:
19 | yield(owner, "ready")
20 | state.enter()
21 |
22 |
23 | func _unhandled_input(event: InputEvent) -> void:
24 | state.unhandled_input(event)
25 |
26 |
27 | func _process(delta: float) -> void:
28 | state.process(delta)
29 |
30 |
31 | func _physics_process(delta: float) -> void:
32 | state.physics_process(delta)
33 |
34 |
35 | func transition_to(target_state_path: String, msg: Dictionary = {}) -> void:
36 | if not has_node(target_state_path):
37 | return
38 |
39 | var target_state := get_node(target_state_path)
40 |
41 | state.exit()
42 | self.state = target_state
43 | state.enter(msg)
44 | emit_signal("transitioned", target_state_path)
45 |
46 |
47 | func set_state(value: State) -> void:
48 | state = value
49 | _state_name = state.name
50 |
--------------------------------------------------------------------------------
/godot/src/Player/Mannequiny.gd:
--------------------------------------------------------------------------------
1 | extends Spatial
2 | class_name Mannequiny
3 | # Controls the animation tree's transitions for this animated character.
4 |
5 | # # It has a signal connected to the player state machine, and uses the resulting
6 | # state names to translate them into the states for the animation tree.
7 |
8 | enum States { IDLE, RUN, AIR, LAND }
9 |
10 | onready var animation_tree: AnimationTree = $AnimationTree
11 | onready var _playback: AnimationNodeStateMachinePlayback = animation_tree["parameters/playback"]
12 |
13 | var move_direction := Vector3.ZERO setget set_move_direction
14 | var is_moving := false setget set_is_moving
15 |
16 |
17 | func _ready() -> void:
18 | animation_tree.active = true
19 |
20 |
21 | func set_move_direction(direction: Vector3) -> void:
22 | move_direction = direction
23 | animation_tree["parameters/move_ground/blend_position"] = direction.length()
24 |
25 |
26 | func set_is_moving(value: bool) -> void:
27 | is_moving = value
28 | animation_tree["parameters/conditions/is_moving"] = value
29 |
30 |
31 | func transition_to(state_id: int) -> void:
32 | match state_id:
33 | States.IDLE:
34 | _playback.travel("idle")
35 | States.LAND:
36 | _playback.travel("land")
37 | States.RUN:
38 | _playback.travel("move_ground")
39 | States.AIR:
40 | _playback.travel("jump")
41 | _:
42 | _playback.travel("idle")
43 |
--------------------------------------------------------------------------------
/godot/src/Player/States/Extensions/Zip.gd:
--------------------------------------------------------------------------------
1 | extends PlayerState
2 | # Hookshot style state for the player - gets a destination from an outside
3 | # piece of logic (in this case, the Camera's aim state firing with a raycast)
4 | # and flies through the air to reach it.
5 |
6 |
7 | var speed: = 10.0
8 | var target: = Vector3.ZERO
9 |
10 |
11 | func unhandled_input(event: InputEvent) -> void:
12 | if event.is_action_pressed("interact"):
13 | _state_machine.transition_to("Move/Idle")
14 |
15 |
16 | func physics_process(delta: float) -> void:
17 | var direction: = (target - player.get_global_transform().origin).normalized()
18 | var aim_length: float = player.camera.aim_ray.cast_to.length() - target.length() + 1.0
19 |
20 | _parent.velocity = direction * speed
21 | _parent.physics_process(delta)
22 |
23 | if player.get_slide_count() > 0:
24 | if Input.is_action_pressed("interact"):
25 | _parent.velocity = Vector3.ZERO
26 | _state_machine.transition_to("Move/Hang")
27 | else:
28 | _parent.velocity = Vector3.ZERO
29 | _state_machine.transition_to("Move/Air")
30 |
31 |
32 | func enter(msg: Dictionary = {}) -> void:
33 | _parent.gravity = 0.0
34 | if "target" in msg:
35 | target = msg.target
36 | else:
37 | _state_machine.transition_to("Move/Idle")
38 |
39 |
40 | func exit() -> void:
41 | # FIXME: redo this bit
42 | _parent.gravity = -80.0
43 | target = Vector3.ZERO
44 |
--------------------------------------------------------------------------------
/godot-csharp/src/Player/States/Run.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System.Collections.Generic;
3 |
4 | public class Run : PlayerState
5 | {
6 | [Export]
7 | float speedRun = 500.0f;
8 | [Export]
9 | float speedSprint = 800.0f;
10 | public override void _Ready()
11 | {
12 | base._Ready();
13 | }
14 |
15 | public override void UnhandledInput(InputEvent @event)
16 | {
17 | _parent.UnhandledInput(@event);
18 | }
19 | public override void PhysicsProcess(float delta)
20 | {
21 | (_parent as Move).moveSpeed = (Input.IsActionPressed("sprint") ? speedSprint : speedRun);
22 | (_player.skin as Mannequiny).SetPlaybackSpeed((_parent as Move).moveSpeed / speedRun);
23 |
24 |
25 | _parent.PhysicsProcess(delta);
26 |
27 | if (_player.IsOnFloor() || _player.IsOnWall())
28 | {
29 | if ((_parent as Move).velocity.Length() < 0.01)
30 | {
31 | (_stateMachine as StateMachine).TransitionTo("Move/Idle");
32 | }
33 | } else {
34 | (_stateMachine as StateMachine).TransitionTo("Move/Air");
35 | }
36 | }
37 |
38 | public override void Enter(Dictionary msg = null)
39 | {
40 | (_skin as Mannequiny).TransitionTo(Mannequiny.States.RUN);
41 | _parent.Enter(msg);
42 | }
43 |
44 | public override void Exit()
45 | {
46 | _parent.Exit();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This project is dual-licensed:
2 |
3 | - The source code is available under the MIT license.
4 | - Art assets (images, audio files) are [CC-By 4.0](https://creativecommons.org/licenses/by/4.0/). You can attribute them to `GDQuest and contributors (https://www.gdquest.com/)`.
5 |
6 |
7 | MIT License
8 |
9 | Copyright (c) 2020 GDQuest
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining a copy
12 | of this software and associated documentation files (the "Software"), to deal
13 | in the Software without restriction, including without limitation the rights
14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | copies of the Software, and to permit persons to whom the Software is
16 | furnished to do so, subject to the following conditions:
17 |
18 | The above copyright notice and this permission notice shall be included in all
19 | copies or substantial portions of the Software.
20 |
21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | SOFTWARE.
28 |
29 |
30 | Creative Commons Attribution 4.0 International Public License
31 |
32 | Read the full license on: https://creativecommons.org/licenses/by/4.0/legalcode
33 |
--------------------------------------------------------------------------------
/godot/src/Debug/DebugPanel.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=1]
4 | [ext_resource path="res://src/Debug/DebugPanel.gd" type="Script" id=2]
5 | [ext_resource path="res://assets/theme/fonts/font_title.tres" type="DynamicFont" id=3]
6 |
7 |
8 | [node name="DebugPanel" type="PanelContainer"]
9 | anchor_right = 1.0
10 | anchor_bottom = 1.0
11 | margin_right = -1630.0
12 | margin_bottom = -998.0
13 | theme = ExtResource( 1 )
14 | script = ExtResource( 2 )
15 | reference_path = NodePath("")
16 | properties = PoolStringArray( )
17 |
18 | [node name="VBoxContainer" type="VBoxContainer" parent="."]
19 | margin_right = 290.0
20 | margin_bottom = 102.0
21 |
22 | [node name="ReferenceName" type="Label" parent="VBoxContainer"]
23 | margin_right = 290.0
24 | margin_bottom = 54.0
25 | rect_min_size = Vector2( 0, 54 )
26 | custom_fonts/font = ExtResource( 3 )
27 | text = "DebugPanel"
28 | align = 1
29 | valign = 1
30 |
31 | [node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"]
32 | margin_top = 62.0
33 | margin_right = 290.0
34 | margin_bottom = 102.0
35 | size_flags_horizontal = 3
36 | size_flags_vertical = 3
37 | custom_constants/margin_right = 20
38 | custom_constants/margin_top = 20
39 | custom_constants/margin_left = 20
40 | custom_constants/margin_bottom = 20
41 |
42 | [node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/MarginContainer"]
43 | margin_left = 20.0
44 | margin_top = 20.0
45 | margin_right = 270.0
46 | margin_bottom = 20.0
47 | size_flags_horizontal = 3
48 | size_flags_vertical = 3
49 |
--------------------------------------------------------------------------------
/godot-csharp/src/Main/Game.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=7 format=2]
2 |
3 | [ext_resource path="res://src/Player/Player.tscn" type="PackedScene" id=1]
4 | [ext_resource path="res://src/Level/Playground.tscn" type="PackedScene" id=2]
5 | [ext_resource path="res://assets/3d/level/level_environment.tres" type="Environment" id=3]
6 | [ext_resource path="res://src/Main/Game.cs" type="Script" id=4]
7 |
8 | [sub_resource type="PlaneMesh" id=1]
9 | size = Vector2( 50, 50 )
10 |
11 | [sub_resource type="BoxShape" id=2]
12 | extents = Vector3( 25, 1, 25 )
13 |
14 | [node name="Game" type="Node"]
15 | script = ExtResource( 4 )
16 |
17 | [node name="Player" parent="." instance=ExtResource( 1 )]
18 |
19 | [node name="MeshInstance" type="MeshInstance" parent="."]
20 | mesh = SubResource( 1 )
21 | material/0 = null
22 |
23 | [node name="StaticBody" type="StaticBody" parent="MeshInstance"]
24 | collision_layer = 2
25 | collision_mask = 0
26 |
27 | [node name="CollisionShape" type="CollisionShape" parent="MeshInstance/StaticBody"]
28 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0 )
29 | shape = SubResource( 2 )
30 |
31 | [node name="Playground" parent="." instance=ExtResource( 2 )]
32 | transform = Transform( -1.62921e-07, 0, -1, 0, 1, 0, 1, 0, -1.62921e-07, 0, 0, -14.5668 )
33 |
34 | [node name="DirectionalLight" type="DirectionalLight" parent="."]
35 | transform = Transform( 0.866025, 0.487656, -0.110417, 0, 0.220834, 0.975312, 0.5, -0.844645, 0.191247, -3.28834, 4.72299, 2.39486 )
36 | shadow_enabled = true
37 |
38 | [node name="WorldEnvironment" type="WorldEnvironment" parent="."]
39 | environment = ExtResource( 3 )
40 |
--------------------------------------------------------------------------------
/godot-csharp/src/Player/States/Air.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System.Collections.Generic;
3 |
4 | public class Air : PlayerState
5 | {
6 | public override void _Ready()
7 | {
8 | base._Ready();
9 | }
10 |
11 | public override void PhysicsProcess(float delta)
12 | {
13 | (_parent as Move).PhysicsProcess(delta);
14 |
15 | if (_player.IsOnFloor())
16 | {
17 | Vector3 inputDirection = Move.GetInputDirection();
18 | // See if moving then return after fall to run else idle
19 | if (inputDirection.Length() > 0.001)
20 | {
21 | (_stateMachine as StateMachine).TransitionTo("Move/Run");
22 | }
23 | else
24 | {
25 | (_stateMachine as StateMachine).TransitionTo("Move/Idle");
26 | }
27 | }
28 | }
29 |
30 | public override void Enter(Dictionary msg)
31 | {
32 | if (msg != null)
33 | {
34 | // TODO: maybe change to consts or an enum for dictionary keys for easier use
35 | if (msg.ContainsKey("velocity") && msg.ContainsKey("jumpImpulse"))
36 | {
37 | var v = (Vector3)msg["velocity"];
38 | var j = (float)msg["jumpImpulse"];
39 | (_parent as Move).velocity = v + new Vector3(0.0f, j, 0.0f);
40 | }
41 | }
42 | (_skin as Mannequiny).TransitionTo(Mannequiny.States.AIR);
43 | _parent.Enter(msg);
44 | }
45 |
46 | public override void Exit()
47 | {
48 | (_parent as Move).Exit();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/godot-csharp/src/Camera/CameraRig.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System.Threading.Tasks;
3 |
4 | public class CameraRig : Spatial
5 | {
6 | public RayCast aimRay = null;
7 | public AimTarget aimTarget = null;
8 | public InterpolatedCamera camera = null;
9 | public SpringArm springArm = null;
10 | public KinematicBody player = null;
11 | public Vector3 _positionStart;
12 | float zoom = 0.5f;
13 |
14 | public float Zoom {
15 | get { return zoom; }
16 | set {
17 | zoom = Mathf.Clamp(value, 0.0f, 1.0f);
18 | springArm.Zoom = zoom;
19 | }
20 | }
21 | public override void _Ready()
22 | {
23 | aimTarget = GetNode("AimTarget");
24 | if (aimTarget == null) GD.PushError("AimTarget reference not found!");
25 |
26 |
27 | aimRay = GetNode("InterpolatedCamera/AimRay");
28 | if (aimRay == null) GD.PushError("AimRay reference not found!");
29 |
30 | camera = GetNode("InterpolatedCamera");
31 | if (camera == null) GD.PushError("InterpolatedCamera reference not found!");
32 |
33 | springArm = GetNode("SpringArm");
34 | if (springArm == null) GD.PushError("SpringArm reference not found!");
35 |
36 | _positionStart = this.Translation;
37 |
38 | // node transformations only in Global Space
39 | SetAsToplevel(true);
40 |
41 | WaitForParentNode();
42 | }
43 |
44 | async void WaitForParentNode()
45 | {
46 | await ToSignal(Owner, "ready");
47 | player = (Owner as KinematicBody);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/godot-csharp/src/Main/StateMachine/State.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 | using System.Threading.Tasks;
4 | using System.Collections.Generic;
5 |
6 | public class State : Node
7 | {
8 | protected Node _stateMachine = null;
9 | protected State _parent = null;
10 | public bool isActive
11 | {
12 | set
13 | {
14 | SetIsActive(value);
15 | }
16 | }
17 |
18 | private void SetIsActive(bool value)
19 | {
20 | isActive = value;
21 | SetBlockSignals(!value);
22 | }
23 |
24 | public override void _Ready()
25 | {
26 | WaitForParentNode();
27 | }
28 |
29 | private async void WaitForParentNode()
30 | {
31 | await ToSignal(Owner, "ready");
32 |
33 | Node parent = GetParent();
34 |
35 | _stateMachine = GetStateMachine(this);
36 |
37 | if (parent == null) GD.PushError("parent in State is null!");
38 |
39 | if (!(parent.IsInGroup("stateMachine")))
40 | _parent = GetParent() as State;
41 | }
42 | public virtual void UnhandledInput(InputEvent @event)
43 | {
44 |
45 | }
46 |
47 | public virtual void Process(float delta)
48 | {
49 |
50 | }
51 |
52 | public virtual void PhysicsProcess(float delta)
53 | {
54 |
55 | }
56 |
57 | public virtual void Enter(Dictionary msg = null)
58 | {
59 |
60 | }
61 |
62 | public virtual void Exit()
63 | {
64 |
65 | }
66 |
67 | private Node GetStateMachine(Node node)
68 | {
69 | if ((node != null) && !(node.IsInGroup("stateMachine")))
70 | {
71 | return GetStateMachine(node.GetParent());
72 | }
73 | return node;
74 | }
75 |
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/godot/src/Player/Camera/States/Aim.gd:
--------------------------------------------------------------------------------
1 | extends CameraState
2 | # Activates the aiming mode for the camera.
3 | # Moves the camera to the character's shoulder, and narrows the field of view.
4 | # Projects a target on the environment.
5 |
6 | onready var tween := $Tween
7 |
8 | export var fov := 40.0
9 | export var offset_camera := Vector3(0.75, -0.7, 0)
10 |
11 |
12 | func unhandled_input(event: InputEvent) -> void:
13 | if event.is_action_pressed("toggle_aim"):
14 | _state_machine.transition_to("Camera/Default")
15 |
16 | elif event.is_action_pressed("fire"):
17 | _state_machine.transition_to("Camera/Default")
18 | var target_position: Vector3 = (
19 | camera_rig.aim_ray.get_collision_point()
20 | if camera_rig.aim_ray.is_colliding()
21 | else camera_rig.get_global_transform().origin
22 | )
23 | camera_rig.emit_signal("aim_fired", target_position)
24 |
25 | else:
26 | _parent.unhandled_input(event)
27 |
28 |
29 | func process(delta: float) -> void:
30 | _parent.process(delta)
31 | camera_rig.aim_target.update(camera_rig.aim_ray)
32 |
33 |
34 | func enter(msg: Dictionary = {}) -> void:
35 | _parent._is_aiming = true
36 | camera_rig.aim_target.visible = true
37 |
38 | camera_rig.spring_arm.translation = camera_rig._position_start + offset_camera
39 |
40 | tween.interpolate_property(
41 | camera_rig.camera, 'fov', camera_rig.camera.fov, fov, 0.5, Tween.TRANS_QUAD, Tween.EASE_OUT
42 | )
43 | tween.start()
44 |
45 |
46 | func exit() -> void:
47 | _parent._is_aiming = false
48 | camera_rig.aim_target.visible = false
49 |
50 | camera_rig.spring_arm.translation = camera_rig.spring_arm._position_start
51 |
52 | tween.interpolate_property(
53 | camera_rig.camera,
54 | 'fov',
55 | camera_rig.camera.fov,
56 | _parent.fov_default,
57 | 0.5,
58 | Tween.TRANS_QUAD,
59 | Tween.EASE_OUT
60 | )
61 | tween.start()
62 |
--------------------------------------------------------------------------------
/godot-csharp/src/Player/Player.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=10 format=2]
2 |
3 | [ext_resource path="res://src/Player/Mannequiny.tscn" type="PackedScene" id=1]
4 | [ext_resource path="res://src/Player/Player.cs" type="Script" id=2]
5 | [ext_resource path="res://src/Player/States/Move.cs" type="Script" id=3]
6 | [ext_resource path="res://src/Main/StateMachine/StateMachine.cs" type="Script" id=4]
7 | [ext_resource path="res://src/Player/States/Idle.cs" type="Script" id=5]
8 | [ext_resource path="res://src/Player/States/Run.cs" type="Script" id=6]
9 | [ext_resource path="res://src/Player/States/Air.cs" type="Script" id=7]
10 | [ext_resource path="res://src/Camera/CameraRig.tscn" type="PackedScene" id=8]
11 |
12 | [sub_resource type="CapsuleShape" id=1]
13 | radius = 0.25
14 | height = 1.25
15 |
16 | [node name="Player" type="KinematicBody"]
17 | collision_mask = 2
18 | script = ExtResource( 2 )
19 |
20 | [node name="CameraRig" parent="." instance=ExtResource( 8 )]
21 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.60486, 0 )
22 |
23 | [node name="CollisionShape" type="CollisionShape" parent="."]
24 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.872622, 0 )
25 | shape = SubResource( 1 )
26 |
27 | [node name="Mannequiny" parent="." instance=ExtResource( 1 )]
28 | transform = Transform( -1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0 )
29 |
30 | [node name="StateMachine" type="Node" parent="."]
31 | script = ExtResource( 4 )
32 | initialState = NodePath("Move/Idle")
33 |
34 | [node name="Move" type="Node" parent="StateMachine"]
35 | script = ExtResource( 3 )
36 |
37 | [node name="Idle" type="Node" parent="StateMachine/Move"]
38 | script = ExtResource( 5 )
39 |
40 | [node name="Run" type="Node" parent="StateMachine/Move"]
41 | script = ExtResource( 6 )
42 |
43 | [node name="Air" type="Node" parent="StateMachine/Move"]
44 | script = ExtResource( 7 )
45 |
46 | [editable path="CameraRig"]
47 |
--------------------------------------------------------------------------------
/godot-csharp/src/Camera/States/Aim.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class Aim : CameraState
5 | {
6 | Tween tween = null;
7 | [Export]
8 | float fov = 40.0f;
9 | [Export]
10 | Vector3 offsetCamera = new Vector3(0.75f, -0.7f, 0);
11 | public override void _Ready()
12 | {
13 | base._Ready();
14 | tween = GetNode("Tween");
15 | if (tween == null) GD.PushError("Tween reference not found!");
16 | }
17 |
18 | public override void UnhandledInput(InputEvent @event)
19 | {
20 | if (@event.IsActionPressed("toggle_aim"))
21 | {
22 | (_stateMachine as StateMachine).TransitionTo("Camera/Default");
23 | }
24 | else
25 | {
26 | _parent.UnhandledInput(@event);
27 | }
28 | }
29 |
30 | public override void Process(float delta)
31 | {
32 | _parent.Process(delta);
33 | cameraRig.aimTarget.Update(cameraRig.aimRay);
34 | }
35 |
36 | public override void Enter(System.Collections.Generic.Dictionary msg = null)
37 | {
38 | (_parent as Camera).isAiming = true;
39 | cameraRig.aimTarget.Visible = true;
40 |
41 | cameraRig.springArm.Translation = cameraRig._positionStart + offsetCamera;
42 |
43 | tween.InterpolateProperty(cameraRig.camera, "fov", cameraRig.camera.Fov, fov, 0.5f, Tween.TransitionType.Quad, Tween.EaseType.Out);
44 | tween.Start();
45 | }
46 |
47 | public override void Exit()
48 | {
49 | (_parent as Camera).isAiming = false;
50 | cameraRig.aimTarget.Visible = false;
51 |
52 | cameraRig.springArm.Translation = cameraRig.springArm._positionStart;
53 |
54 | tween.InterpolateProperty(cameraRig.camera, "fov", cameraRig.camera.Fov, (_parent as Camera).fovDefault, 0.5f, Tween.TransitionType.Quad, Tween.EaseType.Out);
55 | tween.Start();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/godot-csharp/src/Player/Mannequiny.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 |
5 |
6 | public class Mannequiny : Spatial
7 | {
8 | public enum States
9 | {
10 | IDLE, RUN, AIR
11 | }
12 |
13 | AnimationTree animationTree = null;
14 | AnimationNodeStateMachinePlayback playback = null;
15 | AnimationPlayer animationPlayer = null;
16 | float playbackSpeed = 0.0f;
17 | Vector3 moveDirection;
18 |
19 | public override void _Ready()
20 | {
21 | moveDirection = Vector3.Zero;
22 |
23 | animationTree = GetNode("AnimationTree");
24 | if (animationTree == null)
25 | {
26 | GD.PushError("AnimationTree reference is null!");
27 | }
28 | else
29 | {
30 | animationTree.Active = true;
31 | playback = animationTree.Get("parameters/playback") as AnimationNodeStateMachinePlayback;
32 | }
33 | animationPlayer = GetNode("AnimationPlayer");
34 | if (animationPlayer == null) GD.PushError("AnimationPlayer reference is null!");
35 | }
36 |
37 | public void SetPlaybackSpeed(float speed) {
38 | playbackSpeed = speed;
39 | animationPlayer.PlaybackSpeed = speed;
40 | }
41 |
42 | public void setMoveDirection(Vector3 direction) {
43 | moveDirection = direction;
44 | animationTree.Set("parameters/move_ground/blend_position", direction.Length());
45 | }
46 |
47 |
48 | public void TransitionTo(States stateID)
49 | {
50 | switch (stateID)
51 | {
52 | case States.IDLE:
53 | playback.Travel("idle");
54 | break;
55 | case States.RUN:
56 | playback.Travel("move_ground");
57 | break;
58 | case States.AIR:
59 | playback.Travel("jump");
60 | break;
61 | default:
62 | playback.Travel("idle");
63 | break;
64 | }
65 | }
66 |
67 | }
--------------------------------------------------------------------------------
/godot/src/Player/Player.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=11 format=2]
2 |
3 | [ext_resource path="res://src/Player/Player.gd" type="Script" id=1]
4 | [ext_resource path="res://src/Player/Mannequiny.tscn" type="PackedScene" id=2]
5 | [ext_resource path="res://src/Main/StateMachine/StateMachine.gd" type="Script" id=3]
6 | [ext_resource path="res://src/Player/States/Move.gd" type="Script" id=4]
7 | [ext_resource path="res://src/Player/States/Idle.gd" type="Script" id=5]
8 | [ext_resource path="res://src/Player/States/Air.gd" type="Script" id=6]
9 | [ext_resource path="res://src/Player/States/Run.gd" type="Script" id=7]
10 | [ext_resource path="res://src/Player/Camera/CameraRig.tscn" type="PackedScene" id=8]
11 |
12 | [sub_resource type="AnimationNodeStateMachinePlayback" id=1]
13 |
14 | [sub_resource type="CapsuleShape" id=2]
15 | radius = 0.25
16 | height = 1.25
17 |
18 | [node name="Player" type="KinematicBody"]
19 | script = ExtResource( 1 )
20 |
21 | [node name="Mannequiny" parent="." instance=ExtResource( 2 )]
22 | transform = Transform( -1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0.222992 )
23 |
24 | [node name="AnimationTree" parent="Mannequiny" index="2"]
25 | parameters/playback = SubResource( 1 )
26 |
27 | [node name="CollisionShape" type="CollisionShape" parent="."]
28 | transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.875, 0 )
29 | shape = SubResource( 2 )
30 |
31 | [node name="StateMachine" type="Node" parent="."]
32 | script = ExtResource( 3 )
33 | initial_state = NodePath("Move/Idle")
34 |
35 | [node name="Move" type="Node" parent="StateMachine"]
36 | script = ExtResource( 4 )
37 | gravity = -100.0
38 |
39 | [node name="Idle" type="Node" parent="StateMachine/Move"]
40 | script = ExtResource( 5 )
41 |
42 | [node name="Air" type="Node" parent="StateMachine/Move"]
43 | script = ExtResource( 6 )
44 |
45 | [node name="Run" type="Node" parent="StateMachine/Move"]
46 | script = ExtResource( 7 )
47 |
48 | [node name="CameraRig" parent="." instance=ExtResource( 8 )]
49 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.38644, 0 )
50 |
51 | [editable path="Mannequiny"]
52 |
--------------------------------------------------------------------------------
/godot-csharp/src/Main/StateMachine/StateMachine.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | public class StateMachine : Node
6 | {
7 |
8 | [Signal]
9 | delegate void Transitioned(NodePath statePath);
10 | [Export]
11 | NodePath initialState = null;
12 | State state = null;
13 | String _stateName { get; set; } = "";
14 | public bool isActive
15 | {
16 | get
17 | {
18 | return this.isActive;
19 | }
20 | set
21 | {
22 | SetIsActive(value);
23 | }
24 | }
25 |
26 | void SetIsActive(bool value)
27 | {
28 | this.isActive = value;
29 | SetProcess(value);
30 | SetPhysicsProcess(value);
31 | SetProcessUnhandledInput(value);
32 | state.isActive = value;
33 | }
34 |
35 | public StateMachine()
36 | {
37 | AddToGroup("stateMachine");
38 | }
39 |
40 | public override void _Ready()
41 | {
42 | WaitForParentNode();
43 |
44 | state = GetNode(initialState) as State;
45 | if (state == null)
46 | {
47 | GD.PushError("initalstate in statemachine is null!");
48 | }
49 | }
50 |
51 | private async void WaitForParentNode()
52 | {
53 | await ToSignal(Owner, "ready");
54 | state.Enter();
55 | }
56 |
57 | public override void _UnhandledInput(InputEvent @event)
58 | {
59 | state.UnhandledInput(@event);
60 | }
61 |
62 | public override void _Process(float delta)
63 | {
64 | state.Process(delta);
65 | }
66 |
67 | public override void _PhysicsProcess(float delta)
68 | {
69 | state.PhysicsProcess(delta);
70 | }
71 |
72 | public void TransitionTo(String targetStatePath, Dictionary msg = null)
73 | {
74 | if (!HasNode(targetStatePath))
75 | return;
76 |
77 | State targetState = GetNode(targetStatePath) as State;
78 |
79 | state.Exit();
80 | this.state = targetState;
81 | state.Enter(msg);
82 | EmitSignal("Transitioned", targetStatePath);
83 | }
84 |
85 | public void SetState(State value)
86 | {
87 | state = value;
88 | _stateName = state.Name;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/godot-csharp/src/Camera/CameraRig.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=10 format=2]
2 |
3 | [ext_resource path="res://src/Main/StateMachine/StateMachine.cs" type="Script" id=1]
4 | [ext_resource path="res://src/Camera/States/Camera.cs" type="Script" id=2]
5 | [ext_resource path="res://src/Camera/CameraRig.cs" type="Script" id=3]
6 | [ext_resource path="res://src/Camera/States/Default.cs" type="Script" id=4]
7 | [ext_resource path="res://src/Camera/States/Aim.cs" type="Script" id=5]
8 | [ext_resource path="res://assets/2d/reticle.png" type="Texture" id=6]
9 | [ext_resource path="res://src/Camera/AimTarget.cs" type="Script" id=7]
10 | [ext_resource path="res://src/Camera/SpringArm.cs" type="Script" id=8]
11 |
12 | [sub_resource type="CapsuleShape" id=1]
13 | height = 0.5
14 |
15 | [node name="CameraRig" type="Spatial"]
16 | script = ExtResource( 3 )
17 |
18 | [node name="InterpolatedCamera" type="InterpolatedCamera" parent="."]
19 | transform = Transform( 1, 0, 0, 0, 0.866025, 0.5, 0, -0.5, 0.866025, 0, 0, 0 )
20 | current = true
21 | target = NodePath("../SpringArm/CameraTarget")
22 | speed = 7.0
23 | enabled = true
24 |
25 | [node name="AimRay" type="RayCast" parent="InterpolatedCamera"]
26 | cast_to = Vector3( 0, 0, -40 )
27 | collision_mask = 2
28 |
29 | [node name="SpringArm" type="SpringArm" parent="."]
30 | transform = Transform( 1, 0, 0, 0, 0.866025, 0.5, 0, -0.5, 0.866025, 0, 0, 0 )
31 | collision_mask = 2
32 | shape = SubResource( 1 )
33 | spring_length = 5.0
34 | script = ExtResource( 8 )
35 |
36 | [node name="CameraTarget" type="Position3D" parent="SpringArm"]
37 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )
38 |
39 | [node name="AimTarget" type="Sprite3D" parent="."]
40 | transform = Transform( -0.154568, 0, 0, 0, -0.154568, 0, 0, 0, -0.154568, 0, 0, 0 )
41 | cast_shadow = 0
42 | texture = ExtResource( 6 )
43 | script = ExtResource( 7 )
44 |
45 | [node name="StateMachine" type="Node" parent="."]
46 | script = ExtResource( 1 )
47 | initialState = NodePath("Camera/Default")
48 |
49 | [node name="Camera" type="Node" parent="StateMachine"]
50 | script = ExtResource( 2 )
51 |
52 | [node name="Default" type="Node" parent="StateMachine/Camera"]
53 | script = ExtResource( 4 )
54 |
55 | [node name="Aim" type="Node" parent="StateMachine/Camera"]
56 | script = ExtResource( 5 )
57 | offsetCamera = Vector3( 0.7, -1.8, 0 )
58 |
59 | [node name="Tween" type="Tween" parent="StateMachine/Camera/Aim"]
60 |
--------------------------------------------------------------------------------
/godot/src/Player/Camera/CameraRig.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=10 format=2]
2 |
3 | [ext_resource path="res://src/Player/Camera/CameraRig.gd" type="Script" id=1]
4 | [ext_resource path="res://src/Player/Camera/AimTarget.gd" type="Script" id=2]
5 | [ext_resource path="res://src/Player/Camera/States/Default.gd" type="Script" id=3]
6 | [ext_resource path="res://src/Main/StateMachine/StateMachine.gd" type="Script" id=4]
7 | [ext_resource path="res://assets/2d/reticle.png" type="Texture" id=5]
8 | [ext_resource path="res://src/Player/Camera/States/Camera.gd" type="Script" id=6]
9 | [ext_resource path="res://src/Player/Camera/States/Aim.gd" type="Script" id=7]
10 | [ext_resource path="res://src/Player/Camera/SpringArm.gd" type="Script" id=8]
11 |
12 | [sub_resource type="CapsuleShape" id=1]
13 | height = 0.5
14 |
15 | [node name="CameraRig" type="Spatial"]
16 | script = ExtResource( 1 )
17 |
18 | [node name="InterpolatedCamera" type="InterpolatedCamera" parent="."]
19 | transform = Transform( 1, 0, 0, 0, 0.87462, 0.48481, 0, -0.48481, 0.87462, 0, 0.5, 0.5 )
20 | current = true
21 | target = NodePath("../SpringArm/CameraTarget")
22 | speed = 7.0
23 | enabled = true
24 |
25 | [node name="AimRay" type="RayCast" parent="InterpolatedCamera"]
26 | transform = Transform( 1, 0, 0, 0, 0.999847, 0.0174524, 0, -0.0174524, 0.999847, 0, -0.194905, -0.679715 )
27 | cast_to = Vector3( 0, 0, -20 )
28 | collision_mask = 2
29 |
30 | [node name="SpringArm" type="SpringArm" parent="."]
31 | transform = Transform( 1, 0, 0, 0, 0.87462, 0.48481, 0, -0.48481, 0.87462, 0, 0.5, 0.5 )
32 | collision_mask = 2
33 | shape = SubResource( 1 )
34 | spring_length = 4.5
35 | margin = 0.5
36 | script = ExtResource( 8 )
37 |
38 | [node name="CameraTarget" type="Position3D" parent="SpringArm"]
39 | transform = Transform( 1, 0, 0, 0, 1, 2.98023e-08, 0, -2.98023e-08, 1, 0, 0, 0 )
40 |
41 | [node name="AimTarget" type="Sprite3D" parent="."]
42 | visible = false
43 | pixel_size = 0.001
44 | texture = ExtResource( 5 )
45 | script = ExtResource( 2 )
46 |
47 | [node name="StateMachine" type="Node" parent="."]
48 | script = ExtResource( 4 )
49 | initial_state = NodePath("../../CameraRig/StateMachine/Camera/Default")
50 |
51 | [node name="Camera" type="Node" parent="StateMachine"]
52 | script = ExtResource( 6 )
53 |
54 | [node name="Default" type="Node" parent="StateMachine/Camera"]
55 | script = ExtResource( 3 )
56 |
57 | [node name="Aim" type="Node" parent="StateMachine/Camera"]
58 | script = ExtResource( 7 )
59 | offset_camera = Vector3( 0.75, -1, 0 )
60 |
61 | [node name="Tween" type="Tween" parent="StateMachine/Camera/Aim"]
62 |
--------------------------------------------------------------------------------
/godot-csharp/src/Player/States/Move.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System.Collections.Generic;
3 |
4 | public class Move : PlayerState
5 | {
6 | public Vector3 velocity = Vector3.Zero;
7 | public float moveSpeed = 100.0f;
8 | public Vector3 moveDirection = Vector3.Zero;
9 | [Export]
10 | float maxSpeed = 50.0f;
11 | [Export]
12 | float gravity = -80.0f;
13 | [Export]
14 | float jumpImpulse = 25.0f;
15 | public override void _Ready()
16 | {
17 | base._Ready();
18 | }
19 |
20 | public override void UnhandledInput(InputEvent @event) {
21 | if (@event.IsActionPressed("jump")) {
22 |
23 | var msg = new Dictionary();
24 | msg.Add("velocity", velocity);
25 | msg.Add("jumpImpulse", jumpImpulse);
26 |
27 | (_stateMachine as StateMachine).TransitionTo("Move/Air", msg);
28 | }
29 | }
30 |
31 | public override void PhysicsProcess(float delta)
32 | {
33 | Vector3 inputDirection = GetInputDirection();
34 |
35 | // only forward direction if player trying to move forward or right
36 | Vector3 forwards = _player.camera.GlobalTransform.basis.z * inputDirection.z;
37 | Vector3 right = _player.camera.GlobalTransform.basis.x * inputDirection.x;
38 |
39 | // Get Move Direction relative to the camera
40 | moveDirection = forwards + right;
41 | if (moveDirection.Length() > 1.0f)
42 | {
43 | moveDirection = moveDirection.Normalized();
44 | }
45 | moveDirection.y = 0.0f;
46 |
47 | (_skin as Mannequiny).setMoveDirection(moveDirection);
48 |
49 | // check if player hits key and rotate
50 | if (moveDirection.Length() > 0.001)
51 | {
52 | _player.LookAt(_player.GlobalTransform.origin + moveDirection, Vector3.Up);
53 | }
54 |
55 | // move character
56 | velocity = CalculateVelocity(velocity, moveDirection, delta);
57 | velocity = _player.MoveAndSlide(velocity, Vector3.Up);
58 | }
59 |
60 | public static Vector3 GetInputDirection()
61 | {
62 | return new Vector3(
63 | Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left"),
64 | 0.0f,
65 | Input.GetActionStrength("move_back") - Input.GetActionStrength("move_front")
66 | );
67 | }
68 |
69 | Vector3 CalculateVelocity(Vector3 velocityCurrent, Vector3 moveDirection, float delta)
70 | {
71 | Vector3 velocityNew = velocityCurrent;
72 | velocityNew = moveDirection * delta * moveSpeed;
73 | if ( velocityNew.Length() > maxSpeed) {
74 | velocityNew = velocityNew.Normalized() * maxSpeed;
75 | }
76 | // override because start value is 0.0f
77 | velocityNew.y = velocityCurrent.y + gravity * delta;
78 |
79 | return velocityNew;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/godot/src/Player/States/Move.gd:
--------------------------------------------------------------------------------
1 | extends PlayerState
2 | # Parent state for all movement-related states for the Player.
3 | # Holds all of the base movement logic.
4 | # Child states can override this state's functions or change its properties.
5 | # This keeps the logic grouped in one location.
6 |
7 |
8 | export var max_speed: = 12.0
9 | export var move_speed: = 10.0
10 | export var gravity = -80.0
11 | export var jump_impulse = 25
12 | export(float, 0.1, 20.0, 0.1) var rotation_speed_factor: = 10.0
13 |
14 | var velocity: = Vector3.ZERO
15 |
16 |
17 | func unhandled_input(event: InputEvent) -> void:
18 | if event.is_action_pressed("jump"):
19 | _state_machine.transition_to("Move/Air", { velocity = velocity, jump_impulse = jump_impulse })
20 |
21 |
22 | func physics_process(delta: float) -> void:
23 | var input_direction: = get_input_direction()
24 |
25 | # Calculate a move direction vector relative to the camera
26 | # The basis stores the (right, up, -forwards) vectors of our camera.
27 | var forwards: Vector3 = player.camera.global_transform.basis.z * input_direction.z
28 | var right: Vector3 = player.camera.global_transform.basis.x * input_direction.x
29 | var move_direction: = forwards + right
30 | if move_direction.length() > 1.0:
31 | move_direction = move_direction.normalized()
32 | move_direction.y = 0
33 | skin.move_direction = move_direction
34 |
35 | # Rotation
36 | if move_direction:
37 | var target_direction: = player.transform.looking_at(player.global_transform.origin + move_direction, Vector3.UP)
38 | player.transform = player.transform.interpolate_with(target_direction, rotation_speed_factor * delta)
39 |
40 | # Movement
41 | velocity = calculate_velocity(velocity, move_direction, delta)
42 | velocity = player.move_and_slide(velocity, Vector3.UP)
43 |
44 |
45 | func enter(msg: Dictionary = {}) -> void:
46 | player.camera.connect("aim_fired", self, "_on_Camera_aim_fired")
47 |
48 |
49 | func exit() -> void:
50 | player.camera.disconnect("aim_fired", self, "_on_Camera_aim_fired")
51 |
52 |
53 | # Callback to transition to the optional Zip state
54 | # It only works if the Zip state node exists.
55 | # It is intended to work via signals
56 | func _on_Camera_aim_fired(target_vector: Vector3) -> void:
57 | _state_machine.transition_to("Move/Zip", { target = target_vector })
58 |
59 |
60 | static func get_input_direction() -> Vector3:
61 | return Vector3(
62 | Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
63 | 0,
64 | Input.get_action_strength("move_back") - Input.get_action_strength("move_front")
65 | )
66 |
67 |
68 | func calculate_velocity(
69 | velocity_current: Vector3,
70 | move_direction: Vector3,
71 | delta: float
72 | ) -> Vector3:
73 | var velocity_new := move_direction * move_speed
74 | if velocity_new.length() > max_speed:
75 | velocity_new = velocity_new.normalized() * max_speed
76 | velocity_new.y = velocity_current.y + gravity * delta
77 |
78 | return velocity_new
79 |
--------------------------------------------------------------------------------
/godot-csharp/assets/2d/icons/state_machine.svg:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/godot/src/Main/Game.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=11 format=2]
2 |
3 | [ext_resource path="res://src/Player/Player.tscn" type="PackedScene" id=1]
4 | [ext_resource path="res://assets/3d/materials/floor.tres" type="Material" id=2]
5 | [ext_resource path="res://src/Main/Game.gd" type="Script" id=3]
6 | [ext_resource path="res://assets/3d/level/level_environment.tres" type="Environment" id=4]
7 | [ext_resource path="res://src/Level/Playground.tscn" type="PackedScene" id=5]
8 | [ext_resource path="res://src/Debug/DebugPanel.tscn" type="PackedScene" id=6]
9 | [ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=7]
10 | [ext_resource path="res://src/Debug/DebugDock.gd" type="Script" id=8]
11 |
12 | [sub_resource type="PlaneMesh" id=1]
13 | size = Vector2( 100, 100 )
14 |
15 | [sub_resource type="BoxShape" id=2]
16 | margin = 0.001
17 | extents = Vector3( 50, 1, 50 )
18 |
19 | [node name="Game" type="Node"]
20 | script = ExtResource( 3 )
21 |
22 | [node name="Player" parent="." instance=ExtResource( 1 )]
23 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -1.58673, -0.0176746, -5.36121 )
24 | collision_mask = 2
25 |
26 | [node name="SpringArm" parent="Player/CameraRig" index="1"]
27 | length_range = Vector2( 3, 6 )
28 | zoom = 0.5
29 |
30 | [node name="Playground" parent="." instance=ExtResource( 5 )]
31 | transform = Transform( -4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 0, -16 )
32 |
33 | [node name="TestMap" type="Spatial" parent="."]
34 |
35 | [node name="Ground" type="MeshInstance" parent="TestMap"]
36 | mesh = SubResource( 1 )
37 | material/0 = ExtResource( 2 )
38 |
39 | [node name="StaticBody" type="StaticBody" parent="TestMap/Ground"]
40 | collision_layer = 2
41 | collision_mask = 0
42 |
43 | [node name="CollisionShape" type="CollisionShape" parent="TestMap/Ground/StaticBody"]
44 | transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0 )
45 | shape = SubResource( 2 )
46 |
47 | [node name="DirectionalLight" type="DirectionalLight" parent="."]
48 | transform = Transform( 0.766044, 0.166366, -0.620885, 0.271654, 0.791635, 0.547283, 0.582563, -0.587909, 0.561233, -3.00978, 2.72808, 0 )
49 | light_energy = 0.8
50 | shadow_enabled = true
51 | directional_shadow_blend_splits = true
52 | directional_shadow_normal_bias = 0.2
53 | directional_shadow_bias_split_scale = 0.75
54 |
55 | [node name="WorldEnvironment" type="WorldEnvironment" parent="."]
56 | environment = ExtResource( 4 )
57 |
58 | [node name="MarginContainer" type="MarginContainer" parent="."]
59 | anchor_bottom = 1.0
60 | margin_right = 461.0
61 | theme = ExtResource( 7 )
62 | script = ExtResource( 8 )
63 | __meta__ = {
64 | "_edit_use_anchors_": false
65 | }
66 |
67 | [node name="DebugPanel" parent="MarginContainer" instance=ExtResource( 6 )]
68 | anchor_right = 0.0
69 | anchor_bottom = 0.0
70 | margin_left = 16.0
71 | margin_top = 16.0
72 | margin_right = 445.0
73 | margin_bottom = 1064.0
74 | reference_path = NodePath("../../Player/CameraRig/InterpolatedCamera")
75 | properties = PoolStringArray( "transform", "fov" )
76 | round_decimals = 3
77 |
78 | [editable path="Player"]
79 |
80 | [editable path="Player/CameraRig"]
81 |
--------------------------------------------------------------------------------
/godot/src/Debug/DebugPanel.gd:
--------------------------------------------------------------------------------
1 | tool
2 | extends Control
3 | # Displays the values of properties of a given node
4 | # You can directly change the `properties` property to display multiple values from the `reference` node
5 | # E.g. properties = PoolStringArray(['speed', 'position', 'modulate'])
6 |
7 | export var reference_path: NodePath
8 | export var properties: PoolStringArray setget set_properties
9 | export var round_decimals := 2
10 |
11 | onready var _container: VBoxContainer = $VBoxContainer/MarginContainer/VBoxContainer
12 | onready var _title: Label = $VBoxContainer/ReferenceName
13 | onready var reference: Node = get_node(reference_path) setget set_reference
14 |
15 | var _step := 1.0 / pow(10, round_decimals)
16 |
17 |
18 | func _ready() -> void:
19 | if not reference:
20 | return
21 | _setup()
22 |
23 |
24 | func _process(delta) -> void:
25 | _update()
26 |
27 |
28 | func _setup() -> void:
29 | _clear()
30 | _title.text = reference.name
31 | for property in properties:
32 | track(property)
33 |
34 |
35 | func _get_configuration_warning() -> String:
36 | return "" if not reference_path.is_empty() else "Reference Path should not be empty."
37 |
38 |
39 | func track(property: String) -> void:
40 | var label := Label.new()
41 | label.autowrap = true
42 | label.name = property.capitalize()
43 | _container.add_child(label)
44 | if not property in properties:
45 | properties.append(property)
46 |
47 |
48 | func _clear() -> void:
49 | for property_label in _container.get_children():
50 | property_label.queue_free()
51 |
52 |
53 | func _update() -> void:
54 | if Engine.editor_hint:
55 | return
56 | var search_array: Array = properties
57 | for property in properties:
58 | var value = reference.get(property)
59 | var label: Label = _container.get_child(search_array.find(property))
60 | var text := ""
61 | if value is float:
62 | text = str(stepify(value, _step))
63 | if value is Vector2:
64 | text = "(%s %s)" % [stepify(value.x, _step), stepify(value.y, _step)]
65 | elif value is Vector3:
66 | text = get_vector3_as_string(value)
67 | elif value is Transform:
68 | var elements: PoolStringArray = [
69 | get_vector3_as_string(value.basis.x),
70 | get_vector3_as_string(value.basis.y),
71 | get_vector3_as_string(value.basis.z),
72 | get_vector3_as_string(value.origin)
73 | ]
74 | text = elements.join("\n")
75 | else:
76 | text = str(value)
77 | label.text = "%s: %s" % [property.capitalize(), text]
78 |
79 |
80 | func get_vector2_as_string(vector: Vector2) -> String:
81 | return "(%s %s)" % [stepify(vector.x, _step), stepify(vector.y, _step)]
82 |
83 |
84 | func get_vector3_as_string(vector: Vector3) -> String:
85 | return (
86 | "(%s %s %s)"
87 | % [stepify(vector.x, _step), stepify(vector.y, _step), stepify(vector.z, _step)]
88 | )
89 |
90 |
91 | func set_properties(value: PoolStringArray) -> void:
92 | properties = value
93 | if not reference:
94 | return
95 | _setup()
96 |
97 |
98 | func set_reference(value: Node) -> void:
99 | reference = value
100 | if reference:
101 | _setup()
102 |
--------------------------------------------------------------------------------
/godot/src/Player/Camera/States/Camera.gd:
--------------------------------------------------------------------------------
1 | extends CameraState
2 | # Parent state for all camera based states for the Camera. Handles input based on
3 | # the mouse or the gamepad. The camera's movement depends on the active child state.
4 | # Holds shared logic between all states that move or rotate the camera.
5 |
6 | const ZOOM_STEP := 0.1
7 |
8 | const ANGLE_X_MIN := -PI / 4
9 | const ANGLE_X_MAX := PI / 3
10 |
11 | export var is_y_inverted := false
12 | export var fov_default := 70.0
13 | export var deadzone := PI / 10
14 | export var sensitivity_gamepad := Vector2(2.5, 2.5)
15 | export var sensitivity_mouse := Vector2(0.1, 0.1)
16 |
17 | var _input_relative := Vector2.ZERO
18 | var _is_aiming := false
19 |
20 |
21 | func process(delta: float) -> void:
22 | camera_rig.global_transform.origin = (
23 | camera_rig.player.global_transform.origin
24 | + camera_rig._position_start
25 | )
26 |
27 | var look_direction := get_look_direction()
28 | var move_direction := get_move_direction()
29 |
30 | if _input_relative.length() > 0:
31 | update_rotation(_input_relative * sensitivity_mouse * delta)
32 | _input_relative = Vector2.ZERO
33 | elif look_direction.length() > 0:
34 | update_rotation(look_direction * sensitivity_gamepad * delta)
35 |
36 | var is_moving_towards_camera: bool = (
37 | move_direction.x >= -deadzone
38 | and move_direction.x <= deadzone
39 | )
40 | if not (is_moving_towards_camera or _is_aiming):
41 | auto_rotate(move_direction)
42 |
43 | camera_rig.rotation.y = wrapf(camera_rig.rotation.y, -PI, PI)
44 |
45 |
46 | func auto_rotate(move_direction: Vector3) -> void:
47 | var offset: float = camera_rig.player.rotation.y - camera_rig.rotation.y
48 | var target_angle: float = (
49 | camera_rig.player.rotation.y - 2 * PI
50 | if offset > PI
51 | else camera_rig.player.rotation.y + 2 * PI if offset < -PI else camera_rig.player.rotation.y
52 | )
53 | camera_rig.rotation.y = lerp(camera_rig.rotation.y, target_angle, 0.015)
54 |
55 |
56 | func unhandled_input(event: InputEvent) -> void:
57 | if event.is_action_pressed("zoom_in"):
58 | camera_rig.zoom += ZOOM_STEP
59 | elif event.is_action_pressed("zoom_out"):
60 | camera_rig.zoom -= ZOOM_STEP
61 | elif event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
62 | _input_relative += event.get_relative()
63 |
64 |
65 | func update_rotation(offset: Vector2) -> void:
66 | camera_rig.rotation.y -= offset.x
67 | camera_rig.rotation.x += offset.y * -1.0 if is_y_inverted else offset.y
68 | camera_rig.rotation.x = clamp(camera_rig.rotation.x, ANGLE_X_MIN, ANGLE_X_MAX)
69 | camera_rig.rotation.z = 0
70 |
71 |
72 | # Returns the direction of the camera movement from the player
73 | static func get_look_direction() -> Vector2:
74 | return Vector2(Input.get_action_strength("look_right") - Input.get_action_strength("look_left"), Input.get_action_strength("look_up") - Input.get_action_strength("look_down")).normalized()
75 |
76 | # Returns the move direction of the character controlled by the player
77 | static func get_move_direction() -> Vector3:
78 | return Vector3(
79 | Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
80 | 0,
81 | Input.get_action_strength("move_back") - Input.get_action_strength("move_front")
82 | )
83 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | This document lists the new features, improvements, changes, and bug fixes in each new release of the Open 3D Mannequin.
4 |
5 | ## Open 3D Mannequin 0.4
6 |
7 | ### Improvements
8 |
9 | - The mannequin now smoothly rotates instead of changing direction instantly.
10 |
11 | ### Changes
12 |
13 | - The character now comes rig-free. We use the free blender add-on [Rig on the Fly](https://gitlab.com/dypsloom/rigonthefly/) to rig the character dynamically.
14 |
15 | ## Open 3D Mannequin 0.3
16 |
17 | ### New features
18 |
19 | - Smooth camera zoom in and out using the mouse wheel.
20 | - Added debug panel to monitor object properties. Toggle open with TAB.
21 |
22 | ### Improvements
23 |
24 | - Toggle fullscreen with F11.
25 | - Improved the light settings for nicer looking shadows.
26 | - The `SpringArm` now projects a capsule to prevent the camera from going below the floor.
27 |
28 | ### Changes
29 |
30 | In this release, we mostly refactored and improved the code for future development, but also for the release of our [3D game creation course](https://gdquest.mavenseed.com/courses/code-a-professional-3d-character-with-godot), based on this project.
31 |
32 | - Refactored the code
33 | - Use PI for angles in radians, replace magic values with constants.
34 | - Removed unused values in the Move state.
35 | - Removed unused jump delay feature.
36 | - Changed the `get_look_direction` calculation for correct y inversion.
37 | - Replaced all docstrings with comment blocks.
38 | - Use `Vector3.ZERO` constant instead of `Vector3(0, 0, 0)`.
39 | - Improved encapsulation of code in the Aim state.
40 | - Renamed input actions to all use action verbs.
41 | - Moved mouse capture mode code to a game class, improve logic.
42 | - Simplified camera code, in particular the rotation code.
43 | - Simplified variables.
44 | - Simplified and encapsulated the logic for the `AimTarget`.
45 |
46 | ### Bug fixes
47 |
48 | - Fixed `SpringArm` not returning to its start position after aiming.
49 | - Fixed type error in the latest Godot 3.2 build.
50 | - Fixed calculating the opposite value for camera Y inversion logic.
51 | - Fixed slow camera movement on monitors with high refresh rates. We now use `_process` instead of `_physics_process` for camera movement.
52 | - Fixed a memory leak in Godot 3.2.
53 |
54 | ## Known Issues
55 |
56 | I started refactoring the Zip state, that takes the character to a wall or
57 | ground the player is aiming at. It is not working at the moment.
58 |
59 | ## Open 3D Mannequin 0.2
60 |
61 | ### New features
62 |
63 | - Added analog movement with joysticks and Walk -> Run animation blending.
64 | - Added smooth camera motion.
65 |
66 | ### Improvements
67 |
68 | - Re-rigged and re-targeted the character using [AutoRig Pro](https://blendermarket.com/products/auto-rig-pro), getting it down from 100+ joints to 44 after export.
69 | - Improved the animation tree to add an interruptable land animation.
70 | - Reworked lighting for more contrasted visuals.
71 | - Improved default environment to make it easier to work inside the editor.
72 | - Added boilerplate classes to get autocompletion and type checks in state classes.
73 |
74 | ### Changes
75 |
76 | - Made animation tree code controllable from the player's state machine, instead of using signals.
77 | - Refactored the code to make it simpler.
78 | - Reorganized files and folders to make the project easier to browse.
79 |
80 | ### Bug fixes
81 |
82 | - Fixed the character sometimes playing the fall animation over ridges in the level's collision boxes.
83 | - Fixed the AimTarget blinking on the surface it was projected on.
84 |
85 | ## Open 3D Mannequin 0.1
86 |
87 | This was the initial release of the project
88 |
89 | ### Features
90 |
91 | - Camera rig with zoom to aim and auto-rotation features
92 | - Mouse/keyboard and gamepad support
93 | - 10 professional animations
94 | - Extensible as it's based on a Finite State Machine
95 |
--------------------------------------------------------------------------------
/godot/src/Level/Playground.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://assets/3d/level/playground.glb" type="PackedScene" id=1]
4 | [ext_resource path="res://assets/3d/materials/obstacle.tres" type="Material" id=2]
5 |
6 | [sub_resource type="ConcavePolygonShape" id=1]
7 | data = PoolVector3Array( -2.3333, 2, 11, -6, 2, -11, -2.3333, 2, -11, -2.3333, 2, 11, -6, 2, 11, -6, 2, -11, -2.3333, 2, 13, -6, 2, 11, -2.3333, 2, 11, -2.3333, 2, 13, -6, 2, 13, -6, 2, 11, -6, 2, -11, -6, 0, 11, -6, 0, -11, -6, 2, -11, -6, 2, 11, -6, 0, 11, 2.3333, 0, 11, 6, 0, -11, 2.3333, 0, -11, 2.3333, 0, 11, 6, 0, 11, 6, 0, -11, 6, 2, 11, 6, 0, -11, 6, 0, 11, 6, 2, 11, 6, 2, -11, 6, 0, -11, 6, 2, -11, 6, 0, -13, 6, 0, -11, 6, 2, -11, 6, 2, -13, 6, 0, -13, -2.3333, 0, -11, 2.3333, 0, -13, -2.3333, 0, -13, -2.3333, 0, -11, 2.3333, 0, -11, 2.3333, 0, -13, 2.3333, 2, -11, -2.3333, 2, -13, 2.3333, 2, -13, 2.3333, 2, -11, -2.3333, 2, -11, -2.3333, 2, -13, -6, 0, 11, -2.3333, 0, -11, -6, 0, -11, -6, 0, 11, -2.3333, 0, 11, -2.3333, 0, -11, -2.3333, 0, 11, 2.3333, 0, -11, -2.3333, 0, -11, -2.3333, 0, 11, 2.3333, 0, 11, 2.3333, 0, -11, -2.3333, 0, 13, 2.3333, 0, 11, -2.3333, 0, 11, -2.3333, 0, 13, 2.3333, 0, 13, 2.3333, 0, 11, 2.3333, 0, 13, 6, 0, 11, 2.3333, 0, 11, 2.3333, 0, 13, 6, 0, 13, 6, 0, 11, 6, 2, 11, 2.3333, 2, -11, 6, 2, -11, 6, 2, 11, 2.3333, 2, 11, 2.3333, 2, -11, 2.3333, 6, -11, -2.3333, 2, -11, 2.3333, 2, -11, 2.3333, 6, -11, -2.3333, 6, -11, -2.3333, 2, -11, 2.3333, 6, -8, -2.3333, 6, -11, 2.3333, 6, -11, 2.3333, 6, -8, -2.3333, 6, -8, -2.3333, 6, -11, -2.3333, 6, 11, 2.3333, 2, 11, -2.3333, 2, 11, -2.3333, 6, 11, 2.3333, 6, 11, 2.3333, 2, 11, 2.3333, 6, 11, 2.3333, 4, 8, 2.3333, 2, 11, 2.3333, 4, 8, 2.3333, 2, -11, 2.3333, 2, 11, 2.3333, 4, 8, 2.3333, 4, -8, 2.3333, 2, -11, 2.3333, 4, -8, 2.3333, 6, -11, 2.3333, 2, -11, 2.3333, 6, 11, 2.3333, 6, 8, 2.3333, 4, 8, 2.3333, 6, -8, 2.3333, 6, -11, 2.3333, 4, -8, -2.3333, 6, -11, -2.3333, 4, -8, -2.3333, 2, -11, -2.3333, 4, -8, -2.3333, 2, 11, -2.3333, 2, -11, -2.3333, 4, -8, -2.3333, 4, 8, -2.3333, 2, 11, -2.3333, 4, 8, -2.3333, 6, 11, -2.3333, 2, 11, -2.3333, 6, -11, -2.3333, 6, -8, -2.3333, 4, -8, -2.3333, 6, 8, -2.3333, 6, 11, -2.3333, 4, 8, -2.3333, 6, -8, 2.3333, 4, -8, -2.3333, 4, -8, -2.3333, 6, -8, 2.3333, 6, -8, 2.3333, 4, -8, 2.3333, 6, 11, -2.3333, 6, 8, 2.3333, 6, 8, 2.3333, 6, 11, -2.3333, 6, 11, -2.3333, 6, 8, 2.3333, 4, 8, -2.3333, 4, -8, 2.3333, 4, -8, 2.3333, 4, 8, -2.3333, 4, 8, -2.3333, 4, -8, 2.3333, 6, 8, -2.3333, 4, 8, 2.3333, 4, 8, 2.3333, 6, 8, -2.3333, 6, 8, -2.3333, 4, 8, -6, 2, 13, -2.3333, 0, 13, -6, 0, 13, -6, 2, 13, -2.3333, 2, 13, -2.3333, 0, 13, 2.3333, 2, 13, 6, 0, 13, 2.3333, 0, 13, 2.3333, 2, 13, 6, 2, 13, 6, 0, 13, -2.3333, 2, 13, 2.3333, 0, 13, -2.3333, 0, 13, -2.3333, 2, 13, 2.3333, 2, 13, 2.3333, 0, 13, 2.3333, 2, 13, -2.3333, 2, 11, 2.3333, 2, 11, 2.3333, 2, 13, -2.3333, 2, 13, -2.3333, 2, 11, 6, 2, 13, 6, 0, 11, 6, 0, 13, 6, 2, 13, 6, 2, 11, 6, 0, 11, -6, 0, 13, -2.3333, 0, 11, -6, 0, 11, -6, 0, 13, -2.3333, 0, 13, -2.3333, 0, 11, 6, 2, 13, 2.3333, 2, 11, 6, 2, 11, 6, 2, 13, 2.3333, 2, 13, 2.3333, 2, 11, -6, 2, 11, -6, 0, 13, -6, 0, 11, -6, 2, 11, -6, 2, 13, -6, 0, 13, 6, 2, -13, 2.3333, 0, -13, 6, 0, -13, 6, 2, -13, 2.3333, 2, -13, 2.3333, 0, -13, -2.3333, 2, -13, -6, 0, -13, -2.3333, 0, -13, -2.3333, 2, -13, -6, 2, -13, -6, 0, -13, 2.3333, 2, -13, -2.3333, 0, -13, 2.3333, 0, -13, 2.3333, 2, -13, -2.3333, 2, -13, -2.3333, 0, -13, -2.3333, 2, -11, -6, 2, -13, -2.3333, 2, -13, -2.3333, 2, -11, -6, 2, -11, -6, 2, -13, -6, 2, -13, -6, 0, -11, -6, 0, -13, -6, 2, -13, -6, 2, -11, -6, 0, -11, 2.3333, 0, -11, 6, 0, -13, 2.3333, 0, -13, 2.3333, 0, -11, 6, 0, -11, 6, 0, -13, -6, 0, -11, -2.3333, 0, -13, -6, 0, -13, -6, 0, -11, -2.3333, 0, -11, -2.3333, 0, -13, 6, 2, -11, 2.3333, 2, -13, 6, 2, -13, 6, 2, -11, 2.3333, 2, -11, 2.3333, 2, -13 )
8 |
9 | [node name="Playground" index="0" instance=ExtResource( 1 )]
10 |
11 | [node name="Cube" parent="." index="0"]
12 | material/0 = ExtResource( 2 )
13 |
14 | [node name="StaticBody" type="StaticBody" parent="Cube" index="0"]
15 | collision_layer = 2
16 | collision_mask = 0
17 |
18 | [node name="CollisionShape" type="CollisionShape" parent="Cube/StaticBody" index="0"]
19 | shape = SubResource( 1 )
20 |
--------------------------------------------------------------------------------
/godot-csharp/src/Level/Playground.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://assets/3d/level/playground.glb" type="PackedScene" id=1]
4 | [ext_resource path="res://assets/3d/materials/obstacle.tres" type="Material" id=2]
5 |
6 | [sub_resource type="ConcavePolygonShape" id=1]
7 | data = PoolVector3Array( -2.3333, 2, 11, -6, 2, -11, -2.3333, 2, -11, -2.3333, 2, 11, -6, 2, 11, -6, 2, -11, -2.3333, 2, 13, -6, 2, 11, -2.3333, 2, 11, -2.3333, 2, 13, -6, 2, 13, -6, 2, 11, -6, 2, -11, -6, 0, 11, -6, 0, -11, -6, 2, -11, -6, 2, 11, -6, 0, 11, 2.3333, 0, 11, 6, 0, -11, 2.3333, 0, -11, 2.3333, 0, 11, 6, 0, 11, 6, 0, -11, 6, 2, 11, 6, 0, -11, 6, 0, 11, 6, 2, 11, 6, 2, -11, 6, 0, -11, 6, 2, -11, 6, 0, -13, 6, 0, -11, 6, 2, -11, 6, 2, -13, 6, 0, -13, -2.3333, 0, -11, 2.3333, 0, -13, -2.3333, 0, -13, -2.3333, 0, -11, 2.3333, 0, -11, 2.3333, 0, -13, 2.3333, 2, -11, -2.3333, 2, -13, 2.3333, 2, -13, 2.3333, 2, -11, -2.3333, 2, -11, -2.3333, 2, -13, -6, 0, 11, -2.3333, 0, -11, -6, 0, -11, -6, 0, 11, -2.3333, 0, 11, -2.3333, 0, -11, -2.3333, 0, 11, 2.3333, 0, -11, -2.3333, 0, -11, -2.3333, 0, 11, 2.3333, 0, 11, 2.3333, 0, -11, -2.3333, 0, 13, 2.3333, 0, 11, -2.3333, 0, 11, -2.3333, 0, 13, 2.3333, 0, 13, 2.3333, 0, 11, 2.3333, 0, 13, 6, 0, 11, 2.3333, 0, 11, 2.3333, 0, 13, 6, 0, 13, 6, 0, 11, 6, 2, 11, 2.3333, 2, -11, 6, 2, -11, 6, 2, 11, 2.3333, 2, 11, 2.3333, 2, -11, 2.3333, 6, -11, -2.3333, 2, -11, 2.3333, 2, -11, 2.3333, 6, -11, -2.3333, 6, -11, -2.3333, 2, -11, 2.3333, 6, -8, -2.3333, 6, -11, 2.3333, 6, -11, 2.3333, 6, -8, -2.3333, 6, -8, -2.3333, 6, -11, -2.3333, 6, 11, 2.3333, 2, 11, -2.3333, 2, 11, -2.3333, 6, 11, 2.3333, 6, 11, 2.3333, 2, 11, 2.3333, 6, 11, 2.3333, 4, 8, 2.3333, 2, 11, 2.3333, 4, 8, 2.3333, 2, -11, 2.3333, 2, 11, 2.3333, 4, 8, 2.3333, 4, -8, 2.3333, 2, -11, 2.3333, 4, -8, 2.3333, 6, -11, 2.3333, 2, -11, 2.3333, 6, 11, 2.3333, 6, 8, 2.3333, 4, 8, 2.3333, 6, -8, 2.3333, 6, -11, 2.3333, 4, -8, -2.3333, 6, -11, -2.3333, 4, -8, -2.3333, 2, -11, -2.3333, 4, -8, -2.3333, 2, 11, -2.3333, 2, -11, -2.3333, 4, -8, -2.3333, 4, 8, -2.3333, 2, 11, -2.3333, 4, 8, -2.3333, 6, 11, -2.3333, 2, 11, -2.3333, 6, -11, -2.3333, 6, -8, -2.3333, 4, -8, -2.3333, 6, 8, -2.3333, 6, 11, -2.3333, 4, 8, -2.3333, 6, -8, 2.3333, 4, -8, -2.3333, 4, -8, -2.3333, 6, -8, 2.3333, 6, -8, 2.3333, 4, -8, 2.3333, 6, 11, -2.3333, 6, 8, 2.3333, 6, 8, 2.3333, 6, 11, -2.3333, 6, 11, -2.3333, 6, 8, 2.3333, 4, 8, -2.3333, 4, -8, 2.3333, 4, -8, 2.3333, 4, 8, -2.3333, 4, 8, -2.3333, 4, -8, 2.3333, 6, 8, -2.3333, 4, 8, 2.3333, 4, 8, 2.3333, 6, 8, -2.3333, 6, 8, -2.3333, 4, 8, -6, 2, 13, -2.3333, 0, 13, -6, 0, 13, -6, 2, 13, -2.3333, 2, 13, -2.3333, 0, 13, 2.3333, 2, 13, 6, 0, 13, 2.3333, 0, 13, 2.3333, 2, 13, 6, 2, 13, 6, 0, 13, -2.3333, 2, 13, 2.3333, 0, 13, -2.3333, 0, 13, -2.3333, 2, 13, 2.3333, 2, 13, 2.3333, 0, 13, 2.3333, 2, 13, -2.3333, 2, 11, 2.3333, 2, 11, 2.3333, 2, 13, -2.3333, 2, 13, -2.3333, 2, 11, 6, 2, 13, 6, 0, 11, 6, 0, 13, 6, 2, 13, 6, 2, 11, 6, 0, 11, -6, 0, 13, -2.3333, 0, 11, -6, 0, 11, -6, 0, 13, -2.3333, 0, 13, -2.3333, 0, 11, 6, 2, 13, 2.3333, 2, 11, 6, 2, 11, 6, 2, 13, 2.3333, 2, 13, 2.3333, 2, 11, -6, 2, 11, -6, 0, 13, -6, 0, 11, -6, 2, 11, -6, 2, 13, -6, 0, 13, 6, 2, -13, 2.3333, 0, -13, 6, 0, -13, 6, 2, -13, 2.3333, 2, -13, 2.3333, 0, -13, -2.3333, 2, -13, -6, 0, -13, -2.3333, 0, -13, -2.3333, 2, -13, -6, 2, -13, -6, 0, -13, 2.3333, 2, -13, -2.3333, 0, -13, 2.3333, 0, -13, 2.3333, 2, -13, -2.3333, 2, -13, -2.3333, 0, -13, -2.3333, 2, -11, -6, 2, -13, -2.3333, 2, -13, -2.3333, 2, -11, -6, 2, -11, -6, 2, -13, -6, 2, -13, -6, 0, -11, -6, 0, -13, -6, 2, -13, -6, 2, -11, -6, 0, -11, 2.3333, 0, -11, 6, 0, -13, 2.3333, 0, -13, 2.3333, 0, -11, 6, 0, -11, 6, 0, -13, -6, 0, -11, -2.3333, 0, -13, -6, 0, -13, -6, 0, -11, -2.3333, 0, -11, -2.3333, 0, -13, 6, 2, -11, 2.3333, 2, -13, 6, 2, -13, 6, 2, -11, 2.3333, 2, -11, 2.3333, 2, -13 )
8 |
9 | [node name="Playground" index="0" instance=ExtResource( 1 )]
10 |
11 | [node name="Cube" parent="." index="0"]
12 | material/0 = ExtResource( 2 )
13 |
14 | [node name="StaticBody" type="StaticBody" parent="Cube" index="0"]
15 | collision_layer = 2
16 | collision_mask = 0
17 |
18 | [node name="CollisionShape" type="CollisionShape" parent="Cube/StaticBody" index="0"]
19 | shape = SubResource( 1 )
20 |
--------------------------------------------------------------------------------
/godot-csharp/Learn to Code a Pro 3D Character with Godot (start).csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Tools
5 | AnyCPU
6 | {88DCB668-1E0F-40F7-BFC3-96BBEA3AA5D1}
7 | Library
8 | .mono/temp/bin/$(Configuration)
9 | LearntoCodeaPro3DCharacterwithGodotstart
10 | Learn to Code a Pro 3D Character with Godot (start)
11 | v4.5
12 | 1.0.7315.757
13 | .mono/temp/obj
14 | $(BaseIntermediateOutputPath)/$(Configuration)
15 | Debug
16 | Release
17 |
18 |
19 | true
20 | portable
21 | false
22 | $(GodotDefineConstants);GODOT;DEBUG;
23 | prompt
24 | 4
25 | false
26 |
27 |
28 | portable
29 | true
30 | $(GodotDefineConstants);GODOT;
31 | prompt
32 | 4
33 | false
34 |
35 |
36 | true
37 | portable
38 | false
39 | $(GodotDefineConstants);GODOT;DEBUG;TOOLS;
40 | prompt
41 | 4
42 | false
43 |
44 |
45 |
46 | $(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/GodotSharp.dll
47 | False
48 |
49 |
50 | $(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/GodotSharpEditor.dll
51 | False
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/godot-csharp/assets/2d/icons/state.svg:
--------------------------------------------------------------------------------
1 |
2 |
64 |
--------------------------------------------------------------------------------
/godot-csharp/src/Camera/States/Camera.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class Camera : CameraState
5 | {
6 |
7 | [Export]
8 | public float fovDefault = 70.0f;
9 | [Export]
10 | public bool isYInverted = true;
11 | [Export]
12 | public float deadZoneBackwards = 0.3f;
13 | [Export]
14 | public Vector2 sensivityGamePad = new Vector2(2.5f, 2.5f);
15 | [Export]
16 | public Vector2 sensivityMouse = new Vector2(0.1f, 0.1f);
17 |
18 | public bool isAiming = false;
19 |
20 | Vector2 _input_relative = Vector2.Zero;
21 | const float ZOOM_STEP = 0.1f;
22 |
23 | public override void _Ready()
24 | {
25 | base._Ready();
26 | }
27 |
28 | public override void Process(float delta)
29 | {
30 |
31 | // todo: is there a way to make that better
32 | var transform = cameraRig.Transform;
33 | transform.origin = new Vector3(cameraRig.player.GlobalTransform.origin + cameraRig._positionStart);
34 | cameraRig.GlobalTransform = transform;
35 |
36 | Vector2 lookDirection = GetLookDirection();
37 | Vector3 moveDirection = GetMoveDirection();
38 |
39 | if (_input_relative.Length() > 0.0f)
40 | {
41 | UpdateRotation(_input_relative * sensivityMouse * delta);
42 | _input_relative = Vector2.Zero;
43 | }
44 |
45 | if (lookDirection.Length() > 0.0f)
46 | {
47 | UpdateRotation(lookDirection * sensivityGamePad * delta);
48 | }
49 |
50 | bool isMovingTowardsCamera = ((
51 | moveDirection.x >= -deadZoneBackwards) &&
52 | (moveDirection.x <= deadZoneBackwards));
53 |
54 | if (!isMovingTowardsCamera && !isAiming) {
55 | AutoRotate(moveDirection);
56 | }
57 |
58 | // prevent winding
59 | var rot = cameraRig.Rotation;
60 | rot.y = Mathf.Wrap(cameraRig.Rotation.y, -Mathf.Pi, Mathf.Pi);
61 | cameraRig.Rotation = rot;
62 | }
63 |
64 | public override void UnhandledInput(InputEvent @event)
65 | {
66 | if (@event.IsActionPressed("zoom_in")) {
67 | cameraRig.Zoom += ZOOM_STEP;
68 | }else if (@event.IsActionPressed("zoom_out")) {
69 | cameraRig.Zoom -= ZOOM_STEP;
70 | }
71 | else if ((@event is InputEventMouseMotion) && (Input.GetMouseMode() == Input.MouseMode.Captured))
72 | {
73 | _input_relative += (@event as InputEventMouseMotion).Relative;
74 | }
75 | }
76 |
77 | void AutoRotate(Vector3 moveDirection) {
78 | float offset = (cameraRig.player.Rotation.y - cameraRig.Rotation.y);
79 | float targetAngle = CalculateTargetAngle(offset);
80 | var rot = cameraRig.Rotation;
81 | rot.y = Mathf.Lerp(rot.y, targetAngle, 0.015f);
82 | cameraRig.Rotation = rot;
83 | }
84 |
85 | float CalculateTargetAngle(float offset) {
86 | if (offset > Mathf.Pi) {
87 | return (cameraRig.player.Rotation.y - 2 * Mathf.Pi);
88 | } else if (offset < -Mathf.Pi)
89 | {
90 | return (cameraRig.player.Rotation.y + 2 * Mathf.Pi);
91 | } else
92 | {
93 | return cameraRig.player.Rotation.y;
94 | }
95 | }
96 |
97 | void UpdateRotation(Vector2 offset)
98 | {
99 |
100 | // left right rotation
101 | var rot = cameraRig.Rotation;
102 | rot.y -= offset.x;
103 | cameraRig.Rotation = rot;
104 |
105 | // up down rotation
106 | rot.x += (isYInverted ? (offset.y * -1.0f) : offset.y);
107 | cameraRig.Rotation = rot;
108 |
109 | // limit camera rotation
110 | rot.x = Mathf.Clamp(rot.x, -0.75f, 1.25f);
111 | cameraRig.Rotation = rot;
112 |
113 | // not z rotation
114 | rot.z = 0.0f;
115 | cameraRig.Rotation = rot;
116 | }
117 |
118 | static Vector2 GetLookDirection()
119 | {
120 | return new Vector2(
121 | Input.GetActionStrength("look_right") - Input.GetActionStrength("look_left"),
122 | Input.GetActionStrength("look_up") - Input.GetActionStrength("look_down")
123 | );
124 | }
125 |
126 | static Vector3 GetMoveDirection()
127 | {
128 | return new Vector3(
129 | Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left"),
130 | 0.0f,
131 | Input.GetActionStrength("move_back") - Input.GetActionStrength("move_front")
132 | );
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | Open 3D Mannequin is an Open Source 3d character and character controller for the [Godot game engine](https://godotengine.org/)
4 |
5 | ⚠ The project only supports Godot version 3.2 and above.
6 |
7 | ➡ Follow us on [Twitter](https://twitter.com/NathanGDQuest) and [YouTube](https://www.youtube.com/c/gdquest/) for free game creation tutorials, tips, and news! Get one of our [Godot game creation courses](https://gdquest.mavenseed.com/) to support our work on Free Software.
8 |
9 | 
10 |
11 |
12 |
13 | **Table of Contents**
14 |
15 | - [Quick Start Guide](#quick-start-guide)
16 | - [Controls](#controls)
17 | - [How it works](#how-it-works)
18 | - [Player](#player)
19 | - [CameraRig](#camera)
20 | - [Configuration](#configuration)
21 | - [Customization](#customization)
22 | - [Credits](#credits)
23 | - [Support our work](#support-our-work)
24 |
25 |
26 |
27 | This is a third person character controller designed to work both with the keyboard and a gamepad. It features a camera that can auto-rotate or that can be controlled with a joystick.
28 |
29 | ## Quick Start Guide
30 |
31 | The 3D Third Person Character Controller is made of two scenes:
32 |
33 | - `CameraRig.tscn` - A 3D camera rig with a state machine for aiming
34 | - `Player.tscn` - A `KinematicBody` with a state machine for player movement. Contains an instance of `CameraRig`. It also includes the animated 3D mannequin.
35 |
36 | To use the default character, instance `Player` in your game. See `Game.tscn` for an example. In this demo, the obstacles are mesh instances with static body collisions making up a cube world.
37 |
38 | ### Controls
39 |
40 | The game supports both mouse and keyboard, and the gamepad.
41 |
42 | ## How it works
43 |
44 | ### Player
45 |
46 | The scene that deals with the movement, collision, and logic of the player. The player is a KinematicBody with a capsule collision shape, and the movement logic is within a [Finite State Machine](http://gameprogrammingpatterns.com/state.html).
47 |
48 | The scene also holds an instance of the `PlayerMesh` for animation purposes. This scene lives in the `PlayerMesh.tscn` scene. It holds the skeletal rig for the mesh's animation, the 3D model of the body and head sepearately, and the animation tree and player to control the animation workflow of the model. The lot is wrapped up in a spatial node with some logic to transition to which animation based on which state the player is in.
49 |
50 | ### CameraRig
51 |
52 | The scene that deals with the CameraRig movement. It follows the Player in the game, but in code it moves and rotates separately from it. It has a `SpringArm` node to help with preventing collision with level geometry - moving the viewpoint forwards to prevent moving the camera inside geometry. It also has a system that holds the raycast for aiming-mode, and the 3D sprite that is a projected reticule. The logic is held in a finite state machine.
53 |
54 | ## Configuration
55 |
56 | To change the player and the camera's behavior, you need to change properties on the corresponding states in their state machine.
57 |
58 | Most of the configuration available for player movement are located on the `Move` state in the Player scene - the player speed and the rotational speed.
59 |
60 | The CameraRig has more options. On the main CameraRig state in the CameraRig scene are items like the default field of view, whether Y is inverted, and sensitivity.
61 |
62 | In addition, the Aim state allows some finer-tuned changes, like whether the aiming camera is first or third person, and by how much it should be offset over-the-shoulder of the character.
63 |
64 | ## Customization
65 |
66 | While the scenes can be modified extensively with new nodes and raw code, the state machine model allow for some simple, new functionality with relative ease.
67 |
68 | As an example, there is the `Extensions` folder which contains additional player states for using the aiming view to fire a hookshot that pulls you towards the reticle. Once those states have been added to the Player's `Move` state, you only need to replace the return statement in Move's `enter` with code like `owner.camera.connect("aim_fired", self, "on_Camera_aim_fired")` and Move's `exit` with code like `owner.camera.disconnect("aim_fired", self, "on_Camera_aim_fired")`
69 |
70 | ## Animating the character
71 |
72 | The source Blender file is available in the [releases tab](releases). The character comes with all its animations. At first glance, it can look like it is lacking a rig.
73 |
74 | Instead of a complex rig with many controls, we use ephemeral rigs as seen in Richard Lico's 2018 GDC talk [Animating Quill](https://www.youtube.com/watch?v=u3CzLVpuE4k&t=2011s). To do so, we work with the Blender add-on [Rig on the Fly](https://gitlab.com/dypsloom/rigonthefly/). This allows you to quickly generate a rig and controls adapted to the animation at hand. Once the animation is done, you bake it, and you're done!
75 |
76 | ## Credits
77 |
78 | 1. The Godot mannequin is a character made by [Luciano Muñoz](https://twitter.com/lucianomunoz_) In blender 2.80.
79 | 1. Godot code by Josh aka [Cheeseness](https://twitter.com/ValiantCheese)
80 | 1. Additional code by Francois Belair aka [Razoric480](https://twitter.com/Razoric480)
81 |
82 | ## Support our work
83 |
84 | GDQuest is a social company focused on education and bringing people together around Free Software.
85 |
86 | This Free Software is sponsored by our course [Code a Professional 3D Character with Godot](https://gdquest.mavenseed.com/courses/code-a-professional-3d-character-with-godot).
87 |
88 | We share **the techniques professionals use to make games** and open source the code for most of our projects on [our GitHub page](https://github.com/GDquest/).
89 |
90 | You can:
91 |
92 | - Join the community on [Discord](https://discord.gg/dKUX7m3)
93 | - Follow us on [Twitter](https://twitter.com/NathanGDQuest)
94 |
95 | ## Licenses
96 |
97 | This project is dual-licensed:
98 |
99 | - The source code is available under the MIT license.
100 | - Art assets (images, audio files) are [CC-By 4.0](https://creativecommons.org/licenses/by/4.0/). You can attribute them to `GDQuest and contributors (https://www.gdquest.com/)`.
101 |
--------------------------------------------------------------------------------
/godot-csharp/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=4
10 |
11 | _global_script_classes=[ ]
12 | _global_script_class_icons={
13 |
14 | }
15 |
16 | [application]
17 |
18 | config/name="Learn to Code a Pro 3D Character with Godot (start)"
19 | run/main_scene="res://src/Main/Game.tscn"
20 | config/icon="res://icon.png"
21 |
22 | [display]
23 |
24 | window/size/width=1920
25 | window/size/height=1080
26 | window/size/test_width=1280
27 | window/size/test_height=720
28 | window/stretch/mode="2d"
29 | window/stretch/aspect="keep"
30 |
31 | [editor_plugins]
32 |
33 | enabled=PoolStringArray( "MonoDebuggerQM" )
34 |
35 | [input]
36 |
37 | move_left={
38 | "deadzone": 0.5,
39 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
40 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
41 | ]
42 | }
43 | move_right={
44 | "deadzone": 0.5,
45 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
46 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
47 | ]
48 | }
49 | move_front={
50 | "deadzone": 0.5,
51 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
52 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
53 | ]
54 | }
55 | move_back={
56 | "deadzone": 0.5,
57 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
58 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
59 | ]
60 | }
61 | jump={
62 | "deadzone": 0.5,
63 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
64 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
65 | ]
66 | }
67 | sprint={
68 | "deadzone": 0.5,
69 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"unicode":0,"echo":false,"script":null)
70 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":5,"pressure":0.0,"pressed":false,"script":null)
71 | ]
72 | }
73 | toggle_mouse_captured={
74 | "deadzone": 0.5,
75 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"unicode":0,"echo":false,"script":null)
76 | ]
77 | }
78 | click={
79 | "deadzone": 0.5,
80 | "events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
81 | ]
82 | }
83 | look_left={
84 | "deadzone": 0.25,
85 | "events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
86 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
87 | ]
88 | }
89 | look_up={
90 | "deadzone": 0.25,
91 | "events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
92 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
93 | ]
94 | }
95 | look_right={
96 | "deadzone": 0.25,
97 | "events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
98 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
99 | ]
100 | }
101 | look_down={
102 | "deadzone": 0.25,
103 | "events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
104 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
105 | ]
106 | }
107 | interact={
108 | "deadzone": 0.5,
109 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":69,"unicode":0,"echo":false,"script":null)
110 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
111 | ]
112 | }
113 | fire={
114 | "deadzone": 0.5,
115 | "events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
116 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":7,"pressure":0.0,"pressed":false,"script":null)
117 | ]
118 | }
119 | toggle_aim={
120 | "deadzone": 0.5,
121 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":81,"unicode":0,"echo":false,"script":null)
122 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":4,"pressure":0.0,"pressed":false,"script":null)
123 | , Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":3,"pressed":false,"doubleclick":false,"script":null)
124 | ]
125 | }
126 | zoom_in={
127 | "deadzone": 0.5,
128 | "events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":4,"pressed":false,"doubleclick":false,"script":null)
129 | ]
130 | }
131 | zoom_out={
132 | "deadzone": 0.5,
133 | "events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":5,"pressed":false,"doubleclick":false,"script":null)
134 | ]
135 | }
136 |
137 | [layer_names]
138 |
139 | 2d_physics/layer_1="player"
140 | 2d_physics/layer_2="world"
141 |
142 | [mono]
143 |
144 | debugger_agent/wait_timeout=10000
145 |
146 | [rendering]
147 |
148 | quality/filters/msaa=3
149 | environment/default_environment="res://default_env.tres"
150 |
--------------------------------------------------------------------------------
/godot/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=4
10 |
11 | _global_script_classes=[ {
12 | "base": "Spatial",
13 | "class": "CameraRig",
14 | "language": "GDScript",
15 | "path": "res://src/Player/Camera/CameraRig.gd"
16 | }, {
17 | "base": "State",
18 | "class": "CameraState",
19 | "language": "GDScript",
20 | "path": "res://src/Player/Camera/CameraState.gd"
21 | }, {
22 | "base": "Spatial",
23 | "class": "Mannequiny",
24 | "language": "GDScript",
25 | "path": "res://src/Player/Mannequiny.gd"
26 | }, {
27 | "base": "KinematicBody",
28 | "class": "Player",
29 | "language": "GDScript",
30 | "path": "res://src/Player/Player.gd"
31 | }, {
32 | "base": "State",
33 | "class": "PlayerState",
34 | "language": "GDScript",
35 | "path": "res://src/Player/PlayerState.gd"
36 | }, {
37 | "base": "Node",
38 | "class": "State",
39 | "language": "GDScript",
40 | "path": "res://src/Main/StateMachine/State.gd"
41 | }, {
42 | "base": "Node",
43 | "class": "StateMachine",
44 | "language": "GDScript",
45 | "path": "res://src/Main/StateMachine/StateMachine.gd"
46 | } ]
47 | _global_script_class_icons={
48 | "CameraRig": "",
49 | "CameraState": "",
50 | "Mannequiny": "",
51 | "Player": "",
52 | "PlayerState": "",
53 | "State": "",
54 | "StateMachine": ""
55 | }
56 |
57 | [application]
58 |
59 | config/name="3D Third-Person Open Mannequin"
60 | run/main_scene="res://src/Main/Game.tscn"
61 | config/icon="res://icon.png"
62 |
63 | [display]
64 |
65 | window/size/width=1920
66 | window/size/height=1080
67 | window/size/test_width=1280
68 | window/size/test_height=720
69 | window/stretch/mode="2d"
70 | window/stretch/aspect="keep"
71 |
72 | [input]
73 |
74 | move_front={
75 | "deadzone": 0.1,
76 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
77 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
78 | ]
79 | }
80 | move_back={
81 | "deadzone": 0.1,
82 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
83 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
84 | ]
85 | }
86 | move_left={
87 | "deadzone": 0.1,
88 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
89 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
90 | ]
91 | }
92 | move_right={
93 | "deadzone": 0.1,
94 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
95 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
96 | ]
97 | }
98 | jump={
99 | "deadzone": 0.5,
100 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
101 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
102 | ]
103 | }
104 | look_left={
105 | "deadzone": 0.25,
106 | "events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":2,"axis_value":-1.0,"script":null)
107 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
108 | ]
109 | }
110 | look_right={
111 | "deadzone": 0.25,
112 | "events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":2,"axis_value":1.0,"script":null)
113 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
114 | ]
115 | }
116 | look_up={
117 | "deadzone": 0.25,
118 | "events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":3,"axis_value":-1.0,"script":null)
119 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
120 | ]
121 | }
122 | look_down={
123 | "deadzone": 0.25,
124 | "events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":3,"axis_value":1.0,"script":null)
125 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
126 | ]
127 | }
128 | toggle_aim={
129 | "deadzone": 0.5,
130 | "events": [ Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":4,"pressure":0.0,"pressed":false,"script":null)
131 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":81,"unicode":0,"echo":false,"script":null)
132 | , Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":3,"pressed":false,"doubleclick":false,"script":null)
133 | ]
134 | }
135 | interact={
136 | "deadzone": 0.5,
137 | "events": [ Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
138 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":69,"unicode":0,"echo":false,"script":null)
139 | , Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
140 | ]
141 | }
142 | toggle_mouse_captured={
143 | "deadzone": 0.5,
144 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"unicode":0,"echo":false,"script":null)
145 | ]
146 | }
147 | click={
148 | "deadzone": 0.5,
149 | "events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
150 | ]
151 | }
152 | fire={
153 | "deadzone": 0.5,
154 | "events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
155 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":7,"pressure":0.0,"pressed":false,"script":null)
156 | ]
157 | }
158 | toggle_fullscreen={
159 | "deadzone": 0.5,
160 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777254,"unicode":0,"echo":false,"script":null)
161 | ]
162 | }
163 | toggle_debug_menu={
164 | "deadzone": 0.5,
165 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777218,"unicode":0,"echo":false,"script":null)
166 | ]
167 | }
168 | zoom_in={
169 | "deadzone": 0.5,
170 | "events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":4,"pressed":false,"doubleclick":false,"script":null)
171 | ]
172 | }
173 | zoom_out={
174 | "deadzone": 0.5,
175 | "events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":5,"pressed":false,"doubleclick":false,"script":null)
176 | ]
177 | }
178 |
179 | [layer_names]
180 |
181 | 2d_physics/layer_1="player"
182 | 2d_physics/layer_2="world"
183 |
184 | [rendering]
185 |
186 | quality/filters/msaa=3
187 | environment/default_environment="res://default_env.tres"
188 |
--------------------------------------------------------------------------------
/godot/assets/3d/level/playground.glb.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="scene"
4 | type="PackedScene"
5 | path="res://.import/playground.glb-ba79c34a960241f3655c817855b40b06.scn"
6 |
7 | [deps]
8 |
9 | source_file="res://assets/3d/level/playground.glb"
10 | dest_files=[ "res://.import/playground.glb-ba79c34a960241f3655c817855b40b06.scn" ]
11 |
12 | [params]
13 |
14 | nodes/root_type="Spatial"
15 | nodes/root_name="Scene Root"
16 | nodes/root_scale=1.0
17 | nodes/custom_script=""
18 | nodes/storage=0
19 | materials/location=1
20 | materials/storage=1
21 | materials/keep_on_reimport=true
22 | meshes/compress=true
23 | meshes/ensure_tangents=true
24 | meshes/storage=0
25 | meshes/light_baking=0
26 | meshes/lightmap_texel_size=0.1
27 | external_files/store_in_subdir=false
28 | animation/import=true
29 | animation/fps=15
30 | animation/filter_script=""
31 | animation/storage=false
32 | animation/keep_custom_tracks=false
33 | animation/optimizer/enabled=true
34 | animation/optimizer/max_linear_error=0.05
35 | animation/optimizer/max_angular_error=0.01
36 | animation/optimizer/max_angle=22
37 | animation/optimizer/remove_unused_tracks=true
38 | animation/clips/amount=0
39 | animation/clip_1/name=""
40 | animation/clip_1/start_frame=0
41 | animation/clip_1/end_frame=0
42 | animation/clip_1/loops=false
43 | animation/clip_2/name=""
44 | animation/clip_2/start_frame=0
45 | animation/clip_2/end_frame=0
46 | animation/clip_2/loops=false
47 | animation/clip_3/name=""
48 | animation/clip_3/start_frame=0
49 | animation/clip_3/end_frame=0
50 | animation/clip_3/loops=false
51 | animation/clip_4/name=""
52 | animation/clip_4/start_frame=0
53 | animation/clip_4/end_frame=0
54 | animation/clip_4/loops=false
55 | animation/clip_5/name=""
56 | animation/clip_5/start_frame=0
57 | animation/clip_5/end_frame=0
58 | animation/clip_5/loops=false
59 | animation/clip_6/name=""
60 | animation/clip_6/start_frame=0
61 | animation/clip_6/end_frame=0
62 | animation/clip_6/loops=false
63 | animation/clip_7/name=""
64 | animation/clip_7/start_frame=0
65 | animation/clip_7/end_frame=0
66 | animation/clip_7/loops=false
67 | animation/clip_8/name=""
68 | animation/clip_8/start_frame=0
69 | animation/clip_8/end_frame=0
70 | animation/clip_8/loops=false
71 | animation/clip_9/name=""
72 | animation/clip_9/start_frame=0
73 | animation/clip_9/end_frame=0
74 | animation/clip_9/loops=false
75 | animation/clip_10/name=""
76 | animation/clip_10/start_frame=0
77 | animation/clip_10/end_frame=0
78 | animation/clip_10/loops=false
79 | animation/clip_11/name=""
80 | animation/clip_11/start_frame=0
81 | animation/clip_11/end_frame=0
82 | animation/clip_11/loops=false
83 | animation/clip_12/name=""
84 | animation/clip_12/start_frame=0
85 | animation/clip_12/end_frame=0
86 | animation/clip_12/loops=false
87 | animation/clip_13/name=""
88 | animation/clip_13/start_frame=0
89 | animation/clip_13/end_frame=0
90 | animation/clip_13/loops=false
91 | animation/clip_14/name=""
92 | animation/clip_14/start_frame=0
93 | animation/clip_14/end_frame=0
94 | animation/clip_14/loops=false
95 | animation/clip_15/name=""
96 | animation/clip_15/start_frame=0
97 | animation/clip_15/end_frame=0
98 | animation/clip_15/loops=false
99 | animation/clip_16/name=""
100 | animation/clip_16/start_frame=0
101 | animation/clip_16/end_frame=0
102 | animation/clip_16/loops=false
103 | animation/clip_17/name=""
104 | animation/clip_17/start_frame=0
105 | animation/clip_17/end_frame=0
106 | animation/clip_17/loops=false
107 | animation/clip_18/name=""
108 | animation/clip_18/start_frame=0
109 | animation/clip_18/end_frame=0
110 | animation/clip_18/loops=false
111 | animation/clip_19/name=""
112 | animation/clip_19/start_frame=0
113 | animation/clip_19/end_frame=0
114 | animation/clip_19/loops=false
115 | animation/clip_20/name=""
116 | animation/clip_20/start_frame=0
117 | animation/clip_20/end_frame=0
118 | animation/clip_20/loops=false
119 | animation/clip_21/name=""
120 | animation/clip_21/start_frame=0
121 | animation/clip_21/end_frame=0
122 | animation/clip_21/loops=false
123 | animation/clip_22/name=""
124 | animation/clip_22/start_frame=0
125 | animation/clip_22/end_frame=0
126 | animation/clip_22/loops=false
127 | animation/clip_23/name=""
128 | animation/clip_23/start_frame=0
129 | animation/clip_23/end_frame=0
130 | animation/clip_23/loops=false
131 | animation/clip_24/name=""
132 | animation/clip_24/start_frame=0
133 | animation/clip_24/end_frame=0
134 | animation/clip_24/loops=false
135 | animation/clip_25/name=""
136 | animation/clip_25/start_frame=0
137 | animation/clip_25/end_frame=0
138 | animation/clip_25/loops=false
139 | animation/clip_26/name=""
140 | animation/clip_26/start_frame=0
141 | animation/clip_26/end_frame=0
142 | animation/clip_26/loops=false
143 | animation/clip_27/name=""
144 | animation/clip_27/start_frame=0
145 | animation/clip_27/end_frame=0
146 | animation/clip_27/loops=false
147 | animation/clip_28/name=""
148 | animation/clip_28/start_frame=0
149 | animation/clip_28/end_frame=0
150 | animation/clip_28/loops=false
151 | animation/clip_29/name=""
152 | animation/clip_29/start_frame=0
153 | animation/clip_29/end_frame=0
154 | animation/clip_29/loops=false
155 | animation/clip_30/name=""
156 | animation/clip_30/start_frame=0
157 | animation/clip_30/end_frame=0
158 | animation/clip_30/loops=false
159 | animation/clip_31/name=""
160 | animation/clip_31/start_frame=0
161 | animation/clip_31/end_frame=0
162 | animation/clip_31/loops=false
163 | animation/clip_32/name=""
164 | animation/clip_32/start_frame=0
165 | animation/clip_32/end_frame=0
166 | animation/clip_32/loops=false
167 | animation/clip_33/name=""
168 | animation/clip_33/start_frame=0
169 | animation/clip_33/end_frame=0
170 | animation/clip_33/loops=false
171 | animation/clip_34/name=""
172 | animation/clip_34/start_frame=0
173 | animation/clip_34/end_frame=0
174 | animation/clip_34/loops=false
175 | animation/clip_35/name=""
176 | animation/clip_35/start_frame=0
177 | animation/clip_35/end_frame=0
178 | animation/clip_35/loops=false
179 | animation/clip_36/name=""
180 | animation/clip_36/start_frame=0
181 | animation/clip_36/end_frame=0
182 | animation/clip_36/loops=false
183 | animation/clip_37/name=""
184 | animation/clip_37/start_frame=0
185 | animation/clip_37/end_frame=0
186 | animation/clip_37/loops=false
187 | animation/clip_38/name=""
188 | animation/clip_38/start_frame=0
189 | animation/clip_38/end_frame=0
190 | animation/clip_38/loops=false
191 | animation/clip_39/name=""
192 | animation/clip_39/start_frame=0
193 | animation/clip_39/end_frame=0
194 | animation/clip_39/loops=false
195 | animation/clip_40/name=""
196 | animation/clip_40/start_frame=0
197 | animation/clip_40/end_frame=0
198 | animation/clip_40/loops=false
199 | animation/clip_41/name=""
200 | animation/clip_41/start_frame=0
201 | animation/clip_41/end_frame=0
202 | animation/clip_41/loops=false
203 | animation/clip_42/name=""
204 | animation/clip_42/start_frame=0
205 | animation/clip_42/end_frame=0
206 | animation/clip_42/loops=false
207 | animation/clip_43/name=""
208 | animation/clip_43/start_frame=0
209 | animation/clip_43/end_frame=0
210 | animation/clip_43/loops=false
211 | animation/clip_44/name=""
212 | animation/clip_44/start_frame=0
213 | animation/clip_44/end_frame=0
214 | animation/clip_44/loops=false
215 | animation/clip_45/name=""
216 | animation/clip_45/start_frame=0
217 | animation/clip_45/end_frame=0
218 | animation/clip_45/loops=false
219 | animation/clip_46/name=""
220 | animation/clip_46/start_frame=0
221 | animation/clip_46/end_frame=0
222 | animation/clip_46/loops=false
223 | animation/clip_47/name=""
224 | animation/clip_47/start_frame=0
225 | animation/clip_47/end_frame=0
226 | animation/clip_47/loops=false
227 | animation/clip_48/name=""
228 | animation/clip_48/start_frame=0
229 | animation/clip_48/end_frame=0
230 | animation/clip_48/loops=false
231 | animation/clip_49/name=""
232 | animation/clip_49/start_frame=0
233 | animation/clip_49/end_frame=0
234 | animation/clip_49/loops=false
235 | animation/clip_50/name=""
236 | animation/clip_50/start_frame=0
237 | animation/clip_50/end_frame=0
238 | animation/clip_50/loops=false
239 | animation/clip_51/name=""
240 | animation/clip_51/start_frame=0
241 | animation/clip_51/end_frame=0
242 | animation/clip_51/loops=false
243 | animation/clip_52/name=""
244 | animation/clip_52/start_frame=0
245 | animation/clip_52/end_frame=0
246 | animation/clip_52/loops=false
247 | animation/clip_53/name=""
248 | animation/clip_53/start_frame=0
249 | animation/clip_53/end_frame=0
250 | animation/clip_53/loops=false
251 | animation/clip_54/name=""
252 | animation/clip_54/start_frame=0
253 | animation/clip_54/end_frame=0
254 | animation/clip_54/loops=false
255 | animation/clip_55/name=""
256 | animation/clip_55/start_frame=0
257 | animation/clip_55/end_frame=0
258 | animation/clip_55/loops=false
259 | animation/clip_56/name=""
260 | animation/clip_56/start_frame=0
261 | animation/clip_56/end_frame=0
262 | animation/clip_56/loops=false
263 | animation/clip_57/name=""
264 | animation/clip_57/start_frame=0
265 | animation/clip_57/end_frame=0
266 | animation/clip_57/loops=false
267 | animation/clip_58/name=""
268 | animation/clip_58/start_frame=0
269 | animation/clip_58/end_frame=0
270 | animation/clip_58/loops=false
271 | animation/clip_59/name=""
272 | animation/clip_59/start_frame=0
273 | animation/clip_59/end_frame=0
274 | animation/clip_59/loops=false
275 | animation/clip_60/name=""
276 | animation/clip_60/start_frame=0
277 | animation/clip_60/end_frame=0
278 | animation/clip_60/loops=false
279 | animation/clip_61/name=""
280 | animation/clip_61/start_frame=0
281 | animation/clip_61/end_frame=0
282 | animation/clip_61/loops=false
283 | animation/clip_62/name=""
284 | animation/clip_62/start_frame=0
285 | animation/clip_62/end_frame=0
286 | animation/clip_62/loops=false
287 | animation/clip_63/name=""
288 | animation/clip_63/start_frame=0
289 | animation/clip_63/end_frame=0
290 | animation/clip_63/loops=false
291 | animation/clip_64/name=""
292 | animation/clip_64/start_frame=0
293 | animation/clip_64/end_frame=0
294 | animation/clip_64/loops=false
295 | animation/clip_65/name=""
296 | animation/clip_65/start_frame=0
297 | animation/clip_65/end_frame=0
298 | animation/clip_65/loops=false
299 | animation/clip_66/name=""
300 | animation/clip_66/start_frame=0
301 | animation/clip_66/end_frame=0
302 | animation/clip_66/loops=false
303 | animation/clip_67/name=""
304 | animation/clip_67/start_frame=0
305 | animation/clip_67/end_frame=0
306 | animation/clip_67/loops=false
307 | animation/clip_68/name=""
308 | animation/clip_68/start_frame=0
309 | animation/clip_68/end_frame=0
310 | animation/clip_68/loops=false
311 | animation/clip_69/name=""
312 | animation/clip_69/start_frame=0
313 | animation/clip_69/end_frame=0
314 | animation/clip_69/loops=false
315 | animation/clip_70/name=""
316 | animation/clip_70/start_frame=0
317 | animation/clip_70/end_frame=0
318 | animation/clip_70/loops=false
319 | animation/clip_71/name=""
320 | animation/clip_71/start_frame=0
321 | animation/clip_71/end_frame=0
322 | animation/clip_71/loops=false
323 | animation/clip_72/name=""
324 | animation/clip_72/start_frame=0
325 | animation/clip_72/end_frame=0
326 | animation/clip_72/loops=false
327 | animation/clip_73/name=""
328 | animation/clip_73/start_frame=0
329 | animation/clip_73/end_frame=0
330 | animation/clip_73/loops=false
331 | animation/clip_74/name=""
332 | animation/clip_74/start_frame=0
333 | animation/clip_74/end_frame=0
334 | animation/clip_74/loops=false
335 | animation/clip_75/name=""
336 | animation/clip_75/start_frame=0
337 | animation/clip_75/end_frame=0
338 | animation/clip_75/loops=false
339 | animation/clip_76/name=""
340 | animation/clip_76/start_frame=0
341 | animation/clip_76/end_frame=0
342 | animation/clip_76/loops=false
343 | animation/clip_77/name=""
344 | animation/clip_77/start_frame=0
345 | animation/clip_77/end_frame=0
346 | animation/clip_77/loops=false
347 | animation/clip_78/name=""
348 | animation/clip_78/start_frame=0
349 | animation/clip_78/end_frame=0
350 | animation/clip_78/loops=false
351 | animation/clip_79/name=""
352 | animation/clip_79/start_frame=0
353 | animation/clip_79/end_frame=0
354 | animation/clip_79/loops=false
355 | animation/clip_80/name=""
356 | animation/clip_80/start_frame=0
357 | animation/clip_80/end_frame=0
358 | animation/clip_80/loops=false
359 | animation/clip_81/name=""
360 | animation/clip_81/start_frame=0
361 | animation/clip_81/end_frame=0
362 | animation/clip_81/loops=false
363 | animation/clip_82/name=""
364 | animation/clip_82/start_frame=0
365 | animation/clip_82/end_frame=0
366 | animation/clip_82/loops=false
367 | animation/clip_83/name=""
368 | animation/clip_83/start_frame=0
369 | animation/clip_83/end_frame=0
370 | animation/clip_83/loops=false
371 | animation/clip_84/name=""
372 | animation/clip_84/start_frame=0
373 | animation/clip_84/end_frame=0
374 | animation/clip_84/loops=false
375 | animation/clip_85/name=""
376 | animation/clip_85/start_frame=0
377 | animation/clip_85/end_frame=0
378 | animation/clip_85/loops=false
379 | animation/clip_86/name=""
380 | animation/clip_86/start_frame=0
381 | animation/clip_86/end_frame=0
382 | animation/clip_86/loops=false
383 | animation/clip_87/name=""
384 | animation/clip_87/start_frame=0
385 | animation/clip_87/end_frame=0
386 | animation/clip_87/loops=false
387 | animation/clip_88/name=""
388 | animation/clip_88/start_frame=0
389 | animation/clip_88/end_frame=0
390 | animation/clip_88/loops=false
391 | animation/clip_89/name=""
392 | animation/clip_89/start_frame=0
393 | animation/clip_89/end_frame=0
394 | animation/clip_89/loops=false
395 | animation/clip_90/name=""
396 | animation/clip_90/start_frame=0
397 | animation/clip_90/end_frame=0
398 | animation/clip_90/loops=false
399 | animation/clip_91/name=""
400 | animation/clip_91/start_frame=0
401 | animation/clip_91/end_frame=0
402 | animation/clip_91/loops=false
403 | animation/clip_92/name=""
404 | animation/clip_92/start_frame=0
405 | animation/clip_92/end_frame=0
406 | animation/clip_92/loops=false
407 | animation/clip_93/name=""
408 | animation/clip_93/start_frame=0
409 | animation/clip_93/end_frame=0
410 | animation/clip_93/loops=false
411 | animation/clip_94/name=""
412 | animation/clip_94/start_frame=0
413 | animation/clip_94/end_frame=0
414 | animation/clip_94/loops=false
415 | animation/clip_95/name=""
416 | animation/clip_95/start_frame=0
417 | animation/clip_95/end_frame=0
418 | animation/clip_95/loops=false
419 | animation/clip_96/name=""
420 | animation/clip_96/start_frame=0
421 | animation/clip_96/end_frame=0
422 | animation/clip_96/loops=false
423 | animation/clip_97/name=""
424 | animation/clip_97/start_frame=0
425 | animation/clip_97/end_frame=0
426 | animation/clip_97/loops=false
427 | animation/clip_98/name=""
428 | animation/clip_98/start_frame=0
429 | animation/clip_98/end_frame=0
430 | animation/clip_98/loops=false
431 | animation/clip_99/name=""
432 | animation/clip_99/start_frame=0
433 | animation/clip_99/end_frame=0
434 | animation/clip_99/loops=false
435 | animation/clip_100/name=""
436 | animation/clip_100/start_frame=0
437 | animation/clip_100/end_frame=0
438 | animation/clip_100/loops=false
439 | animation/clip_101/name=""
440 | animation/clip_101/start_frame=0
441 | animation/clip_101/end_frame=0
442 | animation/clip_101/loops=false
443 | animation/clip_102/name=""
444 | animation/clip_102/start_frame=0
445 | animation/clip_102/end_frame=0
446 | animation/clip_102/loops=false
447 | animation/clip_103/name=""
448 | animation/clip_103/start_frame=0
449 | animation/clip_103/end_frame=0
450 | animation/clip_103/loops=false
451 | animation/clip_104/name=""
452 | animation/clip_104/start_frame=0
453 | animation/clip_104/end_frame=0
454 | animation/clip_104/loops=false
455 | animation/clip_105/name=""
456 | animation/clip_105/start_frame=0
457 | animation/clip_105/end_frame=0
458 | animation/clip_105/loops=false
459 | animation/clip_106/name=""
460 | animation/clip_106/start_frame=0
461 | animation/clip_106/end_frame=0
462 | animation/clip_106/loops=false
463 | animation/clip_107/name=""
464 | animation/clip_107/start_frame=0
465 | animation/clip_107/end_frame=0
466 | animation/clip_107/loops=false
467 | animation/clip_108/name=""
468 | animation/clip_108/start_frame=0
469 | animation/clip_108/end_frame=0
470 | animation/clip_108/loops=false
471 | animation/clip_109/name=""
472 | animation/clip_109/start_frame=0
473 | animation/clip_109/end_frame=0
474 | animation/clip_109/loops=false
475 | animation/clip_110/name=""
476 | animation/clip_110/start_frame=0
477 | animation/clip_110/end_frame=0
478 | animation/clip_110/loops=false
479 | animation/clip_111/name=""
480 | animation/clip_111/start_frame=0
481 | animation/clip_111/end_frame=0
482 | animation/clip_111/loops=false
483 | animation/clip_112/name=""
484 | animation/clip_112/start_frame=0
485 | animation/clip_112/end_frame=0
486 | animation/clip_112/loops=false
487 | animation/clip_113/name=""
488 | animation/clip_113/start_frame=0
489 | animation/clip_113/end_frame=0
490 | animation/clip_113/loops=false
491 | animation/clip_114/name=""
492 | animation/clip_114/start_frame=0
493 | animation/clip_114/end_frame=0
494 | animation/clip_114/loops=false
495 | animation/clip_115/name=""
496 | animation/clip_115/start_frame=0
497 | animation/clip_115/end_frame=0
498 | animation/clip_115/loops=false
499 | animation/clip_116/name=""
500 | animation/clip_116/start_frame=0
501 | animation/clip_116/end_frame=0
502 | animation/clip_116/loops=false
503 | animation/clip_117/name=""
504 | animation/clip_117/start_frame=0
505 | animation/clip_117/end_frame=0
506 | animation/clip_117/loops=false
507 | animation/clip_118/name=""
508 | animation/clip_118/start_frame=0
509 | animation/clip_118/end_frame=0
510 | animation/clip_118/loops=false
511 | animation/clip_119/name=""
512 | animation/clip_119/start_frame=0
513 | animation/clip_119/end_frame=0
514 | animation/clip_119/loops=false
515 | animation/clip_120/name=""
516 | animation/clip_120/start_frame=0
517 | animation/clip_120/end_frame=0
518 | animation/clip_120/loops=false
519 | animation/clip_121/name=""
520 | animation/clip_121/start_frame=0
521 | animation/clip_121/end_frame=0
522 | animation/clip_121/loops=false
523 | animation/clip_122/name=""
524 | animation/clip_122/start_frame=0
525 | animation/clip_122/end_frame=0
526 | animation/clip_122/loops=false
527 | animation/clip_123/name=""
528 | animation/clip_123/start_frame=0
529 | animation/clip_123/end_frame=0
530 | animation/clip_123/loops=false
531 | animation/clip_124/name=""
532 | animation/clip_124/start_frame=0
533 | animation/clip_124/end_frame=0
534 | animation/clip_124/loops=false
535 | animation/clip_125/name=""
536 | animation/clip_125/start_frame=0
537 | animation/clip_125/end_frame=0
538 | animation/clip_125/loops=false
539 | animation/clip_126/name=""
540 | animation/clip_126/start_frame=0
541 | animation/clip_126/end_frame=0
542 | animation/clip_126/loops=false
543 | animation/clip_127/name=""
544 | animation/clip_127/start_frame=0
545 | animation/clip_127/end_frame=0
546 | animation/clip_127/loops=false
547 | animation/clip_128/name=""
548 | animation/clip_128/start_frame=0
549 | animation/clip_128/end_frame=0
550 | animation/clip_128/loops=false
551 | animation/clip_129/name=""
552 | animation/clip_129/start_frame=0
553 | animation/clip_129/end_frame=0
554 | animation/clip_129/loops=false
555 | animation/clip_130/name=""
556 | animation/clip_130/start_frame=0
557 | animation/clip_130/end_frame=0
558 | animation/clip_130/loops=false
559 | animation/clip_131/name=""
560 | animation/clip_131/start_frame=0
561 | animation/clip_131/end_frame=0
562 | animation/clip_131/loops=false
563 | animation/clip_132/name=""
564 | animation/clip_132/start_frame=0
565 | animation/clip_132/end_frame=0
566 | animation/clip_132/loops=false
567 | animation/clip_133/name=""
568 | animation/clip_133/start_frame=0
569 | animation/clip_133/end_frame=0
570 | animation/clip_133/loops=false
571 | animation/clip_134/name=""
572 | animation/clip_134/start_frame=0
573 | animation/clip_134/end_frame=0
574 | animation/clip_134/loops=false
575 | animation/clip_135/name=""
576 | animation/clip_135/start_frame=0
577 | animation/clip_135/end_frame=0
578 | animation/clip_135/loops=false
579 | animation/clip_136/name=""
580 | animation/clip_136/start_frame=0
581 | animation/clip_136/end_frame=0
582 | animation/clip_136/loops=false
583 | animation/clip_137/name=""
584 | animation/clip_137/start_frame=0
585 | animation/clip_137/end_frame=0
586 | animation/clip_137/loops=false
587 | animation/clip_138/name=""
588 | animation/clip_138/start_frame=0
589 | animation/clip_138/end_frame=0
590 | animation/clip_138/loops=false
591 | animation/clip_139/name=""
592 | animation/clip_139/start_frame=0
593 | animation/clip_139/end_frame=0
594 | animation/clip_139/loops=false
595 | animation/clip_140/name=""
596 | animation/clip_140/start_frame=0
597 | animation/clip_140/end_frame=0
598 | animation/clip_140/loops=false
599 | animation/clip_141/name=""
600 | animation/clip_141/start_frame=0
601 | animation/clip_141/end_frame=0
602 | animation/clip_141/loops=false
603 | animation/clip_142/name=""
604 | animation/clip_142/start_frame=0
605 | animation/clip_142/end_frame=0
606 | animation/clip_142/loops=false
607 | animation/clip_143/name=""
608 | animation/clip_143/start_frame=0
609 | animation/clip_143/end_frame=0
610 | animation/clip_143/loops=false
611 | animation/clip_144/name=""
612 | animation/clip_144/start_frame=0
613 | animation/clip_144/end_frame=0
614 | animation/clip_144/loops=false
615 | animation/clip_145/name=""
616 | animation/clip_145/start_frame=0
617 | animation/clip_145/end_frame=0
618 | animation/clip_145/loops=false
619 | animation/clip_146/name=""
620 | animation/clip_146/start_frame=0
621 | animation/clip_146/end_frame=0
622 | animation/clip_146/loops=false
623 | animation/clip_147/name=""
624 | animation/clip_147/start_frame=0
625 | animation/clip_147/end_frame=0
626 | animation/clip_147/loops=false
627 | animation/clip_148/name=""
628 | animation/clip_148/start_frame=0
629 | animation/clip_148/end_frame=0
630 | animation/clip_148/loops=false
631 | animation/clip_149/name=""
632 | animation/clip_149/start_frame=0
633 | animation/clip_149/end_frame=0
634 | animation/clip_149/loops=false
635 | animation/clip_150/name=""
636 | animation/clip_150/start_frame=0
637 | animation/clip_150/end_frame=0
638 | animation/clip_150/loops=false
639 | animation/clip_151/name=""
640 | animation/clip_151/start_frame=0
641 | animation/clip_151/end_frame=0
642 | animation/clip_151/loops=false
643 | animation/clip_152/name=""
644 | animation/clip_152/start_frame=0
645 | animation/clip_152/end_frame=0
646 | animation/clip_152/loops=false
647 | animation/clip_153/name=""
648 | animation/clip_153/start_frame=0
649 | animation/clip_153/end_frame=0
650 | animation/clip_153/loops=false
651 | animation/clip_154/name=""
652 | animation/clip_154/start_frame=0
653 | animation/clip_154/end_frame=0
654 | animation/clip_154/loops=false
655 | animation/clip_155/name=""
656 | animation/clip_155/start_frame=0
657 | animation/clip_155/end_frame=0
658 | animation/clip_155/loops=false
659 | animation/clip_156/name=""
660 | animation/clip_156/start_frame=0
661 | animation/clip_156/end_frame=0
662 | animation/clip_156/loops=false
663 | animation/clip_157/name=""
664 | animation/clip_157/start_frame=0
665 | animation/clip_157/end_frame=0
666 | animation/clip_157/loops=false
667 | animation/clip_158/name=""
668 | animation/clip_158/start_frame=0
669 | animation/clip_158/end_frame=0
670 | animation/clip_158/loops=false
671 | animation/clip_159/name=""
672 | animation/clip_159/start_frame=0
673 | animation/clip_159/end_frame=0
674 | animation/clip_159/loops=false
675 | animation/clip_160/name=""
676 | animation/clip_160/start_frame=0
677 | animation/clip_160/end_frame=0
678 | animation/clip_160/loops=false
679 | animation/clip_161/name=""
680 | animation/clip_161/start_frame=0
681 | animation/clip_161/end_frame=0
682 | animation/clip_161/loops=false
683 | animation/clip_162/name=""
684 | animation/clip_162/start_frame=0
685 | animation/clip_162/end_frame=0
686 | animation/clip_162/loops=false
687 | animation/clip_163/name=""
688 | animation/clip_163/start_frame=0
689 | animation/clip_163/end_frame=0
690 | animation/clip_163/loops=false
691 | animation/clip_164/name=""
692 | animation/clip_164/start_frame=0
693 | animation/clip_164/end_frame=0
694 | animation/clip_164/loops=false
695 | animation/clip_165/name=""
696 | animation/clip_165/start_frame=0
697 | animation/clip_165/end_frame=0
698 | animation/clip_165/loops=false
699 | animation/clip_166/name=""
700 | animation/clip_166/start_frame=0
701 | animation/clip_166/end_frame=0
702 | animation/clip_166/loops=false
703 | animation/clip_167/name=""
704 | animation/clip_167/start_frame=0
705 | animation/clip_167/end_frame=0
706 | animation/clip_167/loops=false
707 | animation/clip_168/name=""
708 | animation/clip_168/start_frame=0
709 | animation/clip_168/end_frame=0
710 | animation/clip_168/loops=false
711 | animation/clip_169/name=""
712 | animation/clip_169/start_frame=0
713 | animation/clip_169/end_frame=0
714 | animation/clip_169/loops=false
715 | animation/clip_170/name=""
716 | animation/clip_170/start_frame=0
717 | animation/clip_170/end_frame=0
718 | animation/clip_170/loops=false
719 | animation/clip_171/name=""
720 | animation/clip_171/start_frame=0
721 | animation/clip_171/end_frame=0
722 | animation/clip_171/loops=false
723 | animation/clip_172/name=""
724 | animation/clip_172/start_frame=0
725 | animation/clip_172/end_frame=0
726 | animation/clip_172/loops=false
727 | animation/clip_173/name=""
728 | animation/clip_173/start_frame=0
729 | animation/clip_173/end_frame=0
730 | animation/clip_173/loops=false
731 | animation/clip_174/name=""
732 | animation/clip_174/start_frame=0
733 | animation/clip_174/end_frame=0
734 | animation/clip_174/loops=false
735 | animation/clip_175/name=""
736 | animation/clip_175/start_frame=0
737 | animation/clip_175/end_frame=0
738 | animation/clip_175/loops=false
739 | animation/clip_176/name=""
740 | animation/clip_176/start_frame=0
741 | animation/clip_176/end_frame=0
742 | animation/clip_176/loops=false
743 | animation/clip_177/name=""
744 | animation/clip_177/start_frame=0
745 | animation/clip_177/end_frame=0
746 | animation/clip_177/loops=false
747 | animation/clip_178/name=""
748 | animation/clip_178/start_frame=0
749 | animation/clip_178/end_frame=0
750 | animation/clip_178/loops=false
751 | animation/clip_179/name=""
752 | animation/clip_179/start_frame=0
753 | animation/clip_179/end_frame=0
754 | animation/clip_179/loops=false
755 | animation/clip_180/name=""
756 | animation/clip_180/start_frame=0
757 | animation/clip_180/end_frame=0
758 | animation/clip_180/loops=false
759 | animation/clip_181/name=""
760 | animation/clip_181/start_frame=0
761 | animation/clip_181/end_frame=0
762 | animation/clip_181/loops=false
763 | animation/clip_182/name=""
764 | animation/clip_182/start_frame=0
765 | animation/clip_182/end_frame=0
766 | animation/clip_182/loops=false
767 | animation/clip_183/name=""
768 | animation/clip_183/start_frame=0
769 | animation/clip_183/end_frame=0
770 | animation/clip_183/loops=false
771 | animation/clip_184/name=""
772 | animation/clip_184/start_frame=0
773 | animation/clip_184/end_frame=0
774 | animation/clip_184/loops=false
775 | animation/clip_185/name=""
776 | animation/clip_185/start_frame=0
777 | animation/clip_185/end_frame=0
778 | animation/clip_185/loops=false
779 | animation/clip_186/name=""
780 | animation/clip_186/start_frame=0
781 | animation/clip_186/end_frame=0
782 | animation/clip_186/loops=false
783 | animation/clip_187/name=""
784 | animation/clip_187/start_frame=0
785 | animation/clip_187/end_frame=0
786 | animation/clip_187/loops=false
787 | animation/clip_188/name=""
788 | animation/clip_188/start_frame=0
789 | animation/clip_188/end_frame=0
790 | animation/clip_188/loops=false
791 | animation/clip_189/name=""
792 | animation/clip_189/start_frame=0
793 | animation/clip_189/end_frame=0
794 | animation/clip_189/loops=false
795 | animation/clip_190/name=""
796 | animation/clip_190/start_frame=0
797 | animation/clip_190/end_frame=0
798 | animation/clip_190/loops=false
799 | animation/clip_191/name=""
800 | animation/clip_191/start_frame=0
801 | animation/clip_191/end_frame=0
802 | animation/clip_191/loops=false
803 | animation/clip_192/name=""
804 | animation/clip_192/start_frame=0
805 | animation/clip_192/end_frame=0
806 | animation/clip_192/loops=false
807 | animation/clip_193/name=""
808 | animation/clip_193/start_frame=0
809 | animation/clip_193/end_frame=0
810 | animation/clip_193/loops=false
811 | animation/clip_194/name=""
812 | animation/clip_194/start_frame=0
813 | animation/clip_194/end_frame=0
814 | animation/clip_194/loops=false
815 | animation/clip_195/name=""
816 | animation/clip_195/start_frame=0
817 | animation/clip_195/end_frame=0
818 | animation/clip_195/loops=false
819 | animation/clip_196/name=""
820 | animation/clip_196/start_frame=0
821 | animation/clip_196/end_frame=0
822 | animation/clip_196/loops=false
823 | animation/clip_197/name=""
824 | animation/clip_197/start_frame=0
825 | animation/clip_197/end_frame=0
826 | animation/clip_197/loops=false
827 | animation/clip_198/name=""
828 | animation/clip_198/start_frame=0
829 | animation/clip_198/end_frame=0
830 | animation/clip_198/loops=false
831 | animation/clip_199/name=""
832 | animation/clip_199/start_frame=0
833 | animation/clip_199/end_frame=0
834 | animation/clip_199/loops=false
835 | animation/clip_200/name=""
836 | animation/clip_200/start_frame=0
837 | animation/clip_200/end_frame=0
838 | animation/clip_200/loops=false
839 | animation/clip_201/name=""
840 | animation/clip_201/start_frame=0
841 | animation/clip_201/end_frame=0
842 | animation/clip_201/loops=false
843 | animation/clip_202/name=""
844 | animation/clip_202/start_frame=0
845 | animation/clip_202/end_frame=0
846 | animation/clip_202/loops=false
847 | animation/clip_203/name=""
848 | animation/clip_203/start_frame=0
849 | animation/clip_203/end_frame=0
850 | animation/clip_203/loops=false
851 | animation/clip_204/name=""
852 | animation/clip_204/start_frame=0
853 | animation/clip_204/end_frame=0
854 | animation/clip_204/loops=false
855 | animation/clip_205/name=""
856 | animation/clip_205/start_frame=0
857 | animation/clip_205/end_frame=0
858 | animation/clip_205/loops=false
859 | animation/clip_206/name=""
860 | animation/clip_206/start_frame=0
861 | animation/clip_206/end_frame=0
862 | animation/clip_206/loops=false
863 | animation/clip_207/name=""
864 | animation/clip_207/start_frame=0
865 | animation/clip_207/end_frame=0
866 | animation/clip_207/loops=false
867 | animation/clip_208/name=""
868 | animation/clip_208/start_frame=0
869 | animation/clip_208/end_frame=0
870 | animation/clip_208/loops=false
871 | animation/clip_209/name=""
872 | animation/clip_209/start_frame=0
873 | animation/clip_209/end_frame=0
874 | animation/clip_209/loops=false
875 | animation/clip_210/name=""
876 | animation/clip_210/start_frame=0
877 | animation/clip_210/end_frame=0
878 | animation/clip_210/loops=false
879 | animation/clip_211/name=""
880 | animation/clip_211/start_frame=0
881 | animation/clip_211/end_frame=0
882 | animation/clip_211/loops=false
883 | animation/clip_212/name=""
884 | animation/clip_212/start_frame=0
885 | animation/clip_212/end_frame=0
886 | animation/clip_212/loops=false
887 | animation/clip_213/name=""
888 | animation/clip_213/start_frame=0
889 | animation/clip_213/end_frame=0
890 | animation/clip_213/loops=false
891 | animation/clip_214/name=""
892 | animation/clip_214/start_frame=0
893 | animation/clip_214/end_frame=0
894 | animation/clip_214/loops=false
895 | animation/clip_215/name=""
896 | animation/clip_215/start_frame=0
897 | animation/clip_215/end_frame=0
898 | animation/clip_215/loops=false
899 | animation/clip_216/name=""
900 | animation/clip_216/start_frame=0
901 | animation/clip_216/end_frame=0
902 | animation/clip_216/loops=false
903 | animation/clip_217/name=""
904 | animation/clip_217/start_frame=0
905 | animation/clip_217/end_frame=0
906 | animation/clip_217/loops=false
907 | animation/clip_218/name=""
908 | animation/clip_218/start_frame=0
909 | animation/clip_218/end_frame=0
910 | animation/clip_218/loops=false
911 | animation/clip_219/name=""
912 | animation/clip_219/start_frame=0
913 | animation/clip_219/end_frame=0
914 | animation/clip_219/loops=false
915 | animation/clip_220/name=""
916 | animation/clip_220/start_frame=0
917 | animation/clip_220/end_frame=0
918 | animation/clip_220/loops=false
919 | animation/clip_221/name=""
920 | animation/clip_221/start_frame=0
921 | animation/clip_221/end_frame=0
922 | animation/clip_221/loops=false
923 | animation/clip_222/name=""
924 | animation/clip_222/start_frame=0
925 | animation/clip_222/end_frame=0
926 | animation/clip_222/loops=false
927 | animation/clip_223/name=""
928 | animation/clip_223/start_frame=0
929 | animation/clip_223/end_frame=0
930 | animation/clip_223/loops=false
931 | animation/clip_224/name=""
932 | animation/clip_224/start_frame=0
933 | animation/clip_224/end_frame=0
934 | animation/clip_224/loops=false
935 | animation/clip_225/name=""
936 | animation/clip_225/start_frame=0
937 | animation/clip_225/end_frame=0
938 | animation/clip_225/loops=false
939 | animation/clip_226/name=""
940 | animation/clip_226/start_frame=0
941 | animation/clip_226/end_frame=0
942 | animation/clip_226/loops=false
943 | animation/clip_227/name=""
944 | animation/clip_227/start_frame=0
945 | animation/clip_227/end_frame=0
946 | animation/clip_227/loops=false
947 | animation/clip_228/name=""
948 | animation/clip_228/start_frame=0
949 | animation/clip_228/end_frame=0
950 | animation/clip_228/loops=false
951 | animation/clip_229/name=""
952 | animation/clip_229/start_frame=0
953 | animation/clip_229/end_frame=0
954 | animation/clip_229/loops=false
955 | animation/clip_230/name=""
956 | animation/clip_230/start_frame=0
957 | animation/clip_230/end_frame=0
958 | animation/clip_230/loops=false
959 | animation/clip_231/name=""
960 | animation/clip_231/start_frame=0
961 | animation/clip_231/end_frame=0
962 | animation/clip_231/loops=false
963 | animation/clip_232/name=""
964 | animation/clip_232/start_frame=0
965 | animation/clip_232/end_frame=0
966 | animation/clip_232/loops=false
967 | animation/clip_233/name=""
968 | animation/clip_233/start_frame=0
969 | animation/clip_233/end_frame=0
970 | animation/clip_233/loops=false
971 | animation/clip_234/name=""
972 | animation/clip_234/start_frame=0
973 | animation/clip_234/end_frame=0
974 | animation/clip_234/loops=false
975 | animation/clip_235/name=""
976 | animation/clip_235/start_frame=0
977 | animation/clip_235/end_frame=0
978 | animation/clip_235/loops=false
979 | animation/clip_236/name=""
980 | animation/clip_236/start_frame=0
981 | animation/clip_236/end_frame=0
982 | animation/clip_236/loops=false
983 | animation/clip_237/name=""
984 | animation/clip_237/start_frame=0
985 | animation/clip_237/end_frame=0
986 | animation/clip_237/loops=false
987 | animation/clip_238/name=""
988 | animation/clip_238/start_frame=0
989 | animation/clip_238/end_frame=0
990 | animation/clip_238/loops=false
991 | animation/clip_239/name=""
992 | animation/clip_239/start_frame=0
993 | animation/clip_239/end_frame=0
994 | animation/clip_239/loops=false
995 | animation/clip_240/name=""
996 | animation/clip_240/start_frame=0
997 | animation/clip_240/end_frame=0
998 | animation/clip_240/loops=false
999 | animation/clip_241/name=""
1000 | animation/clip_241/start_frame=0
1001 | animation/clip_241/end_frame=0
1002 | animation/clip_241/loops=false
1003 | animation/clip_242/name=""
1004 | animation/clip_242/start_frame=0
1005 | animation/clip_242/end_frame=0
1006 | animation/clip_242/loops=false
1007 | animation/clip_243/name=""
1008 | animation/clip_243/start_frame=0
1009 | animation/clip_243/end_frame=0
1010 | animation/clip_243/loops=false
1011 | animation/clip_244/name=""
1012 | animation/clip_244/start_frame=0
1013 | animation/clip_244/end_frame=0
1014 | animation/clip_244/loops=false
1015 | animation/clip_245/name=""
1016 | animation/clip_245/start_frame=0
1017 | animation/clip_245/end_frame=0
1018 | animation/clip_245/loops=false
1019 | animation/clip_246/name=""
1020 | animation/clip_246/start_frame=0
1021 | animation/clip_246/end_frame=0
1022 | animation/clip_246/loops=false
1023 | animation/clip_247/name=""
1024 | animation/clip_247/start_frame=0
1025 | animation/clip_247/end_frame=0
1026 | animation/clip_247/loops=false
1027 | animation/clip_248/name=""
1028 | animation/clip_248/start_frame=0
1029 | animation/clip_248/end_frame=0
1030 | animation/clip_248/loops=false
1031 | animation/clip_249/name=""
1032 | animation/clip_249/start_frame=0
1033 | animation/clip_249/end_frame=0
1034 | animation/clip_249/loops=false
1035 | animation/clip_250/name=""
1036 | animation/clip_250/start_frame=0
1037 | animation/clip_250/end_frame=0
1038 | animation/clip_250/loops=false
1039 | animation/clip_251/name=""
1040 | animation/clip_251/start_frame=0
1041 | animation/clip_251/end_frame=0
1042 | animation/clip_251/loops=false
1043 | animation/clip_252/name=""
1044 | animation/clip_252/start_frame=0
1045 | animation/clip_252/end_frame=0
1046 | animation/clip_252/loops=false
1047 | animation/clip_253/name=""
1048 | animation/clip_253/start_frame=0
1049 | animation/clip_253/end_frame=0
1050 | animation/clip_253/loops=false
1051 | animation/clip_254/name=""
1052 | animation/clip_254/start_frame=0
1053 | animation/clip_254/end_frame=0
1054 | animation/clip_254/loops=false
1055 | animation/clip_255/name=""
1056 | animation/clip_255/start_frame=0
1057 | animation/clip_255/end_frame=0
1058 | animation/clip_255/loops=false
1059 | animation/clip_256/name=""
1060 | animation/clip_256/start_frame=0
1061 | animation/clip_256/end_frame=0
1062 | animation/clip_256/loops=false
1063 |
--------------------------------------------------------------------------------
/godot-csharp/assets/3d/level/playground.glb.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="scene"
4 | type="PackedScene"
5 | path="res://.import/playground.glb-ba79c34a960241f3655c817855b40b06.scn"
6 |
7 | [deps]
8 |
9 | source_file="res://assets/3d/level/playground.glb"
10 | dest_files=[ "res://.import/playground.glb-ba79c34a960241f3655c817855b40b06.scn" ]
11 |
12 | [params]
13 |
14 | nodes/root_type="Spatial"
15 | nodes/root_name="Scene Root"
16 | nodes/root_scale=1.0
17 | nodes/custom_script=""
18 | nodes/storage=0
19 | materials/location=1
20 | materials/storage=1
21 | materials/keep_on_reimport=true
22 | meshes/compress=true
23 | meshes/ensure_tangents=true
24 | meshes/storage=0
25 | meshes/light_baking=0
26 | meshes/lightmap_texel_size=0.1
27 | external_files/store_in_subdir=false
28 | animation/import=true
29 | animation/fps=15
30 | animation/filter_script=""
31 | animation/storage=false
32 | animation/keep_custom_tracks=false
33 | animation/optimizer/enabled=true
34 | animation/optimizer/max_linear_error=0.05
35 | animation/optimizer/max_angular_error=0.01
36 | animation/optimizer/max_angle=22
37 | animation/optimizer/remove_unused_tracks=true
38 | animation/clips/amount=0
39 | animation/clip_1/name=""
40 | animation/clip_1/start_frame=0
41 | animation/clip_1/end_frame=0
42 | animation/clip_1/loops=false
43 | animation/clip_2/name=""
44 | animation/clip_2/start_frame=0
45 | animation/clip_2/end_frame=0
46 | animation/clip_2/loops=false
47 | animation/clip_3/name=""
48 | animation/clip_3/start_frame=0
49 | animation/clip_3/end_frame=0
50 | animation/clip_3/loops=false
51 | animation/clip_4/name=""
52 | animation/clip_4/start_frame=0
53 | animation/clip_4/end_frame=0
54 | animation/clip_4/loops=false
55 | animation/clip_5/name=""
56 | animation/clip_5/start_frame=0
57 | animation/clip_5/end_frame=0
58 | animation/clip_5/loops=false
59 | animation/clip_6/name=""
60 | animation/clip_6/start_frame=0
61 | animation/clip_6/end_frame=0
62 | animation/clip_6/loops=false
63 | animation/clip_7/name=""
64 | animation/clip_7/start_frame=0
65 | animation/clip_7/end_frame=0
66 | animation/clip_7/loops=false
67 | animation/clip_8/name=""
68 | animation/clip_8/start_frame=0
69 | animation/clip_8/end_frame=0
70 | animation/clip_8/loops=false
71 | animation/clip_9/name=""
72 | animation/clip_9/start_frame=0
73 | animation/clip_9/end_frame=0
74 | animation/clip_9/loops=false
75 | animation/clip_10/name=""
76 | animation/clip_10/start_frame=0
77 | animation/clip_10/end_frame=0
78 | animation/clip_10/loops=false
79 | animation/clip_11/name=""
80 | animation/clip_11/start_frame=0
81 | animation/clip_11/end_frame=0
82 | animation/clip_11/loops=false
83 | animation/clip_12/name=""
84 | animation/clip_12/start_frame=0
85 | animation/clip_12/end_frame=0
86 | animation/clip_12/loops=false
87 | animation/clip_13/name=""
88 | animation/clip_13/start_frame=0
89 | animation/clip_13/end_frame=0
90 | animation/clip_13/loops=false
91 | animation/clip_14/name=""
92 | animation/clip_14/start_frame=0
93 | animation/clip_14/end_frame=0
94 | animation/clip_14/loops=false
95 | animation/clip_15/name=""
96 | animation/clip_15/start_frame=0
97 | animation/clip_15/end_frame=0
98 | animation/clip_15/loops=false
99 | animation/clip_16/name=""
100 | animation/clip_16/start_frame=0
101 | animation/clip_16/end_frame=0
102 | animation/clip_16/loops=false
103 | animation/clip_17/name=""
104 | animation/clip_17/start_frame=0
105 | animation/clip_17/end_frame=0
106 | animation/clip_17/loops=false
107 | animation/clip_18/name=""
108 | animation/clip_18/start_frame=0
109 | animation/clip_18/end_frame=0
110 | animation/clip_18/loops=false
111 | animation/clip_19/name=""
112 | animation/clip_19/start_frame=0
113 | animation/clip_19/end_frame=0
114 | animation/clip_19/loops=false
115 | animation/clip_20/name=""
116 | animation/clip_20/start_frame=0
117 | animation/clip_20/end_frame=0
118 | animation/clip_20/loops=false
119 | animation/clip_21/name=""
120 | animation/clip_21/start_frame=0
121 | animation/clip_21/end_frame=0
122 | animation/clip_21/loops=false
123 | animation/clip_22/name=""
124 | animation/clip_22/start_frame=0
125 | animation/clip_22/end_frame=0
126 | animation/clip_22/loops=false
127 | animation/clip_23/name=""
128 | animation/clip_23/start_frame=0
129 | animation/clip_23/end_frame=0
130 | animation/clip_23/loops=false
131 | animation/clip_24/name=""
132 | animation/clip_24/start_frame=0
133 | animation/clip_24/end_frame=0
134 | animation/clip_24/loops=false
135 | animation/clip_25/name=""
136 | animation/clip_25/start_frame=0
137 | animation/clip_25/end_frame=0
138 | animation/clip_25/loops=false
139 | animation/clip_26/name=""
140 | animation/clip_26/start_frame=0
141 | animation/clip_26/end_frame=0
142 | animation/clip_26/loops=false
143 | animation/clip_27/name=""
144 | animation/clip_27/start_frame=0
145 | animation/clip_27/end_frame=0
146 | animation/clip_27/loops=false
147 | animation/clip_28/name=""
148 | animation/clip_28/start_frame=0
149 | animation/clip_28/end_frame=0
150 | animation/clip_28/loops=false
151 | animation/clip_29/name=""
152 | animation/clip_29/start_frame=0
153 | animation/clip_29/end_frame=0
154 | animation/clip_29/loops=false
155 | animation/clip_30/name=""
156 | animation/clip_30/start_frame=0
157 | animation/clip_30/end_frame=0
158 | animation/clip_30/loops=false
159 | animation/clip_31/name=""
160 | animation/clip_31/start_frame=0
161 | animation/clip_31/end_frame=0
162 | animation/clip_31/loops=false
163 | animation/clip_32/name=""
164 | animation/clip_32/start_frame=0
165 | animation/clip_32/end_frame=0
166 | animation/clip_32/loops=false
167 | animation/clip_33/name=""
168 | animation/clip_33/start_frame=0
169 | animation/clip_33/end_frame=0
170 | animation/clip_33/loops=false
171 | animation/clip_34/name=""
172 | animation/clip_34/start_frame=0
173 | animation/clip_34/end_frame=0
174 | animation/clip_34/loops=false
175 | animation/clip_35/name=""
176 | animation/clip_35/start_frame=0
177 | animation/clip_35/end_frame=0
178 | animation/clip_35/loops=false
179 | animation/clip_36/name=""
180 | animation/clip_36/start_frame=0
181 | animation/clip_36/end_frame=0
182 | animation/clip_36/loops=false
183 | animation/clip_37/name=""
184 | animation/clip_37/start_frame=0
185 | animation/clip_37/end_frame=0
186 | animation/clip_37/loops=false
187 | animation/clip_38/name=""
188 | animation/clip_38/start_frame=0
189 | animation/clip_38/end_frame=0
190 | animation/clip_38/loops=false
191 | animation/clip_39/name=""
192 | animation/clip_39/start_frame=0
193 | animation/clip_39/end_frame=0
194 | animation/clip_39/loops=false
195 | animation/clip_40/name=""
196 | animation/clip_40/start_frame=0
197 | animation/clip_40/end_frame=0
198 | animation/clip_40/loops=false
199 | animation/clip_41/name=""
200 | animation/clip_41/start_frame=0
201 | animation/clip_41/end_frame=0
202 | animation/clip_41/loops=false
203 | animation/clip_42/name=""
204 | animation/clip_42/start_frame=0
205 | animation/clip_42/end_frame=0
206 | animation/clip_42/loops=false
207 | animation/clip_43/name=""
208 | animation/clip_43/start_frame=0
209 | animation/clip_43/end_frame=0
210 | animation/clip_43/loops=false
211 | animation/clip_44/name=""
212 | animation/clip_44/start_frame=0
213 | animation/clip_44/end_frame=0
214 | animation/clip_44/loops=false
215 | animation/clip_45/name=""
216 | animation/clip_45/start_frame=0
217 | animation/clip_45/end_frame=0
218 | animation/clip_45/loops=false
219 | animation/clip_46/name=""
220 | animation/clip_46/start_frame=0
221 | animation/clip_46/end_frame=0
222 | animation/clip_46/loops=false
223 | animation/clip_47/name=""
224 | animation/clip_47/start_frame=0
225 | animation/clip_47/end_frame=0
226 | animation/clip_47/loops=false
227 | animation/clip_48/name=""
228 | animation/clip_48/start_frame=0
229 | animation/clip_48/end_frame=0
230 | animation/clip_48/loops=false
231 | animation/clip_49/name=""
232 | animation/clip_49/start_frame=0
233 | animation/clip_49/end_frame=0
234 | animation/clip_49/loops=false
235 | animation/clip_50/name=""
236 | animation/clip_50/start_frame=0
237 | animation/clip_50/end_frame=0
238 | animation/clip_50/loops=false
239 | animation/clip_51/name=""
240 | animation/clip_51/start_frame=0
241 | animation/clip_51/end_frame=0
242 | animation/clip_51/loops=false
243 | animation/clip_52/name=""
244 | animation/clip_52/start_frame=0
245 | animation/clip_52/end_frame=0
246 | animation/clip_52/loops=false
247 | animation/clip_53/name=""
248 | animation/clip_53/start_frame=0
249 | animation/clip_53/end_frame=0
250 | animation/clip_53/loops=false
251 | animation/clip_54/name=""
252 | animation/clip_54/start_frame=0
253 | animation/clip_54/end_frame=0
254 | animation/clip_54/loops=false
255 | animation/clip_55/name=""
256 | animation/clip_55/start_frame=0
257 | animation/clip_55/end_frame=0
258 | animation/clip_55/loops=false
259 | animation/clip_56/name=""
260 | animation/clip_56/start_frame=0
261 | animation/clip_56/end_frame=0
262 | animation/clip_56/loops=false
263 | animation/clip_57/name=""
264 | animation/clip_57/start_frame=0
265 | animation/clip_57/end_frame=0
266 | animation/clip_57/loops=false
267 | animation/clip_58/name=""
268 | animation/clip_58/start_frame=0
269 | animation/clip_58/end_frame=0
270 | animation/clip_58/loops=false
271 | animation/clip_59/name=""
272 | animation/clip_59/start_frame=0
273 | animation/clip_59/end_frame=0
274 | animation/clip_59/loops=false
275 | animation/clip_60/name=""
276 | animation/clip_60/start_frame=0
277 | animation/clip_60/end_frame=0
278 | animation/clip_60/loops=false
279 | animation/clip_61/name=""
280 | animation/clip_61/start_frame=0
281 | animation/clip_61/end_frame=0
282 | animation/clip_61/loops=false
283 | animation/clip_62/name=""
284 | animation/clip_62/start_frame=0
285 | animation/clip_62/end_frame=0
286 | animation/clip_62/loops=false
287 | animation/clip_63/name=""
288 | animation/clip_63/start_frame=0
289 | animation/clip_63/end_frame=0
290 | animation/clip_63/loops=false
291 | animation/clip_64/name=""
292 | animation/clip_64/start_frame=0
293 | animation/clip_64/end_frame=0
294 | animation/clip_64/loops=false
295 | animation/clip_65/name=""
296 | animation/clip_65/start_frame=0
297 | animation/clip_65/end_frame=0
298 | animation/clip_65/loops=false
299 | animation/clip_66/name=""
300 | animation/clip_66/start_frame=0
301 | animation/clip_66/end_frame=0
302 | animation/clip_66/loops=false
303 | animation/clip_67/name=""
304 | animation/clip_67/start_frame=0
305 | animation/clip_67/end_frame=0
306 | animation/clip_67/loops=false
307 | animation/clip_68/name=""
308 | animation/clip_68/start_frame=0
309 | animation/clip_68/end_frame=0
310 | animation/clip_68/loops=false
311 | animation/clip_69/name=""
312 | animation/clip_69/start_frame=0
313 | animation/clip_69/end_frame=0
314 | animation/clip_69/loops=false
315 | animation/clip_70/name=""
316 | animation/clip_70/start_frame=0
317 | animation/clip_70/end_frame=0
318 | animation/clip_70/loops=false
319 | animation/clip_71/name=""
320 | animation/clip_71/start_frame=0
321 | animation/clip_71/end_frame=0
322 | animation/clip_71/loops=false
323 | animation/clip_72/name=""
324 | animation/clip_72/start_frame=0
325 | animation/clip_72/end_frame=0
326 | animation/clip_72/loops=false
327 | animation/clip_73/name=""
328 | animation/clip_73/start_frame=0
329 | animation/clip_73/end_frame=0
330 | animation/clip_73/loops=false
331 | animation/clip_74/name=""
332 | animation/clip_74/start_frame=0
333 | animation/clip_74/end_frame=0
334 | animation/clip_74/loops=false
335 | animation/clip_75/name=""
336 | animation/clip_75/start_frame=0
337 | animation/clip_75/end_frame=0
338 | animation/clip_75/loops=false
339 | animation/clip_76/name=""
340 | animation/clip_76/start_frame=0
341 | animation/clip_76/end_frame=0
342 | animation/clip_76/loops=false
343 | animation/clip_77/name=""
344 | animation/clip_77/start_frame=0
345 | animation/clip_77/end_frame=0
346 | animation/clip_77/loops=false
347 | animation/clip_78/name=""
348 | animation/clip_78/start_frame=0
349 | animation/clip_78/end_frame=0
350 | animation/clip_78/loops=false
351 | animation/clip_79/name=""
352 | animation/clip_79/start_frame=0
353 | animation/clip_79/end_frame=0
354 | animation/clip_79/loops=false
355 | animation/clip_80/name=""
356 | animation/clip_80/start_frame=0
357 | animation/clip_80/end_frame=0
358 | animation/clip_80/loops=false
359 | animation/clip_81/name=""
360 | animation/clip_81/start_frame=0
361 | animation/clip_81/end_frame=0
362 | animation/clip_81/loops=false
363 | animation/clip_82/name=""
364 | animation/clip_82/start_frame=0
365 | animation/clip_82/end_frame=0
366 | animation/clip_82/loops=false
367 | animation/clip_83/name=""
368 | animation/clip_83/start_frame=0
369 | animation/clip_83/end_frame=0
370 | animation/clip_83/loops=false
371 | animation/clip_84/name=""
372 | animation/clip_84/start_frame=0
373 | animation/clip_84/end_frame=0
374 | animation/clip_84/loops=false
375 | animation/clip_85/name=""
376 | animation/clip_85/start_frame=0
377 | animation/clip_85/end_frame=0
378 | animation/clip_85/loops=false
379 | animation/clip_86/name=""
380 | animation/clip_86/start_frame=0
381 | animation/clip_86/end_frame=0
382 | animation/clip_86/loops=false
383 | animation/clip_87/name=""
384 | animation/clip_87/start_frame=0
385 | animation/clip_87/end_frame=0
386 | animation/clip_87/loops=false
387 | animation/clip_88/name=""
388 | animation/clip_88/start_frame=0
389 | animation/clip_88/end_frame=0
390 | animation/clip_88/loops=false
391 | animation/clip_89/name=""
392 | animation/clip_89/start_frame=0
393 | animation/clip_89/end_frame=0
394 | animation/clip_89/loops=false
395 | animation/clip_90/name=""
396 | animation/clip_90/start_frame=0
397 | animation/clip_90/end_frame=0
398 | animation/clip_90/loops=false
399 | animation/clip_91/name=""
400 | animation/clip_91/start_frame=0
401 | animation/clip_91/end_frame=0
402 | animation/clip_91/loops=false
403 | animation/clip_92/name=""
404 | animation/clip_92/start_frame=0
405 | animation/clip_92/end_frame=0
406 | animation/clip_92/loops=false
407 | animation/clip_93/name=""
408 | animation/clip_93/start_frame=0
409 | animation/clip_93/end_frame=0
410 | animation/clip_93/loops=false
411 | animation/clip_94/name=""
412 | animation/clip_94/start_frame=0
413 | animation/clip_94/end_frame=0
414 | animation/clip_94/loops=false
415 | animation/clip_95/name=""
416 | animation/clip_95/start_frame=0
417 | animation/clip_95/end_frame=0
418 | animation/clip_95/loops=false
419 | animation/clip_96/name=""
420 | animation/clip_96/start_frame=0
421 | animation/clip_96/end_frame=0
422 | animation/clip_96/loops=false
423 | animation/clip_97/name=""
424 | animation/clip_97/start_frame=0
425 | animation/clip_97/end_frame=0
426 | animation/clip_97/loops=false
427 | animation/clip_98/name=""
428 | animation/clip_98/start_frame=0
429 | animation/clip_98/end_frame=0
430 | animation/clip_98/loops=false
431 | animation/clip_99/name=""
432 | animation/clip_99/start_frame=0
433 | animation/clip_99/end_frame=0
434 | animation/clip_99/loops=false
435 | animation/clip_100/name=""
436 | animation/clip_100/start_frame=0
437 | animation/clip_100/end_frame=0
438 | animation/clip_100/loops=false
439 | animation/clip_101/name=""
440 | animation/clip_101/start_frame=0
441 | animation/clip_101/end_frame=0
442 | animation/clip_101/loops=false
443 | animation/clip_102/name=""
444 | animation/clip_102/start_frame=0
445 | animation/clip_102/end_frame=0
446 | animation/clip_102/loops=false
447 | animation/clip_103/name=""
448 | animation/clip_103/start_frame=0
449 | animation/clip_103/end_frame=0
450 | animation/clip_103/loops=false
451 | animation/clip_104/name=""
452 | animation/clip_104/start_frame=0
453 | animation/clip_104/end_frame=0
454 | animation/clip_104/loops=false
455 | animation/clip_105/name=""
456 | animation/clip_105/start_frame=0
457 | animation/clip_105/end_frame=0
458 | animation/clip_105/loops=false
459 | animation/clip_106/name=""
460 | animation/clip_106/start_frame=0
461 | animation/clip_106/end_frame=0
462 | animation/clip_106/loops=false
463 | animation/clip_107/name=""
464 | animation/clip_107/start_frame=0
465 | animation/clip_107/end_frame=0
466 | animation/clip_107/loops=false
467 | animation/clip_108/name=""
468 | animation/clip_108/start_frame=0
469 | animation/clip_108/end_frame=0
470 | animation/clip_108/loops=false
471 | animation/clip_109/name=""
472 | animation/clip_109/start_frame=0
473 | animation/clip_109/end_frame=0
474 | animation/clip_109/loops=false
475 | animation/clip_110/name=""
476 | animation/clip_110/start_frame=0
477 | animation/clip_110/end_frame=0
478 | animation/clip_110/loops=false
479 | animation/clip_111/name=""
480 | animation/clip_111/start_frame=0
481 | animation/clip_111/end_frame=0
482 | animation/clip_111/loops=false
483 | animation/clip_112/name=""
484 | animation/clip_112/start_frame=0
485 | animation/clip_112/end_frame=0
486 | animation/clip_112/loops=false
487 | animation/clip_113/name=""
488 | animation/clip_113/start_frame=0
489 | animation/clip_113/end_frame=0
490 | animation/clip_113/loops=false
491 | animation/clip_114/name=""
492 | animation/clip_114/start_frame=0
493 | animation/clip_114/end_frame=0
494 | animation/clip_114/loops=false
495 | animation/clip_115/name=""
496 | animation/clip_115/start_frame=0
497 | animation/clip_115/end_frame=0
498 | animation/clip_115/loops=false
499 | animation/clip_116/name=""
500 | animation/clip_116/start_frame=0
501 | animation/clip_116/end_frame=0
502 | animation/clip_116/loops=false
503 | animation/clip_117/name=""
504 | animation/clip_117/start_frame=0
505 | animation/clip_117/end_frame=0
506 | animation/clip_117/loops=false
507 | animation/clip_118/name=""
508 | animation/clip_118/start_frame=0
509 | animation/clip_118/end_frame=0
510 | animation/clip_118/loops=false
511 | animation/clip_119/name=""
512 | animation/clip_119/start_frame=0
513 | animation/clip_119/end_frame=0
514 | animation/clip_119/loops=false
515 | animation/clip_120/name=""
516 | animation/clip_120/start_frame=0
517 | animation/clip_120/end_frame=0
518 | animation/clip_120/loops=false
519 | animation/clip_121/name=""
520 | animation/clip_121/start_frame=0
521 | animation/clip_121/end_frame=0
522 | animation/clip_121/loops=false
523 | animation/clip_122/name=""
524 | animation/clip_122/start_frame=0
525 | animation/clip_122/end_frame=0
526 | animation/clip_122/loops=false
527 | animation/clip_123/name=""
528 | animation/clip_123/start_frame=0
529 | animation/clip_123/end_frame=0
530 | animation/clip_123/loops=false
531 | animation/clip_124/name=""
532 | animation/clip_124/start_frame=0
533 | animation/clip_124/end_frame=0
534 | animation/clip_124/loops=false
535 | animation/clip_125/name=""
536 | animation/clip_125/start_frame=0
537 | animation/clip_125/end_frame=0
538 | animation/clip_125/loops=false
539 | animation/clip_126/name=""
540 | animation/clip_126/start_frame=0
541 | animation/clip_126/end_frame=0
542 | animation/clip_126/loops=false
543 | animation/clip_127/name=""
544 | animation/clip_127/start_frame=0
545 | animation/clip_127/end_frame=0
546 | animation/clip_127/loops=false
547 | animation/clip_128/name=""
548 | animation/clip_128/start_frame=0
549 | animation/clip_128/end_frame=0
550 | animation/clip_128/loops=false
551 | animation/clip_129/name=""
552 | animation/clip_129/start_frame=0
553 | animation/clip_129/end_frame=0
554 | animation/clip_129/loops=false
555 | animation/clip_130/name=""
556 | animation/clip_130/start_frame=0
557 | animation/clip_130/end_frame=0
558 | animation/clip_130/loops=false
559 | animation/clip_131/name=""
560 | animation/clip_131/start_frame=0
561 | animation/clip_131/end_frame=0
562 | animation/clip_131/loops=false
563 | animation/clip_132/name=""
564 | animation/clip_132/start_frame=0
565 | animation/clip_132/end_frame=0
566 | animation/clip_132/loops=false
567 | animation/clip_133/name=""
568 | animation/clip_133/start_frame=0
569 | animation/clip_133/end_frame=0
570 | animation/clip_133/loops=false
571 | animation/clip_134/name=""
572 | animation/clip_134/start_frame=0
573 | animation/clip_134/end_frame=0
574 | animation/clip_134/loops=false
575 | animation/clip_135/name=""
576 | animation/clip_135/start_frame=0
577 | animation/clip_135/end_frame=0
578 | animation/clip_135/loops=false
579 | animation/clip_136/name=""
580 | animation/clip_136/start_frame=0
581 | animation/clip_136/end_frame=0
582 | animation/clip_136/loops=false
583 | animation/clip_137/name=""
584 | animation/clip_137/start_frame=0
585 | animation/clip_137/end_frame=0
586 | animation/clip_137/loops=false
587 | animation/clip_138/name=""
588 | animation/clip_138/start_frame=0
589 | animation/clip_138/end_frame=0
590 | animation/clip_138/loops=false
591 | animation/clip_139/name=""
592 | animation/clip_139/start_frame=0
593 | animation/clip_139/end_frame=0
594 | animation/clip_139/loops=false
595 | animation/clip_140/name=""
596 | animation/clip_140/start_frame=0
597 | animation/clip_140/end_frame=0
598 | animation/clip_140/loops=false
599 | animation/clip_141/name=""
600 | animation/clip_141/start_frame=0
601 | animation/clip_141/end_frame=0
602 | animation/clip_141/loops=false
603 | animation/clip_142/name=""
604 | animation/clip_142/start_frame=0
605 | animation/clip_142/end_frame=0
606 | animation/clip_142/loops=false
607 | animation/clip_143/name=""
608 | animation/clip_143/start_frame=0
609 | animation/clip_143/end_frame=0
610 | animation/clip_143/loops=false
611 | animation/clip_144/name=""
612 | animation/clip_144/start_frame=0
613 | animation/clip_144/end_frame=0
614 | animation/clip_144/loops=false
615 | animation/clip_145/name=""
616 | animation/clip_145/start_frame=0
617 | animation/clip_145/end_frame=0
618 | animation/clip_145/loops=false
619 | animation/clip_146/name=""
620 | animation/clip_146/start_frame=0
621 | animation/clip_146/end_frame=0
622 | animation/clip_146/loops=false
623 | animation/clip_147/name=""
624 | animation/clip_147/start_frame=0
625 | animation/clip_147/end_frame=0
626 | animation/clip_147/loops=false
627 | animation/clip_148/name=""
628 | animation/clip_148/start_frame=0
629 | animation/clip_148/end_frame=0
630 | animation/clip_148/loops=false
631 | animation/clip_149/name=""
632 | animation/clip_149/start_frame=0
633 | animation/clip_149/end_frame=0
634 | animation/clip_149/loops=false
635 | animation/clip_150/name=""
636 | animation/clip_150/start_frame=0
637 | animation/clip_150/end_frame=0
638 | animation/clip_150/loops=false
639 | animation/clip_151/name=""
640 | animation/clip_151/start_frame=0
641 | animation/clip_151/end_frame=0
642 | animation/clip_151/loops=false
643 | animation/clip_152/name=""
644 | animation/clip_152/start_frame=0
645 | animation/clip_152/end_frame=0
646 | animation/clip_152/loops=false
647 | animation/clip_153/name=""
648 | animation/clip_153/start_frame=0
649 | animation/clip_153/end_frame=0
650 | animation/clip_153/loops=false
651 | animation/clip_154/name=""
652 | animation/clip_154/start_frame=0
653 | animation/clip_154/end_frame=0
654 | animation/clip_154/loops=false
655 | animation/clip_155/name=""
656 | animation/clip_155/start_frame=0
657 | animation/clip_155/end_frame=0
658 | animation/clip_155/loops=false
659 | animation/clip_156/name=""
660 | animation/clip_156/start_frame=0
661 | animation/clip_156/end_frame=0
662 | animation/clip_156/loops=false
663 | animation/clip_157/name=""
664 | animation/clip_157/start_frame=0
665 | animation/clip_157/end_frame=0
666 | animation/clip_157/loops=false
667 | animation/clip_158/name=""
668 | animation/clip_158/start_frame=0
669 | animation/clip_158/end_frame=0
670 | animation/clip_158/loops=false
671 | animation/clip_159/name=""
672 | animation/clip_159/start_frame=0
673 | animation/clip_159/end_frame=0
674 | animation/clip_159/loops=false
675 | animation/clip_160/name=""
676 | animation/clip_160/start_frame=0
677 | animation/clip_160/end_frame=0
678 | animation/clip_160/loops=false
679 | animation/clip_161/name=""
680 | animation/clip_161/start_frame=0
681 | animation/clip_161/end_frame=0
682 | animation/clip_161/loops=false
683 | animation/clip_162/name=""
684 | animation/clip_162/start_frame=0
685 | animation/clip_162/end_frame=0
686 | animation/clip_162/loops=false
687 | animation/clip_163/name=""
688 | animation/clip_163/start_frame=0
689 | animation/clip_163/end_frame=0
690 | animation/clip_163/loops=false
691 | animation/clip_164/name=""
692 | animation/clip_164/start_frame=0
693 | animation/clip_164/end_frame=0
694 | animation/clip_164/loops=false
695 | animation/clip_165/name=""
696 | animation/clip_165/start_frame=0
697 | animation/clip_165/end_frame=0
698 | animation/clip_165/loops=false
699 | animation/clip_166/name=""
700 | animation/clip_166/start_frame=0
701 | animation/clip_166/end_frame=0
702 | animation/clip_166/loops=false
703 | animation/clip_167/name=""
704 | animation/clip_167/start_frame=0
705 | animation/clip_167/end_frame=0
706 | animation/clip_167/loops=false
707 | animation/clip_168/name=""
708 | animation/clip_168/start_frame=0
709 | animation/clip_168/end_frame=0
710 | animation/clip_168/loops=false
711 | animation/clip_169/name=""
712 | animation/clip_169/start_frame=0
713 | animation/clip_169/end_frame=0
714 | animation/clip_169/loops=false
715 | animation/clip_170/name=""
716 | animation/clip_170/start_frame=0
717 | animation/clip_170/end_frame=0
718 | animation/clip_170/loops=false
719 | animation/clip_171/name=""
720 | animation/clip_171/start_frame=0
721 | animation/clip_171/end_frame=0
722 | animation/clip_171/loops=false
723 | animation/clip_172/name=""
724 | animation/clip_172/start_frame=0
725 | animation/clip_172/end_frame=0
726 | animation/clip_172/loops=false
727 | animation/clip_173/name=""
728 | animation/clip_173/start_frame=0
729 | animation/clip_173/end_frame=0
730 | animation/clip_173/loops=false
731 | animation/clip_174/name=""
732 | animation/clip_174/start_frame=0
733 | animation/clip_174/end_frame=0
734 | animation/clip_174/loops=false
735 | animation/clip_175/name=""
736 | animation/clip_175/start_frame=0
737 | animation/clip_175/end_frame=0
738 | animation/clip_175/loops=false
739 | animation/clip_176/name=""
740 | animation/clip_176/start_frame=0
741 | animation/clip_176/end_frame=0
742 | animation/clip_176/loops=false
743 | animation/clip_177/name=""
744 | animation/clip_177/start_frame=0
745 | animation/clip_177/end_frame=0
746 | animation/clip_177/loops=false
747 | animation/clip_178/name=""
748 | animation/clip_178/start_frame=0
749 | animation/clip_178/end_frame=0
750 | animation/clip_178/loops=false
751 | animation/clip_179/name=""
752 | animation/clip_179/start_frame=0
753 | animation/clip_179/end_frame=0
754 | animation/clip_179/loops=false
755 | animation/clip_180/name=""
756 | animation/clip_180/start_frame=0
757 | animation/clip_180/end_frame=0
758 | animation/clip_180/loops=false
759 | animation/clip_181/name=""
760 | animation/clip_181/start_frame=0
761 | animation/clip_181/end_frame=0
762 | animation/clip_181/loops=false
763 | animation/clip_182/name=""
764 | animation/clip_182/start_frame=0
765 | animation/clip_182/end_frame=0
766 | animation/clip_182/loops=false
767 | animation/clip_183/name=""
768 | animation/clip_183/start_frame=0
769 | animation/clip_183/end_frame=0
770 | animation/clip_183/loops=false
771 | animation/clip_184/name=""
772 | animation/clip_184/start_frame=0
773 | animation/clip_184/end_frame=0
774 | animation/clip_184/loops=false
775 | animation/clip_185/name=""
776 | animation/clip_185/start_frame=0
777 | animation/clip_185/end_frame=0
778 | animation/clip_185/loops=false
779 | animation/clip_186/name=""
780 | animation/clip_186/start_frame=0
781 | animation/clip_186/end_frame=0
782 | animation/clip_186/loops=false
783 | animation/clip_187/name=""
784 | animation/clip_187/start_frame=0
785 | animation/clip_187/end_frame=0
786 | animation/clip_187/loops=false
787 | animation/clip_188/name=""
788 | animation/clip_188/start_frame=0
789 | animation/clip_188/end_frame=0
790 | animation/clip_188/loops=false
791 | animation/clip_189/name=""
792 | animation/clip_189/start_frame=0
793 | animation/clip_189/end_frame=0
794 | animation/clip_189/loops=false
795 | animation/clip_190/name=""
796 | animation/clip_190/start_frame=0
797 | animation/clip_190/end_frame=0
798 | animation/clip_190/loops=false
799 | animation/clip_191/name=""
800 | animation/clip_191/start_frame=0
801 | animation/clip_191/end_frame=0
802 | animation/clip_191/loops=false
803 | animation/clip_192/name=""
804 | animation/clip_192/start_frame=0
805 | animation/clip_192/end_frame=0
806 | animation/clip_192/loops=false
807 | animation/clip_193/name=""
808 | animation/clip_193/start_frame=0
809 | animation/clip_193/end_frame=0
810 | animation/clip_193/loops=false
811 | animation/clip_194/name=""
812 | animation/clip_194/start_frame=0
813 | animation/clip_194/end_frame=0
814 | animation/clip_194/loops=false
815 | animation/clip_195/name=""
816 | animation/clip_195/start_frame=0
817 | animation/clip_195/end_frame=0
818 | animation/clip_195/loops=false
819 | animation/clip_196/name=""
820 | animation/clip_196/start_frame=0
821 | animation/clip_196/end_frame=0
822 | animation/clip_196/loops=false
823 | animation/clip_197/name=""
824 | animation/clip_197/start_frame=0
825 | animation/clip_197/end_frame=0
826 | animation/clip_197/loops=false
827 | animation/clip_198/name=""
828 | animation/clip_198/start_frame=0
829 | animation/clip_198/end_frame=0
830 | animation/clip_198/loops=false
831 | animation/clip_199/name=""
832 | animation/clip_199/start_frame=0
833 | animation/clip_199/end_frame=0
834 | animation/clip_199/loops=false
835 | animation/clip_200/name=""
836 | animation/clip_200/start_frame=0
837 | animation/clip_200/end_frame=0
838 | animation/clip_200/loops=false
839 | animation/clip_201/name=""
840 | animation/clip_201/start_frame=0
841 | animation/clip_201/end_frame=0
842 | animation/clip_201/loops=false
843 | animation/clip_202/name=""
844 | animation/clip_202/start_frame=0
845 | animation/clip_202/end_frame=0
846 | animation/clip_202/loops=false
847 | animation/clip_203/name=""
848 | animation/clip_203/start_frame=0
849 | animation/clip_203/end_frame=0
850 | animation/clip_203/loops=false
851 | animation/clip_204/name=""
852 | animation/clip_204/start_frame=0
853 | animation/clip_204/end_frame=0
854 | animation/clip_204/loops=false
855 | animation/clip_205/name=""
856 | animation/clip_205/start_frame=0
857 | animation/clip_205/end_frame=0
858 | animation/clip_205/loops=false
859 | animation/clip_206/name=""
860 | animation/clip_206/start_frame=0
861 | animation/clip_206/end_frame=0
862 | animation/clip_206/loops=false
863 | animation/clip_207/name=""
864 | animation/clip_207/start_frame=0
865 | animation/clip_207/end_frame=0
866 | animation/clip_207/loops=false
867 | animation/clip_208/name=""
868 | animation/clip_208/start_frame=0
869 | animation/clip_208/end_frame=0
870 | animation/clip_208/loops=false
871 | animation/clip_209/name=""
872 | animation/clip_209/start_frame=0
873 | animation/clip_209/end_frame=0
874 | animation/clip_209/loops=false
875 | animation/clip_210/name=""
876 | animation/clip_210/start_frame=0
877 | animation/clip_210/end_frame=0
878 | animation/clip_210/loops=false
879 | animation/clip_211/name=""
880 | animation/clip_211/start_frame=0
881 | animation/clip_211/end_frame=0
882 | animation/clip_211/loops=false
883 | animation/clip_212/name=""
884 | animation/clip_212/start_frame=0
885 | animation/clip_212/end_frame=0
886 | animation/clip_212/loops=false
887 | animation/clip_213/name=""
888 | animation/clip_213/start_frame=0
889 | animation/clip_213/end_frame=0
890 | animation/clip_213/loops=false
891 | animation/clip_214/name=""
892 | animation/clip_214/start_frame=0
893 | animation/clip_214/end_frame=0
894 | animation/clip_214/loops=false
895 | animation/clip_215/name=""
896 | animation/clip_215/start_frame=0
897 | animation/clip_215/end_frame=0
898 | animation/clip_215/loops=false
899 | animation/clip_216/name=""
900 | animation/clip_216/start_frame=0
901 | animation/clip_216/end_frame=0
902 | animation/clip_216/loops=false
903 | animation/clip_217/name=""
904 | animation/clip_217/start_frame=0
905 | animation/clip_217/end_frame=0
906 | animation/clip_217/loops=false
907 | animation/clip_218/name=""
908 | animation/clip_218/start_frame=0
909 | animation/clip_218/end_frame=0
910 | animation/clip_218/loops=false
911 | animation/clip_219/name=""
912 | animation/clip_219/start_frame=0
913 | animation/clip_219/end_frame=0
914 | animation/clip_219/loops=false
915 | animation/clip_220/name=""
916 | animation/clip_220/start_frame=0
917 | animation/clip_220/end_frame=0
918 | animation/clip_220/loops=false
919 | animation/clip_221/name=""
920 | animation/clip_221/start_frame=0
921 | animation/clip_221/end_frame=0
922 | animation/clip_221/loops=false
923 | animation/clip_222/name=""
924 | animation/clip_222/start_frame=0
925 | animation/clip_222/end_frame=0
926 | animation/clip_222/loops=false
927 | animation/clip_223/name=""
928 | animation/clip_223/start_frame=0
929 | animation/clip_223/end_frame=0
930 | animation/clip_223/loops=false
931 | animation/clip_224/name=""
932 | animation/clip_224/start_frame=0
933 | animation/clip_224/end_frame=0
934 | animation/clip_224/loops=false
935 | animation/clip_225/name=""
936 | animation/clip_225/start_frame=0
937 | animation/clip_225/end_frame=0
938 | animation/clip_225/loops=false
939 | animation/clip_226/name=""
940 | animation/clip_226/start_frame=0
941 | animation/clip_226/end_frame=0
942 | animation/clip_226/loops=false
943 | animation/clip_227/name=""
944 | animation/clip_227/start_frame=0
945 | animation/clip_227/end_frame=0
946 | animation/clip_227/loops=false
947 | animation/clip_228/name=""
948 | animation/clip_228/start_frame=0
949 | animation/clip_228/end_frame=0
950 | animation/clip_228/loops=false
951 | animation/clip_229/name=""
952 | animation/clip_229/start_frame=0
953 | animation/clip_229/end_frame=0
954 | animation/clip_229/loops=false
955 | animation/clip_230/name=""
956 | animation/clip_230/start_frame=0
957 | animation/clip_230/end_frame=0
958 | animation/clip_230/loops=false
959 | animation/clip_231/name=""
960 | animation/clip_231/start_frame=0
961 | animation/clip_231/end_frame=0
962 | animation/clip_231/loops=false
963 | animation/clip_232/name=""
964 | animation/clip_232/start_frame=0
965 | animation/clip_232/end_frame=0
966 | animation/clip_232/loops=false
967 | animation/clip_233/name=""
968 | animation/clip_233/start_frame=0
969 | animation/clip_233/end_frame=0
970 | animation/clip_233/loops=false
971 | animation/clip_234/name=""
972 | animation/clip_234/start_frame=0
973 | animation/clip_234/end_frame=0
974 | animation/clip_234/loops=false
975 | animation/clip_235/name=""
976 | animation/clip_235/start_frame=0
977 | animation/clip_235/end_frame=0
978 | animation/clip_235/loops=false
979 | animation/clip_236/name=""
980 | animation/clip_236/start_frame=0
981 | animation/clip_236/end_frame=0
982 | animation/clip_236/loops=false
983 | animation/clip_237/name=""
984 | animation/clip_237/start_frame=0
985 | animation/clip_237/end_frame=0
986 | animation/clip_237/loops=false
987 | animation/clip_238/name=""
988 | animation/clip_238/start_frame=0
989 | animation/clip_238/end_frame=0
990 | animation/clip_238/loops=false
991 | animation/clip_239/name=""
992 | animation/clip_239/start_frame=0
993 | animation/clip_239/end_frame=0
994 | animation/clip_239/loops=false
995 | animation/clip_240/name=""
996 | animation/clip_240/start_frame=0
997 | animation/clip_240/end_frame=0
998 | animation/clip_240/loops=false
999 | animation/clip_241/name=""
1000 | animation/clip_241/start_frame=0
1001 | animation/clip_241/end_frame=0
1002 | animation/clip_241/loops=false
1003 | animation/clip_242/name=""
1004 | animation/clip_242/start_frame=0
1005 | animation/clip_242/end_frame=0
1006 | animation/clip_242/loops=false
1007 | animation/clip_243/name=""
1008 | animation/clip_243/start_frame=0
1009 | animation/clip_243/end_frame=0
1010 | animation/clip_243/loops=false
1011 | animation/clip_244/name=""
1012 | animation/clip_244/start_frame=0
1013 | animation/clip_244/end_frame=0
1014 | animation/clip_244/loops=false
1015 | animation/clip_245/name=""
1016 | animation/clip_245/start_frame=0
1017 | animation/clip_245/end_frame=0
1018 | animation/clip_245/loops=false
1019 | animation/clip_246/name=""
1020 | animation/clip_246/start_frame=0
1021 | animation/clip_246/end_frame=0
1022 | animation/clip_246/loops=false
1023 | animation/clip_247/name=""
1024 | animation/clip_247/start_frame=0
1025 | animation/clip_247/end_frame=0
1026 | animation/clip_247/loops=false
1027 | animation/clip_248/name=""
1028 | animation/clip_248/start_frame=0
1029 | animation/clip_248/end_frame=0
1030 | animation/clip_248/loops=false
1031 | animation/clip_249/name=""
1032 | animation/clip_249/start_frame=0
1033 | animation/clip_249/end_frame=0
1034 | animation/clip_249/loops=false
1035 | animation/clip_250/name=""
1036 | animation/clip_250/start_frame=0
1037 | animation/clip_250/end_frame=0
1038 | animation/clip_250/loops=false
1039 | animation/clip_251/name=""
1040 | animation/clip_251/start_frame=0
1041 | animation/clip_251/end_frame=0
1042 | animation/clip_251/loops=false
1043 | animation/clip_252/name=""
1044 | animation/clip_252/start_frame=0
1045 | animation/clip_252/end_frame=0
1046 | animation/clip_252/loops=false
1047 | animation/clip_253/name=""
1048 | animation/clip_253/start_frame=0
1049 | animation/clip_253/end_frame=0
1050 | animation/clip_253/loops=false
1051 | animation/clip_254/name=""
1052 | animation/clip_254/start_frame=0
1053 | animation/clip_254/end_frame=0
1054 | animation/clip_254/loops=false
1055 | animation/clip_255/name=""
1056 | animation/clip_255/start_frame=0
1057 | animation/clip_255/end_frame=0
1058 | animation/clip_255/loops=false
1059 | animation/clip_256/name=""
1060 | animation/clip_256/start_frame=0
1061 | animation/clip_256/end_frame=0
1062 | animation/clip_256/loops=false
1063 |
--------------------------------------------------------------------------------