├── .gitattributes ├── .gitignore ├── LICENSE.md ├── README.md ├── fonts ├── license.txt ├── lilita_one_regular.ttf └── lilita_one_regular.ttf.import ├── htn ├── core │ ├── agent_sensors.gd │ ├── base_task.gd │ ├── compound_task.gd │ ├── plan_runner.gd │ ├── planner.gd │ ├── primitive_task.gd │ └── world_state.gd ├── sensors │ └── npc_sensors.gd └── tasks │ ├── compound │ ├── do_random_idle_actions.gd │ └── run_away_from_player.gd │ ├── domain │ └── be_npc.gd │ └── primitives │ ├── avoid_player.gd │ ├── go_to_target_position.gd │ ├── idle.gd │ ├── pick_flower.gd │ ├── play_jump_scare.gd │ ├── relax.gd │ ├── rest.gd │ ├── set_closest_coin_as_target.gd │ ├── set_random_position_as_target.gd │ └── watch_player.gd ├── icon.png ├── icon.png.import ├── meshes └── dust.res ├── models ├── Textures │ ├── colormap.png │ ├── colormap.png.import │ ├── colormap_npc.png │ └── colormap_npc.png.import ├── character.glb ├── character.glb.import ├── cloud.glb ├── cloud.glb.import ├── coin.glb ├── coin.glb.import ├── dust.glb ├── dust.glb.import ├── flag.glb ├── flag.glb.import ├── grass-small.glb ├── grass-small.glb.import ├── grass.glb ├── grass.glb.import ├── platform-falling.glb ├── platform-falling.glb.import ├── platform-grass-large-round.glb ├── platform-grass-large-round.glb.import ├── platform-large.glb ├── platform-large.glb.import ├── platform-medium.glb ├── platform-medium.glb.import ├── platform.glb └── platform.glb.import ├── objects ├── character.tscn ├── cloud.gd ├── cloud.tscn ├── coin.gd ├── coin.tscn ├── coin_spawner.gd ├── coin_spawner.tscn ├── npc.gd ├── npc.tscn ├── platform.tscn ├── platform_falling.gd ├── platform_falling.tscn ├── platform_grass_large_round.tscn ├── platform_medium.tscn └── player.tscn ├── project.godot ├── scenes ├── HTN_main.tscn ├── HTN_main_multiple_agents.tscn ├── main-environment.tres └── main.tscn ├── screenshots ├── .gdignore └── screenshot.png ├── script_templates ├── HTNAgentSensors │ └── agent_sensors_default.gd ├── HTNCompoundTask │ └── task_overrides.gd └── HTNTask │ └── task_overrides.gd ├── scripts ├── audio.gd ├── events.gd ├── hud.gd ├── player.gd └── view.gd ├── sounds ├── coin.ogg ├── coin.ogg.import ├── fall.ogg ├── fall.ogg.import ├── jump.ogg ├── jump.ogg.import ├── land.ogg ├── land.ogg.import ├── walking.ogg ├── walking.ogg.import └── walking.ogg.sfk ├── splash-screen.png ├── splash-screen.png.import ├── sprites ├── blob_shadow.png ├── blob_shadow.png.import ├── coin.png ├── coin.png.import ├── particle.png └── particle.png.import └── vector ├── .gdignore └── sprites.fla /.gitattributes: -------------------------------------------------------------------------------- 1 | # Normalize EOL for all files that Git considers text files. 2 | * text=auto eol=lf 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Godot 4+ specific ignores 2 | .godot/ 3 | 4 | # Godot-specific ignores 5 | .import/ 6 | export.cfg 7 | export_presets.cfg 8 | 9 | # Imported translations (automatically generated from CSV files) 10 | *.translation 11 | 12 | # Mono-specific ignores 13 | .mono/ 14 | data_*/ 15 | mono_crash.*.json 16 | 17 | # Kenney ignores 18 | build/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Kenney 4 | Copyright (c) 2024 Vinicius Gerevini 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hierarchical task network example in Godot 2 | 3 | This is the code source for my video on [Hierarchical Task Networks](https://youtu.be/Z7uU94yPfD4), a game AI pattern. 4 | 5 | In this project there is a NPC implementation with the following behaviour: 6 | 7 | - Roam 8 | - Look at player if too close 9 | - Get scared and run away if player jumps when close to them 10 | - Get tired after running away 3 times and rest for a bit 11 | - Collect coins when available 12 | 13 | This is a sample project to validate HTNs, but it's not supposed to be production ready. Even though it works, there are a few caveats to consider as mentioned in the video. 14 | 15 | By default, the project is going to run a scene with one NPC. You can run `HTN_main_multiple_agents.tscn` for a scene with multiple NPCs. 16 | 17 | For this project, I used Kenney's 3D Platformer Starter Kit: https://github.com/KenneyNL/Starter-Kit-3D-Platformer 18 | 19 | ## Contact 20 | 21 | I'm happy to chat about anything game dev and answer questions about my projects. Feel free to comment on the youtube video for questions and discussions about this project. 22 | 23 | Check my website for the latest contact info: https://thisisvini.com 24 | 25 | My youtube channel for game dev related stuff: https://www.youtube.com/@ThisIsVini 26 | 27 | Currently, you can find me here: 28 | - https://mastodon.gamedev.place/@thisisvini 29 | - https://x.com/vini_gerevini 30 | 31 | You can also open issues in this project, but keep in mind this is a sample, and even though I intend to keep it working, this is intended to be a demonstration for Godot 4 and I won't be expanding on it. Happy to chat about them though and discuss workarounds. 32 | -------------------------------------------------------------------------------- /fonts/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Juan Montoreano (juan@remolacha.biz), 2 | with Reserved Font Name Lilita 3 | 4 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 5 | This license is copied below, and is also available with a FAQ at: 6 | http://scripts.sil.org/OFL 7 | 8 | 9 | ----------------------------------------------------------- 10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 11 | ----------------------------------------------------------- 12 | 13 | PREAMBLE 14 | The goals of the Open Font License (OFL) are to stimulate worldwide 15 | development of collaborative font projects, to support the font creation 16 | efforts of academic and linguistic communities, and to provide a free and 17 | open framework in which fonts may be shared and improved in partnership 18 | with others. 19 | 20 | The OFL allows the licensed fonts to be used, studied, modified and 21 | redistributed freely as long as they are not sold by themselves. The 22 | fonts, including any derivative works, can be bundled, embedded, 23 | redistributed and/or sold with any software provided that any reserved 24 | names are not used by derivative works. The fonts and derivatives, 25 | however, cannot be released under any other type of license. The 26 | requirement for fonts to remain under this license does not apply 27 | to any document created using the fonts or their derivatives. 28 | 29 | DEFINITIONS 30 | "Font Software" refers to the set of files released by the Copyright 31 | Holder(s) under this license and clearly marked as such. This may 32 | include source files, build scripts and documentation. 33 | 34 | "Reserved Font Name" refers to any names specified as such after the 35 | copyright statement(s). 36 | 37 | "Original Version" refers to the collection of Font Software components as 38 | distributed by the Copyright Holder(s). 39 | 40 | "Modified Version" refers to any derivative made by adding to, deleting, 41 | or substituting -- in part or in whole -- any of the components of the 42 | Original Version, by changing formats or by porting the Font Software to a 43 | new environment. 44 | 45 | "Author" refers to any designer, engineer, programmer, technical 46 | writer or other person who contributed to the Font Software. 47 | 48 | PERMISSION & CONDITIONS 49 | Permission is hereby granted, free of charge, to any person obtaining 50 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 51 | redistribute, and sell modified and unmodified copies of the Font 52 | Software, subject to the following conditions: 53 | 54 | 1) Neither the Font Software nor any of its individual components, 55 | in Original or Modified Versions, may be sold by itself. 56 | 57 | 2) Original or Modified Versions of the Font Software may be bundled, 58 | redistributed and/or sold with any software, provided that each copy 59 | contains the above copyright notice and this license. These can be 60 | included either as stand-alone text files, human-readable headers or 61 | in the appropriate machine-readable metadata fields within text or 62 | binary files as long as those fields can be easily viewed by the user. 63 | 64 | 3) No Modified Version of the Font Software may use the Reserved Font 65 | Name(s) unless explicit written permission is granted by the corresponding 66 | Copyright Holder. This restriction only applies to the primary font name as 67 | presented to the users. 68 | 69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 70 | Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except to acknowledge the contribution(s) of the 72 | Copyright Holder(s) and the Author(s) or with their explicit written 73 | permission. 74 | 75 | 5) The Font Software, modified or unmodified, in part or in whole, 76 | must be distributed entirely under this license, and must not be 77 | distributed under any other license. The requirement for fonts to 78 | remain under this license does not apply to any document created 79 | using the Font Software. 80 | 81 | TERMINATION 82 | This license becomes null and void if any of the above conditions are 83 | not met. 84 | 85 | DISCLAIMER 86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 94 | OTHER DEALINGS IN THE FONT SOFTWARE. 95 | -------------------------------------------------------------------------------- /fonts/lilita_one_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/fonts/lilita_one_regular.ttf -------------------------------------------------------------------------------- /fonts/lilita_one_regular.ttf.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="font_data_dynamic" 4 | type="FontFile" 5 | uid="uid://d0cxd77jybrcn" 6 | path="res://.godot/imported/lilita_one_regular.ttf-68cc4ab6825bdd499d1ad608190f5213.fontdata" 7 | 8 | [deps] 9 | 10 | source_file="res://fonts/lilita_one_regular.ttf" 11 | dest_files=["res://.godot/imported/lilita_one_regular.ttf-68cc4ab6825bdd499d1ad608190f5213.fontdata"] 12 | 13 | [params] 14 | 15 | Rendering=null 16 | antialiasing=1 17 | generate_mipmaps=false 18 | multichannel_signed_distance_field=false 19 | msdf_pixel_range=8 20 | msdf_size=48 21 | allow_system_fallback=true 22 | force_autohinter=false 23 | hinting=1 24 | subpixel_positioning=1 25 | oversampling=0.0 26 | Fallbacks=null 27 | fallbacks=[] 28 | Compress=null 29 | compress=true 30 | preload=[] 31 | language_support={} 32 | script_support={} 33 | opentype_features={} 34 | -------------------------------------------------------------------------------- /htn/core/agent_sensors.gd: -------------------------------------------------------------------------------- 1 | class_name HTNAgentSensors extends Node 2 | 3 | @export 4 | var _actor: Node 5 | @export 6 | var _planner: HTNPlanner 7 | 8 | func _ready(): 9 | _initialize(_actor) 10 | 11 | 12 | func set_state(state_key: String, value: Variant, notify_changes: bool = true) -> void: 13 | _planner.get_world_state().set_value(state_key, value, notify_changes) 14 | 15 | 16 | ## This method is called on startup so you can do any initial setup, like 17 | ## listening to signals and setting initial world state 18 | func _initialize(actor: Node) -> void: 19 | pass 20 | -------------------------------------------------------------------------------- /htn/core/base_task.gd: -------------------------------------------------------------------------------- 1 | class_name HTNBaseTask extends RefCounted 2 | -------------------------------------------------------------------------------- /htn/core/compound_task.gd: -------------------------------------------------------------------------------- 1 | class_name HTNCompoundTask extends HTNBaseTask 2 | 3 | ## Return an array of methods. 4 | ## method format example: 5 | ## { 6 | ## "pre_conditions": { 7 | ## "is_player_nearby": true, 8 | ## }, 9 | ## "tasks": [WatchPlayerTask.new()], 10 | ## } 11 | func get_methods() -> Array: 12 | return [] 13 | -------------------------------------------------------------------------------- /htn/core/plan_runner.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | signal plan_finished 4 | 5 | var _world_state: HTNWorldState 6 | var _tasks: Array[HTNTask] = [] 7 | var _actor: Variant 8 | 9 | 10 | func _init(state: HTNWorldState, actor: Variant): 11 | _world_state = state 12 | _actor = actor 13 | 14 | 15 | func set_plan(tasks: Array[HTNTask]) -> void: 16 | print("\n>>> New plan set. Tasks: %d" % tasks.size()) 17 | _tasks = tasks 18 | 19 | 20 | func _process(delta: float): 21 | if _tasks.size() == 0: 22 | return 23 | _execute_current_task(delta) 24 | 25 | 26 | func _execute_current_task(delta: float) -> void: 27 | var current_task = _tasks[0] 28 | var task_result = current_task.execute(delta, _actor) 29 | 30 | match task_result: 31 | HTNTask.TaskResult.PROCESSING: 32 | return 33 | HTNTask.TaskResult.FAILURE: 34 | print("Task failed %s" % current_task.get_script().get_path()) 35 | _finish_plan() 36 | HTNTask.TaskResult.SUCCESS: 37 | print("Task succeeded %s" % current_task.get_script().get_path()) 38 | _next_task(delta) 39 | 40 | 41 | func _next_task(delta: float) -> void: 42 | _tasks.pop_front() 43 | 44 | if _tasks.size() == 0: 45 | _finish_plan() 46 | return 47 | 48 | var new_task = _tasks[0] 49 | print(_world_state._state) 50 | if not new_task.is_available(_world_state): 51 | print("Task not available %s" % new_task.get_script().get_path()) 52 | _finish_plan() 53 | return 54 | 55 | print("Starting task %s" % new_task.get_script().get_path()) 56 | _execute_current_task(delta) 57 | 58 | 59 | func _finish_plan(): 60 | _tasks = [] 61 | plan_finished.emit() 62 | -------------------------------------------------------------------------------- /htn/core/planner.gd: -------------------------------------------------------------------------------- 1 | class_name HTNPlanner extends Node 2 | 3 | const PlanRunner = preload("res://htn/core/plan_runner.gd") 4 | 5 | @export 6 | var _actor: Node 7 | 8 | @export 9 | var _domain: Script 10 | 11 | var _world_state := HTNWorldState.new() 12 | var _root 13 | var _state_stack: Array[HTNWorldState] = [] 14 | var _plan_runner 15 | 16 | func _ready(): 17 | _setup_world_state() 18 | _setup_domain() 19 | _setup_plan_runner() 20 | _plan() 21 | 22 | 23 | func _setup_world_state(): 24 | _world_state.state_changed.connect(_on_world_state_changed) 25 | 26 | 27 | func _setup_domain(): 28 | if _domain == null: 29 | push_error("Domain was not defined") 30 | return 31 | _root = _domain.new() 32 | 33 | 34 | func _setup_plan_runner(): 35 | if _actor == null: 36 | push_error("Actor not defined") 37 | return 38 | 39 | _plan_runner = PlanRunner.new(_world_state, _actor) 40 | _plan_runner.plan_finished.connect(_on_plan_execution_finished) 41 | add_child(_plan_runner) 42 | 43 | 44 | func _plan(): 45 | _initialize_working_state() 46 | var plan = _decompose_compound_task(_root) 47 | if plan.size() > 0: 48 | print("New plan") 49 | print(plan.map(func(task): return task.get_script().get_path())) 50 | _plan_runner.set_plan(plan) 51 | _clear_working_state() 52 | 53 | 54 | func _decompose_compound_task(task: HTNCompoundTask) -> Array[HTNTask]: 55 | var methods = task.get_methods() 56 | var current_state = _current_working_state() 57 | 58 | for method in methods: 59 | if _check_conditions(method.pre_conditions, current_state): 60 | _save_current_working_state() 61 | var decomposed_tasks = _decompose_tasks(method.tasks) 62 | if decomposed_tasks.size() == 0: 63 | _restore_previous_state() 64 | continue 65 | return decomposed_tasks 66 | 67 | return [] 68 | 69 | 70 | func _decompose_tasks(tasks: Array) -> Array[HTNTask]: 71 | var decomposed_tasks: Array[HTNTask] = [] 72 | var current_state = _current_working_state() 73 | 74 | for child_task in tasks: 75 | if child_task is HTNCompoundTask: 76 | var t = _decompose_compound_task(child_task) 77 | if t.size() == 0: 78 | return [] 79 | decomposed_tasks.append_array(t) 80 | elif child_task.is_available(current_state): 81 | child_task.apply_effects(current_state) 82 | decomposed_tasks.push_back(child_task) 83 | else: 84 | return [] 85 | 86 | return decomposed_tasks 87 | 88 | 89 | func _on_world_state_changed(): 90 | print("World state changed. Re-planning.") 91 | _plan() 92 | 93 | 94 | func _on_plan_execution_finished(): 95 | print("Plan finished. Re-planning.") 96 | _plan() 97 | 98 | 99 | func _check_conditions(conditions: Dictionary, world_state: HTNWorldState) -> bool: 100 | for key in conditions: 101 | if world_state.get_value(key) != conditions[key]: 102 | return false 103 | return true 104 | 105 | 106 | func get_world_state() -> HTNWorldState: 107 | return _world_state 108 | 109 | 110 | func _current_working_state() -> HTNWorldState: 111 | return _state_stack[_state_stack.size() - 1] 112 | 113 | 114 | func _initialize_working_state(): 115 | _state_stack = [_world_state.duplicate()] 116 | 117 | 118 | func _save_current_working_state(): 119 | _state_stack.push_back(_current_working_state().duplicate()) 120 | 121 | 122 | func _restore_previous_state(): 123 | _state_stack.pop_back() 124 | 125 | 126 | func _clear_working_state(): 127 | _state_stack = [] 128 | -------------------------------------------------------------------------------- /htn/core/primitive_task.gd: -------------------------------------------------------------------------------- 1 | class_name HTNTask extends HTNBaseTask 2 | 3 | enum TaskResult { 4 | SUCCESS, 5 | FAILURE, 6 | PROCESSING, 7 | } 8 | 9 | func apply_effects(world_state: HTNWorldState) -> void: 10 | var effects = _effects() 11 | for key in effects: 12 | world_state.set_value(key, effects[key]) 13 | 14 | 15 | func is_available(world_state:HTNWorldState) -> bool: 16 | var conditions = _pre_conditions() 17 | for key in conditions: 18 | if world_state.get_value(key) != conditions[key]: 19 | return false 20 | return true 21 | 22 | 23 | ## Used by the planner to change the world state 24 | ## Effect format: 25 | ## { "effect_key": "value", "effect2_key": "value } 26 | func _effects() -> Dictionary: 27 | return {} 28 | 29 | 30 | ## Used by the planer to check if task is valid 31 | ## Condition format: 32 | ## { "condition_key": "value", "condition_2_key": "value } 33 | func _pre_conditions() -> Dictionary: 34 | return {} 35 | 36 | 37 | ## This is where your task implementation lives. 38 | @warning_ignore("unused_parameter") 39 | func execute(delta: float, actor: Variant) -> TaskResult: 40 | return TaskResult.SUCCESS 41 | -------------------------------------------------------------------------------- /htn/core/world_state.gd: -------------------------------------------------------------------------------- 1 | class_name HTNWorldState extends RefCounted 2 | 3 | signal state_changed 4 | 5 | var _state = {} 6 | 7 | func _init(state: Dictionary = {}): 8 | _state = state 9 | 10 | 11 | func set_value(state_key: String, value: Variant, notify_state_change: bool = true) -> void: 12 | if _state.get(state_key) == value: 13 | return 14 | _state[state_key] = value 15 | 16 | if notify_state_change: 17 | state_changed.emit() 18 | 19 | 20 | func get_value(state_key: String, default_value: Variant = null) -> Variant: 21 | return _state.get(state_key, default_value) 22 | 23 | 24 | func duplicate() -> HTNWorldState: 25 | return HTNWorldState.new(_state.duplicate()) 26 | -------------------------------------------------------------------------------- /htn/sensors/npc_sensors.gd: -------------------------------------------------------------------------------- 1 | class_name NPCSensors extends HTNAgentSensors 2 | 3 | 4 | ## This method is called on startup so you can do any initial setup, like 5 | ## listening to signals and setting initial world state 6 | func _initialize(actor: Node): 7 | var npc = actor as NPC 8 | 9 | npc.target_changed.connect(_on_target_changed) 10 | npc.player_moved_nearby.connect(_on_player_nearby) 11 | npc.player_moved_far.connect(_on_player_far) 12 | npc.scared.connect(_on_scared) 13 | npc.relaxed.connect(_on_relaxed) 14 | npc.tired.connect(_on_tired) 15 | npc.rested.connect(_on_rested) 16 | npc.coin_collection_enabled.connect(_leave_coin_collection_cooldown) 17 | npc.coin_collection_disabled.connect(_start_coin_collection_cooldown) 18 | 19 | Events.coin_collected.connect(_check_coins) 20 | Events.coin_spawned.connect(_check_coins) 21 | 22 | set_state("has_target", false, false) 23 | set_state("is_player_nearby", false, false) 24 | set_state("are_there_coins_in_world", actor.get_tree().get_nodes_in_group("coin").size() > 0) 25 | set_state("in_coin_collection_cooldown", false, false) 26 | 27 | 28 | # not notifying changes on target change because this is only caused by plan changes 29 | func _on_target_changed(target: Variant): 30 | if is_instance_valid(target) or target is Vector3: 31 | set_state("has_target", true, false) 32 | else: 33 | set_state("has_target", false, false) 34 | 35 | 36 | func _on_player_nearby(): 37 | set_state("is_player_nearby", true) 38 | 39 | 40 | func _on_player_far(): 41 | set_state("is_player_nearby", false) 42 | 43 | 44 | func _on_scared(): 45 | set_state("is_scared", true) 46 | 47 | 48 | func _on_relaxed(): 49 | set_state("is_scared", false) 50 | 51 | 52 | func _on_tired(): 53 | set_state("is_tired", true) 54 | 55 | 56 | func _on_rested(): 57 | set_state("is_tired", false) 58 | 59 | 60 | func _check_coins(): 61 | set_state("are_there_coins_in_world", self.get_tree().get_nodes_in_group("coin").size() > 0) 62 | 63 | 64 | func _start_coin_collection_cooldown(): 65 | set_state("in_coin_collection_cooldown", true, false) 66 | 67 | 68 | func _leave_coin_collection_cooldown(): 69 | set_state("in_coin_collection_cooldown", false) 70 | -------------------------------------------------------------------------------- /htn/tasks/compound/do_random_idle_actions.gd: -------------------------------------------------------------------------------- 1 | extends HTNCompoundTask 2 | 3 | const SetRandomPositionAsTarget = preload("res://htn/tasks/primitives/set_random_position_as_target.gd") 4 | const SetClosestCoinAsTarget = preload("res://htn/tasks/primitives/set_closest_coin_as_target.gd") 5 | const GoToTargetPosition = preload("res://htn/tasks/primitives/go_to_target_position.gd") 6 | const Idle = preload("res://htn/tasks/primitives/idle.gd") 7 | 8 | var method_1 = { 9 | "pre_conditions": { 10 | "are_there_coins_in_world": true, 11 | "in_coin_collection_cooldown": false, 12 | }, 13 | "tasks": [SetClosestCoinAsTarget.new(), GoToTargetPosition.new(), Idle.new(1)], 14 | } 15 | 16 | var method_2 = { 17 | "pre_conditions": {}, 18 | "tasks": [SetRandomPositionAsTarget.new(), GoToTargetPosition.new(), Idle.new()], 19 | } 20 | 21 | func get_methods() -> Array: 22 | return [method_1, method_2] 23 | 24 | 25 | -------------------------------------------------------------------------------- /htn/tasks/compound/run_away_from_player.gd: -------------------------------------------------------------------------------- 1 | extends HTNCompoundTask 2 | 3 | const AvoidPlayer = preload("res://htn/tasks/primitives/avoid_player.gd") 4 | const Relax = preload("res://htn/tasks/primitives/relax.gd") 5 | const PlayJumpScare = preload("res://htn/tasks/primitives/play_jump_scare.gd") 6 | 7 | var method_1 = { 8 | "pre_conditions": { 9 | "is_scared": true, 10 | }, 11 | "tasks": [PlayJumpScare.new(), AvoidPlayer.new(), Relax.new()], 12 | } 13 | 14 | 15 | func get_methods() -> Array: 16 | return [method_1] 17 | -------------------------------------------------------------------------------- /htn/tasks/domain/be_npc.gd: -------------------------------------------------------------------------------- 1 | extends HTNCompoundTask 2 | 3 | const RunAwayFromPlayerTask = preload("res://htn/tasks/compound/run_away_from_player.gd") 4 | const WatchPlayerTask = preload("res://htn/tasks/primitives/watch_player.gd") 5 | const DoRandomIdleActionsTask = preload("res://htn/tasks/compound/do_random_idle_actions.gd") 6 | const Rest = preload("res://htn/tasks/primitives/rest.gd") 7 | 8 | var method_1 = { 9 | "pre_conditions": { 10 | "is_tired": true, 11 | }, 12 | "tasks": [Rest.new()], 13 | } 14 | 15 | var method_2 = { 16 | "pre_conditions": { 17 | "is_scared": true, 18 | }, 19 | "tasks": [RunAwayFromPlayerTask.new()], 20 | } 21 | 22 | var method_3 = { 23 | "pre_conditions": { 24 | "is_player_nearby": true, 25 | }, 26 | "tasks": [WatchPlayerTask.new()], 27 | } 28 | 29 | var method_4 = { 30 | "pre_conditions": {}, 31 | "tasks": [DoRandomIdleActionsTask.new()], 32 | } 33 | 34 | func get_methods() -> Array: 35 | return [ method_1, method_2, method_3, method_4 ] 36 | -------------------------------------------------------------------------------- /htn/tasks/primitives/avoid_player.gd: -------------------------------------------------------------------------------- 1 | extends HTNTask 2 | 3 | 4 | func _pre_conditions() -> Dictionary: 5 | return { 6 | "is_scared": true, 7 | } 8 | 9 | 10 | func _effects() -> Dictionary: 11 | return {} 12 | 13 | 14 | func execute(delta, actor: Variant) -> TaskResult: 15 | var npc = actor as NPC 16 | var player = actor.player_in_sight as CharacterBody3D 17 | 18 | if is_instance_valid(player): 19 | var run_direction = player.position.direction_to(npc.position) 20 | var target = run_direction * 4 21 | target.y = 0 22 | npc.move_towards_target(delta, target) 23 | return TaskResult.PROCESSING 24 | 25 | return TaskResult.SUCCESS 26 | -------------------------------------------------------------------------------- /htn/tasks/primitives/go_to_target_position.gd: -------------------------------------------------------------------------------- 1 | extends HTNTask 2 | 3 | func _pre_conditions() -> Dictionary: 4 | return { 5 | "has_target": true, 6 | } 7 | 8 | 9 | func _effects() -> Dictionary: 10 | return { 11 | "has_target": false, 12 | } 13 | 14 | 15 | func execute(delta, actor: Variant) -> TaskResult: 16 | var target = actor.get_target() 17 | 18 | if target == null: 19 | return TaskResult.FAILURE 20 | 21 | var target_position = target if target is Vector3 else target.position 22 | 23 | actor.move_towards_target(delta, target_position) 24 | 25 | if actor.position.distance_to(target_position) <= 1: 26 | actor.set_target(null) 27 | return TaskResult.SUCCESS 28 | 29 | return TaskResult.PROCESSING 30 | 31 | -------------------------------------------------------------------------------- /htn/tasks/primitives/idle.gd: -------------------------------------------------------------------------------- 1 | extends HTNTask 2 | 3 | var MIN_IDLE_TIME = 0.0 4 | var MAX_IDLE_TIME = 3.0 5 | 6 | func _init(min_idle_time: float = 0.0, max_idle_time: float = 3.0): 7 | MIN_IDLE_TIME = min_idle_time 8 | MAX_IDLE_TIME = max_idle_time 9 | 10 | 11 | ## This is where your task implementation lives. 12 | func execute(delta: float, actor: Variant) -> TaskResult: 13 | if not actor.is_idling: 14 | actor.idle_time = randf_range(MIN_IDLE_TIME, MAX_IDLE_TIME) 15 | actor.is_idling = true 16 | print("Entering idle for %.2f seconds" % actor.idle_time) 17 | return TaskResult.PROCESSING 18 | 19 | actor.idle_time -= delta 20 | 21 | if actor.idle_time <= 0: 22 | actor.is_idling = false 23 | print("Leaving idle") 24 | return TaskResult.SUCCESS 25 | 26 | return TaskResult.PROCESSING 27 | 28 | -------------------------------------------------------------------------------- /htn/tasks/primitives/pick_flower.gd: -------------------------------------------------------------------------------- 1 | extends HTNTask 2 | 3 | ## Used by the planer to check if task is valid 4 | ## Condition format: 5 | ## { "condition_key": "value", "condition_2_key": "value } 6 | func _pre_conditions() -> Dictionary: 7 | return {} 8 | 9 | 10 | ## Used by the planner to change the world state 11 | ## Effect format: 12 | ## { "effect_key": "value", "effect2_key": "value } 13 | func _effects() -> Dictionary: 14 | return {} 15 | 16 | 17 | ## This is where your task implementation lives. 18 | func execute(delta, actor: Variant) -> TaskResult: 19 | return TaskResult.SUCCESS 20 | 21 | -------------------------------------------------------------------------------- /htn/tasks/primitives/play_jump_scare.gd: -------------------------------------------------------------------------------- 1 | extends HTNTask 2 | 3 | func _pre_conditions() -> Dictionary: 4 | return { 5 | "is_scared": true, 6 | } 7 | 8 | 9 | func _effects() -> Dictionary: 10 | return {} 11 | 12 | 13 | func execute(_delta: float, actor: Variant) -> TaskResult: 14 | actor.jump() 15 | return TaskResult.SUCCESS 16 | -------------------------------------------------------------------------------- /htn/tasks/primitives/relax.gd: -------------------------------------------------------------------------------- 1 | extends HTNTask 2 | 3 | func _pre_conditions() -> Dictionary: 4 | return { 5 | "is_scared": true, 6 | } 7 | 8 | 9 | func _effects() -> Dictionary: 10 | return { 11 | "is_scared": false, 12 | } 13 | 14 | 15 | func execute(_delta: float, actor: Variant) -> TaskResult: 16 | actor.relax() 17 | return TaskResult.SUCCESS 18 | 19 | -------------------------------------------------------------------------------- /htn/tasks/primitives/rest.gd: -------------------------------------------------------------------------------- 1 | extends HTNTask 2 | 3 | func _pre_conditions() -> Dictionary: 4 | return { 5 | "is_tired": true, 6 | } 7 | 8 | 9 | func _effects() -> Dictionary: 10 | return { 11 | "is_tired": false, 12 | } 13 | 14 | 15 | func execute(delta: float, actor: Variant) -> TaskResult: 16 | if actor.rest(delta): 17 | return TaskResult.SUCCESS 18 | return TaskResult.PROCESSING 19 | -------------------------------------------------------------------------------- /htn/tasks/primitives/set_closest_coin_as_target.gd: -------------------------------------------------------------------------------- 1 | extends HTNTask 2 | 3 | 4 | func _pre_conditions() -> Dictionary: 5 | return { 6 | "are_there_coins_in_world": true, 7 | "in_coin_collection_cooldown": false, 8 | } 9 | 10 | 11 | func _effects() -> Dictionary: 12 | return { 13 | "has_target": true, 14 | } 15 | 16 | 17 | func execute(_delta, actor: Variant) -> TaskResult: 18 | var coins = actor.get_tree().get_nodes_in_group("coin") 19 | var closest_distance = 9999999 20 | var closest_coin = null 21 | 22 | for coin in coins: 23 | var coin_distance = actor.position.distance_to(coin.position) 24 | if coin_distance <= closest_distance: 25 | closest_coin = coin 26 | closest_distance = coin_distance 27 | 28 | if closest_coin == null: 29 | return TaskResult.FAILURE 30 | 31 | actor.set_target(closest_coin) 32 | return TaskResult.SUCCESS 33 | 34 | -------------------------------------------------------------------------------- /htn/tasks/primitives/set_random_position_as_target.gd: -------------------------------------------------------------------------------- 1 | extends HTNTask 2 | 3 | 4 | func _effects() -> Dictionary: 5 | return { 6 | "has_target": true, 7 | } 8 | 9 | func execute(_delta, actor: Variant) -> TaskResult: 10 | print("Set random target") 11 | var max_distance = 3 12 | var current_position = actor.position 13 | var target_position = Vector3( 14 | randf_range(current_position.x - max_distance, current_position.x + max_distance), 15 | current_position.y, 16 | randf_range(current_position.z - max_distance, current_position.z + max_distance), 17 | ) 18 | actor.set_target(target_position) 19 | return TaskResult.SUCCESS 20 | 21 | -------------------------------------------------------------------------------- /htn/tasks/primitives/watch_player.gd: -------------------------------------------------------------------------------- 1 | extends HTNTask 2 | 3 | 4 | ## This is where your task implementation lives. 5 | func execute(_delta: float, actor: Variant) -> TaskResult: 6 | var npc = actor as NPC 7 | var player = actor.player_in_sight 8 | 9 | if is_instance_valid(player): 10 | npc.look_at(player.position, Vector3.UP, true) 11 | return TaskResult.PROCESSING 12 | 13 | return TaskResult.FAILURE 14 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/icon.png -------------------------------------------------------------------------------- /icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://csn5q1hkfae20" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /meshes/dust.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/meshes/dust.res -------------------------------------------------------------------------------- /models/Textures/colormap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/Textures/colormap.png -------------------------------------------------------------------------------- /models/Textures/colormap.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://0odt7cvj574e" 6 | path.bptc="res://.godot/imported/colormap.png-c1bc3c3aabeec406ff4b53328583776a.bptc.ctex" 7 | metadata={ 8 | "imported_formats": ["s3tc_bptc"], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://models/Textures/colormap.png" 15 | dest_files=["res://.godot/imported/colormap.png-c1bc3c3aabeec406ff4b53328583776a.bptc.ctex"] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/high_quality=true 21 | compress/lossy_quality=0.7 22 | compress/hdr_compression=1 23 | compress/normal_map=0 24 | compress/channel_pack=0 25 | mipmaps/generate=true 26 | mipmaps/limit=-1 27 | roughness/mode=0 28 | roughness/src_normal="" 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/normal_map_invert_y=false 32 | process/hdr_as_srgb=false 33 | process/hdr_clamp_exposure=false 34 | process/size_limit=0 35 | detect_3d/compress_to=0 36 | -------------------------------------------------------------------------------- /models/Textures/colormap_npc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/Textures/colormap_npc.png -------------------------------------------------------------------------------- /models/Textures/colormap_npc.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://f87ajpfeaace" 6 | path.s3tc="res://.godot/imported/colormap_npc.png-c11f3ef04444db826f6dd9bdac6fe648.s3tc.ctex" 7 | metadata={ 8 | "imported_formats": ["s3tc_bptc"], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://models/Textures/colormap_npc.png" 15 | dest_files=["res://.godot/imported/colormap_npc.png-c11f3ef04444db826f6dd9bdac6fe648.s3tc.ctex"] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/high_quality=false 21 | compress/lossy_quality=0.7 22 | compress/hdr_compression=1 23 | compress/normal_map=0 24 | compress/channel_pack=0 25 | mipmaps/generate=true 26 | mipmaps/limit=-1 27 | roughness/mode=0 28 | roughness/src_normal="" 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/normal_map_invert_y=false 32 | process/hdr_as_srgb=false 33 | process/hdr_clamp_exposure=false 34 | process/size_limit=0 35 | detect_3d/compress_to=0 36 | -------------------------------------------------------------------------------- /models/character.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/character.glb -------------------------------------------------------------------------------- /models/character.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://xy8rvnjp22n5" 7 | path="res://.godot/imported/character.glb-d7ae052b4627e9fafc1b5a3d6bdef701.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/character.glb" 12 | dest_files=["res://.godot/imported/character.glb-d7ae052b4627e9fafc1b5a3d6bdef701.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /models/cloud.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/cloud.glb -------------------------------------------------------------------------------- /models/cloud.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://bsrmqj84lksd7" 7 | path="res://.godot/imported/cloud.glb-53daedc24f8d7f4baa42baf232c66643.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/cloud.glb" 12 | dest_files=["res://.godot/imported/cloud.glb-53daedc24f8d7f4baa42baf232c66643.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /models/coin.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/coin.glb -------------------------------------------------------------------------------- /models/coin.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://e64a4omgpcs" 7 | path="res://.godot/imported/coin.glb-71ddb7e9cec3b646e7e111521df88060.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/coin.glb" 12 | dest_files=["res://.godot/imported/coin.glb-71ddb7e9cec3b646e7e111521df88060.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /models/dust.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/dust.glb -------------------------------------------------------------------------------- /models/dust.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://brg64eln7l7wv" 7 | path="res://.godot/imported/dust.glb-1353ca834ae15b165f2b80c04f99a5a8.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/dust.glb" 12 | dest_files=["res://.godot/imported/dust.glb-1353ca834ae15b165f2b80c04f99a5a8.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={ 33 | "meshes": { 34 | "cloud_cloud": { 35 | "generate/lightmap_uv": 0, 36 | "generate/lods": 0, 37 | "generate/shadow_meshes": 0, 38 | "lods/normal_merge_angle": 60.0, 39 | "lods/normal_split_angle": 25.0, 40 | "save_to_file/enabled": true, 41 | "save_to_file/make_streamable": "", 42 | "save_to_file/path": "res://prefabs/cloud.res" 43 | } 44 | } 45 | } 46 | gltf/naming_version=0 47 | gltf/embedded_image_handling=1 48 | -------------------------------------------------------------------------------- /models/flag.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/flag.glb -------------------------------------------------------------------------------- /models/flag.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://dtjvjdjl8cs6e" 7 | path="res://.godot/imported/flag.glb-0b6fa3c4b5180c1221a26057702dcf53.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/flag.glb" 12 | dest_files=["res://.godot/imported/flag.glb-0b6fa3c4b5180c1221a26057702dcf53.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /models/grass-small.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/grass-small.glb -------------------------------------------------------------------------------- /models/grass-small.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://dkw27llxh1d4w" 7 | path="res://.godot/imported/grass-small.glb-0be1c06405ef2ce478dc00acb5be5be8.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/grass-small.glb" 12 | dest_files=["res://.godot/imported/grass-small.glb-0be1c06405ef2ce478dc00acb5be5be8.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /models/grass.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/grass.glb -------------------------------------------------------------------------------- /models/grass.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://blqf5cwsk25xj" 7 | path="res://.godot/imported/grass.glb-0ce858eae1c69c894a569863f13e24f1.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/grass.glb" 12 | dest_files=["res://.godot/imported/grass.glb-0ce858eae1c69c894a569863f13e24f1.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /models/platform-falling.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/platform-falling.glb -------------------------------------------------------------------------------- /models/platform-falling.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://biyd6x403gvny" 7 | path="res://.godot/imported/platform-falling.glb-a1321a8710589d27b2a6e247cfe23359.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/platform-falling.glb" 12 | dest_files=["res://.godot/imported/platform-falling.glb-a1321a8710589d27b2a6e247cfe23359.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /models/platform-grass-large-round.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/platform-grass-large-round.glb -------------------------------------------------------------------------------- /models/platform-grass-large-round.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://fqfc0dtl2xlc" 7 | path="res://.godot/imported/platform-grass-large-round.glb-1baa8c47f88d676b171370cee4874a31.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/platform-grass-large-round.glb" 12 | dest_files=["res://.godot/imported/platform-grass-large-round.glb-1baa8c47f88d676b171370cee4874a31.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /models/platform-large.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/platform-large.glb -------------------------------------------------------------------------------- /models/platform-large.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://bn0iedr5b0xbv" 7 | path="res://.godot/imported/platform-large.glb-0787c0d4110cac7aeebc2ebcb57e003b.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/platform-large.glb" 12 | dest_files=["res://.godot/imported/platform-large.glb-0787c0d4110cac7aeebc2ebcb57e003b.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /models/platform-medium.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/platform-medium.glb -------------------------------------------------------------------------------- /models/platform-medium.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://c5vgh1v6juur0" 7 | path="res://.godot/imported/platform-medium.glb-fef62c5a42cae1343dea58f537fab43f.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/platform-medium.glb" 12 | dest_files=["res://.godot/imported/platform-medium.glb-fef62c5a42cae1343dea58f537fab43f.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /models/platform.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/models/platform.glb -------------------------------------------------------------------------------- /models/platform.glb.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="scene" 4 | importer_version=1 5 | type="PackedScene" 6 | uid="uid://do8sg1k5xvj2h" 7 | path="res://.godot/imported/platform.glb-3476c7cd272116fb58fd5d0a0eddb703.scn" 8 | 9 | [deps] 10 | 11 | source_file="res://models/platform.glb" 12 | dest_files=["res://.godot/imported/platform.glb-3476c7cd272116fb58fd5d0a0eddb703.scn"] 13 | 14 | [params] 15 | 16 | nodes/root_type="Node3D" 17 | nodes/root_name="Scene Root" 18 | nodes/apply_root_scale=true 19 | nodes/root_scale=1.0 20 | meshes/ensure_tangents=true 21 | meshes/generate_lods=true 22 | meshes/create_shadow_meshes=true 23 | meshes/light_baking=1 24 | meshes/lightmap_texel_size=0.2 25 | meshes/force_disable_compression=false 26 | skins/use_named_skins=true 27 | animation/import=true 28 | animation/fps=30 29 | animation/trimming=false 30 | animation/remove_immutable_tracks=true 31 | import_script/path="" 32 | _subresources={} 33 | gltf/naming_version=0 34 | gltf/embedded_image_handling=1 35 | -------------------------------------------------------------------------------- /objects/character.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://c0e27836xgmhi"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://xy8rvnjp22n5" path="res://models/character.glb" id="1_vn7w5"] 4 | 5 | [node name="character" instance=ExtResource("1_vn7w5")] 6 | 7 | [node name="leg-left" parent="character2/root" index="0"] 8 | transform = Transform3D(0.965926, 0, 0.258819, 0, 1, 0, -0.258819, 0, 0.965926, 0.125, 0.17625, -0.02375) 9 | 10 | [node name="leg-right" parent="character2/root" index="1"] 11 | transform = Transform3D(0.965926, 0, -0.258819, 0, 1, 0, 0.258819, 0, 0.965926, -0.125, 0.17625, -0.02375) 12 | 13 | [node name="torso" parent="character2/root" index="2"] 14 | transform = Transform3D(1, 0, 0, 0, 0.996195, 0.0871557, 0, -0.0871557, 0.996195, -1.80478e-15, 0.17625, -0.02375) 15 | 16 | [node name="arm-left" parent="character2/root/torso" index="0"] 17 | transform = Transform3D(0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 0, 0, 1, 0.3, 0.175, 0) 18 | 19 | [node name="arm-right" parent="character2/root/torso" index="1"] 20 | transform = Transform3D(0.707107, -0.707107, 0, 0.707107, 0.707107, 0, 0, 0, 1, -0.3, 0.1195, 0) 21 | -------------------------------------------------------------------------------- /objects/cloud.gd: -------------------------------------------------------------------------------- 1 | extends Node3D 2 | 3 | var time = 0.0 4 | 5 | var random_number = RandomNumberGenerator.new() 6 | 7 | var random_velocity:float 8 | var random_time:float 9 | 10 | func _ready(): 11 | 12 | random_velocity = random_number.randf_range(0.1, 2.0) 13 | random_time = random_number.randf_range(0.1, 2.0) 14 | 15 | func _process(delta): 16 | 17 | position.y += (cos(time * random_time) * random_velocity) * delta # Sine movement 18 | 19 | time += delta 20 | -------------------------------------------------------------------------------- /objects/cloud.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://dy017k58p20sk"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://bsrmqj84lksd7" path="res://models/cloud.glb" id="1_pjiy0"] 4 | [ext_resource type="Script" path="res://objects/cloud.gd" id="2_hugjq"] 5 | 6 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8nets"] 7 | transparency = 1 8 | distance_fade_mode = 1 9 | distance_fade_min_distance = 2.0 10 | distance_fade_max_distance = 3.0 11 | 12 | [node name="cube" instance=ExtResource("1_pjiy0")] 13 | script = ExtResource("2_hugjq") 14 | 15 | [node name="cube2" parent="." index="0"] 16 | visibility_range_fade_mode = 1 17 | surface_material_override/0 = SubResource("StandardMaterial3D_8nets") 18 | -------------------------------------------------------------------------------- /objects/coin.gd: -------------------------------------------------------------------------------- 1 | extends Area3D 2 | 3 | signal collected 4 | 5 | var time := 0.0 6 | var grabbed := false 7 | 8 | func _on_body_entered(body): 9 | if body.has_method("collect_coin") and !grabbed: 10 | 11 | body.collect_coin() 12 | 13 | Audio.play("res://sounds/coin.ogg") # Play sound 14 | 15 | $Mesh.queue_free() # Make invisible 16 | $Particles.emitting = false # Stop emitting stars 17 | 18 | grabbed = true 19 | 20 | self.remove_from_group("coin") 21 | collected.emit() 22 | #await get_tree().create_timer(3).timeout 23 | self.queue_free() 24 | 25 | 26 | func _process(delta): 27 | 28 | rotate_y(2 * delta) # Rotation 29 | position.y += (cos(time * 5) * 1) * delta # Sine movement 30 | 31 | time += delta 32 | -------------------------------------------------------------------------------- /objects/coin_spawner.gd: -------------------------------------------------------------------------------- 1 | extends Node3D 2 | 3 | const Coin = preload("res://objects/coin.tscn") 4 | 5 | const MAX_DISTANCE = 10 6 | 7 | func _on_timer_timeout(): 8 | if self.get_tree().get_nodes_in_group("coin").size() < 5: 9 | _spawn_coin() 10 | 11 | 12 | func _spawn_coin(): 13 | var coin = Coin.instantiate() 14 | self.get_parent().add_child(coin) 15 | coin.position = _get_random_position() 16 | coin.collected.connect(_on_coin_collected) 17 | Events.coin_spawned.emit() 18 | 19 | 20 | func _get_random_position() -> Vector3: 21 | var spawn_position = self.position 22 | 23 | return Vector3( 24 | randf_range(spawn_position.x - MAX_DISTANCE, spawn_position.x + MAX_DISTANCE), 25 | spawn_position.y, 26 | randf_range(spawn_position.z - MAX_DISTANCE, spawn_position.z + MAX_DISTANCE), 27 | ) 28 | 29 | 30 | func _on_coin_collected(): 31 | print("coin collected") 32 | Events.coin_collected.emit() 33 | -------------------------------------------------------------------------------- /objects/coin_spawner.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://bggq7sr56jogd"] 2 | 3 | [ext_resource type="Script" path="res://objects/coin_spawner.gd" id="1_ntrg2"] 4 | 5 | [node name="CoinSpawner" type="Node3D"] 6 | script = ExtResource("1_ntrg2") 7 | 8 | [node name="Timer" type="Timer" parent="."] 9 | wait_time = 15.0 10 | autostart = true 11 | 12 | [connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"] 13 | -------------------------------------------------------------------------------- /objects/npc.gd: -------------------------------------------------------------------------------- 1 | class_name NPC extends CharacterBody3D 2 | 3 | @export_subgroup("Components") 4 | @export var view: Node3D 5 | 6 | @export_subgroup("Properties") 7 | @export var movement_speed = 250 8 | @export var jump_strength = 7 9 | 10 | var movement_velocity: Vector3 11 | var rotation_direction: float 12 | var gravity = 0 13 | 14 | var previously_floored = false 15 | 16 | var jump_single = true 17 | var jump_double = true 18 | 19 | var coins = 0 20 | 21 | @onready var particles_trail = $ParticlesTrail 22 | @onready var sound_footsteps = $SoundFootsteps 23 | @onready var model = $Character 24 | @onready var animation = $Character/AnimationPlayer 25 | 26 | # These props were added for the HTN example 27 | signal target_changed(target: Variant) 28 | signal player_moved_nearby 29 | signal player_moved_far 30 | signal scared 31 | signal relaxed 32 | signal tired 33 | signal rested 34 | signal coin_collection_enabled 35 | signal coin_collection_disabled 36 | 37 | var _target 38 | var player_in_sight 39 | var is_idling = false 40 | var idle_time = 0 41 | var scares = 0 42 | var tired_recover_left = 0 43 | var coin_collection_cooldown 44 | 45 | 46 | func _physics_process(delta): 47 | handle_gravity(delta) 48 | handle_effects() 49 | 50 | # Movement 51 | 52 | var applied_velocity: Vector3 53 | 54 | applied_velocity = velocity.lerp(movement_velocity, delta * 10) 55 | applied_velocity.y = -gravity 56 | 57 | velocity = applied_velocity 58 | move_and_slide() 59 | movement_velocity = Vector3.ZERO 60 | 61 | # Rotation 62 | 63 | if Vector2(velocity.z, velocity.x).length() > 0: 64 | rotation_direction = Vector2(velocity.z, velocity.x).angle() 65 | 66 | rotation.y = lerp_angle(rotation.y, rotation_direction, delta * 10) 67 | 68 | 69 | # Animation for scale (jumping and landing) 70 | 71 | model.scale = model.scale.lerp(Vector3(1, 1, 1), delta * 10) 72 | 73 | # Animation when landing 74 | 75 | if is_on_floor() and gravity > 2 and !previously_floored: 76 | model.scale = Vector3(1.25, 0.75, 1.25) 77 | Audio.play("res://sounds/land.ogg") 78 | 79 | previously_floored = is_on_floor() 80 | 81 | # Handle animation(s) 82 | 83 | func handle_effects(): 84 | particles_trail.emitting = false 85 | sound_footsteps.stream_paused = true 86 | 87 | if is_on_floor(): 88 | if abs(velocity.x) > 1 or abs(velocity.z) > 1: 89 | animation.play("walk", 0.5) 90 | particles_trail.emitting = true 91 | sound_footsteps.stream_paused = false 92 | else: 93 | animation.play("idle", 0.5) 94 | else: 95 | animation.play("jump", 0.5) 96 | 97 | 98 | func handle_gravity(delta): 99 | 100 | gravity += 25 * delta 101 | 102 | if gravity > 0 and is_on_floor(): 103 | 104 | jump_single = true 105 | gravity = 0 106 | 107 | 108 | func jump(): 109 | gravity = -jump_strength 110 | 111 | model.scale = Vector3(0.5, 1.5, 0.5) 112 | 113 | jump_single = false; 114 | jump_double = true; 115 | 116 | 117 | func set_target(target: Variant): 118 | _target = target 119 | target_changed.emit(_target) 120 | 121 | 122 | func get_target(): 123 | return _target 124 | 125 | 126 | func _on_player_detection_sensor_body_entered(body): 127 | player_in_sight = body 128 | player_in_sight.jumped.connect(_on_player_jumped) 129 | 130 | 131 | func _on_player_detection_sensor_body_exited(_body): 132 | player_in_sight.jumped.disconnect(_on_player_jumped) 133 | player_in_sight = null 134 | 135 | 136 | func move_towards_target(delta: float, target: Vector3): 137 | var target_direction = self.position.direction_to(target) 138 | target_direction.y = 0 139 | 140 | target_direction = target_direction.normalized() 141 | 142 | movement_velocity = target_direction * movement_speed * delta 143 | 144 | 145 | func _on_player_jumped(): 146 | if self.position.distance_to(player_in_sight.position) < 3: 147 | scared.emit() 148 | scares += 1 149 | 150 | 151 | func relax(): 152 | relaxed.emit() 153 | if scares > 2: 154 | scares = 0 155 | tired.emit() 156 | 157 | 158 | func rest(delta: float): 159 | $RestParticle.emitting = true 160 | tired_recover_left += delta 161 | if tired_recover_left >= 10: 162 | tired_recover_left = 0 163 | $RestParticle.emitting = false 164 | rested.emit() 165 | return true 166 | return false 167 | 168 | 169 | func _on_close_range_sensor_body_entered(_body): 170 | player_moved_nearby.emit() 171 | 172 | 173 | func _on_close_range_sensor_body_exited(_body): 174 | player_moved_far.emit() 175 | 176 | 177 | func collect_coin(): 178 | coins += 1 179 | coin_collection_disabled.emit() 180 | await get_tree().create_timer(randf_range(3, 10)).timeout 181 | coin_collection_enabled.emit() 182 | 183 | -------------------------------------------------------------------------------- /objects/platform.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://cnymdajj1vsqm"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://do8sg1k5xvj2h" path="res://models/platform.glb" id="1_xagml"] 4 | 5 | [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_hyw7p"] 6 | data = PackedVector3Array(-0.9, 0, -0.72, -1, 0.2, -0.8, -1, 0.2, 0.8, -1, 0.2, 0.8, -0.9, 0, 0.72, -0.9, 0, -0.72, -0.95, 0.5, -0.95, -0.95, 0.2, -0.95, -0.8, 0.2, -1, -0.8, 0.2, -1, -0.8, 0.5, -1, -0.95, 0.5, -0.95, -1, 0.2, -0.8, -0.95, 0.2, -0.95, -0.95, 0.5, -0.95, -0.95, 0.5, -0.95, -1, 0.5, -0.8, -1, 0.2, -0.8, -1, 0.2, 0.8, -1, 0.2, -0.8, -1, 0.5, -0.8, -1, 0.5, -0.8, -1, 0.5, 0.8, -1, 0.2, 0.8, 0.8, 0.5, -1, 0.8, 0.2, -1, 0.95, 0.2, -0.95, 0.95, 0.2, -0.95, 0.95, 0.5, -0.95, 0.8, 0.5, -1, -0.8, 0.5, -1, -0.8, 0.2, -1, 0.8, 0.2, -1, 0.8, 0.2, -1, 0.8, 0.5, -1, -0.8, 0.5, -1, 1, 0.5, -0.8, 0.95, 0.5, -0.95, 0.95, 0.2, -0.95, 0.95, 0.2, -0.95, 1, 0.2, -0.8, 1, 0.5, -0.8, -0.8, 0.5, 1, -0.8, 0.2, 1, -0.95, 0.2, 0.95, -0.95, 0.2, 0.95, -0.95, 0.5, 0.95, -0.8, 0.5, 1, -0.95, 0.2, 0.95, -1, 0.2, 0.8, -1, 0.5, 0.8, -1, 0.5, 0.8, -0.95, 0.5, 0.95, -0.95, 0.2, 0.95, -0.8, 0.2, -1, -0.72, 0, -0.9, 0.72, 0, -0.9, 0.72, 0, -0.9, 0.8, 0.2, -1, -0.8, 0.2, -1, 1, 0.2, 0.8, 1, 0.2, -0.8, 0.9, 0, -0.72, 0.9, 0, -0.72, 0.9, 0, 0.72, 1, 0.2, 0.8, -0.95, 0.2, -0.95, -0.855, 0, -0.855, -0.72, 0, -0.9, -0.72, 0, -0.9, -0.8, 0.2, -1, -0.95, 0.2, -0.95, 1, 0.2, 0.8, 0.9, 0, 0.72, 0.855, 0, 0.855, 0.855, 0, 0.855, 0.95, 0.2, 0.95, 1, 0.2, 0.8, -0.855, 0, 0.855, -0.9, 0, 0.72, -1, 0.2, 0.8, -1, 0.2, 0.8, -0.95, 0.2, 0.95, -0.855, 0, 0.855, 0.8, 0.2, 1, 0.72, 0, 0.9, -0.72, 0, 0.9, -0.72, 0, 0.9, -0.8, 0.2, 1, 0.8, 0.2, 1, 0.95, 0.5, 0.95, 1, 0.5, 0.8, 1, 0.2, 0.8, 1, 0.2, 0.8, 0.95, 0.2, 0.95, 0.95, 0.5, 0.95, 1, 0.5, 0.8, 1, 0.5, -0.8, 1, 0.2, -0.8, 1, 0.2, -0.8, 1, 0.2, 0.8, 1, 0.5, 0.8, 1, 0.2, -0.8, 0.95, 0.2, -0.95, 0.855, 0, -0.855, 0.855, 0, -0.855, 0.9, 0, -0.72, 1, 0.2, -0.8, -0.855, 0, -0.855, -0.95, 0.2, -0.95, -1, 0.2, -0.8, -1, 0.2, -0.8, -0.9, 0, -0.72, -0.855, 0, -0.855, 0.8, 0.2, -1, 0.72, 0, -0.9, 0.855, 0, -0.855, 0.855, 0, -0.855, 0.95, 0.2, -0.95, 0.8, 0.2, -1, 0.95, 0.2, 0.95, 0.855, 0, 0.855, 0.72, 0, 0.9, 0.72, 0, 0.9, 0.8, 0.2, 1, 0.95, 0.2, 0.95, 0.855, 0, 0.855, 0.9, 0, 0.72, 0.9, 0, -0.72, 0.9, 0, -0.72, 0.855, 0, -0.855, 0.855, 0, 0.855, 0.855, 0, -0.855, 0.72, 0, 0.9, 0.855, 0, 0.855, 0.855, 0, -0.855, 0.72, 0, -0.9, 0.72, 0, 0.9, 0.72, 0, -0.9, -0.72, 0, 0.9, 0.72, 0, 0.9, 0.72, 0, -0.9, -0.72, 0, -0.9, -0.72, 0, 0.9, -0.72, 0, -0.9, -0.855, 0, -0.855, -0.72, 0, 0.9, -0.855, 0, -0.855, -0.855, 0, 0.855, -0.72, 0, 0.9, -0.855, 0, -0.855, -0.9, 0, -0.72, -0.855, 0, 0.855, -0.9, 0, -0.72, -0.9, 0, 0.72, -0.855, 0, 0.855, -0.8, 0.2, 1, -0.72, 0, 0.9, -0.855, 0, 0.855, -0.855, 0, 0.855, -0.95, 0.2, 0.95, -0.8, 0.2, 1, 0.95, 0.5, 0.95, 0.95, 0.2, 0.95, 0.8, 0.2, 1, 0.8, 0.2, 1, 0.8, 0.5, 1, 0.95, 0.5, 0.95, 0.8, 0.5, 1, 0.8, 0.2, 1, -0.8, 0.2, 1, -0.8, 0.2, 1, -0.8, 0.5, 1, 0.8, 0.5, 1, -0.95, 0.5, 0.95, -1, 0.5, 0.8, -1, 0.5, -0.8, -0.95, 0.5, 0.95, -1, 0.5, -0.8, -0.95, 0.5, -0.95, -0.8, 0.5, 1, -0.95, 0.5, 0.95, -0.95, 0.5, -0.95, -0.8, 0.5, 0.7675, -0.8, 0.5, 1, -0.95, 0.5, -0.95, -0.8, 0.5, -0.7675, -0.8, 0.5, 0.7675, -0.95, 0.5, -0.95, -0.8, 0.5, 1, -0.8, 0.5, 0.7675, -0.7919, 0.5, 0.7919, -0.8, 0.5, 1, -0.7919, 0.5, 0.7919, -0.7675, 0.5, 0.8, -0.8, 0.5, 1, -0.7675, 0.5, 0.8, 0.7675, 0.5, 0.8, -0.8, 0.5, -0.7675, -0.95, 0.5, -0.95, -0.8, 0.5, -1, 0.8, 0.5, 1, -0.8, 0.5, 1, 0.7675, 0.5, 0.8, -0.7919, 0.5, -0.7919, -0.8, 0.5, -0.7675, -0.8, 0.5, -1, -0.7675, 0.5, -0.8, -0.7919, 0.5, -0.7919, -0.8, 0.5, -1, 0.7675, 0.5, -0.8, -0.7675, 0.5, -0.8, -0.8, 0.5, -1, 0.8, 0.5, 1, 0.7675, 0.5, 0.8, 0.7919, 0.5, 0.7919, 0.7675, 0.5, -0.8, -0.8, 0.5, -1, 0.8, 0.5, -1, 0.7919, 0.5, -0.7919, 0.7675, 0.5, -0.8, 0.8, 0.5, -1, 0.8, 0.5, -0.7675, 0.7919, 0.5, -0.7919, 0.8, 0.5, -1, 0.8, 0.5, 0.7675, 0.8, 0.5, -0.7675, 0.8, 0.5, -1, 0.8, 0.5, 1, 0.7919, 0.5, 0.7919, 0.8, 0.5, 0.7675, 0.8, 0.5, -1, 0.95, 0.5, -0.95, 0.8, 0.5, 0.7675, 0.8, 0.5, 1, 0.8, 0.5, 0.7675, 0.95, 0.5, -0.95, 0.95, 0.5, 0.95, 0.8, 0.5, 1, 0.95, 0.5, -0.95, 0.95, 0.5, 0.95, 0.95, 0.5, -0.95, 1, 0.5, -0.8, 1, 0.5, -0.8, 1, 0.5, 0.8, 0.95, 0.5, 0.95, 0.8, 0.5, -0.7675, 0.8, 0.5, 0.7675, 0.7919, 0.5, 0.7919, 0.7919, 0.5, 0.7919, 0.7919, 0.5, -0.7919, 0.8, 0.5, -0.7675, 0.7919, 0.5, 0.7919, 0.7675, 0.5, 0.8, 0.7919, 0.5, -0.7919, 0.7675, 0.5, 0.8, 0.7675, 0.5, -0.8, 0.7919, 0.5, -0.7919, 0.7675, 0.5, 0.8, 0.6, 0.5, -0.6, 0.7675, 0.5, -0.8, 0.6, 0.5, -0.6, -0.7675, 0.5, -0.8, 0.7675, 0.5, -0.8, 0.7675, 0.5, 0.8, 0.6, 0.5, 0.6, 0.6, 0.5, -0.6, 0.6, 0.5, -0.6, -0.6, 0.5, -0.6, -0.7675, 0.5, -0.8, 0.6, 0.5, 0.6, 0.7675, 0.5, 0.8, -0.7675, 0.5, 0.8, -0.6, 0.5, -0.6, -0.6, 0.5, 0.6, -0.7675, 0.5, -0.8, -0.7675, 0.5, 0.8, -0.6, 0.5, 0.6, 0.6, 0.5, 0.6, -0.7675, 0.5, 0.8, -0.7675, 0.5, -0.8, -0.6, 0.5, 0.6, -0.7675, 0.5, 0.8, -0.7919, 0.5, -0.7919, -0.7675, 0.5, -0.8, -0.7675, 0.5, 0.8, -0.7919, 0.5, 0.7919, -0.7919, 0.5, -0.7919, -0.7919, 0.5, 0.7919, -0.8, 0.5, -0.7675, -0.7919, 0.5, -0.7919, -0.7919, 0.5, 0.7919, -0.8, 0.5, 0.7675, -0.8, 0.5, -0.7675, 0.6, 0.5, -0.6, 0.6, 0.5, 0.6, -0.6, 0.5, 0.6, -0.6, 0.5, 0.6, -0.6, 0.5, -0.6, 0.6, 0.5, -0.6, -0.45, 0.5, -0.2788, -0.4946, 0.5, -0.3391, -0.4946, 0.55, -0.3391, -0.4946, 0.55, -0.3391, -0.45, 0.55, -0.2788, -0.45, 0.5, -0.2788, -0.3372, 0.55, -0.3156, -0.3372, 0.5, -0.3156, -0.3975, 0.5, -0.271, -0.3975, 0.5, -0.271, -0.3975, 0.55, -0.271, -0.3372, 0.55, -0.3156, -0.3294, 0.55, -0.3681, -0.374, 0.55, -0.4284, -0.374, 0.5, -0.4284, -0.374, 0.5, -0.4284, -0.3294, 0.5, -0.3681, -0.3294, 0.55, -0.3681, -0.4867, 0.55, -0.3916, -0.4867, 0.5, -0.3916, -0.4265, 0.5, -0.4362, -0.4265, 0.5, -0.4362, -0.4265, 0.55, -0.4362, -0.4867, 0.55, -0.3916, -0.4265, 0.55, -0.4362, -0.374, 0.55, -0.4284, -0.3294, 0.55, -0.3681, -0.3294, 0.55, -0.3681, -0.3372, 0.55, -0.3156, -0.4265, 0.55, -0.4362, -0.3372, 0.55, -0.3156, -0.3975, 0.55, -0.271, -0.4265, 0.55, -0.4362, -0.3975, 0.55, -0.271, -0.4867, 0.55, -0.3916, -0.4265, 0.55, -0.4362, -0.3975, 0.55, -0.271, -0.4946, 0.55, -0.3391, -0.4867, 0.55, -0.3916, -0.3975, 0.55, -0.271, -0.45, 0.55, -0.2788, -0.4946, 0.55, -0.3391, -0.3975, 0.55, -0.271, -0.3975, 0.5, -0.271, -0.45, 0.5, -0.2788, -0.45, 0.5, -0.2788, -0.45, 0.55, -0.2788, -0.3975, 0.55, -0.271, -0.4946, 0.5, -0.3391, -0.4867, 0.5, -0.3916, -0.4867, 0.55, -0.3916, -0.4867, 0.55, -0.3916, -0.4946, 0.55, -0.3391, -0.4946, 0.5, -0.3391, -0.3294, 0.55, -0.3681, -0.3294, 0.5, -0.3681, -0.3372, 0.5, -0.3156, -0.3372, 0.5, -0.3156, -0.3372, 0.55, -0.3156, -0.3294, 0.55, -0.3681, -0.4265, 0.55, -0.4362, -0.4265, 0.5, -0.4362, -0.374, 0.5, -0.4284, -0.374, 0.5, -0.4284, -0.374, 0.55, -0.4284, -0.4265, 0.55, -0.4362, -0.2345, 0.5, -0.2685, -0.1786, 0.5, -0.4077, -0.1786, 0.55, -0.4077, -0.1786, 0.55, -0.4077, -0.2345, 0.55, -0.2685, -0.2345, 0.5, -0.2685, -0.0537, 0.55, -0.115, -0.0537, 0.5, -0.115, -0.1929, 0.5, -0.171, -0.1929, 0.5, -0.171, -0.1929, 0.55, -0.171, -0.0537, 0.55, -0.115, 0.0438, 0.55, -0.1566, 0.0998, 0.55, -0.2958, 0.0998, 0.5, -0.2958, 0.0998, 0.5, -0.2958, 0.0438, 0.5, -0.1566, 0.0438, 0.55, -0.1566, -0.081, 0.55, -0.4493, -0.081, 0.5, -0.4493, 0.0582, 0.5, -0.3934, 0.0582, 0.5, -0.3934, 0.0582, 0.55, -0.3934, -0.081, 0.55, -0.4493, 0.0582, 0.55, -0.3934, 0.0998, 0.55, -0.2958, 0.0438, 0.55, -0.1566, 0.0438, 0.55, -0.1566, -0.0537, 0.55, -0.115, 0.0582, 0.55, -0.3934, -0.0537, 0.55, -0.115, -0.081, 0.55, -0.4493, 0.0582, 0.55, -0.3934, -0.0537, 0.55, -0.115, -0.1929, 0.55, -0.171, -0.081, 0.55, -0.4493, -0.1929, 0.55, -0.171, -0.2345, 0.55, -0.2685, -0.081, 0.55, -0.4493, -0.2345, 0.55, -0.2685, -0.1786, 0.55, -0.4077, -0.081, 0.55, -0.4493, -0.1929, 0.55, -0.171, -0.1929, 0.5, -0.171, -0.2345, 0.5, -0.2685, -0.2345, 0.5, -0.2685, -0.2345, 0.55, -0.2685, -0.1929, 0.55, -0.171, -0.1786, 0.5, -0.4077, -0.081, 0.5, -0.4493, -0.081, 0.55, -0.4493, -0.081, 0.55, -0.4493, -0.1786, 0.55, -0.4077, -0.1786, 0.5, -0.4077, 0.0438, 0.55, -0.1566, 0.0438, 0.5, -0.1566, -0.0537, 0.5, -0.115, -0.0537, 0.5, -0.115, -0.0537, 0.55, -0.115, 0.0438, 0.55, -0.1566, 0.0582, 0.55, -0.3934, 0.0582, 0.5, -0.3934, 0.0998, 0.5, -0.2958, 0.0998, 0.5, -0.2958, 0.0998, 0.55, -0.2958, 0.0582, 0.55, -0.3934) 7 | 8 | [node name="platform" instance=ExtResource("1_xagml")] 9 | 10 | [node name="StaticBody3D" type="StaticBody3D" parent="platform2" index="0"] 11 | 12 | [node name="CollisionShape3D" type="CollisionShape3D" parent="platform2/StaticBody3D" index="0"] 13 | shape = SubResource("ConcavePolygonShape3D_hyw7p") 14 | -------------------------------------------------------------------------------- /objects/platform_falling.gd: -------------------------------------------------------------------------------- 1 | extends Node3D 2 | 3 | var falling := false 4 | var gravity := 0.0 5 | 6 | func _process(delta): 7 | scale = scale.lerp(Vector3(1, 1, 1), delta * 10) # Animate scale 8 | 9 | position.y -= gravity * delta 10 | 11 | if position.y < -10: 12 | queue_free() # Remove platform if below threshold 13 | 14 | if falling: 15 | gravity += 0.25 16 | 17 | 18 | func _on_body_entered(_body): 19 | if !falling: 20 | Audio.play("res://sounds/fall.ogg") # Play sound 21 | scale = Vector3(1.25, 1, 1.25) # Animate scale 22 | 23 | falling = true 24 | -------------------------------------------------------------------------------- /objects/platform_falling.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=3 uid="uid://c8up71en5djgm"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://biyd6x403gvny" path="res://models/platform-falling.glb" id="1_gkggt"] 4 | [ext_resource type="Script" path="res://objects/platform_falling.gd" id="2_6ganw"] 5 | 6 | [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_4mmvt"] 7 | data = PackedVector3Array(-0.9, 0, -0.72, -1, 0.2, -0.8, -1, 0.2, 0.8, -1, 0.2, 0.8, -0.9, 0, 0.72, -0.9, 0, -0.72, -0.95, 0.5, -0.95, -0.95, 0.2, -0.95, -0.8, 0.2, -1, -0.8, 0.2, -1, -0.8, 0.5, -1, -0.95, 0.5, -0.95, -1, 0.2, -0.8, -0.95, 0.2, -0.95, -0.95, 0.5, -0.95, -0.95, 0.5, -0.95, -1, 0.5, -0.8, -1, 0.2, -0.8, -1, 0.2, 0.8, -1, 0.2, -0.8, -1, 0.5, -0.8, -1, 0.5, -0.8, -1, 0.5, 0.8, -1, 0.2, 0.8, 0.8, 0.5, -1, 0.8, 0.2, -1, 0.95, 0.2, -0.95, 0.95, 0.2, -0.95, 0.95, 0.5, -0.95, 0.8, 0.5, -1, -0.8, 0.5, -1, -0.8, 0.2, -1, 0.8, 0.2, -1, 0.8, 0.2, -1, 0.8, 0.5, -1, -0.8, 0.5, -1, 1, 0.5, -0.8, 0.95, 0.5, -0.95, 0.95, 0.2, -0.95, 0.95, 0.2, -0.95, 1, 0.2, -0.8, 1, 0.5, -0.8, -0.8, 0.5, 1, -0.8, 0.2, 1, -0.95, 0.2, 0.95, -0.95, 0.2, 0.95, -0.95, 0.5, 0.95, -0.8, 0.5, 1, -0.95, 0.2, 0.95, -1, 0.2, 0.8, -1, 0.5, 0.8, -1, 0.5, 0.8, -0.95, 0.5, 0.95, -0.95, 0.2, 0.95, -0.8, 0.2, -1, -0.72, 0, -0.9, 0.72, 0, -0.9, 0.72, 0, -0.9, 0.8, 0.2, -1, -0.8, 0.2, -1, 1, 0.2, 0.8, 1, 0.2, -0.8, 0.9, 0, -0.72, 0.9, 0, -0.72, 0.9, 0, 0.72, 1, 0.2, 0.8, -0.95, 0.2, -0.95, -0.855, 0, -0.855, -0.72, 0, -0.9, -0.72, 0, -0.9, -0.8, 0.2, -1, -0.95, 0.2, -0.95, 1, 0.2, 0.8, 0.9, 0, 0.72, 0.855, 0, 0.855, 0.855, 0, 0.855, 0.95, 0.2, 0.95, 1, 0.2, 0.8, -0.855, 0, 0.855, -0.9, 0, 0.72, -1, 0.2, 0.8, -1, 0.2, 0.8, -0.95, 0.2, 0.95, -0.855, 0, 0.855, 0.8, 0.2, 1, 0.72, 0, 0.9, -0.72, 0, 0.9, -0.72, 0, 0.9, -0.8, 0.2, 1, 0.8, 0.2, 1, 0.95, 0.5, 0.95, 1, 0.5, 0.8, 1, 0.2, 0.8, 1, 0.2, 0.8, 0.95, 0.2, 0.95, 0.95, 0.5, 0.95, 1, 0.5, 0.8, 1, 0.5, -0.8, 1, 0.2, -0.8, 1, 0.2, -0.8, 1, 0.2, 0.8, 1, 0.5, 0.8, 1, 0.2, -0.8, 0.95, 0.2, -0.95, 0.855, 0, -0.855, 0.855, 0, -0.855, 0.9, 0, -0.72, 1, 0.2, -0.8, -0.855, 0, -0.855, -0.95, 0.2, -0.95, -1, 0.2, -0.8, -1, 0.2, -0.8, -0.9, 0, -0.72, -0.855, 0, -0.855, 0.8, 0.2, -1, 0.72, 0, -0.9, 0.855, 0, -0.855, 0.855, 0, -0.855, 0.95, 0.2, -0.95, 0.8, 0.2, -1, 0.95, 0.2, 0.95, 0.855, 0, 0.855, 0.72, 0, 0.9, 0.72, 0, 0.9, 0.8, 0.2, 1, 0.95, 0.2, 0.95, 0.855, 0, 0.855, 0.9, 0, 0.72, 0.9, 0, -0.72, 0.9, 0, -0.72, 0.855, 0, -0.855, 0.855, 0, 0.855, 0.855, 0, -0.855, 0.72, 0, 0.9, 0.855, 0, 0.855, 0.855, 0, -0.855, 0.72, 0, -0.9, 0.72, 0, 0.9, 0.72, 0, -0.9, -0.72, 0, 0.9, 0.72, 0, 0.9, 0.72, 0, -0.9, -0.72, 0, -0.9, -0.72, 0, 0.9, -0.72, 0, -0.9, -0.855, 0, -0.855, -0.72, 0, 0.9, -0.855, 0, -0.855, -0.855, 0, 0.855, -0.72, 0, 0.9, -0.855, 0, -0.855, -0.9, 0, -0.72, -0.855, 0, 0.855, -0.9, 0, -0.72, -0.9, 0, 0.72, -0.855, 0, 0.855, -0.8, 0.2, 1, -0.72, 0, 0.9, -0.855, 0, 0.855, -0.855, 0, 0.855, -0.95, 0.2, 0.95, -0.8, 0.2, 1, 0.95, 0.5, 0.95, 0.95, 0.2, 0.95, 0.8, 0.2, 1, 0.8, 0.2, 1, 0.8, 0.5, 1, 0.95, 0.5, 0.95, 0.8, 0.5, 1, 0.8, 0.2, 1, -0.8, 0.2, 1, -0.8, 0.2, 1, -0.8, 0.5, 1, 0.8, 0.5, 1, -0.95, 0.5, 0.95, -1, 0.5, 0.8, -1, 0.5, -0.8, -0.95, 0.5, 0.95, -1, 0.5, -0.8, -0.95, 0.5, -0.95, -0.8, 0.5, 1, -0.95, 0.5, 0.95, -0.95, 0.5, -0.95, -0.8, 0.5, 0.7675, -0.8, 0.5, 1, -0.95, 0.5, -0.95, -0.8, 0.5, -0.7675, -0.8, 0.5, 0.7675, -0.95, 0.5, -0.95, -0.8, 0.5, 1, -0.8, 0.5, 0.7675, -0.7919, 0.5, 0.7919, -0.8, 0.5, 1, -0.7919, 0.5, 0.7919, -0.7675, 0.5, 0.8, -0.8, 0.5, 1, -0.7675, 0.5, 0.8, 0.7675, 0.5, 0.8, -0.8, 0.5, -0.7675, -0.95, 0.5, -0.95, -0.8, 0.5, -1, 0.8, 0.5, 1, -0.8, 0.5, 1, 0.7675, 0.5, 0.8, -0.7919, 0.5, -0.7919, -0.8, 0.5, -0.7675, -0.8, 0.5, -1, -0.7675, 0.5, -0.8, -0.7919, 0.5, -0.7919, -0.8, 0.5, -1, 0.7675, 0.5, -0.8, -0.7675, 0.5, -0.8, -0.8, 0.5, -1, 0.8, 0.5, 1, 0.7675, 0.5, 0.8, 0.7919, 0.5, 0.7919, 0.7675, 0.5, -0.8, -0.8, 0.5, -1, 0.8, 0.5, -1, 0.7919, 0.5, -0.7919, 0.7675, 0.5, -0.8, 0.8, 0.5, -1, 0.8, 0.5, -0.7675, 0.7919, 0.5, -0.7919, 0.8, 0.5, -1, 0.8, 0.5, 0.7675, 0.8, 0.5, -0.7675, 0.8, 0.5, -1, 0.8, 0.5, 1, 0.7919, 0.5, 0.7919, 0.8, 0.5, 0.7675, 0.8, 0.5, -1, 0.95, 0.5, -0.95, 0.8, 0.5, 0.7675, 0.8, 0.5, 1, 0.8, 0.5, 0.7675, 0.95, 0.5, -0.95, 0.95, 0.5, 0.95, 0.8, 0.5, 1, 0.95, 0.5, -0.95, 0.95, 0.5, 0.95, 0.95, 0.5, -0.95, 1, 0.5, -0.8, 1, 0.5, -0.8, 1, 0.5, 0.8, 0.95, 0.5, 0.95, 0.8, 0.5, -0.7675, 0.8, 0.5, 0.7675, 0.7919, 0.5, 0.7919, 0.7919, 0.5, 0.7919, 0.7919, 0.5, -0.7919, 0.8, 0.5, -0.7675, 0.7919, 0.5, 0.7919, 0.7675, 0.5, 0.8, 0.7919, 0.5, -0.7919, 0.7675, 0.5, 0.8, 0.7675, 0.5, -0.8, 0.7919, 0.5, -0.7919, 0.7675, 0.5, 0.8, 0.6, 0.5, -0.6, 0.7675, 0.5, -0.8, 0.6, 0.5, -0.6, -0.7675, 0.5, -0.8, 0.7675, 0.5, -0.8, 0.7675, 0.5, 0.8, 0.6, 0.5, 0.6, 0.6, 0.5, -0.6, 0.6, 0.5, -0.6, -0.6, 0.5, -0.6, -0.7675, 0.5, -0.8, 0.6, 0.5, 0.6, 0.7675, 0.5, 0.8, -0.7675, 0.5, 0.8, -0.6, 0.5, -0.6, -0.6, 0.5, 0.6, -0.7675, 0.5, -0.8, -0.7675, 0.5, 0.8, -0.6, 0.5, 0.6, 0.6, 0.5, 0.6, -0.7675, 0.5, 0.8, -0.7675, 0.5, -0.8, -0.6, 0.5, 0.6, -0.7675, 0.5, 0.8, -0.7919, 0.5, -0.7919, -0.7675, 0.5, -0.8, -0.7675, 0.5, 0.8, -0.7919, 0.5, 0.7919, -0.7919, 0.5, -0.7919, -0.7919, 0.5, 0.7919, -0.8, 0.5, -0.7675, -0.7919, 0.5, -0.7919, -0.7919, 0.5, 0.7919, -0.8, 0.5, 0.7675, -0.8, 0.5, -0.7675, 0.6, 0.5, -0.6, 0.6, 0.5, 0.6, -0.6, 0.5, 0.6, -0.6, 0.5, 0.6, -0.6, 0.5, -0.6, 0.6, 0.5, -0.6, 0.7, 0.4, 0.7, 0.7, 0.2, 0.7, 1.1, 0.2, 0.7, 1.1, 0.2, 0.7, 1.1, 0.4, 0.7, 0.7, 0.4, 0.7, 0.7, 0.4, 0.7, 1.1, 0.4, 0.7, 1.1, 0.4, 0.8162, 1.1, 0.4, 0.8162, 1.0291, 0.4, 1.0291, 0.7, 0.4, 0.7, 1.0291, 0.4, 1.0291, 0.8162, 0.4, 1.1, 0.7, 0.4, 0.7, 0.8162, 0.4, 1.1, 0.7, 0.4, 1.1, 0.7, 0.4, 0.7, 1.1, 0.2, 0.8162, 1.1, 0.2, 0.7, 0.7, 0.2, 0.7, 0.7, 0.2, 0.7, 1.0291, 0.2, 1.0291, 1.1, 0.2, 0.8162, 0.7, 0.2, 0.7, 0.8162, 0.2, 1.1, 1.0291, 0.2, 1.0291, 0.7, 0.2, 0.7, 0.7, 0.2, 1.1, 0.8162, 0.2, 1.1, 1.0291, 0.4, 1.0291, 1.0291, 0.2, 1.0291, 0.8162, 0.2, 1.1, 0.8162, 0.2, 1.1, 0.8162, 0.4, 1.1, 1.0291, 0.4, 1.0291, 1.0291, 0.4, 1.0291, 1.1, 0.4, 0.8162, 1.1, 0.2, 0.8162, 1.1, 0.2, 0.8162, 1.0291, 0.2, 1.0291, 1.0291, 0.4, 1.0291, 1.1, 0.4, 0.8162, 1.1, 0.4, 0.7, 1.1, 0.2, 0.7, 1.1, 0.2, 0.7, 1.1, 0.2, 0.8162, 1.1, 0.4, 0.8162, 0.8162, 0.4, 1.1, 0.8162, 0.2, 1.1, 0.7, 0.2, 1.1, 0.7, 0.2, 1.1, 0.7, 0.4, 1.1, 0.8162, 0.4, 1.1, 0.7, 0.2, 1.1, 0.7, 0.2, 0.7, 0.7, 0.4, 0.7, 0.7, 0.4, 0.7, 0.7, 0.4, 1.1, 0.7, 0.2, 1.1, 1.1, 0.4, -0.7, 1.1, 0.2, -0.7, 0.7, 0.2, -0.7, 0.7, 0.2, -0.7, 0.7, 0.4, -0.7, 1.1, 0.4, -0.7, 1.1, 0.4, -0.8162, 1.1, 0.4, -0.7, 0.7, 0.4, -0.7, 0.7, 0.4, -0.7, 1.0291, 0.4, -1.0291, 1.1, 0.4, -0.8162, 0.7, 0.4, -0.7, 0.8162, 0.4, -1.1, 1.0291, 0.4, -1.0291, 0.7, 0.4, -0.7, 0.7, 0.4, -1.1, 0.8162, 0.4, -1.1, 0.7, 0.2, -0.7, 1.1, 0.2, -0.7, 1.1, 0.2, -0.8162, 1.1, 0.2, -0.8162, 1.0291, 0.2, -1.0291, 0.7, 0.2, -0.7, 1.0291, 0.2, -1.0291, 0.8162, 0.2, -1.1, 0.7, 0.2, -0.7, 0.8162, 0.2, -1.1, 0.7, 0.2, -1.1, 0.7, 0.2, -0.7, 0.7, 0.4, -1.1, 0.7, 0.2, -1.1, 0.8162, 0.2, -1.1, 0.8162, 0.2, -1.1, 0.8162, 0.4, -1.1, 0.7, 0.4, -1.1, 0.7, 0.2, -0.7, 0.7, 0.2, -1.1, 0.7, 0.4, -1.1, 0.7, 0.4, -1.1, 0.7, 0.4, -0.7, 0.7, 0.2, -0.7, 1.1, 0.4, -0.7, 1.1, 0.4, -0.8162, 1.1, 0.2, -0.8162, 1.1, 0.2, -0.8162, 1.1, 0.2, -0.7, 1.1, 0.4, -0.7, 1.1, 0.4, -0.8162, 1.0291, 0.4, -1.0291, 1.0291, 0.2, -1.0291, 1.0291, 0.2, -1.0291, 1.1, 0.2, -0.8162, 1.1, 0.4, -0.8162, 0.8162, 0.4, -1.1, 0.8162, 0.2, -1.1, 1.0291, 0.2, -1.0291, 1.0291, 0.2, -1.0291, 1.0291, 0.4, -1.0291, 0.8162, 0.4, -1.1, -1.1, 0.2, -0.7, -1.1, 0.2, -0.8162, -1.1, 0.4, -0.8162, -1.1, 0.4, -0.8162, -1.1, 0.4, -0.7, -1.1, 0.2, -0.7, -0.8162, 0.4, -1.1, -0.8162, 0.2, -1.1, -0.7, 0.2, -1.1, -0.7, 0.2, -1.1, -0.7, 0.4, -1.1, -0.8162, 0.4, -1.1, -0.8162, 0.4, -1.1, -0.7, 0.4, -1.1, -0.7, 0.4, -0.7, -0.7, 0.4, -0.7, -1.1, 0.4, -0.7, -0.8162, 0.4, -1.1, -1.1, 0.4, -0.7, -1.0291, 0.4, -1.0291, -0.8162, 0.4, -1.1, -1.1, 0.4, -0.7, -1.1, 0.4, -0.8162, -1.0291, 0.4, -1.0291, -0.7, 0.4, -0.7, -0.7, 0.4, -1.1, -0.7, 0.2, -1.1, -0.7, 0.2, -1.1, -0.7, 0.2, -0.7, -0.7, 0.4, -0.7, -0.7, 0.4, -0.7, -0.7, 0.2, -0.7, -1.1, 0.2, -0.7, -1.1, 0.2, -0.7, -1.1, 0.4, -0.7, -0.7, 0.4, -0.7, -1.0291, 0.4, -1.0291, -1.0291, 0.2, -1.0291, -0.8162, 0.2, -1.1, -0.8162, 0.2, -1.1, -0.8162, 0.4, -1.1, -1.0291, 0.4, -1.0291, -1.1, 0.2, -0.8162, -1.0291, 0.2, -1.0291, -1.0291, 0.4, -1.0291, -1.0291, 0.4, -1.0291, -1.1, 0.4, -0.8162, -1.1, 0.2, -0.8162, -0.7, 0.2, -0.7, -0.7, 0.2, -1.1, -0.8162, 0.2, -1.1, -0.8162, 0.2, -1.1, -1.1, 0.2, -0.7, -0.7, 0.2, -0.7, -0.8162, 0.2, -1.1, -1.0291, 0.2, -1.0291, -1.1, 0.2, -0.7, -1.0291, 0.2, -1.0291, -1.1, 0.2, -0.8162, -1.1, 0.2, -0.7, -0.8162, 0.2, 1.1, -0.7, 0.2, 1.1, -0.7, 0.2, 0.7, -0.7, 0.2, 0.7, -1.1, 0.2, 0.7, -0.8162, 0.2, 1.1, -1.1, 0.2, 0.7, -1.0291, 0.2, 1.0291, -0.8162, 0.2, 1.1, -1.1, 0.2, 0.7, -1.1, 0.2, 0.8162, -1.0291, 0.2, 1.0291, -1.1, 0.4, 0.7, -0.7, 0.4, 0.7, -0.7, 0.4, 1.1, -0.7, 0.4, 1.1, -0.8162, 0.4, 1.1, -1.1, 0.4, 0.7, -0.8162, 0.4, 1.1, -1.0291, 0.4, 1.0291, -1.1, 0.4, 0.7, -1.0291, 0.4, 1.0291, -1.1, 0.4, 0.8162, -1.1, 0.4, 0.7, -1.0291, 0.2, 1.0291, -1.1, 0.2, 0.8162, -1.1, 0.4, 0.8162, -1.1, 0.4, 0.8162, -1.0291, 0.4, 1.0291, -1.0291, 0.2, 1.0291, -1.1, 0.2, 0.8162, -1.1, 0.2, 0.7, -1.1, 0.4, 0.7, -1.1, 0.4, 0.7, -1.1, 0.4, 0.8162, -1.1, 0.2, 0.8162, -0.7, 0.4, 1.1, -0.7, 0.4, 0.7, -0.7, 0.2, 0.7, -0.7, 0.2, 0.7, -0.7, 0.2, 1.1, -0.7, 0.4, 1.1, -0.7, 0.4, 1.1, -0.7, 0.2, 1.1, -0.8162, 0.2, 1.1, -0.8162, 0.2, 1.1, -0.8162, 0.4, 1.1, -0.7, 0.4, 1.1, -0.8162, 0.4, 1.1, -0.8162, 0.2, 1.1, -1.0291, 0.2, 1.0291, -1.0291, 0.2, 1.0291, -1.0291, 0.4, 1.0291, -0.8162, 0.4, 1.1, -1.1, 0.4, 0.7, -1.1, 0.2, 0.7, -0.7, 0.2, 0.7, -0.7, 0.2, 0.7, -0.7, 0.4, 0.7, -1.1, 0.4, 0.7) 8 | 9 | [sub_resource type="BoxShape3D" id="BoxShape3D_t551e"] 10 | size = Vector3(2, 0.1, 2) 11 | 12 | [node name="platform-falling" instance=ExtResource("1_gkggt")] 13 | script = ExtResource("2_6ganw") 14 | 15 | [node name="StaticBody3D" type="StaticBody3D" parent="platform-falling2" index="0"] 16 | 17 | [node name="CollisionShape3D" type="CollisionShape3D" parent="platform-falling2/StaticBody3D" index="0"] 18 | shape = SubResource("ConcavePolygonShape3D_4mmvt") 19 | 20 | [node name="Area3D" type="Area3D" parent="." index="1"] 21 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.6, 0) 22 | 23 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Area3D" index="0"] 24 | shape = SubResource("BoxShape3D_t551e") 25 | 26 | [connection signal="body_entered" from="Area3D" to="." method="_on_body_entered"] 27 | -------------------------------------------------------------------------------- /objects/platform_grass_large_round.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=3 uid="uid://uqr4hswv6d2g"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://fqfc0dtl2xlc" path="res://models/platform-grass-large-round.glb" id="1_k36fp"] 4 | [ext_resource type="PackedScene" uid="uid://dkw27llxh1d4w" path="res://models/grass-small.glb" id="2_dmbou"] 5 | [ext_resource type="PackedScene" uid="uid://blqf5cwsk25xj" path="res://models/grass.glb" id="3_uynxe"] 6 | 7 | [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_xh0ma"] 8 | data = PackedVector3Array(-0.9567, 0.2, 2.3097, 0, 0.2, 2.5, 0, 0, 2.25, 0, 0, 2.25, -0.861, 0, 2.0787, -0.9567, 0.2, 2.3097, 1.7678, 0.2, 1.7678, 2.3097, 0.2, 0.9567, 2.0787, 0, 0.861, 2.0787, 0, 0.861, 1.591, 0, 1.591, 1.7678, 0.2, 1.7678, 2.0787, 0, -0.861, 2.3097, 0.2, -0.9567, 1.7678, 0.2, -1.7678, 1.7678, 0.2, -1.7678, 1.591, 0, -1.591, 2.0787, 0, -0.861, -2.0787, 0, -0.861, -1.591, 0, -1.591, -1.7678, 0.2, -1.7678, -1.7678, 0.2, -1.7678, -2.3097, 0.2, -0.9567, -2.0787, 0, -0.861, -2.25, 0, 0, -2.0787, 0, -0.861, -2.3097, 0.2, -0.9567, -2.3097, 0.2, -0.9567, -2.5, 0.2, 0, -2.25, 0, 0, 2.25, 0, 0, 2.5, 0.2, 0, 2.3097, 0.2, -0.9567, 2.3097, 0.2, -0.9567, 2.0787, 0, -0.861, 2.25, 0, 0, -1.591, 0, -1.591, -0.861, 0, -2.0787, -0.9567, 0.2, -2.3097, -0.9567, 0.2, -2.3097, -1.7678, 0.2, -1.7678, -1.591, 0, -1.591, 2.3097, 0.2, 0.9567, 2.5, 0.2, 0, 2.25, 0, 0, 2.25, 0, 0, 2.0787, 0, 0.861, 2.3097, 0.2, 0.9567, -2.3097, 0.2, 0.9567, -2.0787, 0, 0.861, -2.25, 0, 0, -2.25, 0, 0, -2.5, 0.2, 0, -2.3097, 0.2, 0.9567, 0.861, 0, -2.0787, 0.9567, 0.2, -2.3097, 0, 0.2, -2.5, 0, 0.2, -2.5, 0, 0, -2.25, 0.861, 0, -2.0787, 1.591, 0, -1.591, 1.7678, 0.2, -1.7678, 0.9567, 0.2, -2.3097, 0.9567, 0.2, -2.3097, 0.861, 0, -2.0787, 1.591, 0, -1.591, 0.9567, 0.2, 2.3097, 1.7678, 0.2, 1.7678, 1.591, 0, 1.591, 1.591, 0, 1.591, 0.861, 0, 2.0787, 0.9567, 0.2, 2.3097, -0.9567, 0.2, 2.3097, -0.861, 0, 2.0787, -1.591, 0, 1.591, -1.591, 0, 1.591, -1.7678, 0.2, 1.7678, -0.9567, 0.2, 2.3097, -1.7678, 0.2, 1.7678, -1.591, 0, 1.591, -2.0787, 0, 0.861, -2.0787, 0, 0.861, -2.3097, 0.2, 0.9567, -1.7678, 0.2, 1.7678, -0.861, 0, -2.0787, 0, 0, -2.25, 0, 0.2, -2.5, 0, 0.2, -2.5, -0.9567, 0.2, -2.3097, -0.861, 0, -2.0787, 0, 0.2, 2.5, 0.9567, 0.2, 2.3097, 0.861, 0, 2.0787, 0.861, 0, 2.0787, 0, 0, 2.25, 0, 0.2, 2.5, -1.7678, 0.5, -1.7678, -1.7678, 0.2, -1.7678, -0.9567, 0.2, -2.3097, -0.9567, 0.2, -2.3097, -0.9567, 0.5, -2.3097, -1.7678, 0.5, -1.7678, 2.3097, 0.5, 0.9567, 2.5, 0.5, 0, 2.5, 0.2, 0, 2.5, 0.2, 0, 2.3097, 0.2, 0.9567, 2.3097, 0.5, 0.9567, -2.3097, 0.2, -0.9567, -1.7678, 0.2, -1.7678, -1.7678, 0.5, -1.7678, -1.7678, 0.5, -1.7678, -2.3097, 0.5, -0.9567, -2.3097, 0.2, -0.9567, 0, 0.5, 2.5, 0, 0.2, 2.5, -0.9567, 0.2, 2.3097, -0.9567, 0.2, 2.3097, -0.9567, 0.5, 2.3097, 0, 0.5, 2.5, -0.9567, 0.5, 2.3097, -0.9567, 0.2, 2.3097, -1.7678, 0.2, 1.7678, -1.7678, 0.2, 1.7678, -1.7678, 0.5, 1.7678, -0.9567, 0.5, 2.3097, -2.5, 0.2, 0, -2.3097, 0.2, -0.9567, -2.3097, 0.5, -0.9567, -2.3097, 0.5, -0.9567, -2.5, 0.5, 0, -2.5, 0.2, 0, -1.7678, 0.2, 1.7678, -2.3097, 0.2, 0.9567, -2.3097, 0.5, 0.9567, -2.3097, 0.5, 0.9567, -1.7678, 0.5, 1.7678, -1.7678, 0.2, 1.7678, 0.9567, 0.5, 2.3097, 0.9567, 0.2, 2.3097, 0, 0.2, 2.5, 0, 0.2, 2.5, 0, 0.5, 2.5, 0.9567, 0.5, 2.3097, 1.7678, 0.5, 1.7678, 2.3097, 0.5, 0.9567, 2.3097, 0.2, 0.9567, 2.3097, 0.2, 0.9567, 1.7678, 0.2, 1.7678, 1.7678, 0.5, 1.7678, 1.7678, 0.5, 1.7678, 1.7678, 0.2, 1.7678, 0.9567, 0.2, 2.3097, 0.9567, 0.2, 2.3097, 0.9567, 0.5, 2.3097, 1.7678, 0.5, 1.7678, -2.3097, 0.2, 0.9567, -2.5, 0.2, 0, -2.5, 0.5, 0, -2.5, 0.5, 0, -2.3097, 0.5, 0.9567, -2.3097, 0.2, 0.9567, 2.0787, 0, 0.861, 2.25, 0, 0, 2.0787, 0, -0.861, 2.0787, 0, -0.861, 1.591, 0, 1.591, 2.0787, 0, 0.861, 2.0787, 0, -0.861, 1.591, 0, -1.591, 1.591, 0, 1.591, 1.591, 0, -1.591, 0.861, 0, 2.0787, 1.591, 0, 1.591, 1.591, 0, -1.591, 0.861, 0, -2.0787, 0.861, 0, 2.0787, 0.861, 0, -2.0787, 0, 0, 2.25, 0.861, 0, 2.0787, 0.861, 0, -2.0787, 0, 0, -2.25, 0, 0, 2.25, 0, 0, -2.25, -0.861, 0, 2.0787, 0, 0, 2.25, 0, 0, -2.25, -0.861, 0, -2.0787, -0.861, 0, 2.0787, -0.861, 0, -2.0787, -1.591, 0, -1.591, -0.861, 0, 2.0787, -1.591, 0, -1.591, -1.591, 0, 1.591, -0.861, 0, 2.0787, -1.591, 0, -1.591, -2.0787, 0, 0.861, -1.591, 0, 1.591, -1.591, 0, -1.591, -2.0787, 0, -0.861, -2.0787, 0, 0.861, -2.0787, 0, -0.861, -2.25, 0, 0, -2.0787, 0, 0.861, 0, 0.5, -2.5, 0, 0.2, -2.5, 0.9567, 0.2, -2.3097, 0.9567, 0.2, -2.3097, 0.9567, 0.5, -2.3097, 0, 0.5, -2.5, 0.9567, 0.5, -2.3097, 0.9567, 0.2, -2.3097, 1.7678, 0.2, -1.7678, 1.7678, 0.2, -1.7678, 1.7678, 0.5, -1.7678, 0.9567, 0.5, -2.3097, 2.3097, 0.5, -0.9567, 1.7678, 0.5, -1.7678, 1.7678, 0.2, -1.7678, 1.7678, 0.2, -1.7678, 2.3097, 0.2, -0.9567, 2.3097, 0.5, -0.9567, 2.5, 0.5, 0, 2.3097, 0.5, -0.9567, 2.3097, 0.2, -0.9567, 2.3097, 0.2, -0.9567, 2.5, 0.2, 0, 2.5, 0.5, 0, 2.3097, 0.5, -0.9567, 2.5, 0.5, 0, 2.3097, 0.5, 0.9567, 2.3097, 0.5, 0.9567, 2.2961, 0.5, 0, 2.3097, 0.5, -0.9567, 2.2961, 0.5, 0, 2.1213, 0.5, -0.8787, 2.3097, 0.5, -0.9567, 2.1213, 0.5, 0.8787, 2.2961, 0.5, 0, 2.3097, 0.5, 0.9567, 2.1213, 0.5, -0.8787, 1.7678, 0.5, -1.7678, 2.3097, 0.5, -0.9567, 2.3097, 0.5, 0.9567, 1.7678, 0.5, 1.7678, 2.1213, 0.5, 0.8787, 2.1213, 0.5, -0.8787, 1.6236, 0.5, -1.6236, 1.7678, 0.5, -1.7678, 1.7678, 0.5, 1.7678, 1.6236, 0.5, 1.6236, 2.1213, 0.5, 0.8787, 1.6236, 0.5, -1.6236, 0.9567, 0.5, -2.3097, 1.7678, 0.5, -1.7678, 1.7678, 0.5, 1.7678, 0.9567, 0.5, 2.3097, 1.6236, 0.5, 1.6236, 1.6236, 0.5, -1.6236, 0.8787, 0.5, -2.1213, 0.9567, 0.5, -2.3097, 0.9567, 0.5, 2.3097, 0.8787, 0.5, 2.1213, 1.6236, 0.5, 1.6236, 0.8787, 0.5, -2.1213, 0, 0.5, -2.5, 0.9567, 0.5, -2.3097, 0.8787, 0.5, -2.1213, 0, 0.5, -2.2961, 0, 0.5, -2.5, 0.9567, 0.5, 2.3097, 0, 0.5, 2.5, 0.8787, 0.5, 2.1213, 0, 0.5, 2.5, 0, 0.5, 2.2961, 0.8787, 0.5, 2.1213, 0, 0.5, 2.5, -0.8787, 0.5, 2.1213, 0, 0.5, 2.2961, 0, 0.5, 2.5, -0.9567, 0.5, 2.3097, -0.8787, 0.5, 2.1213, -0.9567, 0.5, 2.3097, -1.6236, 0.5, 1.6236, -0.8787, 0.5, 2.1213, -0.9567, 0.5, 2.3097, -1.7678, 0.5, 1.7678, -1.6236, 0.5, 1.6236, -1.7678, 0.5, 1.7678, -2.1213, 0.5, 0.8787, -1.6236, 0.5, 1.6236, 0, 0.5, -2.2961, -0.9567, 0.5, -2.3097, 0, 0.5, -2.5, 0, 0.5, -2.2961, -0.8787, 0.5, -2.1213, -0.9567, 0.5, -2.3097, -0.8787, 0.5, -2.1213, -1.6236, 0.5, -1.6236, -0.9567, 0.5, -2.3097, -1.6236, 0.5, -1.6236, -1.7678, 0.5, -1.7678, -0.9567, 0.5, -2.3097, -1.6236, 0.5, -1.6236, -2.1213, 0.5, -0.8787, -1.7678, 0.5, -1.7678, -1.7678, 0.5, 1.7678, -2.3097, 0.5, 0.9567, -2.1213, 0.5, 0.8787, -2.1213, 0.5, -0.8787, -2.3097, 0.5, -0.9567, -1.7678, 0.5, -1.7678, -2.3097, 0.5, 0.9567, -2.2961, 0.5, 0, -2.1213, 0.5, 0.8787, -2.1213, 0.5, -0.8787, -2.2961, 0.5, 0, -2.3097, 0.5, -0.9567, -2.3097, 0.5, 0.9567, -2.3097, 0.5, -0.9567, -2.2961, 0.5, 0, -2.3097, 0.5, 0.9567, -2.5, 0.5, 0, -2.3097, 0.5, -0.9567, -0.9567, 0.5, -2.3097, -0.9567, 0.2, -2.3097, 0, 0.2, -2.5, 0, 0.2, -2.5, 0, 0.5, -2.5, -0.9567, 0.5, -2.3097, 2.1213, 0.5, -0.8787, 2.2961, 0.5, 0, 2.1213, 0.5, 0.8787, 2.1213, 0.5, 0.8787, 1.6236, 0.5, -1.6236, 2.1213, 0.5, -0.8787, 2.1213, 0.5, 0.8787, 1.6236, 0.5, 1.6236, 1.6236, 0.5, -1.6236, 1.6236, 0.5, 1.6236, 0.8787, 0.5, -2.1213, 1.6236, 0.5, -1.6236, 1.6236, 0.5, 1.6236, 0.8787, 0.5, 2.1213, 0.8787, 0.5, -2.1213, 0.8787, 0.5, 2.1213, 0, 0.5, -2.2961, 0.8787, 0.5, -2.1213, 0.8787, 0.5, 2.1213, 0, 0.5, 2.2961, 0, 0.5, -2.2961, 0, 0.5, 2.2961, -0.8787, 0.5, 2.1213, 0, 0.5, -2.2961, -0.8787, 0.5, 2.1213, -0.8787, 0.5, -2.1213, 0, 0.5, -2.2961, -0.8787, 0.5, 2.1213, -1.6236, 0.5, -1.6236, -0.8787, 0.5, -2.1213, -0.8787, 0.5, 2.1213, -1.6236, 0.5, 1.6236, -1.6236, 0.5, -1.6236, -1.6236, 0.5, 1.6236, -2.1213, 0.5, -0.8787, -1.6236, 0.5, -1.6236, -1.6236, 0.5, 1.6236, -2.1213, 0.5, 0.8787, -2.1213, 0.5, -0.8787, -2.1213, 0.5, 0.8787, -2.2961, 0.5, 0, -2.1213, 0.5, -0.8787) 9 | 10 | [node name="platform-grass-large-round" instance=ExtResource("1_k36fp")] 11 | 12 | [node name="grass-small" parent="." index="0" instance=ExtResource("2_dmbou")] 13 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.33068, 0.495496, 4.08559) 14 | 15 | [node name="grass-small2" parent="." index="1" instance=ExtResource("2_dmbou")] 16 | transform = Transform3D(0.352495, 0, -0.935814, 0, 1, 0, 0.935814, 0, 0.352495, 1.13637, 0.495496, 4.08559) 17 | 18 | [node name="grass" parent="." index="2" instance=ExtResource("3_uynxe")] 19 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.66267, 0.443581, 3.83396) 20 | 21 | [node name="grass3" parent="." index="3" instance=ExtResource("3_uynxe")] 22 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.224619, 0.443581, 0.451932) 23 | 24 | [node name="grass4" parent="." index="4" instance=ExtResource("3_uynxe")] 25 | transform = Transform3D(0.742432, 0, 0.669921, 0, 1, 0, -0.669921, 0, 0.742432, 2.96463, 0.443581, 2.23451) 26 | 27 | [node name="grass2" parent="." index="5" instance=ExtResource("3_uynxe")] 28 | transform = Transform3D(-0.402795, 0, 0.91529, 0, 1, 0, -0.91529, 0, -0.402795, 2.39318, 0.466624, -4.4154) 29 | 30 | [node name="grass-small13" parent="." index="6" instance=ExtResource("2_dmbou")] 31 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.7734, 0.495496, 4.08559) 32 | 33 | [node name="grass-small14" parent="." index="7" instance=ExtResource("2_dmbou")] 34 | transform = Transform3D(0.352495, 0, -0.935814, 0, 1, 0, 0.935814, 0, 0.352495, -3.60211, 0.495496, -8.49426) 35 | 36 | [node name="grass25" parent="." index="8" instance=ExtResource("3_uynxe")] 37 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.78001, 0.443581, 3.83396) 38 | 39 | [node name="grass26" parent="." index="9" instance=ExtResource("3_uynxe")] 40 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.6673, 0.443581, 0.451932) 41 | 42 | [node name="grass27" parent="." index="10" instance=ExtResource("3_uynxe")] 43 | transform = Transform3D(0.742432, 0, 0.669921, 0, 1, 0, -0.669921, 0, 0.742432, -7.01565, 0.443581, 11.24) 44 | 45 | [node name="grass28" parent="." index="11" instance=ExtResource("3_uynxe")] 46 | transform = Transform3D(-0.402795, 0, 0.91529, 0, 1, 0, -0.91529, 0, -0.402795, 7.80782, 0.466624, 7.88855) 47 | 48 | [node name="grass-small15" parent="." index="12" instance=ExtResource("2_dmbou")] 49 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -28.8572, 0.495496, 4.08559) 50 | 51 | [node name="grass-small16" parent="." index="13" instance=ExtResource("2_dmbou")] 52 | transform = Transform3D(0.352495, 0, -0.935814, 0, 1, 0, 0.935814, 0, 0.352495, -7.8616, 0.495496, -19.8025) 53 | 54 | [node name="grass29" parent="." index="14" instance=ExtResource("3_uynxe")] 55 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.8638, 0.443581, 3.83396) 56 | 57 | [node name="grass30" parent="." index="15" instance=ExtResource("3_uynxe")] 58 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -25.7511, 0.443581, 0.451932) 59 | 60 | [node name="grass31" parent="." index="16" instance=ExtResource("3_uynxe")] 61 | transform = Transform3D(0.742432, 0, 0.669921, 0, 1, 0, -0.669921, 0, 0.742432, -15.9871, 0.443581, 19.3353) 62 | 63 | [node name="grass32" parent="." index="17" instance=ExtResource("3_uynxe")] 64 | transform = Transform3D(-0.402795, 0, 0.91529, 0, 1, 0, -0.91529, 0, -0.402795, 12.6751, 0.466624, 18.9488) 65 | 66 | [node name="grass-small17" parent="." index="18" instance=ExtResource("2_dmbou")] 67 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -44.2053, 0.495496, 4.08559) 68 | 69 | [node name="grass-small18" parent="." index="19" instance=ExtResource("2_dmbou")] 70 | transform = Transform3D(0.352495, 0, -0.935814, 0, 1, 0, 0.935814, 0, 0.352495, -13.2717, 0.495496, -34.1654) 71 | 72 | [node name="grass33" parent="." index="20" instance=ExtResource("3_uynxe")] 73 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -37.2119, 0.443581, 3.83396) 74 | 75 | [node name="grass34" parent="." index="21" instance=ExtResource("3_uynxe")] 76 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -41.0992, 0.443581, 0.451932) 77 | 78 | [node name="grass35" parent="." index="22" instance=ExtResource("3_uynxe")] 79 | transform = Transform3D(0.742432, 0, 0.669921, 0, 1, 0, -0.669921, 0, 0.742432, -27.382, 0.443581, 29.6172) 80 | 81 | [node name="grass36" parent="." index="23" instance=ExtResource("3_uynxe")] 82 | transform = Transform3D(-0.402795, 0, 0.91529, 0, 1, 0, -0.91529, 0, -0.402795, 18.8573, 0.466624, 32.9967) 83 | 84 | [node name="grass-small3" parent="." index="24" instance=ExtResource("2_dmbou")] 85 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.52018, 0.495496, 4.08559) 86 | 87 | [node name="grass-small4" parent="." index="25" instance=ExtResource("2_dmbou")] 88 | transform = Transform3D(0.352495, 0, -0.935814, 0, 1, 0, 0.935814, 0, 0.352495, 4.96124, 0.495496, 14.24) 89 | 90 | [node name="grass5" parent="." index="26" instance=ExtResource("3_uynxe")] 91 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.5135, 0.443581, 3.83396) 92 | 93 | [node name="grass6" parent="." index="27" instance=ExtResource("3_uynxe")] 94 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.6262, 0.443581, 0.451932) 95 | 96 | [node name="grass7" parent="." index="28" instance=ExtResource("3_uynxe")] 97 | transform = Transform3D(0.742432, 0, 0.669921, 0, 1, 0, -0.669921, 0, 0.742432, 11.0207, 0.443581, -5.03471) 98 | 99 | [node name="grass8" parent="." index="29" instance=ExtResource("3_uynxe")] 100 | transform = Transform3D(-0.402795, 0, 0.91529, 0, 1, 0, -0.91529, 0, -0.402795, -1.97749, 0.466624, -14.3471) 101 | 102 | [node name="grass-small5" parent="." index="30" instance=ExtResource("2_dmbou")] 103 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.52018, 0.495496, 15.023) 104 | 105 | [node name="grass-small6" parent="." index="31" instance=ExtResource("2_dmbou")] 106 | transform = Transform3D(0.352495, 0, -0.935814, 0, 1, 0, 0.935814, 0, 0.352495, -5.27415, 0.495496, 18.0954) 107 | 108 | [node name="grass9" parent="." index="32" instance=ExtResource("3_uynxe")] 109 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.5135, 0.443581, 14.7714) 110 | 111 | [node name="grass10" parent="." index="33" instance=ExtResource("3_uynxe")] 112 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.6262, 0.443581, 11.3894) 113 | 114 | [node name="grass11" parent="." index="34" instance=ExtResource("3_uynxe")] 115 | transform = Transform3D(0.742432, 0, 0.669921, 0, 1, 0, -0.669921, 0, 0.742432, 18.3479, 0.443581, 3.08558) 116 | 117 | [node name="grass12" parent="." index="35" instance=ExtResource("3_uynxe")] 118 | transform = Transform3D(-0.402795, 0, 0.91529, 0, 1, 0, -0.91529, 0, -0.402795, 8.03342, 0.466624, -18.7526) 119 | 120 | [node name="grass-small7" parent="." index="36" instance=ExtResource("2_dmbou")] 121 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.52018, 0.495496, 28.0813) 122 | 123 | [node name="grass-small8" parent="." index="37" instance=ExtResource("2_dmbou")] 124 | transform = Transform3D(0.352495, 0, -0.935814, 0, 1, 0, 0.935814, 0, 0.352495, -17.4943, 0.495496, 22.6984) 125 | 126 | [node name="grass13" parent="." index="38" instance=ExtResource("3_uynxe")] 127 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.5135, 0.443581, 27.8297) 128 | 129 | [node name="grass14" parent="." index="39" instance=ExtResource("3_uynxe")] 130 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.6262, 0.443581, 24.4477) 131 | 132 | [node name="grass15" parent="." index="40" instance=ExtResource("3_uynxe")] 133 | transform = Transform3D(0.742432, 0, 0.669921, 0, 1, 0, -0.669921, 0, 0.742432, 27.0959, 0.443581, 12.7805) 134 | 135 | [node name="grass16" parent="." index="41" instance=ExtResource("3_uynxe")] 136 | transform = Transform3D(-0.402795, 0, 0.91529, 0, 1, 0, -0.91529, 0, -0.402795, 19.9856, 0.466624, -24.0125) 137 | 138 | [node name="grass-small9" parent="." index="42" instance=ExtResource("2_dmbou")] 139 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 20.2955, 0.495496, 28.0813) 140 | 141 | [node name="grass-small10" parent="." index="43" instance=ExtResource("2_dmbou")] 142 | transform = Transform3D(0.352495, 0, -0.935814, 0, 1, 0, 0.935814, 0, 0.352495, -12.9911, 0.495496, 34.6537) 143 | 144 | [node name="grass17" parent="." index="44" instance=ExtResource("3_uynxe")] 145 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 27.2888, 0.443581, 27.8297) 146 | 147 | [node name="grass18" parent="." index="45" instance=ExtResource("3_uynxe")] 148 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 23.4016, 0.443581, 24.4477) 149 | 150 | [node name="grass19" parent="." index="46" instance=ExtResource("3_uynxe")] 151 | transform = Transform3D(0.742432, 0, 0.669921, 0, 1, 0, -0.669921, 0, 0.742432, 36.5807, 0.443581, 4.22206) 152 | 153 | [node name="grass20" parent="." index="47" instance=ExtResource("3_uynxe")] 154 | transform = Transform3D(-0.402795, 0, 0.91529, 0, 1, 0, -0.91529, 0, -0.402795, 14.8397, 0.466624, -35.7056) 155 | 156 | [node name="grass-small11" parent="." index="48" instance=ExtResource("2_dmbou")] 157 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 20.2955, 0.495496, 35.4008) 158 | 159 | [node name="grass-small12" parent="." index="49" instance=ExtResource("2_dmbou")] 160 | transform = Transform3D(0.352495, 0, -0.935814, 0, 1, 0, 0.935814, 0, 0.352495, -19.8408, 0.495496, 37.2338) 161 | 162 | [node name="grass21" parent="." index="50" instance=ExtResource("3_uynxe")] 163 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 27.2888, 0.443581, 35.1492) 164 | 165 | [node name="grass22" parent="." index="51" instance=ExtResource("3_uynxe")] 166 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 23.4016, 0.443581, 31.7672) 167 | 168 | [node name="grass23" parent="." index="52" instance=ExtResource("3_uynxe")] 169 | transform = Transform3D(0.742432, 0, 0.669921, 0, 1, 0, -0.669921, 0, 0.742432, 41.4842, 0.443581, 9.65627) 170 | 171 | [node name="grass24" parent="." index="53" instance=ExtResource("3_uynxe")] 172 | transform = Transform3D(-0.402795, 0, 0.91529, 0, 1, 0, -0.91529, 0, -0.402795, 21.5392, 0.466624, -38.6538) 173 | 174 | [node name="platform-grass-large-round2" parent="." index="54"] 175 | transform = Transform3D(22, 0, 0, 0, 1, 0, 0, 0, 22, 0, 0, 0) 176 | 177 | [node name="StaticBody3D" type="StaticBody3D" parent="platform-grass-large-round2" index="0"] 178 | 179 | [node name="CollisionShape3D" type="CollisionShape3D" parent="platform-grass-large-round2/StaticBody3D" index="0"] 180 | shape = SubResource("ConcavePolygonShape3D_xh0ma") 181 | -------------------------------------------------------------------------------- /objects/platform_medium.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://rjh4ifidqrfp"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://c5vgh1v6juur0" path="res://models/platform-medium.glb" id="1_ihbp6"] 4 | 5 | [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_gwolp"] 6 | data = PackedVector3Array(1.5, 0.2, 1.3, 1.4, 0, 1.22, 1.355, 0, 1.355, 1.355, 0, 1.355, 1.45, 0.2, 1.45, 1.5, 0.2, 1.3, 1.45, 0.5, 1.45, 1.5, 0.5, 1.3, 1.5, 0.2, 1.3, 1.5, 0.2, 1.3, 1.45, 0.2, 1.45, 1.45, 0.5, 1.45, 1.45, 0.2, 1.45, 1.355, 0, 1.355, 1.22, 0, 1.4, 1.22, 0, 1.4, 1.3, 0.2, 1.5, 1.45, 0.2, 1.45, 1.45, 0.5, 1.45, 1.45, 0.2, 1.45, 1.3, 0.2, 1.5, 1.3, 0.2, 1.5, 1.3, 0.5, 1.5, 1.45, 0.5, 1.45, 1.3, 0.5, 1.5, 1.3, 0.2, 1.5, -1.3, 0.2, 1.5, -1.3, 0.2, 1.5, -1.3, 0.5, 1.5, 1.3, 0.5, 1.5, -1.3, 0.2, 1.5, -1.22, 0, 1.4, -1.355, 0, 1.355, -1.355, 0, 1.355, -1.45, 0.2, 1.45, -1.3, 0.2, 1.5, -1.45, 0.2, 1.45, -1.5, 0.2, 1.3, -1.5, 0.5, 1.3, -1.5, 0.5, 1.3, -1.45, 0.5, 1.45, -1.45, 0.2, 1.45, 1.3, 0.2, 1.5, 1.22, 0, 1.4, -1.22, 0, 1.4, -1.22, 0, 1.4, -1.3, 0.2, 1.5, 1.3, 0.2, 1.5, -1.355, 0, 1.355, -1.4, 0, 1.22, -1.5, 0.2, 1.3, -1.5, 0.2, 1.3, -1.45, 0.2, 1.45, -1.355, 0, 1.355, -1.3, 0.5, 1.5, -1.3, 0.2, 1.5, -1.45, 0.2, 1.45, -1.45, 0.2, 1.45, -1.45, 0.5, 1.45, -1.3, 0.5, 1.5, 1.5, 0.5, -1.3, 1.5, 0.5, 1.3, 1.45, 0.5, 1.45, 1.45, 0.5, 1.45, 1.45, 0.5, -1.45, 1.5, 0.5, -1.3, 1.45, 0.5, 1.45, 1.3, 0.5, -1.5, 1.45, 0.5, -1.45, 1.45, 0.5, 1.45, 1.3, 0.5, 1.2675, 1.3, 0.5, -1.5, 1.3, 0.5, 1.2675, 1.45, 0.5, 1.45, 1.3, 0.5, 1.5, 1.3, 0.5, 1.5, 1.2919, 0.5, 1.2919, 1.3, 0.5, 1.2675, 1.3, 0.5, 1.5, 1.2675, 0.5, 1.3, 1.2919, 0.5, 1.2919, 1.3, 0.5, 1.2675, 1.3, 0.5, -1.2675, 1.3, 0.5, -1.5, 1.3, 0.5, -1.2675, 1.2919, 0.5, -1.2919, 1.3, 0.5, -1.5, 1.2919, 0.5, -1.2919, 1.2675, 0.5, -1.3, 1.3, 0.5, -1.5, 1.3, 0.5, 1.5, -1.3, 0.5, 1.5, 1.2675, 0.5, 1.3, 1.2675, 0.5, -1.3, -1.3, 0.5, -1.5, 1.3, 0.5, -1.5, -1.3, 0.5, 1.5, -1.2675, 0.5, 1.3, 1.2675, 0.5, 1.3, 1.2675, 0.5, -1.3, -1.2675, 0.5, -1.3, -1.3, 0.5, -1.5, -1.2675, 0.5, -1.3, -1.2919, 0.5, -1.2919, -1.3, 0.5, -1.5, -1.2919, 0.5, -1.2919, -1.3, 0.5, -1.2675, -1.3, 0.5, -1.5, -1.3, 0.5, 1.5, -1.2919, 0.5, 1.2919, -1.2675, 0.5, 1.3, -1.3, 0.5, -1.2675, -1.45, 0.5, -1.45, -1.3, 0.5, -1.5, -1.3, 0.5, 1.5, -1.3, 0.5, 1.2675, -1.2919, 0.5, 1.2919, -1.3, 0.5, -1.2675, -1.3, 0.5, 1.2675, -1.45, 0.5, -1.45, -1.3, 0.5, 1.2675, -1.3, 0.5, 1.5, -1.45, 0.5, -1.45, -1.3, 0.5, 1.5, -1.45, 0.5, 1.45, -1.45, 0.5, -1.45, -1.45, 0.5, 1.45, -1.5, 0.5, -1.3, -1.45, 0.5, -1.45, -1.45, 0.5, 1.45, -1.5, 0.5, 1.3, -1.5, 0.5, -1.3, -1.355, 0, -1.355, -1.45, 0.2, -1.45, -1.5, 0.2, -1.3, -1.5, 0.2, -1.3, -1.4, 0, -1.22, -1.355, 0, -1.355, -1.3, 0.2, -1.5, -1.22, 0, -1.4, 1.22, 0, -1.4, 1.22, 0, -1.4, 1.3, 0.2, -1.5, -1.3, 0.2, -1.5, -1.45, 0.2, -1.45, -1.355, 0, -1.355, -1.22, 0, -1.4, -1.22, 0, -1.4, -1.3, 0.2, -1.5, -1.45, 0.2, -1.45, 1.355, 0, 1.355, 1.4, 0, 1.22, 1.4, 0, -1.22, 1.4, 0, -1.22, 1.355, 0, -1.355, 1.355, 0, 1.355, 1.355, 0, -1.355, 1.22, 0, 1.4, 1.355, 0, 1.355, 1.355, 0, -1.355, 1.22, 0, -1.4, 1.22, 0, 1.4, 1.22, 0, -1.4, -1.22, 0, 1.4, 1.22, 0, 1.4, 1.22, 0, -1.4, -1.22, 0, -1.4, -1.22, 0, 1.4, -1.22, 0, -1.4, -1.355, 0, -1.355, -1.22, 0, 1.4, -1.355, 0, -1.355, -1.355, 0, 1.355, -1.22, 0, 1.4, -1.355, 0, -1.355, -1.4, 0, -1.22, -1.355, 0, 1.355, -1.4, 0, -1.22, -1.4, 0, 1.22, -1.355, 0, 1.355, -1.5, 0.2, 1.3, -1.5, 0.2, -1.3, -1.5, 0.5, -1.3, -1.5, 0.5, -1.3, -1.5, 0.5, 1.3, -1.5, 0.2, 1.3, -1.45, 0.5, -1.45, -1.45, 0.2, -1.45, -1.3, 0.2, -1.5, -1.3, 0.2, -1.5, -1.3, 0.5, -1.5, -1.45, 0.5, -1.45, -1.5, 0.2, -1.3, -1.45, 0.2, -1.45, -1.45, 0.5, -1.45, -1.45, 0.5, -1.45, -1.5, 0.5, -1.3, -1.5, 0.2, -1.3, -1.3, 0.5, -1.5, -1.3, 0.2, -1.5, 1.3, 0.2, -1.5, 1.3, 0.2, -1.5, 1.3, 0.5, -1.5, -1.3, 0.5, -1.5, -1.4, 0, -1.22, -1.5, 0.2, -1.3, -1.5, 0.2, 1.3, -1.5, 0.2, 1.3, -1.4, 0, 1.22, -1.4, 0, -1.22, 1.3, 0.2, -1.5, 1.22, 0, -1.4, 1.355, 0, -1.355, 1.355, 0, -1.355, 1.45, 0.2, -1.45, 1.3, 0.2, -1.5, 1.5, 0.2, -1.3, 1.45, 0.2, -1.45, 1.355, 0, -1.355, 1.355, 0, -1.355, 1.4, 0, -1.22, 1.5, 0.2, -1.3, 1.5, 0.5, 1.3, 1.5, 0.5, -1.3, 1.5, 0.2, -1.3, 1.5, 0.2, -1.3, 1.5, 0.2, 1.3, 1.5, 0.5, 1.3, 1.5, 0.2, 1.3, 1.5, 0.2, -1.3, 1.4, 0, -1.22, 1.4, 0, -1.22, 1.4, 0, 1.22, 1.5, 0.2, 1.3, 1.3, 0.5, -1.5, 1.3, 0.2, -1.5, 1.45, 0.2, -1.45, 1.45, 0.2, -1.45, 1.45, 0.5, -1.45, 1.3, 0.5, -1.5, 1.5, 0.5, -1.3, 1.45, 0.5, -1.45, 1.45, 0.2, -1.45, 1.45, 0.2, -1.45, 1.5, 0.2, -1.3, 1.5, 0.5, -1.3, 1.3, 0.5, -1.2675, 1.3, 0.5, 1.2675, 1.2919, 0.5, 1.2919, 1.2919, 0.5, 1.2919, 1.2919, 0.5, -1.2919, 1.3, 0.5, -1.2675, 1.2919, 0.5, 1.2919, 1.2675, 0.5, 1.3, 1.2919, 0.5, -1.2919, 1.2675, 0.5, 1.3, 1.2675, 0.5, -1.3, 1.2919, 0.5, -1.2919, 1.2675, 0.5, 1.3, 1.1, 0.5, -1.1, 1.2675, 0.5, -1.3, 1.1, 0.5, -1.1, -1.2675, 0.5, -1.3, 1.2675, 0.5, -1.3, 1.1, 0.5, 1.1, 1.1, 0.5, -1.1, 1.2675, 0.5, 1.3, 1.1, 0.5, -1.1, -1.1, 0.5, -1.1, -1.2675, 0.5, -1.3, 1.2675, 0.5, 1.3, -1.2675, 0.5, 1.3, 1.1, 0.5, 1.1, -1.1, 0.5, -1.1, -1.1, 0.5, 1.1, -1.2675, 0.5, -1.3, -1.2675, 0.5, 1.3, -1.1, 0.5, 1.1, 1.1, 0.5, 1.1, -1.2675, 0.5, 1.3, -1.2675, 0.5, -1.3, -1.1, 0.5, 1.1, -1.2675, 0.5, 1.3, -1.2919, 0.5, -1.2919, -1.2675, 0.5, -1.3, -1.2675, 0.5, 1.3, -1.2919, 0.5, 1.2919, -1.2919, 0.5, -1.2919, -1.2919, 0.5, 1.2919, -1.3, 0.5, -1.2675, -1.2919, 0.5, -1.2919, -1.2919, 0.5, 1.2919, -1.3, 0.5, 1.2675, -1.3, 0.5, -1.2675, -1.1, 0.5, -1.1, 1.1, 0.5, -1.1, 1.1, 0.5, 1.1, 1.1, 0.5, 1.1, -1.1, 0.5, 1.1, -1.1, 0.5, -1.1, -0.8139, 0.5, 1.0077, -0.8889, 0.5, 0.8778, -0.8889, 0.55, 0.8778, -0.8889, 0.55, 0.8778, -0.8139, 0.55, 1.0077, -0.8139, 0.5, 1.0077, -0.5815, 0.55, 0.9602, -0.5815, 0.5, 0.9602, -0.7114, 0.5, 1.0352, -0.7114, 0.5, 1.0352, -0.7114, 0.55, 1.0352, -0.5815, 0.55, 0.9602, -0.5541, 0.55, 0.8577, -0.6291, 0.55, 0.7278, -0.6291, 0.5, 0.7278, -0.6291, 0.5, 0.7278, -0.5541, 0.5, 0.8577, -0.5541, 0.55, 0.8577, -0.8614, 0.55, 0.7754, -0.8614, 0.5, 0.7754, -0.7315, 0.5, 0.7004, -0.7315, 0.5, 0.7004, -0.7315, 0.55, 0.7004, -0.8614, 0.55, 0.7754, -0.7315, 0.55, 0.7004, -0.6291, 0.55, 0.7278, -0.5541, 0.55, 0.8577, -0.5541, 0.55, 0.8577, -0.5815, 0.55, 0.9602, -0.7315, 0.55, 0.7004, -0.5815, 0.55, 0.9602, -0.8614, 0.55, 0.7754, -0.7315, 0.55, 0.7004, -0.5815, 0.55, 0.9602, -0.7114, 0.55, 1.0352, -0.8614, 0.55, 0.7754, -0.7114, 0.55, 1.0352, -0.8139, 0.55, 1.0077, -0.8614, 0.55, 0.7754, -0.8139, 0.55, 1.0077, -0.8889, 0.55, 0.8778, -0.8614, 0.55, 0.7754, -0.7114, 0.55, 1.0352, -0.7114, 0.5, 1.0352, -0.8139, 0.5, 1.0077, -0.8139, 0.5, 1.0077, -0.8139, 0.55, 1.0077, -0.7114, 0.55, 1.0352, -0.8889, 0.5, 0.8778, -0.8614, 0.5, 0.7754, -0.8614, 0.55, 0.7754, -0.8614, 0.55, 0.7754, -0.8889, 0.55, 0.8778, -0.8889, 0.5, 0.8778, -0.5541, 0.55, 0.8577, -0.5541, 0.5, 0.8577, -0.5815, 0.5, 0.9602, -0.5815, 0.5, 0.9602, -0.5815, 0.55, 0.9602, -0.5541, 0.55, 0.8577, -0.7315, 0.55, 0.7004, -0.7315, 0.5, 0.7004, -0.6291, 0.5, 0.7278, -0.6291, 0.5, 0.7278, -0.6291, 0.55, 0.7278, -0.7315, 0.55, 0.7004, -0.5371, 0.5, 0.6817, -0.5818, 0.5, 0.6214, -0.5818, 0.55, 0.6214, -0.5818, 0.55, 0.6214, -0.5371, 0.55, 0.6817, -0.5371, 0.5, 0.6817, -0.4244, 0.55, 0.6449, -0.4244, 0.5, 0.6449, -0.4847, 0.5, 0.6895, -0.4847, 0.5, 0.6895, -0.4847, 0.55, 0.6895, -0.4244, 0.55, 0.6449, -0.4166, 0.55, 0.5925, -0.4612, 0.55, 0.5322, -0.4612, 0.5, 0.5322, -0.4612, 0.5, 0.5322, -0.4166, 0.5, 0.5925, -0.4166, 0.55, 0.5925, -0.5739, 0.55, 0.5689, -0.5739, 0.5, 0.5689, -0.5136, 0.5, 0.5243, -0.5136, 0.5, 0.5243, -0.5136, 0.55, 0.5243, -0.5739, 0.55, 0.5689, -0.5136, 0.55, 0.5243, -0.4612, 0.55, 0.5322, -0.4166, 0.55, 0.5925, -0.4166, 0.55, 0.5925, -0.4244, 0.55, 0.6449, -0.5136, 0.55, 0.5243, -0.4244, 0.55, 0.6449, -0.4847, 0.55, 0.6895, -0.5136, 0.55, 0.5243, -0.4847, 0.55, 0.6895, -0.5739, 0.55, 0.5689, -0.5136, 0.55, 0.5243, -0.4847, 0.55, 0.6895, -0.5818, 0.55, 0.6214, -0.5739, 0.55, 0.5689, -0.4847, 0.55, 0.6895, -0.5371, 0.55, 0.6817, -0.5818, 0.55, 0.6214, -0.4847, 0.55, 0.6895, -0.4847, 0.5, 0.6895, -0.5371, 0.5, 0.6817, -0.5371, 0.5, 0.6817, -0.5371, 0.55, 0.6817, -0.4847, 0.55, 0.6895, -0.5818, 0.5, 0.6214, -0.5739, 0.5, 0.5689, -0.5739, 0.55, 0.5689, -0.5739, 0.55, 0.5689, -0.5818, 0.55, 0.6214, -0.5818, 0.5, 0.6214, -0.4166, 0.55, 0.5925, -0.4166, 0.5, 0.5925, -0.4244, 0.5, 0.6449, -0.4244, 0.5, 0.6449, -0.4244, 0.55, 0.6449, -0.4166, 0.55, 0.5925, -0.5136, 0.55, 0.5243, -0.5136, 0.5, 0.5243, -0.4612, 0.5, 0.5322, -0.4612, 0.5, 0.5322, -0.4612, 0.55, 0.5322, -0.5136, 0.55, 0.5243, -0.9934, 0.5, 0.4531, -0.9374, 0.5, 0.3139, -0.9374, 0.55, 0.3139, -0.9374, 0.55, 0.3139, -0.9934, 0.55, 0.4531, -0.9934, 0.5, 0.4531, -0.8126, 0.55, 0.6066, -0.8126, 0.5, 0.6066, -0.9518, 0.5, 0.5507, -0.9518, 0.5, 0.5507, -0.9518, 0.55, 0.5507, -0.8126, 0.55, 0.6066, -0.715, 0.55, 0.565, -0.6591, 0.55, 0.4258, -0.6591, 0.5, 0.4258, -0.6591, 0.5, 0.4258, -0.715, 0.5, 0.565, -0.715, 0.55, 0.565, -0.8399, 0.55, 0.2723, -0.8399, 0.5, 0.2723, -0.7007, 0.5, 0.3283, -0.7007, 0.5, 0.3283, -0.7007, 0.55, 0.3283, -0.8399, 0.55, 0.2723, -0.7007, 0.55, 0.3283, -0.6591, 0.55, 0.4258, -0.715, 0.55, 0.565, -0.715, 0.55, 0.565, -0.8126, 0.55, 0.6066, -0.7007, 0.55, 0.3283, -0.8126, 0.55, 0.6066, -0.8399, 0.55, 0.2723, -0.7007, 0.55, 0.3283, -0.8126, 0.55, 0.6066, -0.9518, 0.55, 0.5507, -0.8399, 0.55, 0.2723, -0.9518, 0.55, 0.5507, -0.9934, 0.55, 0.4531, -0.8399, 0.55, 0.2723, -0.9934, 0.55, 0.4531, -0.9374, 0.55, 0.3139, -0.8399, 0.55, 0.2723, -0.9518, 0.55, 0.5507, -0.9518, 0.5, 0.5507, -0.9934, 0.5, 0.4531, -0.9934, 0.5, 0.4531, -0.9934, 0.55, 0.4531, -0.9518, 0.55, 0.5507, -0.9374, 0.5, 0.3139, -0.8399, 0.5, 0.2723, -0.8399, 0.55, 0.2723, -0.8399, 0.55, 0.2723, -0.9374, 0.55, 0.3139, -0.9374, 0.5, 0.3139, -0.715, 0.55, 0.565, -0.715, 0.5, 0.565, -0.8126, 0.5, 0.6066, -0.8126, 0.5, 0.6066, -0.8126, 0.55, 0.6066, -0.715, 0.55, 0.565, -0.7007, 0.55, 0.3283, -0.7007, 0.5, 0.3283, -0.6591, 0.5, 0.4258, -0.6591, 0.5, 0.4258, -0.6591, 0.55, 0.4258, -0.7007, 0.55, 0.3283, 0.8453, 0.5, -0.7372, 0.8006, 0.5, -0.7975, 0.8006, 0.55, -0.7975, 0.8006, 0.55, -0.7975, 0.8453, 0.55, -0.7372, 0.8453, 0.5, -0.7372, 0.958, 0.55, -0.774, 0.958, 0.5, -0.774, 0.8977, 0.5, -0.7294, 0.8977, 0.5, -0.7294, 0.8977, 0.55, -0.7294, 0.958, 0.55, -0.774, 0.9658, 0.55, -0.8264, 0.9212, 0.55, -0.8867, 0.9212, 0.5, -0.8867, 0.9212, 0.5, -0.8867, 0.9658, 0.5, -0.8264, 0.9658, 0.55, -0.8264, 0.8085, 0.55, -0.8499, 0.8085, 0.5, -0.8499, 0.8688, 0.5, -0.8945, 0.8688, 0.5, -0.8945, 0.8688, 0.55, -0.8945, 0.8085, 0.55, -0.8499, 0.8688, 0.55, -0.8945, 0.9212, 0.55, -0.8867, 0.9658, 0.55, -0.8264, 0.9658, 0.55, -0.8264, 0.958, 0.55, -0.774, 0.8688, 0.55, -0.8945, 0.958, 0.55, -0.774, 0.8977, 0.55, -0.7294, 0.8688, 0.55, -0.8945, 0.8977, 0.55, -0.7294, 0.8085, 0.55, -0.8499, 0.8688, 0.55, -0.8945, 0.8977, 0.55, -0.7294, 0.8006, 0.55, -0.7975, 0.8085, 0.55, -0.8499, 0.8977, 0.55, -0.7294, 0.8453, 0.55, -0.7372, 0.8006, 0.55, -0.7975, 0.8977, 0.55, -0.7294, 0.8977, 0.5, -0.7294, 0.8453, 0.5, -0.7372, 0.8453, 0.5, -0.7372, 0.8453, 0.55, -0.7372, 0.8977, 0.55, -0.7294, 0.8006, 0.5, -0.7975, 0.8085, 0.5, -0.8499, 0.8085, 0.55, -0.8499, 0.8085, 0.55, -0.8499, 0.8006, 0.55, -0.7975, 0.8006, 0.5, -0.7975, 0.9658, 0.55, -0.8264, 0.9658, 0.5, -0.8264, 0.958, 0.5, -0.774, 0.958, 0.5, -0.774, 0.958, 0.55, -0.774, 0.9658, 0.55, -0.8264, 0.8688, 0.55, -0.8945, 0.8688, 0.5, -0.8945, 0.9212, 0.5, -0.8867, 0.9212, 0.5, -0.8867, 0.9212, 0.55, -0.8867, 0.8688, 0.55, -0.8945) 7 | 8 | [node name="platform-medium" instance=ExtResource("1_ihbp6")] 9 | 10 | [node name="StaticBody3D" type="StaticBody3D" parent="platform-medium2" index="0"] 11 | 12 | [node name="CollisionShape3D" type="CollisionShape3D" parent="platform-medium2/StaticBody3D" index="0"] 13 | shape = SubResource("ConcavePolygonShape3D_gwolp") 14 | -------------------------------------------------------------------------------- /objects/player.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=3 uid="uid://dl2ed4gkybggf"] 2 | 3 | [ext_resource type="Script" path="res://scripts/player.gd" id="1_ffboj"] 4 | [ext_resource type="PackedScene" uid="uid://c0e27836xgmhi" path="res://objects/character.tscn" id="2_nero3"] 5 | [ext_resource type="Texture2D" uid="uid://8ggihh27mlrr" path="res://sprites/blob_shadow.png" id="3_0c7wt"] 6 | [ext_resource type="ArrayMesh" uid="uid://deu06eho4c74" path="res://meshes/dust.res" id="4_mvhqy"] 7 | [ext_resource type="AudioStream" uid="uid://cydjn1ct3hps2" path="res://sounds/walking.ogg" id="5_ics1s"] 8 | 9 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_gdq8c"] 10 | radius = 0.3 11 | height = 1.0 12 | 13 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_q7stj"] 14 | diffuse_mode = 2 15 | specular_mode = 2 16 | metallic_specular = 0.0 17 | backlight = Color(0, 0.521569, 0.709804, 1) 18 | billboard_keep_scale = true 19 | grow_amount = 1.882 20 | proximity_fade_distance = 0.25 21 | 22 | [sub_resource type="Curve" id="Curve_xh1e2"] 23 | _data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.249284, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] 24 | point_count = 3 25 | 26 | [node name="Player" type="CharacterBody3D"] 27 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) 28 | collision_layer = 9 29 | script = ExtResource("1_ffboj") 30 | 31 | [node name="Collider" type="CollisionShape3D" parent="."] 32 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.55, 0) 33 | shape = SubResource("CapsuleShape3D_gdq8c") 34 | 35 | [node name="Character" parent="." instance=ExtResource("2_nero3")] 36 | 37 | [node name="arm-left" parent="Character/character2/root/torso" index="0"] 38 | transform = Transform3D(0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 0, 0, 1, 0.3, 0.2, 0) 39 | 40 | [node name="arm-right" parent="Character/character2/root/torso" index="1"] 41 | transform = Transform3D(0.707107, -0.707107, 0, 0.707107, 0.707107, 0, 0, 0, 1, -0.3, 0.1445, 0) 42 | 43 | [node name="Shadow" type="Decal" parent="."] 44 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.9, 0) 45 | size = Vector3(1, 2, 1) 46 | texture_albedo = ExtResource("3_0c7wt") 47 | modulate = Color(1, 1, 1, 0.705882) 48 | normal_fade = 0.5 49 | 50 | [node name="ParticlesTrail" type="CPUParticles3D" parent="."] 51 | material_override = SubResource("StandardMaterial3D_q7stj") 52 | cast_shadow = 0 53 | amount = 60 54 | mesh = ExtResource("4_mvhqy") 55 | emission_shape = 1 56 | emission_sphere_radius = 0.2 57 | particle_flag_align_y = true 58 | direction = Vector3(0, 0, 0) 59 | gravity = Vector3(0, 0.1, 0) 60 | scale_amount_min = 0.75 61 | scale_amount_curve = SubResource("Curve_xh1e2") 62 | 63 | [node name="SoundFootsteps" type="AudioStreamPlayer" parent="."] 64 | stream = ExtResource("5_ics1s") 65 | volume_db = -5.0 66 | pitch_scale = 1.25 67 | autoplay = true 68 | 69 | [node name="AudioListener3D" type="AudioListener3D" parent="."] 70 | current = true 71 | 72 | [editable path="Character"] 73 | -------------------------------------------------------------------------------- /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=5 10 | 11 | [application] 12 | 13 | config/name="HTN Sample" 14 | config/tags=PackedStringArray("starterkit") 15 | run/main_scene="res://scenes/HTN_main.tscn" 16 | config/features=PackedStringArray("4.2", "Forward Plus") 17 | config/icon="res://icon.png" 18 | 19 | [autoload] 20 | 21 | Audio="*res://scripts/audio.gd" 22 | Events="*res://scripts/events.gd" 23 | 24 | [display] 25 | 26 | window/size/viewport_width=1280 27 | window/size/viewport_height=720 28 | 29 | [editor] 30 | 31 | movie_writer/movie_file="C:/Users/Kenney/Desktop/video-footage.avi" 32 | 33 | [input] 34 | 35 | move_right={ 36 | "deadzone": 0.25, 37 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) 38 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) 39 | ] 40 | } 41 | move_left={ 42 | "deadzone": 0.25, 43 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null) 44 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) 45 | ] 46 | } 47 | move_forward={ 48 | "deadzone": 0.25, 49 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) 50 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) 51 | ] 52 | } 53 | move_back={ 54 | "deadzone": 0.25, 55 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) 56 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) 57 | ] 58 | } 59 | jump={ 60 | "deadzone": 0.5, 61 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"echo":false,"script":null) 62 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null) 63 | ] 64 | } 65 | camera_left={ 66 | "deadzone": 0.5, 67 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"echo":false,"script":null) 68 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":-1.0,"script":null) 69 | ] 70 | } 71 | camera_right={ 72 | "deadzone": 0.5, 73 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"echo":false,"script":null) 74 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null) 75 | ] 76 | } 77 | camera_up={ 78 | "deadzone": 0.5, 79 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"echo":false,"script":null) 80 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null) 81 | ] 82 | } 83 | camera_down={ 84 | "deadzone": 0.5, 85 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"echo":false,"script":null) 86 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null) 87 | ] 88 | } 89 | zoom_in={ 90 | "deadzone": 0.5, 91 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"echo":false,"script":null) 92 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null) 93 | ] 94 | } 95 | zoom_out={ 96 | "deadzone": 0.5, 97 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"echo":false,"script":null) 98 | , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null) 99 | ] 100 | } 101 | 102 | [rendering] 103 | 104 | anti_aliasing/quality/screen_space_aa=1 105 | -------------------------------------------------------------------------------- /scenes/HTN_main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=3 uid="uid://bu578jf0i0a47"] 2 | 3 | [ext_resource type="Environment" uid="uid://bqnqgflivjvue" path="res://scenes/main-environment.tres" id="1_1l4vr"] 4 | [ext_resource type="PackedScene" uid="uid://dl2ed4gkybggf" path="res://objects/player.tscn" id="2_uttam"] 5 | [ext_resource type="Script" path="res://scripts/view.gd" id="3_gu4a3"] 6 | [ext_resource type="PackedScene" uid="uid://uqr4hswv6d2g" path="res://objects/platform_grass_large_round.tscn" id="7_7gyn5"] 7 | [ext_resource type="PackedScene" uid="uid://wolpf325pjv" path="res://objects/npc.tscn" id="9_d5ttn"] 8 | [ext_resource type="PackedScene" uid="uid://dy017k58p20sk" path="res://objects/cloud.tscn" id="10_ib867"] 9 | [ext_resource type="PackedScene" uid="uid://bggq7sr56jogd" path="res://objects/coin_spawner.tscn" id="10_tjv47"] 10 | 11 | [node name="Main" type="Node3D"] 12 | 13 | [node name="Environment" type="WorldEnvironment" parent="."] 14 | environment = ExtResource("1_1l4vr") 15 | 16 | [node name="Player" parent="." node_paths=PackedStringArray("view") instance=ExtResource("2_uttam")] 17 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.43125, 1.71415, -2.21409) 18 | view = NodePath("../View") 19 | 20 | [node name="View" type="Node3D" parent="." node_paths=PackedStringArray("target")] 21 | transform = Transform3D(0.707107, -0.298836, 0.640856, 0, 0.906308, 0.422618, -0.707107, -0.298836, 0.640856, 0, 0, 0) 22 | script = ExtResource("3_gu4a3") 23 | target = NodePath("../Player") 24 | 25 | [node name="Camera" type="Camera3D" parent="View"] 26 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10) 27 | current = true 28 | fov = 40.0 29 | 30 | [node name="World" type="Node3D" parent="."] 31 | 32 | [node name="platform-grass-large-round" parent="World" instance=ExtResource("7_7gyn5")] 33 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 0.98568, -2) 34 | 35 | [node name="cube8" parent="World" instance=ExtResource("10_ib867")] 36 | transform = Transform3D(1, 0, 0, 0, 0.999623, 0.0274506, 0, -0.0274506, 0.999623, 15.8876, 3.13459, -55.5434) 37 | 38 | [node name="cube9" parent="World" instance=ExtResource("10_ib867")] 39 | transform = Transform3D(1.27593, -0.401864, 0.422933, 0.471408, 1.30937, -0.178025, -0.343721, 0.304009, 1.32582, 17.6734, 3.39864, -57.0706) 40 | 41 | [node name="cube25" parent="World" instance=ExtResource("10_ib867")] 42 | transform = Transform3D(1, 0, 0, 0, 0.999623, 0.0274506, 0, -0.0274506, 0.999623, 15.8876, 3.13459, 52.9807) 43 | 44 | [node name="cube26" parent="World" instance=ExtResource("10_ib867")] 45 | transform = Transform3D(1.27593, -0.401864, 0.422933, 0.471408, 1.30937, -0.178025, -0.343721, 0.304009, 1.32582, 17.6734, 3.39864, 51.4535) 46 | 47 | [node name="cube27" parent="World" instance=ExtResource("10_ib867")] 48 | transform = Transform3D(1, 0, 0, 0, 0.999623, 0.0274506, 0, -0.0274506, 0.999623, 30.0282, 3.13459, 43.263) 49 | 50 | [node name="cube28" parent="World" instance=ExtResource("10_ib867")] 51 | transform = Transform3D(1.27593, -0.401864, 0.422933, 0.471408, 1.30937, -0.178025, -0.343721, 0.304009, 1.32582, 31.8141, 3.39864, 41.7358) 52 | 53 | [node name="cube29" parent="World" instance=ExtResource("10_ib867")] 54 | transform = Transform3D(0.204171, 0.0268723, -0.978566, 0, 0.999623, 0.0274506, 0.978935, -0.00560463, 0.204095, 46.7793, 3.13459, 25.5333) 55 | 56 | [node name="cube30" parent="World" instance=ExtResource("10_ib867")] 57 | transform = Transform3D(0.596989, -0.379654, -1.21154, 0.471408, 1.30937, -0.178025, 1.17887, -0.331329, 0.684719, 48.6389, 3.39864, 26.9698) 58 | 59 | [node name="cube10" parent="World" instance=ExtResource("10_ib867")] 60 | transform = Transform3D(1.32811, 0.370441, 0.259369, -0.293866, 1.3186, -0.37854, -0.34372, 0.30401, 1.32582, -10.5752, 4.46149, -64.9873) 61 | 62 | [node name="cube13" parent="World" instance=ExtResource("10_ib867")] 63 | transform = Transform3D(1.56209, -1.37982, 1.71508, 1.97375, 1.80907, -0.342241, -0.974547, 1.4522, 2.05595, -14.3045, 4.46149, -65.2921) 64 | 65 | [node name="cube21" parent="World" instance=ExtResource("10_ib867")] 66 | transform = Transform3D(1.32811, 0.370441, 0.259369, -0.293866, 1.3186, -0.37854, -0.34372, 0.30401, 1.32582, -10.5752, 4.46149, 54.8151) 67 | 68 | [node name="cube22" parent="World" instance=ExtResource("10_ib867")] 69 | transform = Transform3D(1.56209, -1.37982, 1.71508, 1.97375, 1.80907, -0.342241, -0.974547, 1.4522, 2.05595, -14.3045, 4.46149, 54.5103) 70 | 71 | [node name="cube23" parent="World" instance=ExtResource("10_ib867")] 72 | transform = Transform3D(1.05262, -0.0315403, -0.927023, -0.293866, 1.3186, -0.37854, 0.879782, 0.478178, 0.9827, -52.2834, 4.46149, 39.7841) 73 | 74 | [node name="cube24" parent="World" instance=ExtResource("10_ib867")] 75 | transform = Transform3D(1.70175, -1.98401, -0.673262, 1.97375, 1.80907, -0.342241, 0.702801, -0.276539, 2.59136, -54.2065, 4.46149, 36.5744) 76 | 77 | [node name="cube11" parent="World" instance=ExtResource("10_ib867")] 78 | transform = Transform3D(0.476646, 0.924607, 0.941422, -0.929853, 0.945559, -0.457882, -0.93624, -0.468385, 0.934042, -63.0797, 4.06537, 6.06208) 79 | 80 | [node name="cube12" parent="World" instance=ExtResource("10_ib867")] 81 | transform = Transform3D(-1.02876, -0.695523, 0.652886, -0.929853, 0.945557, -0.457881, -0.213027, -0.768461, -1.15432, -62.814, 4.82226, 8.29588) 82 | 83 | [node name="cube14" parent="World" instance=ExtResource("10_ib867")] 84 | transform = Transform3D(1.56209, -1.37982, 1.71508, 1.97375, 1.80907, -0.342241, -0.974547, 1.4522, 2.05595, -67.7642, 4.06537, 4.6179) 85 | 86 | [node name="cube18" parent="World" instance=ExtResource("10_ib867")] 87 | transform = Transform3D(0.476646, 0.924607, 0.941422, -0.929853, 0.945559, -0.457882, -0.93624, -0.468385, 0.934042, 54.9768, 4.06537, -25.0039) 88 | 89 | [node name="cube19" parent="World" instance=ExtResource("10_ib867")] 90 | transform = Transform3D(-1.02876, -0.695523, 0.652886, -0.929853, 0.945557, -0.457881, -0.213027, -0.768461, -1.15432, 55.2425, 4.82226, -22.7701) 91 | 92 | [node name="cube20" parent="World" instance=ExtResource("10_ib867")] 93 | transform = Transform3D(1.56209, -1.37982, 1.71508, 1.97375, 1.80907, -0.342241, -0.974547, 1.4522, 2.05595, 50.2923, 4.06537, -26.448) 94 | 95 | [node name="cube15" parent="World" instance=ExtResource("10_ib867")] 96 | transform = Transform3D(1.01182, 0.970583, -0.0504584, -0.929853, 0.945559, -0.457882, -0.282755, 0.363663, 1.3252, -63.362, 4.06537, -45.5228) 97 | 98 | [node name="cube16" parent="World" instance=ExtResource("10_ib867")] 99 | transform = Transform3D(-0.53944, 0.0949872, 1.29165, -0.929853, 0.945557, -0.457881, -0.901517, -1.03212, -0.300609, -64.8266, 4.82226, -43.8153) 100 | 101 | [node name="cube17" parent="World" instance=ExtResource("10_ib867")] 102 | transform = Transform3D(1.77465, -2.00292, -0.35276, 1.97375, 1.80907, -0.342241, 0.490388, -0.0329319, 2.65405, -65.4693, 4.06537, -49.9488) 103 | 104 | [node name="Sun" type="DirectionalLight3D" parent="."] 105 | transform = Transform3D(-0.422618, -0.694272, 0.582563, 0, 0.642788, 0.766044, -0.906308, 0.323744, -0.271654, 0, 0, 0) 106 | shadow_enabled = true 107 | shadow_opacity = 0.75 108 | 109 | [node name="npc" parent="." instance=ExtResource("9_d5ttn")] 110 | transform = Transform3D(-0.178304, 0, 0.983975, 0, 1, 0, -0.983975, 0, -0.178304, -11.6851, 1.83615, 0) 111 | 112 | [node name="CoinSpawner" parent="." instance=ExtResource("10_tjv47")] 113 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.94333, 2.1578, 8.12897) 114 | 115 | [node name="Marker3D" type="Marker3D" parent="CoinSpawner"] 116 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.563552, 0) 117 | -------------------------------------------------------------------------------- /scenes/HTN_main_multiple_agents.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=3 uid="uid://toin0idd1bik"] 2 | 3 | [ext_resource type="Environment" uid="uid://bqnqgflivjvue" path="res://scenes/main-environment.tres" id="1_7j23q"] 4 | [ext_resource type="PackedScene" uid="uid://dl2ed4gkybggf" path="res://objects/player.tscn" id="2_j4k8i"] 5 | [ext_resource type="Script" path="res://scripts/view.gd" id="3_ft7bw"] 6 | [ext_resource type="PackedScene" uid="uid://uqr4hswv6d2g" path="res://objects/platform_grass_large_round.tscn" id="4_kkh17"] 7 | [ext_resource type="PackedScene" uid="uid://dy017k58p20sk" path="res://objects/cloud.tscn" id="5_myusx"] 8 | [ext_resource type="PackedScene" uid="uid://wolpf325pjv" path="res://objects/npc.tscn" id="6_1cce1"] 9 | [ext_resource type="PackedScene" uid="uid://bggq7sr56jogd" path="res://objects/coin_spawner.tscn" id="7_f5mne"] 10 | 11 | [node name="Main" type="Node3D"] 12 | 13 | [node name="Environment" type="WorldEnvironment" parent="."] 14 | environment = ExtResource("1_7j23q") 15 | 16 | [node name="Player" parent="." node_paths=PackedStringArray("view") instance=ExtResource("2_j4k8i")] 17 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.43125, 1.71415, -2.21409) 18 | view = NodePath("../View") 19 | 20 | [node name="View" type="Node3D" parent="." node_paths=PackedStringArray("target")] 21 | transform = Transform3D(0.707107, -0.298836, 0.640856, 0, 0.906308, 0.422618, -0.707107, -0.298836, 0.640856, 0, 0, 0) 22 | script = ExtResource("3_ft7bw") 23 | target = NodePath("../Player") 24 | 25 | [node name="Camera" type="Camera3D" parent="View"] 26 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10) 27 | current = true 28 | fov = 40.0 29 | 30 | [node name="World" type="Node3D" parent="."] 31 | 32 | [node name="platform-grass-large-round" parent="World" instance=ExtResource("4_kkh17")] 33 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 0.98568, -2) 34 | 35 | [node name="cube8" parent="World" instance=ExtResource("5_myusx")] 36 | transform = Transform3D(1, 0, 0, 0, 0.999623, 0.0274506, 0, -0.0274506, 0.999623, 15.8876, 3.13459, -55.5434) 37 | 38 | [node name="cube9" parent="World" instance=ExtResource("5_myusx")] 39 | transform = Transform3D(1.27593, -0.401864, 0.422933, 0.471408, 1.30937, -0.178025, -0.343721, 0.304009, 1.32582, 17.6734, 3.39864, -57.0706) 40 | 41 | [node name="cube25" parent="World" instance=ExtResource("5_myusx")] 42 | transform = Transform3D(1, 0, 0, 0, 0.999623, 0.0274506, 0, -0.0274506, 0.999623, 15.8876, 3.13459, 52.9807) 43 | 44 | [node name="cube26" parent="World" instance=ExtResource("5_myusx")] 45 | transform = Transform3D(1.27593, -0.401864, 0.422933, 0.471408, 1.30937, -0.178025, -0.343721, 0.304009, 1.32582, 17.6734, 3.39864, 51.4535) 46 | 47 | [node name="cube27" parent="World" instance=ExtResource("5_myusx")] 48 | transform = Transform3D(1, 0, 0, 0, 0.999623, 0.0274506, 0, -0.0274506, 0.999623, 30.0282, 3.13459, 43.263) 49 | 50 | [node name="cube28" parent="World" instance=ExtResource("5_myusx")] 51 | transform = Transform3D(1.27593, -0.401864, 0.422933, 0.471408, 1.30937, -0.178025, -0.343721, 0.304009, 1.32582, 31.8141, 3.39864, 41.7358) 52 | 53 | [node name="cube29" parent="World" instance=ExtResource("5_myusx")] 54 | transform = Transform3D(0.204171, 0.0268723, -0.978566, 0, 0.999623, 0.0274506, 0.978935, -0.00560463, 0.204095, 46.7793, 3.13459, 25.5333) 55 | 56 | [node name="cube30" parent="World" instance=ExtResource("5_myusx")] 57 | transform = Transform3D(0.596989, -0.379654, -1.21154, 0.471408, 1.30937, -0.178025, 1.17887, -0.331329, 0.684719, 48.6389, 3.39864, 26.9698) 58 | 59 | [node name="cube10" parent="World" instance=ExtResource("5_myusx")] 60 | transform = Transform3D(1.32811, 0.370441, 0.259369, -0.293866, 1.3186, -0.37854, -0.34372, 0.30401, 1.32582, -10.5752, 4.46149, -64.9873) 61 | 62 | [node name="cube13" parent="World" instance=ExtResource("5_myusx")] 63 | transform = Transform3D(1.56209, -1.37982, 1.71508, 1.97375, 1.80907, -0.342241, -0.974547, 1.4522, 2.05595, -14.3045, 4.46149, -65.2921) 64 | 65 | [node name="cube21" parent="World" instance=ExtResource("5_myusx")] 66 | transform = Transform3D(1.32811, 0.370441, 0.259369, -0.293866, 1.3186, -0.37854, -0.34372, 0.30401, 1.32582, -10.5752, 4.46149, 54.8151) 67 | 68 | [node name="cube22" parent="World" instance=ExtResource("5_myusx")] 69 | transform = Transform3D(1.56209, -1.37982, 1.71508, 1.97375, 1.80907, -0.342241, -0.974547, 1.4522, 2.05595, -14.3045, 4.46149, 54.5103) 70 | 71 | [node name="cube23" parent="World" instance=ExtResource("5_myusx")] 72 | transform = Transform3D(1.05262, -0.0315403, -0.927023, -0.293866, 1.3186, -0.37854, 0.879782, 0.478178, 0.9827, -52.2834, 4.46149, 39.7841) 73 | 74 | [node name="cube24" parent="World" instance=ExtResource("5_myusx")] 75 | transform = Transform3D(1.70175, -1.98401, -0.673262, 1.97375, 1.80907, -0.342241, 0.702801, -0.276539, 2.59136, -54.2065, 4.46149, 36.5744) 76 | 77 | [node name="cube11" parent="World" instance=ExtResource("5_myusx")] 78 | transform = Transform3D(0.476646, 0.924607, 0.941422, -0.929853, 0.945559, -0.457882, -0.93624, -0.468385, 0.934042, -63.0797, 4.06537, 6.06208) 79 | 80 | [node name="cube12" parent="World" instance=ExtResource("5_myusx")] 81 | transform = Transform3D(-1.02876, -0.695523, 0.652886, -0.929853, 0.945557, -0.457881, -0.213027, -0.768461, -1.15432, -62.814, 4.82226, 8.29588) 82 | 83 | [node name="cube14" parent="World" instance=ExtResource("5_myusx")] 84 | transform = Transform3D(1.56209, -1.37982, 1.71508, 1.97375, 1.80907, -0.342241, -0.974547, 1.4522, 2.05595, -67.7642, 4.06537, 4.6179) 85 | 86 | [node name="cube18" parent="World" instance=ExtResource("5_myusx")] 87 | transform = Transform3D(0.476646, 0.924607, 0.941422, -0.929853, 0.945559, -0.457882, -0.93624, -0.468385, 0.934042, 54.9768, 4.06537, -25.0039) 88 | 89 | [node name="cube19" parent="World" instance=ExtResource("5_myusx")] 90 | transform = Transform3D(-1.02876, -0.695523, 0.652886, -0.929853, 0.945557, -0.457881, -0.213027, -0.768461, -1.15432, 55.2425, 4.82226, -22.7701) 91 | 92 | [node name="cube20" parent="World" instance=ExtResource("5_myusx")] 93 | transform = Transform3D(1.56209, -1.37982, 1.71508, 1.97375, 1.80907, -0.342241, -0.974547, 1.4522, 2.05595, 50.2923, 4.06537, -26.448) 94 | 95 | [node name="cube15" parent="World" instance=ExtResource("5_myusx")] 96 | transform = Transform3D(1.01182, 0.970583, -0.0504584, -0.929853, 0.945559, -0.457882, -0.282755, 0.363663, 1.3252, -63.362, 4.06537, -45.5228) 97 | 98 | [node name="cube16" parent="World" instance=ExtResource("5_myusx")] 99 | transform = Transform3D(-0.53944, 0.0949872, 1.29165, -0.929853, 0.945557, -0.457881, -0.901517, -1.03212, -0.300609, -64.8266, 4.82226, -43.8153) 100 | 101 | [node name="cube17" parent="World" instance=ExtResource("5_myusx")] 102 | transform = Transform3D(1.77465, -2.00292, -0.35276, 1.97375, 1.80907, -0.342241, 0.490388, -0.0329319, 2.65405, -65.4693, 4.06537, -49.9488) 103 | 104 | [node name="Sun" type="DirectionalLight3D" parent="."] 105 | transform = Transform3D(-0.422618, -0.694272, 0.582563, 0, 0.642788, 0.766044, -0.906308, 0.323744, -0.271654, 0, 0, 0) 106 | shadow_enabled = true 107 | shadow_opacity = 0.75 108 | 109 | [node name="npc" parent="." instance=ExtResource("6_1cce1")] 110 | transform = Transform3D(-0.178304, 0, 0.983975, 0, 1, 0, -0.983975, 0, -0.178304, -11.6851, 1.83615, 0) 111 | 112 | [node name="npc2" parent="." instance=ExtResource("6_1cce1")] 113 | transform = Transform3D(-0.965048, 0, 0.262071, 0, 1, 0, -0.262071, 0, -0.965048, -11.6851, 1.83615, 30.9585) 114 | 115 | [node name="npc3" parent="." instance=ExtResource("6_1cce1")] 116 | transform = Transform3D(-0.965048, 0, 0.262071, 0, 1, 0, -0.262071, 0, -0.965048, 16.9562, 1.83615, 30.9585) 117 | 118 | [node name="npc4" parent="." instance=ExtResource("6_1cce1")] 119 | transform = Transform3D(-0.965048, 0, 0.262071, 0, 1, 0, -0.262071, 0, -0.965048, 16.9562, 1.83615, -25.4693) 120 | 121 | [node name="npc6" parent="." instance=ExtResource("6_1cce1")] 122 | transform = Transform3D(-0.965048, 0, 0.262071, 0, 1, 0, -0.262071, 0, -0.965048, -12.2555, 1.83615, -25.4693) 123 | 124 | [node name="npc5" parent="." instance=ExtResource("6_1cce1")] 125 | transform = Transform3D(-0.965048, 0, 0.262071, 0, 1, 0, -0.262071, 0, -0.965048, 16.9562, -121.074, -25.4693) 126 | 127 | [node name="CoinSpawner" parent="." instance=ExtResource("7_f5mne")] 128 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.94333, 2.1578, 8.12897) 129 | 130 | [node name="Marker3D" type="Marker3D" parent="CoinSpawner"] 131 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.563552, 0) 132 | 133 | [node name="CoinSpawner2" parent="." instance=ExtResource("7_f5mne")] 134 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 17.2828, 2.1578, 8.12897) 135 | 136 | [node name="Marker3D" type="Marker3D" parent="CoinSpawner2"] 137 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.563552, 0) 138 | -------------------------------------------------------------------------------- /scenes/main-environment.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=3 format=3 uid="uid://bqnqgflivjvue"] 2 | 3 | [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_lg8b7"] 4 | sky_horizon_color = Color(0.67451, 0.682353, 0.698039, 1) 5 | sky_curve = 0.0175 6 | ground_bottom_color = Color(1, 1, 1, 1) 7 | ground_curve = 0.171484 8 | 9 | [sub_resource type="Sky" id="Sky_7bk1c"] 10 | sky_material = SubResource("ProceduralSkyMaterial_lg8b7") 11 | 12 | [resource] 13 | background_mode = 1 14 | background_color = Color(0.752941, 0.776471, 0.827451, 1) 15 | sky = SubResource("Sky_7bk1c") 16 | ambient_light_source = 2 17 | ambient_light_color = Color(0.662745, 0.694118, 0.772549, 1) 18 | ambient_light_energy = 1.15 19 | tonemap_mode = 2 20 | ssao_enabled = true 21 | ssao_radius = 0.45 22 | ssao_intensity = 1.0 23 | ssao_power = 15.0 24 | glow_enabled = true 25 | glow_levels/2 = 0.6 26 | glow_levels/3 = 0.6 27 | glow_levels/5 = 0.0 28 | glow_intensity = 2.0 29 | -------------------------------------------------------------------------------- /scenes/main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=15 format=3 uid="uid://bqqgyqafm7xwp"] 2 | 3 | [ext_resource type="Environment" uid="uid://bqnqgflivjvue" path="res://scenes/main-environment.tres" id="1_ahusb"] 4 | [ext_resource type="PackedScene" uid="uid://dl2ed4gkybggf" path="res://objects/player.tscn" id="2_onms2"] 5 | [ext_resource type="Script" path="res://scripts/view.gd" id="5_bg0fr"] 6 | [ext_resource type="PackedScene" uid="uid://cnymdajj1vsqm" path="res://objects/platform.tscn" id="6_sdmev"] 7 | [ext_resource type="PackedScene" uid="uid://rjh4ifidqrfp" path="res://objects/platform_medium.tscn" id="7_ixpj3"] 8 | [ext_resource type="PackedScene" uid="uid://uqr4hswv6d2g" path="res://objects/platform_grass_large_round.tscn" id="8_4oh1e"] 9 | [ext_resource type="PackedScene" uid="uid://c8up71en5djgm" path="res://objects/platform_falling.tscn" id="9_2fnpo"] 10 | [ext_resource type="PackedScene" uid="uid://dtjvjdjl8cs6e" path="res://models/flag.glb" id="9_fw1f5"] 11 | [ext_resource type="PackedScene" uid="uid://dfpisimsgf5ce" path="res://objects/coin.tscn" id="10_fwhys"] 12 | [ext_resource type="Script" path="res://scripts/hud.gd" id="11_apvpm"] 13 | [ext_resource type="PackedScene" uid="uid://dy017k58p20sk" path="res://objects/cloud.tscn" id="13_drtpy"] 14 | [ext_resource type="Texture2D" uid="uid://cd7oyc56ehkx1" path="res://sprites/coin.png" id="13_jfda3"] 15 | [ext_resource type="FontFile" uid="uid://d0cxd77jybrcn" path="res://fonts/lilita_one_regular.ttf" id="17_tk810"] 16 | 17 | [sub_resource type="LabelSettings" id="LabelSettings_38ys3"] 18 | font = ExtResource("17_tk810") 19 | font_size = 48 20 | shadow_color = Color(0, 0, 0, 0.376471) 21 | shadow_offset = Vector2(2, 2) 22 | 23 | [node name="Main" type="Node3D"] 24 | 25 | [node name="Environment" type="WorldEnvironment" parent="."] 26 | environment = ExtResource("1_ahusb") 27 | 28 | [node name="Player" parent="." node_paths=PackedStringArray("view") instance=ExtResource("2_onms2")] 29 | view = NodePath("../View") 30 | 31 | [node name="View" type="Node3D" parent="." node_paths=PackedStringArray("target")] 32 | transform = Transform3D(0.707107, -0.298836, 0.640856, 0, 0.906308, 0.422618, -0.707107, -0.298836, 0.640856, 0, 0, 0) 33 | script = ExtResource("5_bg0fr") 34 | target = NodePath("../Player") 35 | 36 | [node name="Camera" type="Camera3D" parent="View"] 37 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10) 38 | current = true 39 | fov = 40.0 40 | 41 | [node name="World" type="Node3D" parent="."] 42 | 43 | [node name="platform" parent="World" instance=ExtResource("6_sdmev")] 44 | transform = Transform3D(0.993085, 0, -0.117399, 0, 1, 0, 0.117399, 0, 0.993085, 0, 0, 0) 45 | 46 | [node name="platform4" parent="World" instance=ExtResource("6_sdmev")] 47 | transform = Transform3D(0.993085, 0, -0.117399, 0, 1, 0, 0.117399, 0, 0.993085, -15, 0, 4) 48 | 49 | [node name="platform2" parent="World" instance=ExtResource("6_sdmev")] 50 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 2, -3) 51 | 52 | [node name="platform3" parent="World" instance=ExtResource("6_sdmev")] 53 | transform = Transform3D(0.966237, 0, -0.257656, 0, 1, 0, 0.257656, 0, 0.966237, -3, 3, -5) 54 | 55 | [node name="platform-medium" parent="World" instance=ExtResource("7_ixpj3")] 56 | transform = Transform3D(0.996134, 0, 0.0878512, 0, 1, 0, -0.0878512, 0, 0.996134, -3, 0, 0) 57 | 58 | [node name="platform-medium2" parent="World" instance=ExtResource("7_ixpj3")] 59 | transform = Transform3D(0.995121, 0, 0.0986598, 0, 1, 0, -0.0986598, 0, 0.995121, -5, 0, 4) 60 | 61 | [node name="platform-medium4" parent="World" instance=ExtResource("7_ixpj3")] 62 | transform = Transform3D(0.929796, 0, -0.368076, 0, 1, 0, 0.368076, 0, 0.929796, -14.9422, 0.991941, 0.128304) 63 | 64 | [node name="platform-medium3" parent="World" instance=ExtResource("7_ixpj3")] 65 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3, -6) 66 | 67 | [node name="platform-falling" parent="World" instance=ExtResource("9_2fnpo")] 68 | transform = Transform3D(0.984808, 0, 0.173648, 0, 1, 0, -0.173648, 0, 0.984808, -9, 0.419294, 4) 69 | 70 | [node name="platform-falling2" parent="World" instance=ExtResource("9_2fnpo")] 71 | transform = Transform3D(0.994522, 0, -0.104528, 0, 1, 0, 0.104528, 0, 0.994522, -12, -0.315063, 4) 72 | 73 | [node name="platform-falling3" parent="World" instance=ExtResource("9_2fnpo")] 74 | transform = Transform3D(0.939693, 0, 0.34202, 0, 1, 0, -0.34202, 0, 0.939693, -11.7527, 1.8303, -2.30579) 75 | 76 | [node name="platform-grass-large-round" parent="World" instance=ExtResource("8_4oh1e")] 77 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 1, -2) 78 | 79 | [node name="flag" parent="World" instance=ExtResource("9_fw1f5")] 80 | transform = Transform3D(0.707107, 0, -0.707107, 0, 1, 0, 0.707107, 0, 0.707107, 0, 3.48077, -6) 81 | 82 | [node name="coin" parent="World" instance=ExtResource("10_fwhys")] 83 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0.635, 0) 84 | 85 | [node name="coin10" parent="World" instance=ExtResource("10_fwhys")] 86 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 0.635, 4) 87 | 88 | [node name="coin2" parent="World" instance=ExtResource("10_fwhys")] 89 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.0437, 1.97005, -0.33003) 90 | 91 | [node name="coin3" parent="World" instance=ExtResource("10_fwhys")] 92 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.0437, 1.97005, -1.33003) 93 | 94 | [node name="coin5" parent="World" instance=ExtResource("10_fwhys")] 95 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.7731, 2.54941, -2.28223) 96 | 97 | [node name="coin6" parent="World" instance=ExtResource("10_fwhys")] 98 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.8111, 1.6888, 0.328574) 99 | 100 | [node name="coin7" parent="World" instance=ExtResource("10_fwhys")] 101 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.8111, 2.6888, 0.328574) 102 | 103 | [node name="coin8" parent="World" instance=ExtResource("10_fwhys")] 104 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.9647, 0.801836, 3.99354) 105 | 106 | [node name="coin9" parent="World" instance=ExtResource("10_fwhys")] 107 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, -6) 108 | 109 | [node name="coin4" parent="World" instance=ExtResource("10_fwhys")] 110 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.0437, 1.97005, -2.33003) 111 | 112 | [node name="cube8" parent="World" instance=ExtResource("13_drtpy")] 113 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5495, 1.10741, -2.666) 114 | 115 | [node name="cube9" parent="World" instance=ExtResource("13_drtpy")] 116 | transform = Transform3D(1.27593, -0.401864, 0.422933, 0.471408, 1.30937, -0.178025, -0.343721, 0.304009, 1.32582, 3.33538, 1.37146, -4.1932) 117 | 118 | [node name="cube10" parent="World" instance=ExtResource("13_drtpy")] 119 | transform = Transform3D(1.32811, 0.370441, 0.259369, -0.293866, 1.3186, -0.37854, -0.34372, 0.30401, 1.32582, -10.5752, 2.03819, -7.93707) 120 | 121 | [node name="cube11" parent="World" instance=ExtResource("13_drtpy")] 122 | transform = Transform3D(0.476646, 0.924607, 0.941422, -0.929853, 0.945559, -0.457882, -0.93624, -0.468385, 0.934042, -11.1815, 2.03819, 9.2812) 123 | 124 | [node name="cube12" parent="World" instance=ExtResource("13_drtpy")] 125 | transform = Transform3D(-1.02876, -0.695523, 0.652886, -0.929853, 0.945557, -0.457881, -0.213027, -0.768461, -1.15432, -10.9158, 2.79508, 11.515) 126 | 127 | [node name="cube13" parent="World" instance=ExtResource("13_drtpy")] 128 | transform = Transform3D(1.56209, -1.37982, 1.71508, 1.97375, 1.80907, -0.342241, -0.974547, 1.4522, 2.05595, -14.3045, 2.03819, -8.24191) 129 | 130 | [node name="cube14" parent="World" instance=ExtResource("13_drtpy")] 131 | transform = Transform3D(1.56209, -1.37982, 1.71508, 1.97375, 1.80907, -0.342241, -0.974547, 1.4522, 2.05595, -15.866, 2.03819, 7.83702) 132 | 133 | [node name="Sun" type="DirectionalLight3D" parent="."] 134 | transform = Transform3D(-0.422618, -0.694272, 0.582563, 0, 0.642788, 0.766044, -0.906308, 0.323744, -0.271654, 0, 0, 0) 135 | shadow_enabled = true 136 | shadow_opacity = 0.75 137 | 138 | [node name="HUD" type="CanvasLayer" parent="."] 139 | script = ExtResource("11_apvpm") 140 | 141 | [node name="Icon" type="TextureRect" parent="HUD"] 142 | offset_left = 57.0 143 | offset_top = 67.0 144 | offset_right = 313.0 145 | offset_bottom = 323.0 146 | scale = Vector2(0.2, 0.2) 147 | texture = ExtResource("13_jfda3") 148 | 149 | [node name="x" type="Label" parent="HUD"] 150 | offset_left = 112.0 151 | offset_top = 64.0 152 | offset_right = 144.0 153 | offset_bottom = 123.0 154 | text = "×" 155 | label_settings = SubResource("LabelSettings_38ys3") 156 | 157 | [node name="Coins" type="Label" parent="HUD"] 158 | offset_left = 144.0 159 | offset_top = 64.0 160 | offset_right = 368.0 161 | offset_bottom = 123.0 162 | text = "0" 163 | label_settings = SubResource("LabelSettings_38ys3") 164 | 165 | [connection signal="coin_collected" from="Player" to="HUD" method="_on_coin_collected"] 166 | -------------------------------------------------------------------------------- /screenshots/.gdignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/screenshots/.gdignore -------------------------------------------------------------------------------- /screenshots/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/screenshots/screenshot.png -------------------------------------------------------------------------------- /script_templates/HTNAgentSensors/agent_sensors_default.gd: -------------------------------------------------------------------------------- 1 | extends HTNAgentSensors 2 | 3 | ## This method is called on startup so you can do any initial setup, like 4 | ## listening to signals and setting initial world state 5 | func _initialize(actor: Node) -> void: 6 | pass 7 | -------------------------------------------------------------------------------- /script_templates/HTNCompoundTask/task_overrides.gd: -------------------------------------------------------------------------------- 1 | # meta-default: true 2 | extends HTNCompoundTask 3 | 4 | ## Return an array of methods. 5 | ## method format example: 6 | ## { 7 | ## "pre_conditions": { 8 | ## "is_player_nearby": true, 9 | ## }, 10 | ## "tasks": [WatchPlayerTask.new()], 11 | ## } 12 | func get_methods() -> Array: 13 | return [] 14 | -------------------------------------------------------------------------------- /script_templates/HTNTask/task_overrides.gd: -------------------------------------------------------------------------------- 1 | # meta-default: true 2 | extends HTNTask 3 | 4 | ## Used by the planer to check if task is valid 5 | ## Condition format: 6 | ## { "condition_key": "value", "condition_2_key": "value } 7 | func _pre_conditions() -> Dictionary: 8 | return {} 9 | 10 | 11 | ## Used by the planner to change the world state 12 | ## Effect format: 13 | ## { "effect_key": "value", "effect2_key": "value } 14 | func _effects() -> Dictionary: 15 | return {} 16 | 17 | 18 | ## This is where your task implementation lives. 19 | func execute(delta: float, actor: Variant) -> TaskResult: 20 | return TaskResult.SUCCESS 21 | -------------------------------------------------------------------------------- /scripts/audio.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | # Code adapted from KidsCanCode 4 | 5 | var num_players = 12 6 | var bus = "master" 7 | 8 | var available = [] # The available players. 9 | var queue = [] # The queue of sounds to play. 10 | 11 | func _ready(): 12 | 13 | for i in num_players: 14 | var p = AudioStreamPlayer.new() 15 | add_child(p) 16 | 17 | available.append(p) 18 | 19 | p.volume_db = -10 20 | p.finished.connect(_on_stream_finished.bind(p)) 21 | p.bus = bus 22 | 23 | 24 | func _on_stream_finished(stream): available.append(stream) 25 | 26 | func play(sound_path): queue.append(sound_path) 27 | 28 | func _process(_delta): 29 | 30 | if not queue.is_empty() and not available.is_empty(): 31 | 32 | available[0].stream = load(queue.pop_front()) 33 | available[0].play() 34 | available[0].pitch_scale = randf_range(0.9, 1.1) 35 | 36 | available.pop_front() 37 | -------------------------------------------------------------------------------- /scripts/events.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | signal coin_spawned 4 | signal coin_collected 5 | -------------------------------------------------------------------------------- /scripts/hud.gd: -------------------------------------------------------------------------------- 1 | extends CanvasLayer 2 | 3 | func _on_coin_collected(coins): 4 | 5 | $Coins.text = str(coins) 6 | -------------------------------------------------------------------------------- /scripts/player.gd: -------------------------------------------------------------------------------- 1 | extends CharacterBody3D 2 | 3 | signal coin_collected 4 | signal jumped 5 | 6 | @export_subgroup("Components") 7 | @export var view: Node3D 8 | 9 | @export_subgroup("Properties") 10 | @export var movement_speed = 250 11 | @export var jump_strength = 7 12 | 13 | var movement_velocity: Vector3 14 | var rotation_direction: float 15 | var gravity = 0 16 | 17 | var previously_floored = false 18 | 19 | var jump_single = true 20 | var jump_double = true 21 | 22 | var coins = 0 23 | 24 | @onready var particles_trail = $ParticlesTrail 25 | @onready var sound_footsteps = $SoundFootsteps 26 | @onready var model = $Character 27 | @onready var animation = $Character/AnimationPlayer 28 | 29 | 30 | func _physics_process(delta): 31 | 32 | # Handle functions 33 | 34 | handle_controls(delta) 35 | handle_gravity(delta) 36 | 37 | handle_effects() 38 | 39 | # Movement 40 | 41 | var applied_velocity: Vector3 42 | 43 | applied_velocity = velocity.lerp(movement_velocity, delta * 10) 44 | applied_velocity.y = -gravity 45 | 46 | velocity = applied_velocity 47 | move_and_slide() 48 | 49 | # Rotation 50 | 51 | if Vector2(velocity.z, velocity.x).length() > 0: 52 | rotation_direction = Vector2(velocity.z, velocity.x).angle() 53 | 54 | rotation.y = lerp_angle(rotation.y, rotation_direction, delta * 10) 55 | 56 | # Falling/respawning 57 | 58 | if position.y < -10: 59 | get_tree().reload_current_scene() 60 | 61 | # Animation for scale (jumping and landing) 62 | 63 | model.scale = model.scale.lerp(Vector3(1, 1, 1), delta * 10) 64 | 65 | # Animation when landing 66 | 67 | if is_on_floor() and gravity > 2 and !previously_floored: 68 | model.scale = Vector3(1.25, 0.75, 1.25) 69 | Audio.play("res://sounds/land.ogg") 70 | 71 | previously_floored = is_on_floor() 72 | 73 | # Handle animation(s) 74 | 75 | func handle_effects(): 76 | 77 | particles_trail.emitting = false 78 | sound_footsteps.stream_paused = true 79 | 80 | if is_on_floor(): 81 | if abs(velocity.x) > 1 or abs(velocity.z) > 1: 82 | animation.play("walk", 0.5) 83 | particles_trail.emitting = true 84 | sound_footsteps.stream_paused = false 85 | else: 86 | animation.play("idle", 0.5) 87 | else: 88 | animation.play("jump", 0.5) 89 | 90 | # Handle movement input 91 | 92 | func handle_controls(delta): 93 | 94 | # Movement 95 | 96 | var input := Vector3.ZERO 97 | 98 | input.x = Input.get_axis("move_left", "move_right") 99 | input.z = Input.get_axis("move_forward", "move_back") 100 | 101 | input = input.rotated(Vector3.UP, view.rotation.y).normalized() 102 | 103 | movement_velocity = input * movement_speed * delta 104 | 105 | # Jumping 106 | 107 | if Input.is_action_just_pressed("jump"): 108 | 109 | if jump_single or jump_double: 110 | Audio.play("res://sounds/jump.ogg") 111 | 112 | if jump_double: 113 | 114 | gravity = -jump_strength 115 | 116 | jump_double = false 117 | model.scale = Vector3(0.5, 1.5, 0.5) 118 | 119 | if(jump_single): jump() 120 | 121 | 122 | func handle_gravity(delta): 123 | gravity += 25 * delta 124 | 125 | if gravity > 0 and is_on_floor(): 126 | 127 | jump_single = true 128 | gravity = 0 129 | 130 | func jump(): 131 | gravity = -jump_strength 132 | 133 | model.scale = Vector3(0.5, 1.5, 0.5) 134 | 135 | jump_single = false; 136 | jump_double = true; 137 | 138 | jumped.emit() 139 | 140 | 141 | func collect_coin(): 142 | coins += 1 143 | coin_collected.emit(coins) 144 | -------------------------------------------------------------------------------- /scripts/view.gd: -------------------------------------------------------------------------------- 1 | extends Node3D 2 | 3 | @export_group("Properties") 4 | @export var target: Node 5 | 6 | @export_group("Zoom") 7 | @export var zoom_minimum = 16 8 | @export var zoom_maximum = 4 9 | @export var zoom_speed = 10 10 | 11 | @export_group("Rotation") 12 | @export var rotation_speed = 120 13 | 14 | var camera_rotation:Vector3 15 | var zoom = 16 16 | 17 | @onready var camera = $Camera 18 | 19 | func _ready(): 20 | 21 | camera_rotation = rotation_degrees # Initial rotation 22 | 23 | pass 24 | 25 | func _physics_process(delta): 26 | 27 | # Set position and rotation to targets 28 | 29 | self.position = self.position.lerp(target.position, delta * 4) 30 | rotation_degrees = rotation_degrees.lerp(camera_rotation, delta * 6) 31 | 32 | camera.position = camera.position.lerp(Vector3(0, 0, zoom), 8 * delta) 33 | 34 | handle_input(delta) 35 | 36 | # Handle input 37 | 38 | func handle_input(delta): 39 | 40 | # Rotation 41 | 42 | var input := Vector3.ZERO 43 | 44 | input.y = Input.get_axis("camera_left", "camera_right") 45 | input.x = Input.get_axis("camera_up", "camera_down") 46 | 47 | camera_rotation += input.limit_length(1.0) * rotation_speed * delta 48 | camera_rotation.x = clamp(camera_rotation.x, -80, -10) 49 | 50 | # Zooming 51 | 52 | zoom += Input.get_axis("zoom_in", "zoom_out") * zoom_speed * delta 53 | zoom = clamp(zoom, zoom_maximum, zoom_minimum) 54 | -------------------------------------------------------------------------------- /sounds/coin.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/sounds/coin.ogg -------------------------------------------------------------------------------- /sounds/coin.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://bygrj12u37fyu" 6 | path="res://.godot/imported/coin.ogg-03bf8cca0d4317de64b04e344cce1fba.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://sounds/coin.ogg" 11 | dest_files=["res://.godot/imported/coin.ogg-03bf8cca0d4317de64b04e344cce1fba.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=false 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /sounds/fall.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/sounds/fall.ogg -------------------------------------------------------------------------------- /sounds/fall.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://cko3em7xury11" 6 | path="res://.godot/imported/fall.ogg-ed1ea1270f869ae1edfb2ff9fa634b4b.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://sounds/fall.ogg" 11 | dest_files=["res://.godot/imported/fall.ogg-ed1ea1270f869ae1edfb2ff9fa634b4b.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=false 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /sounds/jump.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/sounds/jump.ogg -------------------------------------------------------------------------------- /sounds/jump.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://dw2m5fxhfjykq" 6 | path="res://.godot/imported/jump.ogg-de8df8640ff526968292c23fe5ec784f.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://sounds/jump.ogg" 11 | dest_files=["res://.godot/imported/jump.ogg-de8df8640ff526968292c23fe5ec784f.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=false 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /sounds/land.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/sounds/land.ogg -------------------------------------------------------------------------------- /sounds/land.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://xnxidwkp46un" 6 | path="res://.godot/imported/land.ogg-7222ba872273a4a7535937ef5cfdffd0.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://sounds/land.ogg" 11 | dest_files=["res://.godot/imported/land.ogg-7222ba872273a4a7535937ef5cfdffd0.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=false 16 | loop_offset=0 17 | bpm=0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /sounds/walking.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/sounds/walking.ogg -------------------------------------------------------------------------------- /sounds/walking.ogg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="oggvorbisstr" 4 | type="AudioStreamOggVorbis" 5 | uid="uid://cydjn1ct3hps2" 6 | path="res://.godot/imported/walking.ogg-bf61e9916135189ff0d5c06a148b02ab.oggvorbisstr" 7 | 8 | [deps] 9 | 10 | source_file="res://sounds/walking.ogg" 11 | dest_files=["res://.godot/imported/walking.ogg-bf61e9916135189ff0d5c06a148b02ab.oggvorbisstr"] 12 | 13 | [params] 14 | 15 | loop=true 16 | loop_offset=0.0 17 | bpm=0.0 18 | beat_count=0 19 | bar_beats=4 20 | -------------------------------------------------------------------------------- /sounds/walking.ogg.sfk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/sounds/walking.ogg.sfk -------------------------------------------------------------------------------- /splash-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/splash-screen.png -------------------------------------------------------------------------------- /splash-screen.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://i660sjvhsuu" 6 | path="res://.godot/imported/splash-screen.png-ae6c8b07e185ee8a074576008d9ccc5a.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://splash-screen.png" 14 | dest_files=["res://.godot/imported/splash-screen.png-ae6c8b07e185ee8a074576008d9ccc5a.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /sprites/blob_shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/sprites/blob_shadow.png -------------------------------------------------------------------------------- /sprites/blob_shadow.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://8ggihh27mlrr" 6 | path="res://.godot/imported/blob_shadow.png-d19f4ffceb1d99dd3331acec2dc6d7df.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://sprites/blob_shadow.png" 14 | dest_files=["res://.godot/imported/blob_shadow.png-d19f4ffceb1d99dd3331acec2dc6d7df.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /sprites/coin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/sprites/coin.png -------------------------------------------------------------------------------- /sprites/coin.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://cd7oyc56ehkx1" 6 | path.s3tc="res://.godot/imported/coin.png-54d5e156d7891d9603a51f76f85b4fd9.s3tc.ctex" 7 | metadata={ 8 | "imported_formats": ["s3tc_bptc"], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://sprites/coin.png" 15 | dest_files=["res://.godot/imported/coin.png-54d5e156d7891d9603a51f76f85b4fd9.s3tc.ctex"] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/high_quality=false 21 | compress/lossy_quality=0.7 22 | compress/hdr_compression=1 23 | compress/normal_map=0 24 | compress/channel_pack=0 25 | mipmaps/generate=true 26 | mipmaps/limit=-1 27 | roughness/mode=0 28 | roughness/src_normal="" 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/normal_map_invert_y=false 32 | process/hdr_as_srgb=false 33 | process/hdr_clamp_exposure=false 34 | process/size_limit=0 35 | detect_3d/compress_to=0 36 | -------------------------------------------------------------------------------- /sprites/particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/sprites/particle.png -------------------------------------------------------------------------------- /sprites/particle.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bs6puxrivhkk2" 6 | path.s3tc="res://.godot/imported/particle.png-9c8c1748211b697ea72e6a5d18d7f578.s3tc.ctex" 7 | metadata={ 8 | "imported_formats": ["s3tc_bptc"], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://sprites/particle.png" 15 | dest_files=["res://.godot/imported/particle.png-9c8c1748211b697ea72e6a5d18d7f578.s3tc.ctex"] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/high_quality=false 21 | compress/lossy_quality=0.7 22 | compress/hdr_compression=1 23 | compress/normal_map=0 24 | compress/channel_pack=0 25 | mipmaps/generate=true 26 | mipmaps/limit=-1 27 | roughness/mode=0 28 | roughness/src_normal="" 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/normal_map_invert_y=false 32 | process/hdr_as_srgb=false 33 | process/hdr_clamp_exposure=false 34 | process/size_limit=0 35 | detect_3d/compress_to=0 36 | -------------------------------------------------------------------------------- /vector/.gdignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/vector/.gdignore -------------------------------------------------------------------------------- /vector/sprites.fla: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniciusgerevini/godot-hierarchical-task-network-example/66cf1490977c0f1af5a9691aff3703f057b7eb06/vector/sprites.fla --------------------------------------------------------------------------------