commit 4334f4a4b01436bf1db943dc245510b2dd39a14d Author: Reed Date: Mon Dec 29 11:54:31 2025 +0800 init diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..30c2142 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,13 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# Rider 忽略的文件 +/contentModel.xml +/.idea.phantom-agnes.iml +/modules.xml +/projectSettingsUpdater.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/indexLayout.xml b/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..db47362 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/libraries/GdSdk.xml b/.idea/libraries/GdSdk.xml new file mode 100644 index 0000000..226ed03 --- /dev/null +++ b/.idea/libraries/GdSdk.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/NOTENGINE/all.aseprite b/NOTENGINE/all.aseprite new file mode 100644 index 0000000..3e274f3 Binary files /dev/null and b/NOTENGINE/all.aseprite differ diff --git a/NOTENGINE/all.png b/NOTENGINE/all.png new file mode 100644 index 0000000..8f934a7 Binary files /dev/null and b/NOTENGINE/all.png differ diff --git a/NOTENGINE/all.png.import b/NOTENGINE/all.png.import new file mode 100644 index 0000000..90fd4ae --- /dev/null +++ b/NOTENGINE/all.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://oiqrlng3jvnu" +path="res://.godot/imported/all.png-42a8cf7109de190bbde0339d31b78a8d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://NOTENGINE/all.png" +dest_files=["res://.godot/imported/all.png-42a8cf7109de190bbde0339d31b78a8d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/_asset/all.png b/_asset/all.png new file mode 100644 index 0000000..8f934a7 Binary files /dev/null and b/_asset/all.png differ diff --git a/_asset/all.png.import b/_asset/all.png.import new file mode 100644 index 0000000..24e0b98 --- /dev/null +++ b/_asset/all.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://doxhsab56pe50" +path="res://.godot/imported/all.png-666b3389ee629c05e6ece1ebc382b254.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://_asset/all.png" +dest_files=["res://.godot/imported/all.png-666b3389ee629c05e6ece1ebc382b254.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/_asset/brackeys_platformer_assets/LICENSE & CREDITS.txt b/_asset/brackeys_platformer_assets/LICENSE & CREDITS.txt new file mode 100644 index 0000000..e4de28b --- /dev/null +++ b/_asset/brackeys_platformer_assets/LICENSE & CREDITS.txt @@ -0,0 +1,26 @@ +All assets in the pack have been repackaged and many have been modified by Brackeys. + + +LICENSE for all assets: + +Creative Commons Zero (CC0) + + +CREDIT: + +SPRITES by analogStudios_: +knight (https://analogstudios.itch.io/camelot) +slime (https://analogstudios.itch.io/dungeonsprites) +platforms and coin (https://analogstudios.itch.io/four-seasons-platformer-sprites) + +SPRITES by RottingPixels: +world_tileset and fruit (https://rottingpixels.itch.io/four-seasons-platformer-tileset-16x16free) + + +WORLD TILESET originally + +SOUNDS by Brackeys, Asbjørn Thirslund + +MUSIC by Brackeys, Sofia Thirslund + +FONTS by Jayvee Enaguas - HarvettFox96 - (https://www.dafont.com/pixel-operator.font?l[]=10&l[]=1) \ No newline at end of file diff --git a/_asset/brackeys_platformer_assets/fonts/PixelOperator8-Bold.ttf b/_asset/brackeys_platformer_assets/fonts/PixelOperator8-Bold.ttf new file mode 100644 index 0000000..10225eb Binary files /dev/null and b/_asset/brackeys_platformer_assets/fonts/PixelOperator8-Bold.ttf differ diff --git a/_asset/brackeys_platformer_assets/fonts/PixelOperator8-Bold.ttf.import b/_asset/brackeys_platformer_assets/fonts/PixelOperator8-Bold.ttf.import new file mode 100644 index 0000000..2f2bcdf --- /dev/null +++ b/_asset/brackeys_platformer_assets/fonts/PixelOperator8-Bold.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://cbytas3yrpcm" +path="res://.godot/imported/PixelOperator8-Bold.ttf-b1cba22c9dd47952662a77198c0d4c94.fontdata" + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/fonts/PixelOperator8-Bold.ttf" +dest_files=["res://.godot/imported/PixelOperator8-Bold.ttf-b1cba22c9dd47952662a77198c0d4c94.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/_asset/brackeys_platformer_assets/fonts/PixelOperator8.ttf b/_asset/brackeys_platformer_assets/fonts/PixelOperator8.ttf new file mode 100644 index 0000000..f9146ac Binary files /dev/null and b/_asset/brackeys_platformer_assets/fonts/PixelOperator8.ttf differ diff --git a/_asset/brackeys_platformer_assets/fonts/PixelOperator8.ttf.import b/_asset/brackeys_platformer_assets/fonts/PixelOperator8.ttf.import new file mode 100644 index 0000000..49a28da --- /dev/null +++ b/_asset/brackeys_platformer_assets/fonts/PixelOperator8.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://cqtuqjbnswp2q" +path="res://.godot/imported/PixelOperator8.ttf-c3448ca90e1667ccda726c5e4dff9ea8.fontdata" + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/fonts/PixelOperator8.ttf" +dest_files=["res://.godot/imported/PixelOperator8.ttf-c3448ca90e1667ccda726c5e4dff9ea8.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/_asset/brackeys_platformer_assets/music/time_for_adventure.mp3 b/_asset/brackeys_platformer_assets/music/time_for_adventure.mp3 new file mode 100644 index 0000000..2ba9940 Binary files /dev/null and b/_asset/brackeys_platformer_assets/music/time_for_adventure.mp3 differ diff --git a/_asset/brackeys_platformer_assets/music/time_for_adventure.mp3.import b/_asset/brackeys_platformer_assets/music/time_for_adventure.mp3.import new file mode 100644 index 0000000..1d91e8f --- /dev/null +++ b/_asset/brackeys_platformer_assets/music/time_for_adventure.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://qitj6xva2whp" +path="res://.godot/imported/time_for_adventure.mp3-650c944b52016e3af9f2ccdac8b50c4c.mp3str" + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/music/time_for_adventure.mp3" +dest_files=["res://.godot/imported/time_for_adventure.mp3-650c944b52016e3af9f2ccdac8b50c4c.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/_asset/brackeys_platformer_assets/sounds/coin.wav b/_asset/brackeys_platformer_assets/sounds/coin.wav new file mode 100644 index 0000000..0509182 Binary files /dev/null and b/_asset/brackeys_platformer_assets/sounds/coin.wav differ diff --git a/_asset/brackeys_platformer_assets/sounds/coin.wav.import b/_asset/brackeys_platformer_assets/sounds/coin.wav.import new file mode 100644 index 0000000..a874c7d --- /dev/null +++ b/_asset/brackeys_platformer_assets/sounds/coin.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://ev0r1v3ikw84" +path="res://.godot/imported/coin.wav-fc0d38a2d5098eeb7fa27e34a266ab06.sample" + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sounds/coin.wav" +dest_files=["res://.godot/imported/coin.wav-fc0d38a2d5098eeb7fa27e34a266ab06.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/_asset/brackeys_platformer_assets/sounds/explosion.wav b/_asset/brackeys_platformer_assets/sounds/explosion.wav new file mode 100644 index 0000000..8a67b16 Binary files /dev/null and b/_asset/brackeys_platformer_assets/sounds/explosion.wav differ diff --git a/_asset/brackeys_platformer_assets/sounds/explosion.wav.import b/_asset/brackeys_platformer_assets/sounds/explosion.wav.import new file mode 100644 index 0000000..edc1110 --- /dev/null +++ b/_asset/brackeys_platformer_assets/sounds/explosion.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://dikl0lf6yck1h" +path="res://.godot/imported/explosion.wav-9065931af2ee674a8c896c6c4f8fb4cc.sample" + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sounds/explosion.wav" +dest_files=["res://.godot/imported/explosion.wav-9065931af2ee674a8c896c6c4f8fb4cc.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/_asset/brackeys_platformer_assets/sounds/hurt.wav b/_asset/brackeys_platformer_assets/sounds/hurt.wav new file mode 100644 index 0000000..b46ecd7 Binary files /dev/null and b/_asset/brackeys_platformer_assets/sounds/hurt.wav differ diff --git a/_asset/brackeys_platformer_assets/sounds/hurt.wav.import b/_asset/brackeys_platformer_assets/sounds/hurt.wav.import new file mode 100644 index 0000000..04610ba --- /dev/null +++ b/_asset/brackeys_platformer_assets/sounds/hurt.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://bttfdx40rlhgb" +path="res://.godot/imported/hurt.wav-59fed8a2d9027ab66e8c222616ee6ca7.sample" + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sounds/hurt.wav" +dest_files=["res://.godot/imported/hurt.wav-59fed8a2d9027ab66e8c222616ee6ca7.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/_asset/brackeys_platformer_assets/sounds/jump.wav b/_asset/brackeys_platformer_assets/sounds/jump.wav new file mode 100644 index 0000000..611bddf Binary files /dev/null and b/_asset/brackeys_platformer_assets/sounds/jump.wav differ diff --git a/_asset/brackeys_platformer_assets/sounds/jump.wav.import b/_asset/brackeys_platformer_assets/sounds/jump.wav.import new file mode 100644 index 0000000..3791ec7 --- /dev/null +++ b/_asset/brackeys_platformer_assets/sounds/jump.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://biew65u5bw68p" +path="res://.godot/imported/jump.wav-f543d4993c937381059c98b4a0fe0f50.sample" + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sounds/jump.wav" +dest_files=["res://.godot/imported/jump.wav-f543d4993c937381059c98b4a0fe0f50.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/_asset/brackeys_platformer_assets/sounds/power_up.wav b/_asset/brackeys_platformer_assets/sounds/power_up.wav new file mode 100644 index 0000000..d807e3f Binary files /dev/null and b/_asset/brackeys_platformer_assets/sounds/power_up.wav differ diff --git a/_asset/brackeys_platformer_assets/sounds/power_up.wav.import b/_asset/brackeys_platformer_assets/sounds/power_up.wav.import new file mode 100644 index 0000000..1fc4279 --- /dev/null +++ b/_asset/brackeys_platformer_assets/sounds/power_up.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://d2cg4al661d7a" +path="res://.godot/imported/power_up.wav-3502c78671bb1aa46d526d676fb311c9.sample" + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sounds/power_up.wav" +dest_files=["res://.godot/imported/power_up.wav-3502c78671bb1aa46d526d676fb311c9.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/_asset/brackeys_platformer_assets/sounds/tap.wav b/_asset/brackeys_platformer_assets/sounds/tap.wav new file mode 100644 index 0000000..e9dc6ab Binary files /dev/null and b/_asset/brackeys_platformer_assets/sounds/tap.wav differ diff --git a/_asset/brackeys_platformer_assets/sounds/tap.wav.import b/_asset/brackeys_platformer_assets/sounds/tap.wav.import new file mode 100644 index 0000000..65ebefe --- /dev/null +++ b/_asset/brackeys_platformer_assets/sounds/tap.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://dbrbmsi8uyul7" +path="res://.godot/imported/tap.wav-0dad550acf74388091fffd2a612c0bd6.sample" + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sounds/tap.wav" +dest_files=["res://.godot/imported/tap.wav-0dad550acf74388091fffd2a612c0bd6.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/_asset/brackeys_platformer_assets/sprites/coin.png b/_asset/brackeys_platformer_assets/sprites/coin.png new file mode 100644 index 0000000..01ae33d Binary files /dev/null and b/_asset/brackeys_platformer_assets/sprites/coin.png differ diff --git a/_asset/brackeys_platformer_assets/sprites/coin.png.import b/_asset/brackeys_platformer_assets/sprites/coin.png.import new file mode 100644 index 0000000..8fd43a1 --- /dev/null +++ b/_asset/brackeys_platformer_assets/sprites/coin.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://blmcygf06lxay" +path="res://.godot/imported/coin.png-beb87bd1229e7a2d53bf557ba3336f7d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sprites/coin.png" +dest_files=["res://.godot/imported/coin.png-beb87bd1229e7a2d53bf557ba3336f7d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/_asset/brackeys_platformer_assets/sprites/fruit.png b/_asset/brackeys_platformer_assets/sprites/fruit.png new file mode 100644 index 0000000..b9cc7d6 Binary files /dev/null and b/_asset/brackeys_platformer_assets/sprites/fruit.png differ diff --git a/_asset/brackeys_platformer_assets/sprites/fruit.png.import b/_asset/brackeys_platformer_assets/sprites/fruit.png.import new file mode 100644 index 0000000..f17efc1 --- /dev/null +++ b/_asset/brackeys_platformer_assets/sprites/fruit.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d3c7aj54lphin" +path="res://.godot/imported/fruit.png-a5a033fdb4a109b0ce0a99320ddfdcf0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sprites/fruit.png" +dest_files=["res://.godot/imported/fruit.png-a5a033fdb4a109b0ce0a99320ddfdcf0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/_asset/brackeys_platformer_assets/sprites/knight.png b/_asset/brackeys_platformer_assets/sprites/knight.png new file mode 100644 index 0000000..5b0eb4f Binary files /dev/null and b/_asset/brackeys_platformer_assets/sprites/knight.png differ diff --git a/_asset/brackeys_platformer_assets/sprites/knight.png.import b/_asset/brackeys_platformer_assets/sprites/knight.png.import new file mode 100644 index 0000000..e87f627 --- /dev/null +++ b/_asset/brackeys_platformer_assets/sprites/knight.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://db2kdmupks7xw" +path="res://.godot/imported/knight.png-10aa663a6019c3fc4ba27406a490bb65.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sprites/knight.png" +dest_files=["res://.godot/imported/knight.png-10aa663a6019c3fc4ba27406a490bb65.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/_asset/brackeys_platformer_assets/sprites/platforms.png b/_asset/brackeys_platformer_assets/sprites/platforms.png new file mode 100644 index 0000000..9be41db Binary files /dev/null and b/_asset/brackeys_platformer_assets/sprites/platforms.png differ diff --git a/_asset/brackeys_platformer_assets/sprites/platforms.png.import b/_asset/brackeys_platformer_assets/sprites/platforms.png.import new file mode 100644 index 0000000..bfc1b74 --- /dev/null +++ b/_asset/brackeys_platformer_assets/sprites/platforms.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cyojkecmj2toq" +path="res://.godot/imported/platforms.png-201b994e8f646c2c9f88ffe6124bfb7e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sprites/platforms.png" +dest_files=["res://.godot/imported/platforms.png-201b994e8f646c2c9f88ffe6124bfb7e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/_asset/brackeys_platformer_assets/sprites/slime_green.png b/_asset/brackeys_platformer_assets/sprites/slime_green.png new file mode 100644 index 0000000..a21cb6f Binary files /dev/null and b/_asset/brackeys_platformer_assets/sprites/slime_green.png differ diff --git a/_asset/brackeys_platformer_assets/sprites/slime_green.png.import b/_asset/brackeys_platformer_assets/sprites/slime_green.png.import new file mode 100644 index 0000000..01f071e --- /dev/null +++ b/_asset/brackeys_platformer_assets/sprites/slime_green.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dw2i7jelr4a8q" +path="res://.godot/imported/slime_green.png-420249250f66a0ec31a3bd05dc2e2425.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sprites/slime_green.png" +dest_files=["res://.godot/imported/slime_green.png-420249250f66a0ec31a3bd05dc2e2425.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/_asset/brackeys_platformer_assets/sprites/slime_purple.png b/_asset/brackeys_platformer_assets/sprites/slime_purple.png new file mode 100644 index 0000000..76f564e Binary files /dev/null and b/_asset/brackeys_platformer_assets/sprites/slime_purple.png differ diff --git a/_asset/brackeys_platformer_assets/sprites/slime_purple.png.import b/_asset/brackeys_platformer_assets/sprites/slime_purple.png.import new file mode 100644 index 0000000..be2865f --- /dev/null +++ b/_asset/brackeys_platformer_assets/sprites/slime_purple.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://hh7y2udy3o41" +path="res://.godot/imported/slime_purple.png-e4c795221083c86fb16dcd605ac250e5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sprites/slime_purple.png" +dest_files=["res://.godot/imported/slime_purple.png-e4c795221083c86fb16dcd605ac250e5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/_asset/brackeys_platformer_assets/sprites/world_tileset.png b/_asset/brackeys_platformer_assets/sprites/world_tileset.png new file mode 100644 index 0000000..36bbf07 Binary files /dev/null and b/_asset/brackeys_platformer_assets/sprites/world_tileset.png differ diff --git a/_asset/brackeys_platformer_assets/sprites/world_tileset.png.import b/_asset/brackeys_platformer_assets/sprites/world_tileset.png.import new file mode 100644 index 0000000..2346108 --- /dev/null +++ b/_asset/brackeys_platformer_assets/sprites/world_tileset.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cmwkvb4c2n45h" +path="res://.godot/imported/world_tileset.png-80a9cd9d2174af6586e1c33c362cefcd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://_asset/brackeys_platformer_assets/sprites/world_tileset.png" +dest_files=["res://.godot/imported/world_tileset.png-80a9cd9d2174af6586e1c33c362cefcd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/_asset/sound/jump/ai_jump_dirt.wav b/_asset/sound/jump/ai_jump_dirt.wav new file mode 100644 index 0000000..cfeac75 Binary files /dev/null and b/_asset/sound/jump/ai_jump_dirt.wav differ diff --git a/_asset/sound/jump/ai_jump_dirt.wav.import b/_asset/sound/jump/ai_jump_dirt.wav.import new file mode 100644 index 0000000..374c691 --- /dev/null +++ b/_asset/sound/jump/ai_jump_dirt.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://bbdeag44ynd4" +path="res://.godot/imported/ai_jump_dirt.wav-89c40af2c8bcd6ee2b9de25fded3be4f.sample" + +[deps] + +source_file="res://_asset/sound/jump/ai_jump_dirt.wav" +dest_files=["res://.godot/imported/ai_jump_dirt.wav-89c40af2c8bcd6ee2b9de25fded3be4f.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/_game/Game.tscn b/_game/Game.tscn new file mode 100644 index 0000000..78dbead --- /dev/null +++ b/_game/Game.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=3 format=3 uid="uid://3vc8ojbiyy5w"] + +[ext_resource type="PackedScene" uid="uid://gwhff4qaouxy" path="res://_player/Agens.tscn" id="1_fdx6o"] +[ext_resource type="PackedScene" uid="uid://1l06de041i40" path="res://_levels/l_level_1.tscn" id="1_pvnxo"] + +[node name="Game" type="Node2D"] + +[node name="level_1" parent="." instance=ExtResource("1_pvnxo")] + +[node name="Agens" parent="." instance=ExtResource("1_fdx6o")] +position = Vector2(218, 251) +collision_mask = 4 diff --git a/_game/Game.tscn1339568035.tmp b/_game/Game.tscn1339568035.tmp new file mode 100644 index 0000000..78dbead --- /dev/null +++ b/_game/Game.tscn1339568035.tmp @@ -0,0 +1,12 @@ +[gd_scene load_steps=3 format=3 uid="uid://3vc8ojbiyy5w"] + +[ext_resource type="PackedScene" uid="uid://gwhff4qaouxy" path="res://_player/Agens.tscn" id="1_fdx6o"] +[ext_resource type="PackedScene" uid="uid://1l06de041i40" path="res://_levels/l_level_1.tscn" id="1_pvnxo"] + +[node name="Game" type="Node2D"] + +[node name="level_1" parent="." instance=ExtResource("1_pvnxo")] + +[node name="Agens" parent="." instance=ExtResource("1_fdx6o")] +position = Vector2(218, 251) +collision_mask = 4 diff --git a/_game/Game.tscn1345264575.tmp b/_game/Game.tscn1345264575.tmp new file mode 100644 index 0000000..78dbead --- /dev/null +++ b/_game/Game.tscn1345264575.tmp @@ -0,0 +1,12 @@ +[gd_scene load_steps=3 format=3 uid="uid://3vc8ojbiyy5w"] + +[ext_resource type="PackedScene" uid="uid://gwhff4qaouxy" path="res://_player/Agens.tscn" id="1_fdx6o"] +[ext_resource type="PackedScene" uid="uid://1l06de041i40" path="res://_levels/l_level_1.tscn" id="1_pvnxo"] + +[node name="Game" type="Node2D"] + +[node name="level_1" parent="." instance=ExtResource("1_pvnxo")] + +[node name="Agens" parent="." instance=ExtResource("1_fdx6o")] +position = Vector2(218, 251) +collision_mask = 4 diff --git a/_game/GameMain.tscn b/_game/GameMain.tscn new file mode 100644 index 0000000..25cabb3 --- /dev/null +++ b/_game/GameMain.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=3 format=3 uid="uid://ctqkbmyjo65bk"] + +[ext_resource type="Script" uid="uid://dn0ksjoswquf5" path="res://addons/reedscene/scene/SceneManager.gd" id="1_0sb54"] +[ext_resource type="Script" uid="uid://bwvbeodhvhrmw" path="res://addons/reedfx/vfx/VFXLayer.gd" id="2_ghnqe"] + +[node name="GameMain" type="Node" node_paths=PackedStringArray("TransitionNode")] +script = ExtResource("1_0sb54") +TransitionNode = NodePath("Transition") +metadata/_custom_type_script = "uid://dn0ksjoswquf5" + +[node name="Transition" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 0 + +[node name="ReedVFXLayer" type="CanvasLayer" parent="."] +script = ExtResource("2_ghnqe") +metadata/_custom_type_script = "uid://bwvbeodhvhrmw" diff --git a/_levels/l_level_1.tscn b/_levels/l_level_1.tscn new file mode 100644 index 0000000..6d44787 --- /dev/null +++ b/_levels/l_level_1.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=2 format=4 uid="uid://1l06de041i40"] + +[ext_resource type="TileSet" uid="uid://doepkfp83k0lb" path="res://_tileset/test.tres" id="1_pbk25"] + +[node name="level_1" type="TileMapLayer"] +texture_filter = 1 +tile_map_data = PackedByteArray("AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAA0AAAAAAAAAAAAAAA4AAAAAAAAAAAAAAA8AAAAAAAAAAAAAABAAAAAAAAAAAAAAABEAAAAAAAAAAAAAABIAAAAAAAAAAAAAABMAAAAAAAAAAAAAABQAAAAAAAAAAAAAABUAAAAAAAAAAAAAABYAAAAAAAAAAAABAAAAAAAAAAAAAAABAAEAAAAAAAAAAAABAAIAAAAAAAAAAAABAAMAAAAAAAAAAAABAAQAAAAAAAAAAAABAAUAAAAAAAAAAAABAAYAAAAAAAAAAAABAAcAAAAAAAAAAAABAAgAAAAAAAAAAAABAAkAAAAAAAAAAAABAAoAAAAAAAAAAAABAAsAAAAAAAAAAAABAAwAAAAAAAAAAAABAA0AAAAAAAAAAAABAA4AAAAAAAAAAAABAA8AAAAAAAAAAAABABAAAAAAAAAAAAABABEAAAAAAAAAAAABABIAAAAAAAAAAAABABMAAAAAAAAAAAABABQAAAAAAAAAAAABABUAAAAAAAAAAAABABYAAAAAAAAAAAACAAAAAAAAAAAAAAACAAEAAAAAAAAAAAACAAIAAAAAAAAAAAACAAMAAAAAAAAAAAACAAQAAAAAAAAAAAACAAUAAAAAAAAAAAACAAYAAAAAAAAAAAACAAcAAAAAAAAAAAACAAgAAAAAAAAAAAACAAkAAAAAAAAAAAACAAoAAAAAAAAAAAACAAsAAAAAAAAAAAACAAwAAAAAAAAAAAACAA0AAAAAAAAAAAACAA4AAAAAAAAAAAACAA8AAAAAAAAAAAACABAAAAAAAAAAAAACABEAAAAAAAAAAAACABIAAAAAAAAAAAACABMAAAAAAAAAAAACABQAAAAAAAAAAAACABUAAAAAAAAAAAACABYAAAAAAAAAAAADAAAAAAAAAAAAAAADAAEAAAAAAAAAAAADAAIAAAAAAAAAAAADAAMAAAAAAAAAAAADAAQAAAAAAAAAAAADAAUAAAAAAAAAAAADAAYAAAAAAAAAAAADAAcAAAAAAAAAAAADAAgAAAAAAAAAAAADAAkAAAAAAAAAAAADAAoAAAAAAAAAAAADAAsAAAAAAAAAAAADAAwAAAAAAAAAAAADAA0AAAAAAAAAAAADAA4AAAAAAAAAAAADAA8AAAAAAAAAAAADABAAAAAAAAAAAAADABEAAAAAAAAAAAADABIAAAAAAAAAAAADABMAAAAAAAAAAAADABQAAAAAAAAAAAADABUAAAAAAAAAAAADABYAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAEAAAAAAAAAAAAEAAIAAAAAAAAAAAAEAAMAAAAAAAAAAAAEAAQAAAAAAAAAAAAEAAUAAAAAAAAAAAAEAAYAAAAAAAAAAAAEAAcAAAAAAAAAAAAEAAgAAAAAAAAAAAAEAAkAAAAAAAAAAAAEAAoAAAAAAAAAAAAEAAsAAAAAAAAAAAAEAAwAAAAAAAAAAAAEAA0AAAAAAAAAAAAEAA4AAAAAAAAAAAAEAA8AAAAAAAAAAAAEABAAAAAAAAAAAAAEABEAAAAAAAAAAAAEABIAAAAAAAAAAAAEABMAAAAAAAAAAAAEABQAAAAAAAAAAAAEABUAAAAAAAAAAAAEABYAAAAAAAAAAAAFAAAAAAAAAAAAAAAFAAEAAAAAAAAAAAAFAAIAAAAAAAAAAAAFAAMAAAAAAAAAAAAFAAQAAAAAAAAAAAAFAAUAAAAAAAAAAAAFAAYAAAAAAAAAAAAFAAcAAAAAAAAAAAAFAAgAAAAAAAAAAAAFAAkAAAAAAAAAAAAFAAoAAAAAAAAAAAAFAAsAAAAAAAAAAAAFAAwAAAAAAAAAAAAFAA0AAAAAAAAAAAAFAA4AAAAAAAAAAAAFAA8AAAAAAAAAAAAFABAAAAAAAAAAAAAFABEAAAAAAAAAAAAFABIAAAAAAAAAAAAFABMAAAAAAAAAAAAFABQAAAAAAAAAAAAFABUAAAAAAAAAAAAFABYAAAAAAAAAAAAGABIAAAAAAAAAAAAGABMAAAAAAAAAAAAGABQAAAAAAAAAAAAGABUAAAAAAAAAAAAGABYAAAAAAAAAAAAHABIAAAAAAAAAAAAHABMAAAAAAAAAAAAHABQAAAAAAAAAAAAHABUAAAAAAAAAAAAHABYAAAAAAAAAAAAIABIAAAAAAAAAAAAIABMAAAAAAAAAAAAIABQAAAAAAAAAAAAIABUAAAAAAAAAAAAIABYAAAAAAAAAAAAJABIAAAAAAAAAAAAJABMAAAAAAAAAAAAJABQAAAAAAAAAAAAJABUAAAAAAAAAAAAJABYAAAAAAAAAAAAKABIAAAAAAAAAAAAKABMAAAAAAAAAAAAKABQAAAAAAAAAAAAKABUAAAAAAAAAAAAKABYAAAAAAAAAAAALABIAAAAAAAAAAAALABMAAAAAAAAAAAALABQAAAAAAAAAAAALABUAAAAAAAAAAAALABYAAAAAAAAAAAAMABIAAAAAAAAAAAAMABMAAAAAAAAAAAAMABQAAAAAAAAAAAAMABUAAAAAAAAAAAAMABYAAAAAAAAAAAANABIAAAAAAAAAAAANABMAAAAAAAAAAAANABQAAAAAAAAAAAANABUAAAAAAAAAAAANABYAAAAAAAAAAAAOABIAAAAAAAAAAAAOABMAAAAAAAAAAAAOABQAAAAAAAAAAAAOABUAAAAAAAAAAAAOABYAAAAAAAAAAAAPABIAAAAAAAAAAAAPABMAAAAAAAAAAAAPABQAAAAAAAAAAAAPABUAAAAAAAAAAAAPABYAAAAAAAAAAAAQABIAAAAAAAAAAAAQABMAAAAAAAAAAAAQABQAAAAAAAAAAAAQABUAAAAAAAAAAAAQABYAAAAAAAAAAAARABIAAAAAAAAAAAARABMAAAAAAAAAAAARABQAAAAAAAAAAAARABUAAAAAAAAAAAARABYAAAAAAAAAAAASABIAAAAAAAAAAAASABMAAAAAAAAAAAASABQAAAAAAAAAAAASABUAAAAAAAAAAAASABYAAAAAAAAAAAATABIAAAAAAAAAAAATABMAAAAAAAAAAAATABQAAAAAAAAAAAATABUAAAAAAAAAAAATABYAAAAAAAAAAAAUABIAAAAAAAAAAAAUABMAAAAAAAAAAAAUABQAAAAAAAAAAAAUABUAAAAAAAAAAAAUABYAAAAAAAAAAAAVABIAAAAAAAAAAAAVABMAAAAAAAAAAAAVABQAAAAAAAAAAAAVABUAAAAAAAAAAAAVABYAAAAAAAAAAAARAA8AAAAAAAAAAAARABAAAAAAAAAAAAARABEAAAAAAAAAAAASAA8AAAAAAAAAAAASABAAAAAAAAAAAAASABEAAAAAAAAAAAATAA8AAAAAAAAAAAATABAAAAAAAAAAAAATABEAAAAAAAAAAAAUAA8AAAAAAAAAAAAUABAAAAAAAAAAAAAUABEAAAAAAAAAAAAVAA8AAAAAAAAAAAAVABAAAAAAAAAAAAAVABEAAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAEAAAAAAAAAAAAGAAIAAAAAAAAAAAAGAAMAAAAAAAAAAAAGAAQAAAAAAAAAAAAGAAUAAAAAAAAAAAAGAAYAAAAAAAAAAAAGAAcAAAAAAAAAAAAGAAgAAAAAAAAAAAAHAAAAAAAAAAAAAAAHAAEAAAAAAAAAAAAHAAIAAAAAAAAAAAAHAAMAAAAAAAAAAAAHAAQAAAAAAAAAAAAHAAUAAAAAAAAAAAAHAAYAAAAAAAAAAAAHAAcAAAAAAAAAAAAHAAgAAAAAAAAAAAAIAAAAAAAAAAAAAAAIAAEAAAAAAAAAAAAIAAIAAAAAAAAAAAAIAAMAAAAAAAAAAAAIAAQAAAAAAAAAAAAIAAUAAAAAAAAAAAAIAAYAAAAAAAAAAAAIAAcAAAAAAAAAAAAIAAgAAAAAAAAAAAAJAAAAAAAAAAAAAAAJAAEAAAAAAAAAAAAJAAIAAAAAAAAAAAAJAAMAAAAAAAAAAAAJAAQAAAAAAAAAAAAJAAUAAAAAAAAAAAAJAAYAAAAAAAAAAAAJAAcAAAAAAAAAAAAJAAgAAAAAAAAAAAAKAAAAAAAAAAAAAAAKAAEAAAAAAAAAAAAKAAIAAAAAAAAAAAAKAAMAAAAAAAAAAAAKAAQAAAAAAAAAAAAKAAUAAAAAAAAAAAAKAAYAAAAAAAAAAAAKAAcAAAAAAAAAAAAKAAgAAAAAAAAAAAALAAAAAAAAAAAAAAALAAEAAAAAAAAAAAALAAIAAAAAAAAAAAALAAMAAAAAAAAAAAALAAQAAAAAAAAAAAALAAUAAAAAAAAAAAALAAYAAAAAAAAAAAALAAcAAAAAAAAAAAALAAgAAAAAAAAAAAAMAAAAAAAAAAAAAAAMAAEAAAAAAAAAAAAMAAIAAAAAAAAAAAAMAAMAAAAAAAAAAAAMAAQAAAAAAAAAAAAMAAUAAAAAAAAAAAAMAAYAAAAAAAAAAAAMAAcAAAAAAAAAAAAMAAgAAAAAAAAAAAANAAAAAAAAAAAAAAANAAEAAAAAAAAAAAANAAIAAAAAAAAAAAANAAMAAAAAAAAAAAANAAQAAAAAAAAAAAANAAUAAAAAAAAAAAANAAYAAAAAAAAAAAANAAcAAAAAAAAAAAANAAgAAAAAAAAAAAAOAAAAAAAAAAAAAAAOAAEAAAAAAAAAAAAOAAIAAAAAAAAAAAAOAAMAAAAAAAAAAAAOAAQAAAAAAAAAAAAOAAUAAAAAAAAAAAAOAAYAAAAAAAAAAAAOAAcAAAAAAAAAAAAOAAgAAAAAAAAAAAAcAAkAAAAAAAAAAAAcAAoAAAAAAAAAAAAcAAsAAAAAAAAAAAAcAAwAAAAAAAAAAAAcAA0AAAAAAAAAAAAcAA4AAAAAAAAAAAAcAA8AAAAAAAAAAAAcABAAAAAAAAAAAAAcABEAAAAAAAAAAAAcABIAAAAAAAAAAAAcABMAAAAAAAAAAAAcABQAAAAAAAAAAAAcABUAAAAAAAAAAAAcABYAAAAAAAAAAAAdAAkAAAAAAAAAAAAdAAoAAAAAAAAAAAAdAAsAAAAAAAAAAAAdAAwAAAAAAAAAAAAdAA0AAAAAAAAAAAAdAA4AAAAAAAAAAAAdAA8AAAAAAAAAAAAdABAAAAAAAAAAAAAdABEAAAAAAAAAAAAdABIAAAAAAAAAAAAdABMAAAAAAAAAAAAdABQAAAAAAAAAAAAdABUAAAAAAAAAAAAdABYAAAAAAAAAAAAeAAkAAAAAAAAAAAAeAAoAAAAAAAAAAAAeAAsAAAAAAAAAAAAeAAwAAAAAAAAAAAAeAA0AAAAAAAAAAAAeAA4AAAAAAAAAAAAeAA8AAAAAAAAAAAAeABAAAAAAAAAAAAAeABEAAAAAAAAAAAAeABIAAAAAAAAAAAAeABMAAAAAAAAAAAAeABQAAAAAAAAAAAAeABUAAAAAAAAAAAAeABYAAAAAAAAAAAAfAAkAAAAAAAAAAAAfAAoAAAAAAAAAAAAfAAsAAAAAAAAAAAAfAAwAAAAAAAAAAAAfAA0AAAAAAAAAAAAfAA4AAAAAAAAAAAAfAA8AAAAAAAAAAAAfABAAAAAAAAAAAAAfABEAAAAAAAAAAAAfABIAAAAAAAAAAAAfABMAAAAAAAAAAAAfABQAAAAAAAAAAAAfABUAAAAAAAAAAAAfABYAAAAAAAAAAAAgAAkAAAAAAAAAAAAgAAoAAAAAAAAAAAAgAAsAAAAAAAAAAAAgAAwAAAAAAAAAAAAgAA0AAAAAAAAAAAAgAA4AAAAAAAAAAAAgAA8AAAAAAAAAAAAgABAAAAAAAAAAAAAgABEAAAAAAAAAAAAgABIAAAAAAAAAAAAgABMAAAAAAAAAAAAgABQAAAAAAAAAAAAgABUAAAAAAAAAAAAgABYAAAAAAAAAAAAhAAkAAAAAAAAAAAAhAAoAAAAAAAAAAAAhAAsAAAAAAAAAAAAhAAwAAAAAAAAAAAAhAA0AAAAAAAAAAAAhAA4AAAAAAAAAAAAhAA8AAAAAAAAAAAAhABAAAAAAAAAAAAAhABEAAAAAAAAAAAAhABIAAAAAAAAAAAAhABMAAAAAAAAAAAAhABQAAAAAAAAAAAAhABUAAAAAAAAAAAAhABYAAAAAAAAAAAAiAAkAAAAAAAAAAAAiAAoAAAAAAAAAAAAiAAsAAAAAAAAAAAAiAAwAAAAAAAAAAAAiAA0AAAAAAAAAAAAiAA4AAAAAAAAAAAAiAA8AAAAAAAAAAAAiABAAAAAAAAAAAAAiABEAAAAAAAAAAAAiABIAAAAAAAAAAAAiABMAAAAAAAAAAAAiABQAAAAAAAAAAAAiABUAAAAAAAAAAAAiABYAAAAAAAAAAAAjAAkAAAAAAAAAAAAjAAoAAAAAAAAAAAAjAAsAAAAAAAAAAAAjAAwAAAAAAAAAAAAjAA0AAAAAAAAAAAAjAA4AAAAAAAAAAAAjAA8AAAAAAAAAAAAjABAAAAAAAAAAAAAjABEAAAAAAAAAAAAjABIAAAAAAAAAAAAjABMAAAAAAAAAAAAjABQAAAAAAAAAAAAjABUAAAAAAAAAAAAjABYAAAAAAAAAAAAkAAkAAAAAAAAAAAAkAAoAAAAAAAAAAAAkAAsAAAAAAAAAAAAkAAwAAAAAAAAAAAAkAA0AAAAAAAAAAAAkAA4AAAAAAAAAAAAkAA8AAAAAAAAAAAAkABAAAAAAAAAAAAAkABEAAAAAAAAAAAAkABIAAAAAAAAAAAAkABMAAAAAAAAAAAAkABQAAAAAAAAAAAAkABUAAAAAAAAAAAAkABYAAAAAAAAAAAAlAAwAAAAAAAAAAAAlAA0AAAAAAAAAAAAlAA4AAAAAAAAAAAAlAA8AAAAAAAAAAAAlABAAAAAAAAAAAAAlABEAAAAAAAAAAAAlABIAAAAAAAAAAAAlABMAAAAAAAAAAAAlABQAAAAAAAAAAAAlABUAAAAAAAAAAAAlABYAAAAAAAAAAAAmAAwAAAAAAAAAAAAmAA0AAAAAAAAAAAAmAA4AAAAAAAAAAAAmAA8AAAAAAAAAAAAmABAAAAAAAAAAAAAmABEAAAAAAAAAAAAmABIAAAAAAAAAAAAmABMAAAAAAAAAAAAmABQAAAAAAAAAAAAmABUAAAAAAAAAAAAmABYAAAAAAAAAAAAnAA0AAAAAAAAAAAAnAA4AAAAAAAAAAAAnAA8AAAAAAAAAAAAnABAAAAAAAAAAAAAnABEAAAAAAAAAAAAnABIAAAAAAAAAAAAnABMAAAAAAAAAAAAnABQAAAAAAAAAAAAnABUAAAAAAAAAAAAnABYAAAAAAAAAAAAoAA0AAAAAAAAAAAAoAA4AAAAAAAAAAAAoAA8AAAAAAAAAAAAoABAAAAAAAAAAAAAoABEAAAAAAAAAAAAoABIAAAAAAAAAAAAoABMAAAAAAAAAAAAoABQAAAAAAAAAAAAoABUAAAAAAAAAAAAoABYAAAAAAAAAAAApAA0AAAAAAAAAAAApAA4AAAAAAAAAAAApAA8AAAAAAAAAAAApABAAAAAAAAAAAAApABEAAAAAAAAAAAApABIAAAAAAAAAAAApABMAAAAAAAAAAAApABQAAAAAAAAAAAApABUAAAAAAAAAAAApABYAAAAAAAAAAAAqAA0AAAAAAAAAAAAqAA4AAAAAAAAAAAAqAA8AAAAAAAAAAAAqABAAAAAAAAAAAAAqABEAAAAAAAAAAAAqABIAAAAAAAAAAAAqABMAAAAAAAAAAAAqABQAAAAAAAAAAAAqABUAAAAAAAAAAAAqABYAAAAAAAAAAAArAAwAAAAAAAAAAAArAA0AAAAAAAAAAAArAA4AAAAAAAAAAAArAA8AAAAAAAAAAAArABAAAAAAAAAAAAArABEAAAAAAAAAAAArABIAAAAAAAAAAAArABMAAAAAAAAAAAArABQAAAAAAAAAAAArABUAAAAAAAAAAAArABYAAAAAAAAAAAAsAAkAAAAAAAAAAAAsAAoAAAAAAAAAAAAsAAsAAAAAAAAAAAAsAAwAAAAAAAAAAAAsAA0AAAAAAAAAAAAsAA4AAAAAAAAAAAAsAA8AAAAAAAAAAAAsABAAAAAAAAAAAAAsABEAAAAAAAAAAAAsABIAAAAAAAAAAAAsABMAAAAAAAAAAAAsABQAAAAAAAAAAAAsABUAAAAAAAAAAAAsABYAAAAAAAAAAAAtAAkAAAAAAAAAAAAtAAoAAAAAAAAAAAAtAAsAAAAAAAAAAAAtAAwAAAAAAAAAAAAtAA0AAAAAAAAAAAAtAA4AAAAAAAAAAAAtAA8AAAAAAAAAAAAtABAAAAAAAAAAAAAtABEAAAAAAAAAAAAtABIAAAAAAAAAAAAtABMAAAAAAAAAAAAtABQAAAAAAAAAAAAtABUAAAAAAAAAAAAtABYAAAAAAAAAAAAuAAkAAAAAAAAAAAAuAAoAAAAAAAAAAAAuAAsAAAAAAAAAAAAuAAwAAAAAAAAAAAAuAA0AAAAAAAAAAAAuAA4AAAAAAAAAAAAuAA8AAAAAAAAAAAAuABAAAAAAAAAAAAAuABEAAAAAAAAAAAAuABIAAAAAAAAAAAAuABMAAAAAAAAAAAAuABQAAAAAAAAAAAAuABUAAAAAAAAAAAAuABYAAAAAAAAAAAAvAAkAAAAAAAAAAAAvAAoAAAAAAAAAAAAvAAsAAAAAAAAAAAAvAAwAAAAAAAAAAAAvAA0AAAAAAAAAAAAvAA4AAAAAAAAAAAAvAA8AAAAAAAAAAAAvABAAAAAAAAAAAAAvABEAAAAAAAAAAAAvABIAAAAAAAAAAAAvABMAAAAAAAAAAAAvABQAAAAAAAAAAAAvABUAAAAAAAAAAAAvABYAAAAAAAAAAAAwAAkAAAAAAAAAAAAwAAoAAAAAAAAAAAAwAAsAAAAAAAAAAAAwAAwAAAAAAAAAAAAwAA0AAAAAAAAAAAAwAA4AAAAAAAAAAAAwAA8AAAAAAAAAAAAwABAAAAAAAAAAAAAwABEAAAAAAAAAAAAwABIAAAAAAAAAAAAwABMAAAAAAAAAAAAwABQAAAAAAAAAAAAwABUAAAAAAAAAAAAwABYAAAAAAAAAAAAxAAkAAAAAAAAAAAAxAAoAAAAAAAAAAAAxAAsAAAAAAAAAAAAxAAwAAAAAAAAAAAAxAA0AAAAAAAAAAAAxAA4AAAAAAAAAAAAxAA8AAAAAAAAAAAAxABAAAAAAAAAAAAAxABEAAAAAAAAAAAAxABIAAAAAAAAAAAAxABMAAAAAAAAAAAAxABQAAAAAAAAAAAAxABUAAAAAAAAAAAAxABYAAAAAAAAAAAAyAAkAAAAAAAAAAAAyAAoAAAAAAAAAAAAyAAsAAAAAAAAAAAAyAAwAAAAAAAAAAAAyAA0AAAAAAAAAAAAyAA4AAAAAAAAAAAAyAA8AAAAAAAAAAAAyABAAAAAAAAAAAAAyABEAAAAAAAAAAAAyABIAAAAAAAAAAAAyABMAAAAAAAAAAAAyABQAAAAAAAAAAAAyABUAAAAAAAAAAAAyABYAAAAAAAAAAAAzAAkAAAAAAAAAAAAzAAoAAAAAAAAAAAAzAAsAAAAAAAAAAAAzAAwAAAAAAAAAAAAzAA0AAAAAAAAAAAAzAA4AAAAAAAAAAAAzAA8AAAAAAAAAAAAzABAAAAAAAAAAAAAzABEAAAAAAAAAAAAzABIAAAAAAAAAAAAzABMAAAAAAAAAAAAzABQAAAAAAAAAAAAzABUAAAAAAAAAAAAzABYAAAAAAAAAAAAlAAsAAAAAAAAAAAArAAsAAAAAAAAAAAAqAAwAAAAAAAAAAAAAAPv/AAAAAAAAAAAAAPz/AAAAAAAAAAAAAP3/AAAAAAAAAAAAAP7/AAAAAAAAAAAAAP//AAAAAAAAAAABAPv/AAAAAAAAAAABAPz/AAAAAAAAAAABAP3/AAAAAAAAAAABAP7/AAAAAAAAAAABAP//AAAAAAAAAAACAPv/AAAAAAAAAAACAPz/AAAAAAAAAAACAP3/AAAAAAAAAAACAP7/AAAAAAAAAAACAP//AAAAAAAAAAADAPv/AAAAAAAAAAADAPz/AAAAAAAAAAADAP3/AAAAAAAAAAADAP7/AAAAAAAAAAADAP//AAAAAAAAAAAEAPv/AAAAAAAAAAAEAPz/AAAAAAAAAAAEAP3/AAAAAAAAAAAEAP7/AAAAAAAAAAAEAP//AAAAAAAAAAAFAPv/AAAAAAAAAAAFAPz/AAAAAAAAAAAFAP3/AAAAAAAAAAAFAP7/AAAAAAAAAAAFAP//AAAAAAAAAAAGAPv/AAAAAAAAAAAGAPz/AAAAAAAAAAAGAP3/AAAAAAAAAAAGAP7/AAAAAAAAAAAGAP//AAAAAAAAAAAHAPv/AAAAAAAAAAAHAPz/AAAAAAAAAAAHAP3/AAAAAAAAAAAHAP7/AAAAAAAAAAAHAP//AAAAAAAAAAAIAPv/AAAAAAAAAAAIAPz/AAAAAAAAAAAIAP3/AAAAAAAAAAAIAP7/AAAAAAAAAAAIAP//AAAAAAAAAAAJAPv/AAAAAAAAAAAJAPz/AAAAAAAAAAAJAP3/AAAAAAAAAAAJAP7/AAAAAAAAAAAJAP//AAAAAAAAAAAKAPv/AAAAAAAAAAAKAPz/AAAAAAAAAAAKAP3/AAAAAAAAAAAKAP7/AAAAAAAAAAAKAP//AAAAAAAAAAALAPv/AAAAAAAAAAALAPz/AAAAAAAAAAALAP3/AAAAAAAAAAALAP7/AAAAAAAAAAALAP//AAAAAAAAAAAMAPv/AAAAAAAAAAAMAPz/AAAAAAAAAAAMAP3/AAAAAAAAAAAMAP7/AAAAAAAAAAAMAP//AAAAAAAAAAANAPv/AAAAAAAAAAANAPz/AAAAAAAAAAANAP3/AAAAAAAAAAANAP7/AAAAAAAAAAANAP//AAAAAAAAAAAOAPv/AAAAAAAAAAAOAPz/AAAAAAAAAAAOAP3/AAAAAAAAAAAOAP7/AAAAAAAAAAAOAP//AAAAAAAAAAAAAPb/AAAAAAAAAAAAAPf/AAAAAAAAAAAAAPj/AAAAAAAAAAAAAPn/AAAAAAAAAAAAAPr/AAAAAAAAAAABAPb/AAAAAAAAAAABAPf/AAAAAAAAAAABAPj/AAAAAAAAAAABAPn/AAAAAAAAAAABAPr/AAAAAAAAAAACAPb/AAAAAAAAAAACAPf/AAAAAAAAAAACAPj/AAAAAAAAAAACAPn/AAAAAAAAAAACAPr/AAAAAAAAAAADAPb/AAAAAAAAAAADAPf/AAAAAAAAAAADAPj/AAAAAAAAAAADAPn/AAAAAAAAAAADAPr/AAAAAAAAAAAEAPb/AAAAAAAAAAAEAPf/AAAAAAAAAAAEAPj/AAAAAAAAAAAEAPn/AAAAAAAAAAAEAPr/AAAAAAAAAAAFAPb/AAAAAAAAAAAFAPf/AAAAAAAAAAAFAPj/AAAAAAAAAAAFAPn/AAAAAAAAAAAFAPr/AAAAAAAAAAAGAPb/AAAAAAAAAAAGAPf/AAAAAAAAAAAGAPj/AAAAAAAAAAAGAPn/AAAAAAAAAAAGAPr/AAAAAAAAAAAHAPb/AAAAAAAAAAAHAPf/AAAAAAAAAAAHAPj/AAAAAAAAAAAHAPn/AAAAAAAAAAAHAPr/AAAAAAAAAAAIAPb/AAAAAAAAAAAIAPf/AAAAAAAAAAAIAPj/AAAAAAAAAAAIAPn/AAAAAAAAAAAIAPr/AAAAAAAAAAAJAPb/AAAAAAAAAAAJAPf/AAAAAAAAAAAJAPj/AAAAAAAAAAAJAPn/AAAAAAAAAAAJAPr/AAAAAAAAAAAKAPb/AAAAAAAAAAAKAPf/AAAAAAAAAAAKAPj/AAAAAAAAAAAKAPn/AAAAAAAAAAAKAPr/AAAAAAAAAAALAPb/AAAAAAAAAAALAPf/AAAAAAAAAAALAPj/AAAAAAAAAAALAPn/AAAAAAAAAAALAPr/AAAAAAAAAAAMAPb/AAAAAAAAAAAMAPf/AAAAAAAAAAAMAPj/AAAAAAAAAAAMAPn/AAAAAAAAAAAMAPr/AAAAAAAAAAANAPb/AAAAAAAAAAANAPf/AAAAAAAAAAANAPj/AAAAAAAAAAANAPn/AAAAAAAAAAANAPr/AAAAAAAAAAAOAPb/AAAAAAAAAAAOAPf/AAAAAAAAAAAOAPj/AAAAAAAAAAAOAPn/AAAAAAAAAAAOAPr/AAAAAAAAAAAPAPb/AAAAAAAAAAAPAPf/AAAAAAAAAAAPAPj/AAAAAAAAAAAPAPn/AAAAAAAAAAAPAPr/AAAAAAAAAAAQAPb/AAAAAAAAAAAQAPf/AAAAAAAAAAAQAPj/AAAAAAAAAAAQAPn/AAAAAAAAAAAQAPr/AAAAAAAAAAARAPb/AAAAAAAAAAARAPf/AAAAAAAAAAARAPj/AAAAAAAAAAARAPn/AAAAAAAAAAARAPr/AAAAAAAAAAASAPb/AAAAAAAAAAASAPf/AAAAAAAAAAASAPj/AAAAAAAAAAASAPn/AAAAAAAAAAASAPr/AAAAAAAAAAATAPb/AAAAAAAAAAATAPf/AAAAAAAAAAATAPj/AAAAAAAAAAATAPn/AAAAAAAAAAATAPr/AAAAAAAAAAAUAPb/AAAAAAAAAAAUAPf/AAAAAAAAAAAUAPj/AAAAAAAAAAAUAPn/AAAAAAAAAAAUAPr/AAAAAAAAAAAVAPb/AAAAAAAAAAAVAPf/AAAAAAAAAAAVAPj/AAAAAAAAAAAVAPn/AAAAAAAAAAAVAPr/AAAAAAAAAAAWAPb/AAAAAAAAAAAWAPf/AAAAAAAAAAAWAPj/AAAAAAAAAAAWAPn/AAAAAAAAAAAWAPr/AAAAAAAAAAAXAPb/AAAAAAAAAAAXAPf/AAAAAAAAAAAXAPj/AAAAAAAAAAAXAPn/AAAAAAAAAAAXAPr/AAAAAAAAAAAYAPb/AAAAAAAAAAAYAPf/AAAAAAAAAAAYAPj/AAAAAAAAAAAYAPn/AAAAAAAAAAAYAPr/AAAAAAAAAAAZAPb/AAAAAAAAAAAZAPf/AAAAAAAAAAAZAPj/AAAAAAAAAAAZAPn/AAAAAAAAAAAZAPr/AAAAAAAAAAAaAPb/AAAAAAAAAAAaAPf/AAAAAAAAAAAaAPj/AAAAAAAAAAAaAPn/AAAAAAAAAAAaAPr/AAAAAAAAAAAbAPb/AAAAAAAAAAAbAPf/AAAAAAAAAAAbAPj/AAAAAAAAAAAbAPn/AAAAAAAAAAAbAPr/AAAAAAAAAAAcAPb/AAAAAAAAAAAcAPf/AAAAAAAAAAAcAPj/AAAAAAAAAAAcAPn/AAAAAAAAAAAcAPr/AAAAAAAAAAAdAPb/AAAAAAAAAAAdAPf/AAAAAAAAAAAdAPj/AAAAAAAAAAAdAPn/AAAAAAAAAAAdAPr/AAAAAAAAAAAeAPb/AAAAAAAAAAAeAPf/AAAAAAAAAAAeAPj/AAAAAAAAAAAeAPn/AAAAAAAAAAAeAPr/AAAAAAAAAAAfAPb/AAAAAAAAAAAfAPf/AAAAAAAAAAAfAPj/AAAAAAAAAAAfAPn/AAAAAAAAAAAfAPr/AAAAAAAAAAAgAPb/AAAAAAAAAAAgAPf/AAAAAAAAAAAgAPj/AAAAAAAAAAAgAPn/AAAAAAAAAAAgAPr/AAAAAAAAAAAhAPb/AAAAAAAAAAAhAPf/AAAAAAAAAAAhAPj/AAAAAAAAAAAhAPn/AAAAAAAAAAAhAPr/AAAAAAAAAAAiAPb/AAAAAAAAAAAiAPf/AAAAAAAAAAAiAPj/AAAAAAAAAAAiAPn/AAAAAAAAAAAiAPr/AAAAAAAAAAAjAPb/AAAAAAAAAAAjAPf/AAAAAAAAAAAjAPj/AAAAAAAAAAAjAPn/AAAAAAAAAAAjAPr/AAAAAAAAAAAkAPb/AAAAAAAAAAAkAPf/AAAAAAAAAAAkAPj/AAAAAAAAAAAkAPn/AAAAAAAAAAAkAPr/AAAAAAAAAAAlAPb/AAAAAAAAAAAlAPf/AAAAAAAAAAAlAPj/AAAAAAAAAAAlAPn/AAAAAAAAAAAlAPr/AAAAAAAAAAAmAPb/AAAAAAAAAAAmAPf/AAAAAAAAAAAmAPj/AAAAAAAAAAAmAPn/AAAAAAAAAAAmAPr/AAAAAAAAAAAnAPb/AAAAAAAAAAAnAPf/AAAAAAAAAAAnAPj/AAAAAAAAAAAnAPn/AAAAAAAAAAAnAPr/AAAAAAAAAAAoAPb/AAAAAAAAAAAoAPf/AAAAAAAAAAAoAPj/AAAAAAAAAAAoAPn/AAAAAAAAAAAoAPr/AAAAAAAAAAApAPb/AAAAAAAAAAApAPf/AAAAAAAAAAApAPj/AAAAAAAAAAApAPn/AAAAAAAAAAApAPr/AAAAAAAAAAAqAPb/AAAAAAAAAAAqAPf/AAAAAAAAAAAqAPj/AAAAAAAAAAAqAPn/AAAAAAAAAAAqAPr/AAAAAAAAAAArAPb/AAAAAAAAAAArAPf/AAAAAAAAAAArAPj/AAAAAAAAAAArAPn/AAAAAAAAAAArAPr/AAAAAAAAAAAsAPb/AAAAAAAAAAAsAPf/AAAAAAAAAAAsAPj/AAAAAAAAAAAsAPn/AAAAAAAAAAAsAPr/AAAAAAAAAAAtAPb/AAAAAAAAAAAtAPf/AAAAAAAAAAAtAPj/AAAAAAAAAAAtAPn/AAAAAAAAAAAtAPr/AAAAAAAAAAAuAPb/AAAAAAAAAAAuAPf/AAAAAAAAAAAuAPj/AAAAAAAAAAAuAPn/AAAAAAAAAAAuAPr/AAAAAAAAAAAvAPb/AAAAAAAAAAAvAPf/AAAAAAAAAAAvAPj/AAAAAAAAAAAvAPn/AAAAAAAAAAAvAPr/AAAAAAAAAAAwAPb/AAAAAAAAAAAwAPf/AAAAAAAAAAAwAPj/AAAAAAAAAAAwAPn/AAAAAAAAAAAwAPr/AAAAAAAAAAAxAPb/AAAAAAAAAAAxAPf/AAAAAAAAAAAxAPj/AAAAAAAAAAAxAPn/AAAAAAAAAAAxAPr/AAAAAAAAAAAyAPb/AAAAAAAAAAAyAPf/AAAAAAAAAAAyAPj/AAAAAAAAAAAyAPn/AAAAAAAAAAAyAPr/AAAAAAAAAAAzAPb/AAAAAAAAAAAzAPf/AAAAAAAAAAAzAPj/AAAAAAAAAAAzAPn/AAAAAAAAAAAzAPr/AAAAAAAAAAA0APb/AAAAAAAAAAA0APf/AAAAAAAAAAA0APj/AAAAAAAAAAA0APn/AAAAAAAAAAA0APr/AAAAAAAAAAA1APb/AAAAAAAAAAA1APf/AAAAAAAAAAA1APj/AAAAAAAAAAA1APn/AAAAAAAAAAA1APr/AAAAAAAAAAA2APb/AAAAAAAAAAA2APf/AAAAAAAAAAA2APj/AAAAAAAAAAA2APn/AAAAAAAAAAA2APr/AAAAAAAAAAA3APb/AAAAAAAAAAA3APf/AAAAAAAAAAA3APj/AAAAAAAAAAA3APn/AAAAAAAAAAA3APr/AAAAAAAAAAA4APb/AAAAAAAAAAA4APf/AAAAAAAAAAA4APj/AAAAAAAAAAA4APn/AAAAAAAAAAA4APr/AAAAAAAAAAA5APb/AAAAAAAAAAA5APf/AAAAAAAAAAA5APj/AAAAAAAAAAA5APn/AAAAAAAAAAA5APr/AAAAAAAAAAA6APb/AAAAAAAAAAA6APf/AAAAAAAAAAA6APj/AAAAAAAAAAA6APn/AAAAAAAAAAA6APr/AAAAAAAAAAAWAA8AAAABAAAAAAAWABAAAAABAAAAAAAWABEAAAABAAAAAAAWABIAAAABAAAAAAAWABMAAAABAAAAAAAWABQAAAABAAAAAAAWABUAAAABAAAAAAAWABYAAAABAAAAAAAbAA8AAAABAAAAAAAbABAAAAABAAAAAAAbABEAAAABAAAAAAAbABIAAAABAAAAAAAbABMAAAABAAAAAAAbABQAAAABAAAAAAAbABUAAAABAAAAAAAbABYAAAABAAAAAAAhAAgAAAABAAAAAAAiAAgAAAABAAAAAAAjAAgAAAABAAAAAAAkAAgAAAABAAAAAABKAAkAAAAAAAAAAABKAAoAAAAAAAAAAABKAAsAAAAAAAAAAABKAAwAAAAAAAAAAABLAAkAAAAAAAAAAABLAAoAAAAAAAAAAABLAAsAAAAAAAAAAABLAAwAAAAAAAAAAABKAAUAAAAAAAAAAABKAAYAAAAAAAAAAABKAAcAAAAAAAAAAABKAAgAAAAAAAAAAABKAA0AAAAAAAAAAABLAAUAAAAAAAAAAABLAAYAAAAAAAAAAABLAAcAAAAAAAAAAABLAAgAAAAAAAAAAABLAA0AAAAAAAAAAABQABMAAAAAAAAAAABQABQAAAAAAAAAAABQABUAAAAAAAAAAABQABYAAAAAAAAAAABQABcAAAAAAAAAAABRABMAAAAAAAAAAABRABQAAAAAAAAAAABRABUAAAAAAAAAAABRABYAAAAAAAAAAABRABcAAAAAAAAAAABSABMAAAAAAAAAAABSABQAAAAAAAAAAABSABUAAAAAAAAAAABSABYAAAAAAAAAAABSABcAAAAAAAAAAABTABMAAAAAAAAAAABTABQAAAAAAAAAAABTABUAAAAAAAAAAABTABYAAAAAAAAAAABTABcAAAAAAAAAAABUABMAAAAAAAAAAABUABQAAAAAAAAAAABUABUAAAAAAAAAAABUABYAAAAAAAAAAABUABcAAAAAAAAAAABVABMAAAAAAAAAAABVABQAAAAAAAAAAABVABUAAAAAAAAAAABVABYAAAAAAAAAAABVABcAAAAAAAAAAABWABMAAAAAAAAAAABWABQAAAAAAAAAAABWABUAAAAAAAAAAABWABYAAAAAAAAAAABWABcAAAAAAAAAAABXAAsAAAAAAAAAAABXAAwAAAAAAAAAAABXAA0AAAAAAAAAAABXAA4AAAAAAAAAAABXABMAAAAAAAAAAABXABQAAAAAAAAAAABXABUAAAAAAAAAAABXABYAAAAAAAAAAABXABcAAAAAAAAAAABYAAsAAAAAAAAAAABYAAwAAAAAAAAAAABYAA0AAAAAAAAAAABYAA4AAAAAAAAAAABYABMAAAAAAAAAAABYABQAAAAAAAAAAABYABUAAAAAAAAAAABYABYAAAAAAAAAAABYABcAAAAAAAAAAABZAAsAAAAAAAAAAABZAAwAAAAAAAAAAABZAA0AAAAAAAAAAABZAA4AAAAAAAAAAABZABMAAAAAAAAAAABZABQAAAAAAAAAAABZABUAAAAAAAAAAABZABYAAAAAAAAAAABZABcAAAAAAAAAAABaAAsAAAAAAAAAAABaAAwAAAAAAAAAAABaAA0AAAAAAAAAAABaAA4AAAAAAAAAAABaABMAAAAAAAAAAABaABQAAAAAAAAAAABaABUAAAAAAAAAAABaABYAAAAAAAAAAABaABcAAAAAAAAAAABbAAsAAAAAAAAAAABbAAwAAAAAAAAAAABbAA0AAAAAAAAAAABbAA4AAAAAAAAAAABbABMAAAAAAAAAAABbABQAAAAAAAAAAABbABUAAAAAAAAAAABbABYAAAAAAAAAAABbABcAAAAAAAAAAABcAAsAAAAAAAAAAABcAAwAAAAAAAAAAABcAA0AAAAAAAAAAABcAA4AAAAAAAAAAABcABMAAAAAAAAAAABcABQAAAAAAAAAAABcABUAAAAAAAAAAABcABYAAAAAAAAAAABcABcAAAAAAAAAAABdAAsAAAAAAAAAAABdAAwAAAAAAAAAAABdAA0AAAAAAAAAAABdAA4AAAAAAAAAAABdABMAAAAAAAAAAABdABQAAAAAAAAAAABdABUAAAAAAAAAAABdABYAAAAAAAAAAABdABcAAAAAAAAAAABeAAsAAAAAAAAAAABeAAwAAAAAAAAAAABeAA0AAAAAAAAAAABeAA4AAAAAAAAAAABeABMAAAAAAAAAAABeABQAAAAAAAAAAABeABUAAAAAAAAAAABeABYAAAAAAAAAAABeABcAAAAAAAAAAAA0AA8AAAAAAAAAAAA0ABAAAAAAAAAAAAA0ABEAAAAAAAAAAAA0ABIAAAAAAAAAAAA0ABMAAAAAAAAAAAA0ABQAAAAAAAAAAAA0ABUAAAAAAAAAAAA0ABYAAAAAAAAAAAA1AA8AAAAAAAAAAAA1ABAAAAAAAAAAAAA1ABEAAAAAAAAAAAA1ABIAAAAAAAAAAAA1ABMAAAAAAAAAAAA1ABQAAAAAAAAAAAA1ABUAAAAAAAAAAAA1ABYAAAAAAAAAAAA2AA8AAAAAAAAAAAA2ABAAAAAAAAAAAAA2ABEAAAAAAAAAAAA2ABIAAAAAAAAAAAA2ABMAAAAAAAAAAAA2ABQAAAAAAAAAAAA2ABUAAAAAAAAAAAA2ABYAAAAAAAAAAAA3AA8AAAAAAAAAAAA3ABAAAAAAAAAAAAA3ABEAAAAAAAAAAAA3ABIAAAAAAAAAAAA3ABMAAAAAAAAAAAA3ABQAAAAAAAAAAAA3ABUAAAAAAAAAAAA3ABYAAAAAAAAAAAA4AA8AAAAAAAAAAAA4ABAAAAAAAAAAAAA4ABEAAAAAAAAAAAA4ABIAAAAAAAAAAAA4ABMAAAAAAAAAAAA4ABQAAAAAAAAAAAA4ABUAAAAAAAAAAAA4ABYAAAAAAAAAAAA5AA8AAAAAAAAAAAA5ABAAAAAAAAAAAAA5ABEAAAAAAAAAAAA5ABIAAAAAAAAAAAA5ABMAAAAAAAAAAAA5ABQAAAAAAAAAAAA5ABUAAAAAAAAAAAA5ABYAAAAAAAAAAAA6AA8AAAAAAAAAAAA6ABAAAAAAAAAAAAA6ABEAAAAAAAAAAAA6ABIAAAAAAAAAAAA6ABMAAAAAAAAAAAA6ABQAAAAAAAAAAAA6ABUAAAAAAAAAAAA6ABYAAAAAAAAAAAA7AA8AAAAAAAAAAAA7ABAAAAAAAAAAAAA7ABEAAAAAAAAAAAA7ABIAAAAAAAAAAAA7ABMAAAAAAAAAAAA7ABQAAAAAAAAAAAA7ABUAAAAAAAAAAAA7ABYAAAAAAAAAAAA8AA8AAAAAAAAAAAA8ABAAAAAAAAAAAAA8ABEAAAAAAAAAAAA8ABIAAAAAAAAAAAA8ABMAAAAAAAAAAAA8ABQAAAAAAAAAAAA8ABUAAAAAAAAAAAA8ABYAAAAAAAAAAAA9AA8AAAAAAAAAAAA9ABAAAAAAAAAAAAA9ABEAAAAAAAAAAAA9ABIAAAAAAAAAAAA9ABMAAAAAAAAAAAA9ABQAAAAAAAAAAAA9ABUAAAAAAAAAAAA9ABYAAAAAAAAAAAA+AA8AAAAAAAAAAAA+ABAAAAAAAAAAAAA+ABEAAAAAAAAAAAA+ABIAAAAAAAAAAAA+ABMAAAAAAAAAAAA+ABQAAAAAAAAAAAA+ABUAAAAAAAAAAAA+ABYAAAAAAAAAAAA/AA8AAAAAAAAAAAA/ABAAAAAAAAAAAAA/ABEAAAAAAAAAAAA/ABIAAAAAAAAAAAA/ABMAAAAAAAAAAAA/ABQAAAAAAAAAAAA/ABUAAAAAAAAAAAA/ABYAAAAAAAAAAABAAA8AAAAAAAAAAABAABAAAAAAAAAAAABAABEAAAAAAAAAAABAABIAAAAAAAAAAABAABMAAAAAAAAAAABAABQAAAAAAAAAAABAABUAAAAAAAAAAABAABYAAAAAAAAAAABBAA8AAAAAAAAAAABBABAAAAAAAAAAAABBABEAAAAAAAAAAABBABIAAAAAAAAAAABBABMAAAAAAAAAAABBABQAAAAAAAAAAABBABUAAAAAAAAAAABBABYAAAAAAAAAAAA0AAkAAAABAAAAAAA0AAoAAAABAAAAAAA0AAsAAAABAAAAAAA0AAwAAAABAAAAAAA0AA0AAAABAAAAAAA0AA4AAAABAAAAAAA1AA4AAAABAAAAAAA2AA4AAAABAAAAAAA3AA4AAAABAAAAAAA4AA4AAAABAAAAAABJAAUAAAABAAAAAABJAAYAAAABAAAAAABJAAcAAAABAAAAAABJAAgAAAABAAAAAABJAAkAAAABAAAAAABJAAoAAAABAAAAAABJAAsAAAABAAAAAABJAAwAAAABAAAAAABJAA0AAAABAAAAAABMAAkAAAABAAAAAAA=") +tile_set = ExtResource("1_pbk25") diff --git a/_levels/l_test.tscn b/_levels/l_test.tscn new file mode 100644 index 0000000..680bd44 --- /dev/null +++ b/_levels/l_test.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=2 format=4 uid="uid://bomv75fi4uuyi"] + +[ext_resource type="TileSet" uid="uid://doepkfp83k0lb" path="res://_tileset/test.tres" id="1_vei0o"] + +[node name="TileMapLayer" type="TileMapLayer"] +texture_filter = 1 +tile_map_data = PackedByteArray("AAAAAA0AAAAAAAAAAAABAA0AAAAAAAAAAAACAA0AAAAAAAAAAAADAA0AAAAAAAAAAAAEAA0AAAAAAAAAAAAFAA0AAAAAAAAAAAAGAA0AAAAAAAAAAAAHAA0AAAAAAAAAAAAIAA0AAAAAAAAAAAAJAA0AAAAAAAAAAAAKAA0AAAAAAAAAAAALAA0AAAAAAAAAAAAMAA0AAAAAAAAAAAANAA0AAAAAAAAAAAAOAA0AAAAAAAAAAAAPAA0AAAAAAAAAAAAQAA0AAAAAAAAAAAARAA0AAAAAAAAAAAASAA0AAAAAAAAAAAATAA0AAAAAAAAAAAAUAA0AAAAAAAAAAAAVAA0AAAAAAAAAAAAWAA0AAAAAAAAAAAAXAA0AAAAAAAAAAAAYAA0AAAAAAAAAAAAZAA0AAAAAAAAAAAAaAA0AAAAAAAAAAAAbAA0AAAAAAAAAAAAcAA0AAAAAAAAAAAAdAA0AAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAQAAAAAAAAAAAABAAQAAAAAAAAAAAABAAUAAAAAAAAAAAABAAYAAAAAAAAAAAACAAYAAAAAAAAAAAACAAcAAAAAAAAAAAACAAgAAAAAAAAAAAACAAkAAAAAAAAAAAACAAoAAAAAAAAAAAADAAoAAAAAAAAAAAADAAsAAAAAAAAAAAACAAsAAAAAAAAAAAACAAwAAAAAAAAAAAADAAwAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAAwAAAAAAAAAAAABAAcAAAAAAAAAAAABAAgAAAAAAAAAAAABAAkAAAAAAAAAAAABAAoAAAAAAAAAAAABAAsAAAAAAAAAAAABAAwAAAAAAAAAAAAPAAoAAAAAAAAAAAAPAAsAAAAAAAAAAAAQAAoAAAAAAAAAAAAQAAsAAAAAAAAAAAATAAgAAAAAAAAAAAATAAkAAAAAAAAAAAAUAAgAAAAAAAAAAAAUAAkAAAAAAAAAAAAVAAgAAAAAAAAAAAAVAAkAAAAAAAAAAAAYAAUAAAAAAAAAAAAYAAYAAAAAAAAAAAAYAAcAAAAAAAAAAAAYAAsAAAAAAAAAAAAYAAwAAAAAAAAAAAAZAAUAAAAAAAAAAAAZAAYAAAAAAAAAAAAZAAcAAAAAAAAAAAAaAAsAAAAAAAAAAAAaAAwAAAAAAAAAAAAZAAwAAAAAAAAAAAAZAAsAAAAAAAAAAAAaAAUAAAAAAAAAAAAaAAYAAAAAAAAAAAAaAAcAAAAAAAAAAAADAAYAAAAAAAAAAAADAAcAAAAAAAAAAAADAAgAAAAAAAAAAAADAAkAAAAAAAAAAAABAAMAAAAAAAAAAAACAAMAAAAAAAAAAAACAAQAAAAAAAAAAAACAAUAAAAAAAAAAAADAAMAAAAAAAAAAAADAAQAAAAAAAAAAAADAAUAAAAAAAAAAAAAAA4AAAAAAAAAAAABAA4AAAAAAAAAAAACAA4AAAAAAAAAAAADAA4AAAAAAAAAAAAEAA4AAAAAAAAAAAAFAA4AAAAAAAAAAAAGAA4AAAAAAAAAAAAHAA4AAAAAAAAAAAAIAA4AAAAAAAAAAAAJAA4AAAAAAAAAAAAKAA4AAAAAAAAAAAALAA4AAAAAAAAAAAAMAA4AAAAAAAAAAAANAA4AAAAAAAAAAAAOAA4AAAAAAAAAAAAPAA4AAAAAAAAAAAAbAA4AAAAAAAAAAAAcAA4AAAAAAAAAAAAdAA4AAAAAAAAAAAAaAA4AAAAAAAAAAAAZAA4AAAAAAAAAAAAYAA4AAAAAAAAAAAAXAA4AAAAAAAAAAAAWAA4AAAAAAAAAAAAVAA4AAAAAAAAAAAAUAA4AAAAAAAAAAAATAA4AAAAAAAAAAAASAA4AAAAAAAAAAAARAA4AAAAAAAAAAAAQAA4AAAAAAAAAAAAPAA8AAAAAAAAAAAAOAA8AAAAAAAAAAAANAA8AAAAAAAAAAAAMAA8AAAAAAAAAAAALAA8AAAAAAAAAAAAKAA8AAAAAAAAAAAAJAA8AAAAAAAAAAAAIAA8AAAAAAAAAAAAHAA8AAAAAAAAAAAAGAA8AAAAAAAAAAAAFAA8AAAAAAAAAAAAEAA8AAAAAAAAAAAAEABAAAAAAAAAAAAADABAAAAAAAAAAAAACABAAAAAAAAAAAAABABAAAAAAAAAAAAABAA8AAAAAAAAAAAAAAA8AAAAAAAAAAAAAABAAAAAAAAAAAAAFABAAAAAAAAAAAAAGABAAAAAAAAAAAAAHABAAAAAAAAAAAAAIABAAAAAAAAAAAAAJABAAAAAAAAAAAAAKABAAAAAAAAAAAAALABAAAAAAAAAAAAAMABAAAAAAAAAAAAANABAAAAAAAAAAAAAOABAAAAAAAAAAAAAPABAAAAAAAAAAAAAQABAAAAAAAAAAAAARABAAAAAAAAAAAAASABAAAAAAAAAAAAATABAAAAAAAAAAAAAUABAAAAAAAAAAAAAVABAAAAAAAAAAAAAWABAAAAAAAAAAAAAXABAAAAAAAAAAAAAYABAAAAAAAAAAAAAZABAAAAAAAAAAAAAaABAAAAAAAAAAAAAbABAAAAAAAAAAAAAcABAAAAAAAAAAAAAdABAAAAAAAAAAAAAeABAAAAAAAAAAAAAeAA8AAAAAAAAAAAAdAA8AAAAAAAAAAAAcAA8AAAAAAAAAAAAbAA8AAAAAAAAAAAAaAA8AAAAAAAAAAAAZAA8AAAAAAAAAAAAYAA8AAAAAAAAAAAAXAA8AAAAAAAAAAAAWAA8AAAAAAAAAAAAVAA8AAAAAAAAAAAAUAA8AAAAAAAAAAAATAA8AAAAAAAAAAAASAA8AAAAAAAAAAAARAA8AAAAAAAAAAAADAA8AAAAAAAAAAAACAA8AAAAAAAAAAAAQAA8AAAAAAAAAAAD//wMAAAAAAAAAAAD//wQAAAAAAAAAAAD//wUAAAAAAAAAAAD//wYAAAAAAAAAAAD//wcAAAAAAAAAAAD//wgAAAAAAAAAAAD//wkAAAAAAAAAAAD//woAAAAAAAAAAAD//wsAAAAAAAAAAAD//wwAAAAAAAAAAAD//w0AAAAAAAAAAAD//w4AAAAAAAAAAAD//w8AAAAAAAAAAAD//xAAAAAAAAAAAAD+/wQAAAAAAAAAAAD+/wUAAAAAAAAAAAD+/wYAAAAAAAAAAAD+/wcAAAAAAAAAAAD+/wgAAAAAAAAAAAD+/wkAAAAAAAAAAAD+/woAAAAAAAAAAAD+/wsAAAAAAAAAAAD+/wwAAAAAAAAAAAD+/w0AAAAAAAAAAAD+/w4AAAAAAAAAAAD+/w8AAAAAAAAAAAD+/xAAAAAAAAAAAAD+/wMAAAAAAAAAAAD+/wIAAAAAAAAAAAD//wIAAAAAAAAAAAAAAAIAAAAAAAAAAAABAAIAAAAAAAAAAAACAAIAAAAAAAAAAAADAAIAAAAAAAAAAAD+/wEAAAAAAAAAAAD//wEAAAAAAAAAAAAAAAEAAAAAAAAAAAABAAEAAAAAAAAAAAACAAEAAAAAAAAAAAADAAEAAAAAAAAAAAD+/wAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAACAAAAAAAAAAAAAAADAAAAAAAAAAAAAAD+////AAAAAAAAAAD/////AAAAAAAAAAAAAP//AAAAAAAAAAABAP//AAAAAAAAAAACAP//AAAAAAAAAAADAP//AAAAAAAAAAD+//7/AAAAAAAAAAD///7/AAAAAAAAAAAAAP7/AAAAAAAAAAABAP7/AAAAAAAAAAACAP7/AAAAAAAAAAADAP7/AAAAAAAAAAAeAA0AAAAAAAAAAAAeAA4AAAAAAAAAAAAfAA0AAAAAAAAAAAAfAA4AAAAAAAAAAAAfAA8AAAAAAAAAAAAfABAAAAAAAAAAAAAgAA0AAAAAAAAAAAAgAA4AAAAAAAAAAAAgAA8AAAAAAAAAAAAgABAAAAAAAAAAAAAhAA0AAAAAAAAAAAAhAA4AAAAAAAAAAAAhAA8AAAAAAAAAAAAhABAAAAAAAAAAAAAiAA0AAAAAAAAAAAAiAA4AAAAAAAAAAAAiAA8AAAAAAAAAAAAiABAAAAAAAAAAAAAjAA0AAAAAAAAAAAAjAA4AAAAAAAAAAAAjAA8AAAAAAAAAAAAjABAAAAAAAAAAAAAkAA0AAAAAAAAAAAAkAA4AAAAAAAAAAAAkAA8AAAAAAAAAAAAkABAAAAAAAAAAAAAlAA0AAAAAAAAAAAAlAA4AAAAAAAAAAAAlAA8AAAAAAAAAAAAlABAAAAAAAAAAAAAmAA0AAAAAAAAAAAAmAA4AAAAAAAAAAAAmAA8AAAAAAAAAAAAmABAAAAAAAAAAAAAnAA0AAAAAAAAAAAAnAA4AAAAAAAAAAAAnAA8AAAAAAAAAAAAnABAAAAAAAAAAAAAoAA0AAAAAAAAAAAAoAA4AAAAAAAAAAAAoAA8AAAAAAAAAAAAoABAAAAAAAAAAAAApAA0AAAAAAAAAAAApAA4AAAAAAAAAAAApAA8AAAAAAAAAAAApABAAAAAAAAAAAAAqAA0AAAAAAAAAAAAqAA4AAAAAAAAAAAAqAA8AAAAAAAAAAAAqABAAAAAAAAAAAAArAA0AAAAAAAAAAAArAA4AAAAAAAAAAAArAA8AAAAAAAAAAAArABAAAAAAAAAAAAAsAA0AAAAAAAAAAAAsAA4AAAAAAAAAAAAsAA8AAAAAAAAAAAAsABAAAAAAAAAAAAAtAA0AAAAAAAAAAAAtAA4AAAAAAAAAAAAtAA8AAAAAAAAAAAAtABAAAAAAAAAAAAAuAA0AAAAAAAAAAAAuAA4AAAAAAAAAAAAuAA8AAAAAAAAAAAAuABAAAAAAAAAAAAAvAA0AAAAAAAAAAAAvAA4AAAAAAAAAAAAvAA8AAAAAAAAAAAAvABAAAAAAAAAAAAAwAA0AAAAAAAAAAAAwAA4AAAAAAAAAAAAwAA8AAAAAAAAAAAAwABAAAAAAAAAAAAAxAA0AAAAAAAAAAAAxAA4AAAAAAAAAAAAxAA8AAAAAAAAAAAAxABAAAAAAAAAAAAAyAA0AAAAAAAAAAAAyAA4AAAAAAAAAAAAyAA8AAAAAAAAAAAAyABAAAAAAAAAAAAAzAA0AAAAAAAAAAAAzAA4AAAAAAAAAAAAzAA8AAAAAAAAAAAAzABAAAAAAAAAAAAA0AA0AAAAAAAAAAAA0AA4AAAAAAAAAAAA0AA8AAAAAAAAAAAA0ABAAAAAAAAAAAAA1AA0AAAAAAAAAAAA1AA4AAAAAAAAAAAA1AA8AAAAAAAAAAAA1ABAAAAAAAAAAAAA2AA0AAAAAAAAAAAA2AA4AAAAAAAAAAAA2AA8AAAAAAAAAAAA2ABAAAAAAAAAAAAA3AA0AAAAAAAAAAAA3AA4AAAAAAAAAAAA3AA8AAAAAAAAAAAA3ABAAAAAAAAAAAAA4AA0AAAAAAAAAAAA4AA4AAAAAAAAAAAA4AA8AAAAAAAAAAAA4ABAAAAAAAAAAAAA5AA0AAAAAAAAAAAA5AA4AAAAAAAAAAAA5AA8AAAAAAAAAAAA5ABAAAAAAAAAAAAA6AA0AAAAAAAAAAAA6AA4AAAAAAAAAAAA6AA8AAAAAAAAAAAA6ABAAAAAAAAAAAAA7AA0AAAAAAAAAAAA7AA4AAAAAAAAAAAA7AA8AAAAAAAAAAAA7ABAAAAAAAAAAAAA8AA0AAAAAAAAAAAA8AA4AAAAAAAAAAAA8AA8AAAAAAAAAAAA8ABAAAAAAAAAAAAA9AA0AAAAAAAAAAAA9AA4AAAAAAAAAAAA9AA8AAAAAAAAAAAA9ABAAAAAAAAAAAAA+AA0AAAAAAAAAAAA+AA4AAAAAAAAAAAA+AA8AAAAAAAAAAAA+ABAAAAAAAAAAAAA/AA0AAAAAAAAAAAA/AA4AAAAAAAAAAAA/AA8AAAAAAAAAAAA/ABAAAAAAAAAAAABAAA0AAAAAAAAAAABAAA4AAAAAAAAAAABAAA8AAAAAAAAAAABAABAAAAAAAAAAAABBAA0AAAAAAAAAAABBAA4AAAAAAAAAAABBAA8AAAAAAAAAAABBABAAAAAAAAAAAABCAA0AAAAAAAAAAABCAA4AAAAAAAAAAABCAA8AAAAAAAAAAABCABAAAAAAAAAAAABDAA0AAAAAAAAAAABDAA4AAAAAAAAAAABDAA8AAAAAAAAAAABDABAAAAAAAAAAAABEAA0AAAAAAAAAAABEAA4AAAAAAAAAAABEAA8AAAAAAAAAAABEABAAAAAAAAAAAABFAA0AAAAAAAAAAABFAA4AAAAAAAAAAABFAA8AAAAAAAAAAABFABAAAAAAAAAAAABGAA0AAAAAAAAAAABGAA4AAAAAAAAAAABGAA8AAAAAAAAAAABGABAAAAAAAAAAAABHAA0AAAAAAAAAAABHAA4AAAAAAAAAAABHAA8AAAAAAAAAAABHABAAAAAAAAAAAABIAA0AAAAAAAAAAABIAA4AAAAAAAAAAABIAA8AAAAAAAAAAABIABAAAAAAAAAAAABJAA0AAAAAAAAAAABJAA4AAAAAAAAAAABJAA8AAAAAAAAAAABJABAAAAAAAAAAAABKAA0AAAAAAAAAAABKAA4AAAAAAAAAAABKAA8AAAAAAAAAAABKABAAAAAAAAAAAABLAA0AAAAAAAAAAABLAA4AAAAAAAAAAABLAA8AAAAAAAAAAABLABAAAAAAAAAAAABMAA0AAAAAAAAAAABMAA4AAAAAAAAAAABMAA8AAAAAAAAAAABMABAAAAAAAAAAAABNAA0AAAAAAAAAAABNAA4AAAAAAAAAAABNAA8AAAAAAAAAAABNABAAAAAAAAAAAABOAA0AAAAAAAAAAABOAA4AAAAAAAAAAABOAA8AAAAAAAAAAABOABAAAAAAAAAAAABPAA0AAAAAAAAAAABPAA4AAAAAAAAAAABPAA8AAAAAAAAAAABPABAAAAAAAAAAAABQAA0AAAAAAAAAAABQAA4AAAAAAAAAAABQAA8AAAAAAAAAAABQABAAAAAAAAAAAABRAA0AAAAAAAAAAABRAA4AAAAAAAAAAABRAA8AAAAAAAAAAABRABAAAAAAAAAAAABSAA0AAAAAAAAAAABSAA4AAAAAAAAAAABSAA8AAAAAAAAAAABSABAAAAAAAAAAAABTAA0AAAAAAAAAAABTAA4AAAAAAAAAAABTAA8AAAAAAAAAAABTABAAAAAAAAAAAAAhAAUAAAAAAAAAAAAhAAYAAAAAAAAAAAAiAAUAAAAAAAAAAAAiAAYAAAAAAAAAAAAjAAUAAAAAAAAAAAAjAAYAAAAAAAAAAAAkAAUAAAAAAAAAAAAkAAYAAAAAAAAAAAAlAAUAAAAAAAAAAAAlAAYAAAAAAAAAAAAmAAUAAAAAAAAAAAAmAAYAAAAAAAAAAAAnAAUAAAAAAAAAAAAnAAYAAAAAAAAAAAAoAAUAAAAAAAAAAAAoAAYAAAAAAAAAAAApAAUAAAAAAAAAAAApAAYAAAAAAAAAAAAqAAUAAAAAAAAAAAAqAAYAAAAAAAAAAAArAAUAAAAAAAAAAAArAAYAAAAAAAAAAAAlAAsAAAAAAAAAAAAlAAwAAAAAAAAAAAAmAAsAAAAAAAAAAAAmAAwAAAAAAAAAAAAnAAsAAAAAAAAAAAAnAAwAAAAAAAAAAAA0AAsAAAAAAAAAAAA0AAwAAAAAAAAAAAA1AAsAAAAAAAAAAAA1AAwAAAAAAAAAAAA2AAsAAAAAAAAAAAA2AAwAAAAAAAAAAAA3AAsAAAAAAAAAAAA3AAwAAAAAAAAAAAA0AAAAAAAAAAAAAAA0AAEAAAAAAAAAAAA0AAIAAAAAAAAAAAA0AAMAAAAAAAAAAAA0AAQAAAAAAAAAAAA0AAUAAAAAAAAAAAA1AAAAAAAAAAAAAAA1AAEAAAAAAAAAAAA1AAIAAAAAAAAAAAA1AAMAAAAAAAAAAAA1AAQAAAAAAAAAAAA1AAUAAAAAAAAAAAA2AAAAAAAAAAAAAAA2AAEAAAAAAAAAAAA2AAIAAAAAAAAAAAA2AAMAAAAAAAAAAAA2AAQAAAAAAAAAAAA2AAUAAAAAAAAAAAA3AAAAAAAAAAAAAAA3AAEAAAAAAAAAAAA3AAIAAAAAAAAAAAA3AAMAAAAAAAAAAAA3AAQAAAAAAAAAAAA3AAUAAAAAAAAAAAAsAP7/AAAAAAAAAAAsAP//AAAAAAAAAAAtAP7/AAAAAAAAAAAtAP//AAAAAAAAAAAuAP7/AAAAAAAAAAAuAP//AAAAAAAAAAAvAP7/AAAAAAAAAAAvAP//AAAAAAAAAAAwAP7/AAAAAAAAAAAwAP//AAAAAAAAAAAxAP7/AAAAAAAAAAAxAP//AAAAAAAAAAAiAPv/AAAAAAAAAAAiAPz/AAAAAAAAAAAjAPv/AAAAAAAAAAAjAPz/AAAAAAAAAAAkAPv/AAAAAAAAAAAkAPz/AAAAAAAAAAAlAPv/AAAAAAAAAAAlAPz/AAAAAAAAAAAmAPv/AAAAAAAAAAAmAPz/AAAAAAAAAAAnAPv/AAAAAAAAAAAnAPz/AAAAAAAAAAAoAPv/AAAAAAAAAAAoAPz/AAAAAAAAAAApAPv/AAAAAAAAAAApAPz/AAAAAAAAAAAZAPv/AAAAAAAAAAAZAPz/AAAAAAAAAAAZAP3/AAAAAAAAAAAZAP7/AAAAAAAAAAAaAPv/AAAAAAAAAAAaAPz/AAAAAAAAAAAaAP3/AAAAAAAAAAAaAP7/AAAAAAAAAAAbAPv/AAAAAAAAAAAbAPz/AAAAAAAAAAAbAP3/AAAAAAAAAAAbAP7/AAAAAAAAAAAcAPv/AAAAAAAAAAAcAPz/AAAAAAAAAAAcAP3/AAAAAAAAAAAcAP7/AAAAAAAAAAAdAPv/AAAAAAAAAAAdAPz/AAAAAAAAAAAdAP3/AAAAAAAAAAAdAP7/AAAAAAAAAAAeAPv/AAAAAAAAAAAeAPz/AAAAAAAAAAAeAP3/AAAAAAAAAAAeAP7/AAAAAAAAAAAOAPz/AAAAAAAAAAAOAP3/AAAAAAAAAAAOAP7/AAAAAAAAAAAOAP//AAAAAAAAAAAPAPz/AAAAAAAAAAAPAP3/AAAAAAAAAAAPAP7/AAAAAAAAAAAPAP//AAAAAAAAAAAQAPz/AAAAAAAAAAAQAP3/AAAAAAAAAAAQAP7/AAAAAAAAAAAQAP//AAAAAAAAAAARAPz/AAAAAAAAAAARAP3/AAAAAAAAAAARAP7/AAAAAAAAAAARAP//AAAAAAAAAAASAPz/AAAAAAAAAAASAP3/AAAAAAAAAAASAP7/AAAAAAAAAAASAP//AAAAAAAAAAATAPz/AAAAAAAAAAATAP3/AAAAAAAAAAATAP7/AAAAAAAAAAATAP//AAAAAAAAAAAUAPz/AAAAAAAAAAAUAP3/AAAAAAAAAAAUAP7/AAAAAAAAAAAUAP//AAAAAAAAAAAVAPz/AAAAAAAAAAAVAP3/AAAAAAAAAAAVAP7/AAAAAAAAAAAVAP//AAAAAAAAAAD+//j/AAAAAAAAAAD+//n/AAAAAAAAAAD+//r/AAAAAAAAAAD+//v/AAAAAAAAAAD+//z/AAAAAAAAAAD+//3/AAAAAAAAAAD///j/AAAAAAAAAAD///n/AAAAAAAAAAD///r/AAAAAAAAAAD///v/AAAAAAAAAAD///z/AAAAAAAAAAD///3/AAAAAAAAAAAAAPj/AAAAAAAAAAAAAPn/AAAAAAAAAAAAAPr/AAAAAAAAAAAAAPv/AAAAAAAAAAAAAPz/AAAAAAAAAAAAAP3/AAAAAAAAAAABAPj/AAAAAAAAAAABAPn/AAAAAAAAAAABAPr/AAAAAAAAAAABAPv/AAAAAAAAAAABAPz/AAAAAAAAAAABAP3/AAAAAAAAAAACAPj/AAAAAAAAAAACAPn/AAAAAAAAAAACAPr/AAAAAAAAAAACAPv/AAAAAAAAAAACAPz/AAAAAAAAAAACAP3/AAAAAAAAAAADAPj/AAAAAAAAAAADAPn/AAAAAAAAAAADAPr/AAAAAAAAAAADAPv/AAAAAAAAAAADAPz/AAAAAAAAAAADAP3/AAAAAAAAAAAPAAwAAAABAAAAAAAQAAwAAAABAAAAAAAOAAwAAAABAAAAAAARAAwAAAABAAAAAAA=") +tile_set = ExtResource("1_vei0o") diff --git a/_player/Agens.tscn b/_player/Agens.tscn new file mode 100644 index 0000000..2f01de0 --- /dev/null +++ b/_player/Agens.tscn @@ -0,0 +1,218 @@ +[gd_scene load_steps=38 format=3 uid="uid://gwhff4qaouxy"] + +[ext_resource type="Script" uid="uid://dq1g1qp66chwy" path="res://_player/agens.gd" id="1_rkqpu"] +[ext_resource type="Script" uid="uid://isu8onknb75o" path="res://_player/states/character_state_machine.gd" id="1_wvs5h"] +[ext_resource type="Script" uid="uid://15n8yfyr4eqj" path="res://_player/states/grounded.gd" id="2_5p50s"] +[ext_resource type="Texture2D" uid="uid://doxhsab56pe50" path="res://_asset/all.png" id="2_8nsdm"] +[ext_resource type="Script" uid="uid://dcfq4wnx2g6bs" path="res://_player/player_locomotion.gd" id="2_11vl8"] +[ext_resource type="Script" uid="uid://b5hkfpjbye70" path="res://_player/states/idle.gd" id="4_30i7g"] +[ext_resource type="BlackboardPlan" uid="uid://nlw7rxugv5uh" path="res://_player/bbp_player.tres" id="4_mwufa"] +[ext_resource type="Script" uid="uid://bpd54nf8oxwsb" path="res://_player/states/player_hsm.gd" id="6_8q4ov"] +[ext_resource type="Script" uid="uid://po21boe8iqcc" path="res://_player/states/move.gd" id="7_rrwxs"] +[ext_resource type="Script" uid="uid://cjf7kds0cipkw" path="res://_tools/limbo_state_helper.gd" id="8_clxy3"] +[ext_resource type="Script" uid="uid://bbsdsqxujlsbp" path="res://_player/states/airbone.gd" id="8_d42ye"] +[ext_resource type="Script" uid="uid://db6ttwe3skqfv" path="res://_player/states/fall.gd" id="9_iqoog"] +[ext_resource type="Script" uid="uid://dh3115a8iyabg" path="res://_player/states/jump.gd" id="10_mwufa"] +[ext_resource type="Script" uid="uid://cky34pinqpewd" path="res://_player/states/ghost.gd" id="12_8nsdm"] +[ext_resource type="Script" uid="uid://dhlg4ct8al76c" path="res://_player/states/wall_jump.gd" id="12_basl5"] +[ext_resource type="Script" uid="uid://fpfkas0s46xq" path="res://_player/states/on_wall.gd" id="13_l6fs8"] +[ext_resource type="Script" uid="uid://cpruvcwcgmdrx" path="res://_player/states/climb_jump.gd" id="15_l6fs8"] +[ext_resource type="Script" uid="uid://bjjatv4bxv7w" path="res://_player/states/climb.gd" id="15_mt2s8"] +[ext_resource type="Script" uid="uid://d0mw2e4u5u8g" path="res://_player/states/grap_hook.gd" id="16_f07it"] +[ext_resource type="Script" uid="uid://diq7vk63exae7" path="res://_player/states/hook_shooting.gd" id="16_xcbik"] +[ext_resource type="Script" uid="uid://ca88urm45gx2c" path="res://_player/states/dead.gd" id="17_5r2pj"] +[ext_resource type="PackedScene" uid="uid://blm8q46h3v2im" path="res://addons/reedcomponent/locomotion/wall_detector.tscn" id="20_air0b"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="20_ogl63"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="21_5r2pj"] +[ext_resource type="Script" uid="uid://bkkkyugppu7sl" path="res://addons/reedcomponent/grap_hook/spawn_hook_component.gd" id="21_p14kj"] +[ext_resource type="Script" uid="uid://ta2r2bc1nrwe" path="res://addons/reedfx/vfx/VFXManager.gd" id="24_mwlgv"] +[ext_resource type="Script" uid="uid://lp1ge1qbyfr3" path="res://addons/reedfx/sfx/SFXManager.gd" id="24_x5g5e"] +[ext_resource type="Script" uid="uid://du267phqvtqyr" path="res://addons/reedfx/sfx/SFXSignalBinding.gd" id="25_rjd7i"] +[ext_resource type="Script" uid="uid://dipfdfnp506hl" path="res://addons/reedfx/vfx/VFXSignalBinding.gd" id="25_s5egm"] +[ext_resource type="Resource" uid="uid://cb73bysplqpo7" path="res://_player/effect_binding/jump_sound.tres" id="26_256x0"] +[ext_resource type="Resource" uid="uid://do0bnwse614jw" path="res://_player/effect_binding/land_dust.tres" id="26_s5egm"] +[ext_resource type="Script" uid="uid://bijoqygv6tncj" path="res://addons/reedcomponent/SingleComponentRemotor.gd" id="28_mxt3b"] +[ext_resource type="Resource" uid="uid://bdad4yjv1q0uu" path="res://_player/effect_binding/jump_dust.tres" id="30_hquoe"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_qnulu"] +size = Vector2(9, 23) + +[sub_resource type="AtlasTexture" id="AtlasTexture_basl5"] +atlas = ExtResource("2_8nsdm") +region = Rect2(9, 22, 13, 26) + +[sub_resource type="Resource" id="Resource_p14kj"] +script = ExtResource("21_5r2pj") + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_ogl63"] +size = Vector2(10, 25) + +[node name="Agens" type="CharacterBody2D" groups=["PLAYER"]] +collision_layer = 2 +collision_mask = 0 +platform_wall_layers = 4 +script = ExtResource("1_rkqpu") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_qnulu") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture_filter = 1 +position = Vector2(0, -2) +texture = SubResource("AtlasTexture_basl5") + +[node name="LimboStateDebugger" type="Node2D" parent="." node_paths=PackedStringArray("state_root")] +script = ExtResource("8_clxy3") +state_root = NodePath("../PlayerHSM/Normal") +draw_offset = Vector2(20, -10) + +[node name="PlayerHSM" type="LimboHSM" parent="."] +blackboard_plan = ExtResource("4_mwufa") +unique_name_in_owner = true +script = ExtResource("6_8q4ov") + +[node name="Normal" type="LimboHSM" parent="PlayerHSM"] +unique_name_in_owner = true +script = ExtResource("1_wvs5h") + +[node name="Grounded" type="LimboHSM" parent="PlayerHSM/Normal"] +unique_name_in_owner = true +script = ExtResource("2_5p50s") + +[node name="Idle" type="LimboState" parent="PlayerHSM/Normal/Grounded"] +unique_name_in_owner = true +script = ExtResource("4_30i7g") + +[node name="Move" type="LimboState" parent="PlayerHSM/Normal/Grounded"] +unique_name_in_owner = true +script = ExtResource("7_rrwxs") + +[node name="Airbone" type="LimboHSM" parent="PlayerHSM/Normal"] +unique_name_in_owner = true +script = ExtResource("8_d42ye") + +[node name="Fall" type="LimboState" parent="PlayerHSM/Normal/Airbone"] +unique_name_in_owner = true +script = ExtResource("9_iqoog") + +[node name="Jump" type="LimboState" parent="PlayerHSM/Normal/Airbone"] +unique_name_in_owner = true +script = ExtResource("10_mwufa") + +[node name="WallJump" type="LimboState" parent="PlayerHSM/Normal/Airbone"] +unique_name_in_owner = true +script = ExtResource("12_basl5") + +[node name="OnWall" type="LimboHSM" parent="PlayerHSM/Normal"] +unique_name_in_owner = true +script = ExtResource("13_l6fs8") + +[node name="Climb" type="LimboState" parent="PlayerHSM/Normal/OnWall"] +unique_name_in_owner = true +script = ExtResource("15_mt2s8") + +[node name="ClimbJump" type="LimboState" parent="PlayerHSM/Normal/OnWall"] +unique_name_in_owner = true +script = ExtResource("15_l6fs8") + +[node name="GrapHook" type="LimboHSM" parent="PlayerHSM/Normal"] +unique_name_in_owner = true +script = ExtResource("16_f07it") + +[node name="HookShooting" type="LimboState" parent="PlayerHSM/Normal/GrapHook"] +unique_name_in_owner = true +script = ExtResource("16_xcbik") +grap_hook_shooting_time = 0.2 + +[node name="Hooking" type="LimboState" parent="PlayerHSM/Normal/GrapHook"] +unique_name_in_owner = true + +[node name="Dash" type="LimboState" parent="PlayerHSM/Normal"] +unique_name_in_owner = true +script = ExtResource("12_8nsdm") + +[node name="Dead" type="LimboState" parent="PlayerHSM"] +unique_name_in_owner = true +script = ExtResource("17_5r2pj") + +[node name="LocomotionComponent" type="Node" parent="."] +unique_name_in_owner = true +script = ExtResource("2_11vl8") +dash_speed = 400.0 +end_dash_speed = 190.0 +climb_hop_velocity_x = 180.0 +climb_hop_velocity_y = 334.0 +wall_jump_base_force_x = 260.0 +wall_jump_base_force_y = 220.0 +fall_maxium_speed = 430.0 +air_control_mult = 0.7 +run_accel = 2100.0 +run_reduce = 420.0 +move_speed_max = 157.0 + +[node name="WallDetector" parent="LocomotionComponent" instance=ExtResource("20_air0b")] +unique_name_in_owner = true + +[node name="MidRayCast2D" parent="LocomotionComponent/WallDetector" index="1"] +position = Vector2(0, 3) + +[node name="SpawnHookComponet" type="Node" parent="." node_paths=PackedStringArray("binded_hook_ray_cast_2d")] +script = ExtResource("21_p14kj") +binded_hook_ray_cast_2d = NodePath("HookCheckRayer") +binded_hook_move_input_property_name = &"m_input_intent_direction" +metadata/_custom_type_script = "uid://bkkkyugppu7sl" + +[node name="HookCheckRayer" type="RayCast2D" parent="SpawnHookComponet"] +collision_mask = 4 + +[node name="ReedSFXMananger" type="Node" parent="."] +script = ExtResource("24_x5g5e") +bindings = Array[ExtResource("25_rjd7i")]([ExtResource("26_256x0")]) +metadata/_custom_type_script = "uid://lp1ge1qbyfr3" + +[node name="ReedVFXManager" type="Node" parent="."] +script = ExtResource("24_mwlgv") +bindings = Array[ExtResource("25_s5egm")]([ExtResource("26_s5egm"), ExtResource("30_hquoe")]) +metadata/_custom_type_script = "uid://ta2r2bc1nrwe" + +[node name="PhantomCamera2D" type="Node2D" parent="."] +position = Vector2(50, -75) +script = ExtResource("20_ogl63") +tween_resource = SubResource("Resource_p14kj") +metadata/_custom_type_script = "uid://bhexx6mj1xv3q" + +[node name="HitBox" type="Area2D" parent="."] +unique_name_in_owner = true +collision_layer = 0 +collision_mask = 8 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="HitBox"] +position = Vector2(0, -2.5) +shape = SubResource("RectangleShape2D_ogl63") +debug_color = Color(0.95815283, 0, 0.5313341, 0.41960785) + +[node name="RemotePositionSetting" type="Node2D" parent="."] + +[node name="Remotor[HookCheckRayer]" type="RemoteTransform2D" parent="RemotePositionSetting"] +remote_path = NodePath("../../SpawnHookComponet/HookCheckRayer") +update_rotation = false +update_scale = false +script = ExtResource("28_mxt3b") +observed_remote_path = NodePath("../../SpawnHookComponet/HookCheckRayer") +metadata/_custom_type_script = "uid://bijoqygv6tncj" + +[node name="Remotor[WallDetector]" type="RemoteTransform2D" parent="RemotePositionSetting"] +remote_path = NodePath("../../LocomotionComponent/WallDetector") +update_rotation = false +update_scale = false +script = ExtResource("28_mxt3b") +observed_remote_path = NodePath("../../LocomotionComponent/WallDetector") +metadata/_custom_type_script = "uid://bijoqygv6tncj" + +[node name="FootPosMarker" type="Marker2D" parent="."] +unique_name_in_owner = true +position = Vector2(0, 11) + +[connection signal="v_land_dust" from="." to="." method="_on_v_land_dust"] + +[editable path="LocomotionComponent/WallDetector"] diff --git a/_player/Agens.tscn821139048.tmp b/_player/Agens.tscn821139048.tmp new file mode 100644 index 0000000..e8fb4ad --- /dev/null +++ b/_player/Agens.tscn821139048.tmp @@ -0,0 +1,120 @@ +[gd_scene load_steps=21 format=3 uid="uid://gwhff4qaouxy"] + +[ext_resource type="Script" uid="uid://dq1g1qp66chwy" path="res://_player/agens.gd" id="1_rkqpu"] +[ext_resource type="Script" uid="uid://isu8onknb75o" path="res://_player/states/character_state_machine.gd" id="1_wvs5h"] +[ext_resource type="Script" uid="uid://15n8yfyr4eqj" path="res://_player/states/grounded.gd" id="2_5p50s"] +[ext_resource type="Texture2D" uid="uid://doxhsab56pe50" path="res://_asset/all.png" id="2_8nsdm"] +[ext_resource type="Script" uid="uid://dcfq4wnx2g6bs" path="res://_player/player_locomotion.gd" id="2_11vl8"] +[ext_resource type="Script" uid="uid://b5hkfpjbye70" path="res://_player/states/idle.gd" id="4_30i7g"] +[ext_resource type="BlackboardPlan" uid="uid://nlw7rxugv5uh" path="res://_player/bbp_player.tres" id="4_mwufa"] +[ext_resource type="Script" uid="uid://bpd54nf8oxwsb" path="res://_player/states/player_hsm.gd" id="6_8q4ov"] +[ext_resource type="Script" uid="uid://po21boe8iqcc" path="res://_player/states/move.gd" id="7_rrwxs"] +[ext_resource type="Script" uid="uid://cjf7kds0cipkw" path="res://_tools/limbo_state_helper.gd" id="8_clxy3"] +[ext_resource type="Script" uid="uid://bbsdsqxujlsbp" path="res://_player/states/airbone.gd" id="8_d42ye"] +[ext_resource type="Script" uid="uid://db6ttwe3skqfv" path="res://_player/states/fall.gd" id="9_iqoog"] +[ext_resource type="Script" uid="uid://dh3115a8iyabg" path="res://_player/states/jump.gd" id="10_mwufa"] +[ext_resource type="Script" uid="uid://cky34pinqpewd" path="res://_player/states/ghost.gd" id="12_8nsdm"] +[ext_resource type="Script" uid="uid://dhlg4ct8al76c" path="res://_player/states/wall_jump.gd" id="12_basl5"] +[ext_resource type="Script" uid="uid://fpfkas0s46xq" path="res://_player/states/on_wall.gd" id="13_l6fs8"] +[ext_resource type="Script" uid="uid://bjjatv4bxv7w" path="res://_player/states/climb.gd" id="15_mt2s8"] +[ext_resource type="PackedScene" uid="uid://blm8q46h3v2im" path="res://addons/reedcomponent/locomotion/wall_detector.tscn" id="20_air0b"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_qnulu"] +size = Vector2(9, 23) + +[sub_resource type="AtlasTexture" id="AtlasTexture_basl5"] +atlas = ExtResource("2_8nsdm") +region = Rect2(9, 22, 13, 26) + +[node name="Agens" type="CharacterBody2D"] +platform_wall_layers = 4 +script = ExtResource("1_rkqpu") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(-0.5, -0.5) +shape = SubResource("RectangleShape2D_qnulu") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture_filter = 1 +position = Vector2(0, -2) +texture = SubResource("AtlasTexture_basl5") + +[node name="PlayerHSM" type="LimboHSM" parent="."] +blackboard_plan = ExtResource("4_mwufa") +unique_name_in_owner = true +script = ExtResource("6_8q4ov") + +[node name="Normal" type="LimboHSM" parent="PlayerHSM"] +unique_name_in_owner = true +script = ExtResource("1_wvs5h") + +[node name="Grounded" type="LimboHSM" parent="PlayerHSM/Normal"] +unique_name_in_owner = true +script = ExtResource("2_5p50s") + +[node name="Idle" type="LimboState" parent="PlayerHSM/Normal/Grounded"] +unique_name_in_owner = true +script = ExtResource("4_30i7g") + +[node name="Move" type="LimboState" parent="PlayerHSM/Normal/Grounded"] +unique_name_in_owner = true +script = ExtResource("7_rrwxs") + +[node name="Airbone" type="LimboHSM" parent="PlayerHSM/Normal"] +unique_name_in_owner = true +script = ExtResource("8_d42ye") + +[node name="Fall" type="LimboState" parent="PlayerHSM/Normal/Airbone"] +unique_name_in_owner = true +script = ExtResource("9_iqoog") + +[node name="Jump" type="LimboState" parent="PlayerHSM/Normal/Airbone"] +unique_name_in_owner = true +script = ExtResource("10_mwufa") + +[node name="WallJump" type="LimboState" parent="PlayerHSM/Normal/Airbone"] +unique_name_in_owner = true +script = ExtResource("12_basl5") + +[node name="OnWall" type="LimboHSM" parent="PlayerHSM/Normal"] +unique_name_in_owner = true +script = ExtResource("13_l6fs8") + +[node name="Climb" type="LimboState" parent="PlayerHSM/Normal/OnWall"] +unique_name_in_owner = true +script = ExtResource("15_mt2s8") + +[node name="ClimbHop" type="LimboState" parent="PlayerHSM/Normal/OnWall"] +unique_name_in_owner = true + +[node name="ClimbJump" type="LimboState" parent="PlayerHSM/Normal/OnWall"] +unique_name_in_owner = true + +[node name="Dash" type="LimboState" parent="PlayerHSM/Normal"] +unique_name_in_owner = true +script = ExtResource("12_8nsdm") + +[node name="Dead" type="LimboState" parent="PlayerHSM"] +unique_name_in_owner = true + +[node name="LocomotionComponent" type="Node" parent="."] +unique_name_in_owner = true +script = ExtResource("2_11vl8") +fall_maxium_speed = 430.0 +air_control_mult = 0.7 +run_accel = 2100.0 +run_reduce = 420.0 +move_speed_max = 157.0 + +[node name="LimboStateDebugger" type="Node2D" parent="." node_paths=PackedStringArray("state_root")] +script = ExtResource("8_clxy3") +state_root = NodePath("../PlayerHSM/Normal") +draw_offset = Vector2(20, -10) + +[node name="WallCheckRayer" type="RayCast2D" parent="."] +unique_name_in_owner = true +target_position = Vector2(14, 0) +collision_mask = 4 + +[node name="WallDetector" parent="." instance=ExtResource("20_air0b")] +unique_name_in_owner = true diff --git a/_player/agens.gd b/_player/agens.gd new file mode 100644 index 0000000..7341593 --- /dev/null +++ b/_player/agens.gd @@ -0,0 +1,174 @@ +class_name Player extends CharacterBody2D + +@onready var locomotion_comp: LocomotionComponent = %LocomotionComponent +@onready var hsm: LimboHSM = %PlayerHSM +@onready var wall_detector: WallDetector = %WallDetector +@onready var hit_box: Area2D = %HitBox +@onready var spawn_hook_comp: SpawnHookComponet = $SpawnHookComponet + +@onready var foot_pos_marker: Marker2D = %FootPosMarker + +enum Direction{LEFT,RIGHT} +var direction: Direction = Direction.RIGHT: set = _player_direction_changed + +var m_jump_press: bool = false +var m_dash_press: bool = false +var m_climb_press: bool = false +var m_grap_hook_press: bool = false + +##用于记录当前玩家输入的朝向 +var m_input_intent_direction: Vector2 + +var is_dead: bool = false: + set(value): + is_dead = value + if is_dead: + locomotion_comp.is_active = false + GlobalEvent.boradcast_player_dead_event() + player_dead.emit() + +signal player_direction_changed(direction: Direction) +signal player_dead + +##落地尘土特效 +signal v_land_dust +##奔跑尘土特效 +signal v_run_dust +##跳跃尘土特效 +signal v_jump_dust + +##跳跃声音特效 +signal s_jump_sound + +func _ready() -> void: + self.player_direction_changed.connect(_handle_direction_changed) + self.hit_box.area_entered.connect(_handle_hit_box_entered) + self.hit_box.body_entered.connect(_handle_hit_box_entered) + +func _draw() -> void: + draw_string(ThemeDB.fallback_font,Vector2.ZERO,str(get_wall_normal())) + +func _process(delta: float) -> void: + queue_redraw() + +func _physics_process(delta: float) -> void: + + ##用於更新輸入的朝向 + m_input_intent_direction = Input.get_vector( + "move_left", + "move_right", + "move_up", + "move_down" + ) + + spawn_hook_comp.set_ray_direction(m_input_intent_direction) + +func _unhandled_input(event: InputEvent) -> void: + if event.is_echo(): + return + + #jump input + if event.is_action_pressed(&"jump"): + m_jump_press = true + _handle_jump_press() + + if event.is_action_released(&"jump"): + m_jump_press = false + _handle_jump_release() + + #dash input + if event.is_action_pressed(&"dash"): + m_dash_press = true + _handle_dash_press() + + if event.is_action_released(&"dash"): + m_dash_press = false + + #climb input + if event.is_action_pressed(&"climb"): + m_climb_press = true + _handle_climb_press() + + if event.is_action_released(&"climb"): + m_climb_press = false + _handle_climb_release() + + #grap hook input + if event.is_action_pressed(&"grap_hook"): + m_grap_hook_press = true + _handle_grap_hook_press() + + if event.is_action_released(&"grap_hook"): + m_grap_hook_press = false + _handle_grap_hook_release() + +#region 输入处理 +'''对于单次的输入触发动作,我们发送一个格式为 + want_to_...的事件给hsm,用来尝试触发 +''' +##处理 jump 单次输入 +func _handle_jump_press() -> void: + if not m_jump_press: + return + + hsm.dispatch(&"trigger_jump") + +func _handle_jump_release() -> void: + hsm.dispatch(&"completed_jump") + +##处理 Dash 单次输入 +func _handle_dash_press() -> void: + if not m_dash_press: + return + hsm.dispatch(&"trigger_dash") + +##处理 climb 输入 +func _handle_climb_press() -> void: + if not m_climb_press: + return + hsm.dispatch(&"trigger_climb") + +func _handle_climb_release() -> void: + hsm.dispatch(&"completed_climb") + +##处理 Grap Hook 输入 +func _handle_grap_hook_press() -> void: + hsm.dispatch(&"trigger_grap_hook") + +func _handle_grap_hook_release() -> void: + hsm.dispatch(&"completed_grap_hook") +#endregion + +##玩家方向改变时更新 +func _handle_direction_changed(value: Direction): + match value: + Direction.RIGHT: + wall_detector.flip_h = false + Direction.LEFT: + wall_detector.flip_h = true + +func _handle_hit_box_entered(node: Node2D)-> void: + hsm.dispatch(&"try_enter_dead") + +func _player_direction_changed(value: Direction): + if self.direction == value: + return + direction = value + player_direction_changed.emit(direction) + +##播放落地尘土特效 +func on_land_dust() -> void: + v_land_dust.emit({"world_pos": foot_pos_marker.global_position}) + +##播放落地尘土特效 +func on_run_dust() -> void: + v_run_dust.emit({"world_pos": foot_pos_marker.global_position}) + +##播放落地尘土特效 +func on_jump() -> void: + v_jump_dust.emit({"world_pos": foot_pos_marker.global_position}) + s_jump_sound.emit() + +##工具函数 +static func get_direction_vector(dir: Direction) -> Vector2: + return Vector2(1,0) if dir == Direction.RIGHT else Vector2(-1,0) diff --git a/_player/agens.gd.uid b/_player/agens.gd.uid new file mode 100644 index 0000000..ac2ab96 --- /dev/null +++ b/_player/agens.gd.uid @@ -0,0 +1 @@ +uid://dq1g1qp66chwy diff --git a/_player/bbp_player.tres b/_player/bbp_player.tres new file mode 100644 index 0000000..559adde --- /dev/null +++ b/_player/bbp_player.tres @@ -0,0 +1,23 @@ +[gd_resource type="BlackboardPlan" format=3 uid="uid://nlw7rxugv5uh"] + +[resource] +var/want_to_jump/name = &"want_to_jump" +var/want_to_jump/type = 1 +var/want_to_jump/value = false +var/want_to_jump/hint = 0 +var/want_to_jump/hint_string = "" +var/had_jump/name = &"had_jump" +var/had_jump/type = 1 +var/had_jump/value = false +var/had_jump/hint = 0 +var/had_jump/hint_string = "" +var/is_dashing/name = &"is_dashing" +var/is_dashing/type = 1 +var/is_dashing/value = false +var/is_dashing/hint = 0 +var/is_dashing/hint_string = "" +var/lock_direction_changed/name = &"lock_direction_changed" +var/lock_direction_changed/type = 1 +var/lock_direction_changed/value = false +var/lock_direction_changed/hint = 0 +var/lock_direction_changed/hint_string = "" diff --git a/_player/effect_binding/jump_dust.tres b/_player/effect_binding/jump_dust.tres new file mode 100644 index 0000000..9e48040 --- /dev/null +++ b/_player/effect_binding/jump_dust.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="VFXSignalBinding" load_steps=3 format=3 uid="uid://bdad4yjv1q0uu"] + +[ext_resource type="Script" uid="uid://dipfdfnp506hl" path="res://addons/reedfx/vfx/VFXSignalBinding.gd" id="1_solj8"] +[ext_resource type="PackedScene" uid="uid://bs14s8ox4tk0i" path="res://_vfx/dust/land_dust.tscn" id="2_ttrqd"] + +[resource] +script = ExtResource("1_solj8") +target_node = NodePath("..") +signal_name = &"v_jump_dust" +vfx_scene = ExtResource("2_ttrqd") +spawn_space = 1 +metadata/_custom_type_script = "uid://dipfdfnp506hl" diff --git a/_player/effect_binding/jump_sound.tres b/_player/effect_binding/jump_sound.tres new file mode 100644 index 0000000..c7c4f16 --- /dev/null +++ b/_player/effect_binding/jump_sound.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="SFXSignalBinding" load_steps=3 format=3 uid="uid://cb73bysplqpo7"] + +[ext_resource type="Script" uid="uid://du267phqvtqyr" path="res://addons/reedfx/sfx/SFXSignalBinding.gd" id="1_isv5v"] +[ext_resource type="AudioStream" uid="uid://b4moh3s41xi44" path="res://_sfx/player/jump.tres" id="1_ri55b"] + +[resource] +script = ExtResource("1_isv5v") +target_node = NodePath("..") +signal_name = &"s_jump_sound" +audio_stream = ExtResource("1_ri55b") +debug_print = true +metadata/_custom_type_script = "uid://du267phqvtqyr" diff --git a/_player/effect_binding/land_dust.tres b/_player/effect_binding/land_dust.tres new file mode 100644 index 0000000..28fe109 --- /dev/null +++ b/_player/effect_binding/land_dust.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="VFXSignalBinding" load_steps=3 format=3 uid="uid://do0bnwse614jw"] + +[ext_resource type="Script" uid="uid://dipfdfnp506hl" path="res://addons/reedfx/vfx/VFXSignalBinding.gd" id="1_rik1v"] +[ext_resource type="PackedScene" uid="uid://bs14s8ox4tk0i" path="res://_vfx/dust/land_dust.tscn" id="2_t6jy7"] + +[resource] +script = ExtResource("1_rik1v") +target_node = NodePath("..") +signal_name = &"v_land_dust" +vfx_scene = ExtResource("2_t6jy7") +spawn_space = 1 +metadata/_custom_type_script = "uid://dipfdfnp506hl" diff --git a/_player/ghost/Ghost.tscn b/_player/ghost/Ghost.tscn new file mode 100644 index 0000000..3b3cbe1 --- /dev/null +++ b/_player/ghost/Ghost.tscn @@ -0,0 +1,68 @@ +[gd_scene load_steps=8 format=3 uid="uid://cr372ml2gqjrw"] + +[ext_resource type="Script" uid="uid://b7e4wue7oegre" path="res://_player/ghost/ghost.gd" id="1_4fcft"] +[ext_resource type="Texture2D" uid="uid://blmcygf06lxay" path="res://_asset/brackeys_platformer_assets/sprites/coin.png" id="1_jujku"] +[ext_resource type="Script" uid="uid://bvlda3myvuoy3" path="res://_player/ghost/ghost_locomotion.gd" id="2_23gor"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_xwnqk"] +radius = 6.0 + +[sub_resource type="Animation" id="Animation_23gor"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} + +[sub_resource type="Animation" id="Animation_jujku"] +resource_name = "idle" +length = 1.5000125 +loop_mode = 1 +step = 0.125 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1, 1.125, 1.25, 1.375), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 1, +"values": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_s1rgc"] +_data = { +&"RESET": SubResource("Animation_23gor"), +&"idle": SubResource("Animation_jujku") +} + +[node name="Ghost" type="CharacterBody2D"] +texture_filter = 1 +script = ExtResource("1_4fcft") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_xwnqk") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("1_jujku") +hframes = 12 + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_s1rgc") +} + +[node name="GhostLocomotion" type="Node" parent="."] +script = ExtResource("2_23gor") +should_post_process = true +should_apply_gravity = false diff --git a/_player/ghost/ghost.gd b/_player/ghost/ghost.gd new file mode 100644 index 0000000..a3ba9f6 --- /dev/null +++ b/_player/ghost/ghost.gd @@ -0,0 +1,17 @@ +class_name Ghost extends CharacterBody2D + +var _last_frame_direction : Vector2 = Vector2(1.0,0) + +func _physics_process(delta: float) -> void: + #优先让移动的方向等于上一帧的方向,防止出现Zero的情况,上一帧移动方向的默认值是水平向右的 + + var h = Input.get_axis(&"move_left",&"move_right") + var v = Input.get_axis(&"move_down",&"move_up") + + var _current_frame_direction = Vector2(h,v).normalized() + + #只有在输入存在的情况下,我们才更新上一帧的方向 + if _current_frame_direction != Vector2.ZERO: + _last_frame_direction = _current_frame_direction + + var move_dir = _last_frame_direction diff --git a/_player/ghost/ghost.gd.uid b/_player/ghost/ghost.gd.uid new file mode 100644 index 0000000..43082b6 --- /dev/null +++ b/_player/ghost/ghost.gd.uid @@ -0,0 +1 @@ +uid://b7e4wue7oegre diff --git a/_player/ghost/ghost_locomotion.gd b/_player/ghost/ghost_locomotion.gd new file mode 100644 index 0000000..2c42a45 --- /dev/null +++ b/_player/ghost/ghost_locomotion.gd @@ -0,0 +1 @@ +extends LocomotionComponent diff --git a/_player/ghost/ghost_locomotion.gd.uid b/_player/ghost/ghost_locomotion.gd.uid new file mode 100644 index 0000000..fe6b02c --- /dev/null +++ b/_player/ghost/ghost_locomotion.gd.uid @@ -0,0 +1 @@ +uid://bvlda3myvuoy3 diff --git a/_player/player_dash_comp.gd b/_player/player_dash_comp.gd new file mode 100644 index 0000000..2a9a1bb --- /dev/null +++ b/_player/player_dash_comp.gd @@ -0,0 +1 @@ +extends DashComponent diff --git a/_player/player_dash_comp.gd.uid b/_player/player_dash_comp.gd.uid new file mode 100644 index 0000000..e7d1a5a --- /dev/null +++ b/_player/player_dash_comp.gd.uid @@ -0,0 +1 @@ +uid://dxakl6tx1wvfc diff --git a/_player/player_locomotion.gd b/_player/player_locomotion.gd new file mode 100644 index 0000000..e9bd3f3 --- /dev/null +++ b/_player/player_locomotion.gd @@ -0,0 +1,191 @@ +class_name CelesteLocomotionComponent extends JumpLocomotionComponent + +#region 冲刺相关参数 +@export_category("Dash Properties") +##最大的冲刺次数 +@export var maxium_dash_count:int = 1 +##Dash时的速度 +@export var dash_speed: float = 240 +##结束Dash的速度 +@export var end_dash_speed: float = 160 +##Dash的冷却时间 +@export var dash_cold_down: float = .2 +##是否在组件ready时自动补充所有的Dash次数 +@export var auto_recover_dash_count_at_ready: bool = true +#endregion + +#region 攀爬相关参数 +@export_category("Climb Properties") +##角色最大耐力 +@export var climb_max_stamina: float +##角色向上时的速度 +@export var climb_max_speed_upward: float = 45.0 +##角色向下时的速度 +@export var climb_max_speed_downward: float = 80.0 +##角色速度变化时的最大加速度 +@export var climb_acceleration: float = 900.0 +##攀爬到顶点时候的自动代偿速度X +@export var climb_hop_velocity_x: float = 80 +##攀爬到顶点时候的自动代偿速度Y +@export var climb_hop_velocity_y: float = 160 +##攀爬跳的速度X +@export var climb_jump_velocity_x: float = 160 +##攀爬跳的速度Y +@export var climb_jump_velocity_y: float = 160 +##攀爬跳的最大可输入时长 +@export var climb_jump_time: float = .14 +#endregion + +#region 冲刺field +var last_dash_count: int +##此变量为总开关,如果关闭,则在物理更新里无论如何也是不会更新Dash的,这里默认为false,因为Dash需要手动触发,最好不要常开 +var can_dash: bool = false +var _dash_direction: Vector2 #存储Dash的Direction + +signal dash_count_changed(count: int) +signal dash_brusted +signal dash_prepared +#endregion + +#region 攀爬field +var can_climb: bool = false +var _climb_input: float +var _climb_hop_flag: bool = false +var _is_climb_jumping: bool = false +#endregion + +func _init_component() -> void: + super._init_component() + + if auto_recover_dash_count_at_ready: + full_recover_dash_count() + +func _physics_process(delta: float) -> void: + if Engine.is_editor_hint(): + return + + if can_climb: + print("攀爬更新中") + _update_climb(delta) + characterbody.move_and_slide() #移动更新 + return + + if can_dash: + characterbody.move_and_slide() + return + + super._physics_process(delta) + +func _update_climb(delta) -> void: + var target_abs: float + + #更新目标速度 + if sign(_climb_input) == .0: + target_abs = 0 + elif sign(_climb_input) > 0: + target_abs = climb_max_speed_downward + else: + target_abs = climb_max_speed_upward + + var target = target_abs * _climb_input + characterbody.velocity.y = speed_approach(characterbody.velocity.y,target,climb_acceleration * delta) + +func _update_dash(delta) -> void: + return + +##整合之后的函数,如果不需要额外的逻辑,可以直接通过这个触发Dash +func integrate_dash(dash_dir: Vector2) -> bool: + if not predash(dash_dir): + return false + await get_tree().process_frame #等待一帧 + brust_dash() + return true + +##dash函数,输入一个Dash的方向,返回是否成功 +func brust_dash() -> bool: + var old: Vector2 = characterbody.velocity; + var burst: Vector2 = _dash_direction.normalized() * dash_speed; + + if sign(old.x) == sign(burst.x) and abs(old.x) > abs(burst.x): + burst.x = old.x + + characterbody.velocity = burst + dash_brusted.emit() + return true + +##dash准备函数,需要在dash的前一帧触发 +func predash(dash_dir: Vector2) -> bool: + if not get_can_dash(): + return false + + dash_prepared.emit() + last_dash_count = maxi(last_dash_count -1,0) + can_dash = true + + _dash_direction = dash_dir + return true + +##停止Dash,实际上是关闭Dash标识符 +func stop_dash(force_stop: bool = false) -> void: + if force_stop: + characterbody.velocity = Vector2.ZERO + characterbody.move_and_slide() + can_dash = false + +##完全回复的Dash次数 +func full_recover_dash_count() -> void: + dash_count_changed.emit(last_dash_count) + last_dash_count = maxium_dash_count + +##回复指定数量的Dash次数 +func recover_dash_count(recover_count : int) -> void: + last_dash_count = clampi(last_dash_count+ recover_count, 0,maxium_dash_count) + +##子类可以重写此方法以自定义Dash的条件 +func get_can_dash() -> bool: + return last_dash_count > 0 + +##添加攀爬的输入 +func add_climb_input(input: float) -> bool: + _climb_input = input + return true + +##开始攀爬 +func start_climb(force_reset: bool = false) -> void: + if force_reset: + characterbody.velocity = Vector2.ZERO + characterbody.move_and_slide() + + can_climb = true + +##终止攀爬 +func suspend_climb() -> void: + can_climb = false + +##攀爬补充跳跃 +func climb_hop() -> void: + _climb_hop_flag = true + characterbody.velocity = Vector2(climb_hop_velocity_x * Player.get_direction_vector(characterbody.direction).x,-1 * climb_hop_velocity_y) + +func start_climb_jump() -> bool: + if _is_jumping : return false + + #给与一个跳跃的补正速度 + characterbody.velocity.x = _movement_input * climb_jump_velocity_x # 跳跃的水平补正速度 + + _jump_timer = climb_jump_time + _is_jumping = true + _is_climb_jumping = true + can_climb = false #取消掉原本的climb,如果后续重新触发climb,则重新判断 + characterbody.velocity.y = _get_jump_force() + + return true + +func stop_climb_jump() -> void: + _is_jumping = false + _is_climb_jumping = false + +func _get_jump_force() -> float: + if _is_climb_jumping: + return -1 * climb_jump_velocity_y + return super._get_jump_force() diff --git a/_player/player_locomotion.gd.uid b/_player/player_locomotion.gd.uid new file mode 100644 index 0000000..3abd9fb --- /dev/null +++ b/_player/player_locomotion.gd.uid @@ -0,0 +1 @@ +uid://dcfq4wnx2g6bs diff --git a/_player/states/airbone.gd b/_player/states/airbone.gd new file mode 100644 index 0000000..ac866d6 --- /dev/null +++ b/_player/states/airbone.gd @@ -0,0 +1,59 @@ +extends LimboHSM + +@onready var root: Normal = %Normal + +##自动跳跃逻辑 +@export var auto_jump_cached_time: float = .2 +var auto_jump_timer: float + +func _setup() -> void: +#region Jump and fall + #Jump State -> Fall State + self.add_transition(root.jump_state,root.fall_state,root.jump_state.EVENT_FINISHED) + #Fall State -> Jump State + self.add_transition(root.fall_state,root.jump_state,&"air_to_jump") +#endregion + +#region Wall jump + #ANYSTATE -> Wall Jump State + self.add_transition(ANYSTATE,root.wall_jump_state,&"wall_jump") + #Wall Jump State -> Fall State + self.add_transition(root.wall_jump_state,root.fall_state,root.wall_jump_state.EVENT_FINISHED) +#endregion + + self.add_event_handler(&"trigger_jump",_handler_trigger_jump) + +func _enter() -> void: + var want_to_jump = blackboard.get_var(&"want_to_jump",false) + + initial_state = root.fall_state + if want_to_jump: + initial_state = root.jump_state + + self.blackboard.set_var(&"want_to_jump",false) + + +func _update(delta: float) -> void: + if auto_jump_timer > 0: + auto_jump_timer -= delta + + if agent.is_on_floor() && agent.velocity.y >= 0: + #自动跳 + if auto_jump_timer > 0: + auto_jump_timer = 0 + self.blackboard.set_var(&"want_to_jump",true) + change_active_state(root.jump_state) + + get_root().dispatch(self.EVENT_FINISHED) + +func _cache_auto_jump_timer() -> void: + auto_jump_timer = auto_jump_cached_time + +#region 输入绑定事件 +func _handler_trigger_jump() -> bool: + if agent.is_on_wall_only(): + get_root().dispatch(&"wall_jump") + + _cache_auto_jump_timer() + return true +#endregion diff --git a/_player/states/airbone.gd.uid b/_player/states/airbone.gd.uid new file mode 100644 index 0000000..dff0546 --- /dev/null +++ b/_player/states/airbone.gd.uid @@ -0,0 +1 @@ +uid://bbsdsqxujlsbp diff --git a/_player/states/character_state_machine.gd b/_player/states/character_state_machine.gd new file mode 100644 index 0000000..0d216af --- /dev/null +++ b/_player/states/character_state_machine.gd @@ -0,0 +1,92 @@ +class_name Normal extends LimboHSM + +@onready var ground_state : LimboHSM = %Grounded +@onready var idle_state: LimboState = %Idle +@onready var move_state: LimboState = %Move + +@onready var airbone_state : LimboHSM = %Airbone +@onready var fall_state: LimboState = %Fall +@onready var jump_state: LimboState = %Jump +@onready var wall_jump_state: LimboState = %WallJump + +@onready var on_wall_state: LimboHSM = %OnWall +@onready var climb_state: LimboState = %Climb +@onready var climb_jump_state: LimboState = %ClimbJump + +@onready var dash_state: LimboState = %Dash + +@onready var grap_hook_state: LimboHSM = %GrapHook +@onready var hook_shooting_state: LimboState = %HookShooting +@onready var hooking_state: LimboState = %Hooking + + +func _setup() -> void: + self._init_trans() + self._init_handler() + +func _init_handler() -> void: + self.add_event_handler(&"trigger_dash",_handler_trigger_dash) ##处理Dash输入 + self.add_event_handler(&"trigger_climb",_handler_trigger_climb) ##处理瞬时的climb + self.add_event_handler(&"trigger_grap_hook",_handler_grap_hook) ##处理grap hook 的輸入 + +func _init_trans() -> void: + self.add_transition(ground_state,airbone_state,ground_state.EVENT_FINISHED) + self.add_transition(airbone_state,ground_state,airbone_state.EVENT_FINISHED) + self.add_transition(ANYSTATE,dash_state,&"want_to_dash") + self.add_transition(dash_state,ground_state,&"exit_on_ground") + self.add_transition(dash_state,airbone_state,&"exit_on_air") + + ##用於處理貼在墻面的State流轉 + self.add_transition(ANYSTATE,on_wall_state,&"want_to_on_wall") + self.add_transition(on_wall_state,airbone_state,&"exit_on_ground") + self.add_transition(on_wall_state,ground_state,&"exit_on_air") + + ##用於處理鈎爪的State流轉 + self.add_transition(ANYSTATE,grap_hook_state,&"want_to_grap_hook") + self.add_transition(grap_hook_state,airbone_state,&"exit_on_ground") + self.add_transition(grap_hook_state,ground_state,&"exit_on_air") + +func _update(delta: float) -> void: + process_direction() + + ##如果玩家当前在墙上,并且玩家按下了climb + if agent.wall_detector.is_on_wall and agent.m_climb_press: + self.dispatch(&"want_to_on_wall") + +##处理Dash输入 +func _handler_trigger_dash() -> bool: + #如果当前无法Dash,则返回 + if not agent.locomotion_comp.get_can_dash(): + return false + + if get_root().blackboard.get_var(&"is_dashing",false): + return false + + self.dispatch(&"want_to_dash") + return true + +func _handler_trigger_climb() -> bool: + if not agent.is_on_wall(): + return false + + return true + +func _handler_grap_hook() -> bool: + + self.dispatch(&"want_to_grap_hook") + return true + +func process_direction() -> void: + var b = get_root().blackboard.get_var(&"lock_direction_changed",false) as bool + if b: return + + ##切换方向的逻辑 + var move_direction = Input.get_axis(&"move_left",&"move_right") as float + if move_direction * Player.get_direction_vector(agent.direction).x <= 0 and move_direction != 0: + agent.direction = Player.Direction.RIGHT if move_direction> 0 else Player.Direction.LEFT + +func _get_dash_exit_enter_state()->LimboState: + if agent.is_on_floor(): + return ground_state + else: + return airbone_state diff --git a/_player/states/character_state_machine.gd.uid b/_player/states/character_state_machine.gd.uid new file mode 100644 index 0000000..cc0d7ff --- /dev/null +++ b/_player/states/character_state_machine.gd.uid @@ -0,0 +1 @@ +uid://isu8onknb75o diff --git a/_player/states/climb.gd b/_player/states/climb.gd new file mode 100644 index 0000000..f495c17 --- /dev/null +++ b/_player/states/climb.gd @@ -0,0 +1,30 @@ +extends LimboState + +func _setup() -> void: + self.add_event_handler(&"completed_climb",_handler_completed_climb) + +func _enter() -> void: + agent.locomotion_comp.suspend_movement() + agent.locomotion_comp.stop_dash(true) + agent.locomotion_comp.start_climb(true) + + get_root().blackboard.set_var(&"lock_direction_changed",true) + +func _exit() -> void: + agent.locomotion_comp.enable_movement() + agent.locomotion_comp.suspend_climb() + + get_root().blackboard.set_var(&"lock_direction_changed",false) + +func _update(delta: float) -> void: + var climb_dir = Input.get_axis("move_up","move_down") as float + agent.locomotion_comp.add_climb_input(climb_dir) + + var _enter_climb_hop = not agent.wall_detector.up_ray_on_wall and not agent.wall_detector.mid_ray_on_wall and agent.wall_detector.down_ray_on_wall and climb_dir< 0 + if _enter_climb_hop: + agent.locomotion_comp.climb_hop() + self.dispatch(self.EVENT_FINISHED) + +func _handler_completed_climb() -> bool: + self.dispatch(self.EVENT_FINISHED) + return true diff --git a/_player/states/climb.gd.uid b/_player/states/climb.gd.uid new file mode 100644 index 0000000..0905f1f --- /dev/null +++ b/_player/states/climb.gd.uid @@ -0,0 +1 @@ +uid://bjjatv4bxv7w diff --git a/_player/states/climb_hop.gd b/_player/states/climb_hop.gd new file mode 100644 index 0000000..7900f89 --- /dev/null +++ b/_player/states/climb_hop.gd @@ -0,0 +1,4 @@ +extends LimboState + +func _enter() -> void: + agent.locomotion_comp.climb_hop() diff --git a/_player/states/climb_hop.gd.uid b/_player/states/climb_hop.gd.uid new file mode 100644 index 0000000..2c98564 --- /dev/null +++ b/_player/states/climb_hop.gd.uid @@ -0,0 +1 @@ +uid://dpg7wsht1mg8d diff --git a/_player/states/climb_jump.gd b/_player/states/climb_jump.gd new file mode 100644 index 0000000..4417b4b --- /dev/null +++ b/_player/states/climb_jump.gd @@ -0,0 +1,18 @@ +extends LimboState + +func _setup() -> void: + self.add_event_handler(&"completed_jump",_handler_completed_jump) + +func _enter() -> void: + agent.locomotion_comp.start_climb_jump() + +func _update(delta: float) -> void: + if agent.velocity.y >= 0: + get_root().dispatch(self.EVENT_FINISHED) + +func _exit() -> void: + agent.locomotion_comp.stop_climb_jump() + +func _handler_completed_jump() -> bool: + get_root().dispatch(self.EVENT_FINISHED) + return true diff --git a/_player/states/climb_jump.gd.uid b/_player/states/climb_jump.gd.uid new file mode 100644 index 0000000..450aaf1 --- /dev/null +++ b/_player/states/climb_jump.gd.uid @@ -0,0 +1 @@ +uid://cpruvcwcgmdrx diff --git a/_player/states/dead.gd b/_player/states/dead.gd new file mode 100644 index 0000000..474b1ed --- /dev/null +++ b/_player/states/dead.gd @@ -0,0 +1,8 @@ +extends LimboState + +func _enter() -> void: + agent.is_dead = true + + await get_tree().create_timer(.5).timeout + + agent.queue_free() diff --git a/_player/states/dead.gd.uid b/_player/states/dead.gd.uid new file mode 100644 index 0000000..a4c4499 --- /dev/null +++ b/_player/states/dead.gd.uid @@ -0,0 +1 @@ +uid://ca88urm45gx2c diff --git a/_player/states/fall.gd b/_player/states/fall.gd new file mode 100644 index 0000000..2317c0d --- /dev/null +++ b/_player/states/fall.gd @@ -0,0 +1,29 @@ +extends LimboState + +##土狼跳缓存时间 +@export var jump_grace_time: float = .14 + +var jump_grace_timer: float + +func _setup() -> void: + self.add_event_handler(&"trigger_jump",_handler_trigger_jump) + +func _enter() -> void: + jump_grace_timer = jump_grace_time + +func _update(delta: float) -> void: + if jump_grace_timer > 0: + jump_grace_timer -= delta + + var move_direction = Input.get_axis(&"move_left",&"move_right") as float + agent.locomotion_comp.add_movement_input(move_direction) + if move_direction == 0.0: + get_root().dispatch(self.EVENT_FINISHED) + return + +func _handler_trigger_jump() -> bool: + if not get_root().blackboard.get_var(&"is_jumping",false): + if jump_grace_timer > 0: + get_root().dispatch(&"air_to_jump") + + return false diff --git a/_player/states/fall.gd.uid b/_player/states/fall.gd.uid new file mode 100644 index 0000000..1af0017 --- /dev/null +++ b/_player/states/fall.gd.uid @@ -0,0 +1 @@ +uid://db6ttwe3skqfv diff --git a/_player/states/ghost.gd b/_player/states/ghost.gd new file mode 100644 index 0000000..67a2724 --- /dev/null +++ b/_player/states/ghost.gd @@ -0,0 +1,48 @@ +''' Dash的生命周期 + 1. +''' +extends LimboState + +const DASH_FREEZE_TIME: float = .05 +@export var dash_time: float = .15 +var _dash_timer: float + +func _enter() -> void: + get_root().blackboard.set_var(&"is_dashing",true) ##BB里锁住Dash状态 + + #禁用原本Locomotion Component的更新 + agent.locomotion_comp.stop_movement() + agent.locomotion_comp.suspend_movement() + + var dash_start_on_ground: bool = agent.is_on_floor() + + agent.locomotion_comp.integrate_dash(_get_dash_direction()) + _dash_timer = dash_time + +func _exit() -> void: + blackboard.set_var(&"is_dashing",false) ##BB里清除Dash状态 + agent.locomotion_comp.enable_movement() + + agent.locomotion_comp.can_dash = false + +func _update(delta: float) -> void: + if _dash_timer > 0: + _dash_timer -= delta + return + + if agent.is_on_floor(): + self.dispatch(&"exit_on_ground") + else: + self.dispatch(&"exit_on_air") + return + +func _get_dash_direction() -> Vector2: + var r : Vector2 + r = Vector2(1,0) if agent.direction == Player.Direction.RIGHT else Vector2(-1,0) + + var dash_direction_x = Input.get_axis(&"move_left",&"move_right") as float + var dash_direction_y = Input.get_axis(&"move_up",&"move_down") as float + if dash_direction_x != 0 or dash_direction_y != 0: + r = Vector2(dash_direction_x,dash_direction_y) + + return r diff --git a/_player/states/ghost.gd.uid b/_player/states/ghost.gd.uid new file mode 100644 index 0000000..5a511a2 --- /dev/null +++ b/_player/states/ghost.gd.uid @@ -0,0 +1 @@ +uid://cky34pinqpewd diff --git a/_player/states/grap_hook.gd b/_player/states/grap_hook.gd new file mode 100644 index 0000000..d667ba2 --- /dev/null +++ b/_player/states/grap_hook.gd @@ -0,0 +1,10 @@ +extends LimboHSM + +@onready var root: Normal = %Normal + +func _setup() -> void: + self.add_transition(root.hook_shooting_state,root.hooking_state,root.hook_shooting_state.EVENT_FINISHED) + +func _exit() -> void: + agent.locomotion_comp.enable_movement() + agent.spawn_hook_comp._current_grap_hook_inst._leave_rope() diff --git a/_player/states/grap_hook.gd.uid b/_player/states/grap_hook.gd.uid new file mode 100644 index 0000000..21176fa --- /dev/null +++ b/_player/states/grap_hook.gd.uid @@ -0,0 +1 @@ +uid://d0mw2e4u5u8g diff --git a/_player/states/grounded.gd b/_player/states/grounded.gd new file mode 100644 index 0000000..e4a8bfb --- /dev/null +++ b/_player/states/grounded.gd @@ -0,0 +1,36 @@ +extends LimboHSM + +@onready var root: Normal = %Normal + +func _setup() -> void: + self.add_transition(root.idle_state,root.move_state,root.idle_state.EVENT_FINISHED) + self.add_transition(root.move_state,root.idle_state,root.move_state.EVENT_FINISHED) + + self.add_event_handler(&"trigger_jump",_handler_trigger_jump) + +func _enter() -> void: + _land_from_air_check() + + get_root().blackboard.set_var(&"is_jumping",false) + agent.locomotion_comp.full_recover_dash_count() + +func _update(delta: float) -> void: + if not agent.is_on_floor() : + dispatch(self.EVENT_FINISHED) + +func _handler_trigger_jump() -> bool: + self.blackboard.set_var(&"want_to_jump",true) + self.dispatch(self.EVENT_FINISHED) + return true + +##无法在jump state 的时候进入grounded state +func _can_enter_grounded() -> bool: + return not get_active_state() == root.jump_state + +func _land_from_air_check() -> bool: + var last_state = root.get_previous_active_state() as LimboState + if last_state and last_state == root.airbone_state : + agent.on_land_dust() + return true + + return false diff --git a/_player/states/grounded.gd.uid b/_player/states/grounded.gd.uid new file mode 100644 index 0000000..2e927d7 --- /dev/null +++ b/_player/states/grounded.gd.uid @@ -0,0 +1 @@ +uid://15n8yfyr4eqj diff --git a/_player/states/hook_shooting.gd b/_player/states/hook_shooting.gd new file mode 100644 index 0000000..a9c2e65 --- /dev/null +++ b/_player/states/hook_shooting.gd @@ -0,0 +1,25 @@ +extends LimboState + +@export var grap_hook_shooting_time: float + +var _timer: float + +func _enter() -> void: + agent.locomotion_comp.suspend_movement() + agent.locomotion_comp.stop_dash(true) + + agent.spawn_hook_comp.spawn_grap_hook_inst() + agent.spawn_hook_comp.grap_reach_target(grap_hook_shooting_time) + + _timer = grap_hook_shooting_time + +func _update(delta: float) -> void: + + if _timer <= 0: + self.dispatch(self.EVENT_FINISHED) + + _timer -= delta + +func _exit() -> void: + #agent.locomotion_comp.enable_movement() + pass diff --git a/_player/states/hook_shooting.gd.uid b/_player/states/hook_shooting.gd.uid new file mode 100644 index 0000000..8672496 --- /dev/null +++ b/_player/states/hook_shooting.gd.uid @@ -0,0 +1 @@ +uid://diq7vk63exae7 diff --git a/_player/states/idle.gd b/_player/states/idle.gd new file mode 100644 index 0000000..c757974 --- /dev/null +++ b/_player/states/idle.gd @@ -0,0 +1,8 @@ +extends LimboState + +func _enter() -> void: + return + +func _update(delta: float) -> void: + if Input.get_axis(&"move_left",&"move_right") != 0.0: + get_root().dispatch(self.EVENT_FINISHED) diff --git a/_player/states/idle.gd.uid b/_player/states/idle.gd.uid new file mode 100644 index 0000000..86fbfc7 --- /dev/null +++ b/_player/states/idle.gd.uid @@ -0,0 +1 @@ +uid://b5hkfpjbye70 diff --git a/_player/states/jump.gd b/_player/states/jump.gd new file mode 100644 index 0000000..396fb6a --- /dev/null +++ b/_player/states/jump.gd @@ -0,0 +1,36 @@ +extends LimboState + +@onready var root: Normal = %Normal + +func _setup() -> void: + self.add_event_handler(&"completed_jump",_handler_completed_jump) + +func _enter() -> void: + _jump_from_land_check() + + var _j = agent.locomotion_comp.jump() as bool + get_root().blackboard.set_var(&"is_jumping",true) #标记jump + +func _exit() -> void: + #这里强制重置一下 + agent.locomotion_comp.stop_jump() + + +func _update(delta: float) -> void: + var move_dir = Input.get_axis(&"move_left",&"move_right") + agent.locomotion_comp.add_movement_input(move_dir) + + if agent.velocity.y >= 0: + get_root().dispatch(self.EVENT_FINISHED) + +func _handler_completed_jump() -> bool: + agent.locomotion_comp.stop_jump() + return true + +func _jump_from_land_check() -> bool: + var last_state = root.get_previous_active_state() as LimboState + if last_state and last_state == root.ground_state : + agent.on_jump() + return true + + return false diff --git a/_player/states/jump.gd.uid b/_player/states/jump.gd.uid new file mode 100644 index 0000000..7f65e6b --- /dev/null +++ b/_player/states/jump.gd.uid @@ -0,0 +1 @@ +uid://dh3115a8iyabg diff --git a/_player/states/move.gd b/_player/states/move.gd new file mode 100644 index 0000000..e2a1923 --- /dev/null +++ b/_player/states/move.gd @@ -0,0 +1,63 @@ +extends LimboState + +@export var run_dust_distance:= 50 + +var _accelerated_distance: float +var _is_first_update: bool +var _last_frame_position: Vector2 + +var _run_dust_counter: float + +func _enter() -> void: + _reset_distance() + _reset_run_dust_counter() + _is_first_update = true + return + +func _exit() -> void: + _reset_distance() + +func _update(delta: float) -> void: + _handle_move_input() + + ## 更新並獲取到delta ditance + var delta_distance = _update_accelerated_distance() as float + + print(delta_distance) + + ## 如果移動了一定的距離,則播放dust特效 + _run_dust_counter -= delta_distance + if _run_dust_counter < 0: + agent.on_run_dust() + _reset_run_dust_counter() + +func _handle_move_input() -> void: + var move_direction = Input.get_axis(&"move_left",&"move_right") as float + if move_direction == 0.0: + get_root().dispatch(self.EVENT_FINISHED) + agent.locomotion_comp.add_movement_input(0.0) #用0唤起制动加速度 + return + agent.locomotion_comp.add_movement_input(move_direction) + +##更新距離,返回的是Delta Distance +func _update_accelerated_distance() -> float: + var c = agent.global_position as Vector2 + + if _is_first_update: + _last_frame_position = c + _accelerated_distance = 0 + _is_first_update = false + return _accelerated_distance + + var _delta = c.distance_to(_last_frame_position) as float + _last_frame_position = c + _accelerated_distance += _delta + + return _delta + +func _reset_distance() -> void: + _accelerated_distance = 0 + _last_frame_position = Vector2.ZERO + +func _reset_run_dust_counter() -> void: + _run_dust_counter = run_dust_distance diff --git a/_player/states/move.gd.uid b/_player/states/move.gd.uid new file mode 100644 index 0000000..ae0a4be --- /dev/null +++ b/_player/states/move.gd.uid @@ -0,0 +1 @@ +uid://po21boe8iqcc diff --git a/_player/states/on_wall.gd b/_player/states/on_wall.gd new file mode 100644 index 0000000..3ccd2db --- /dev/null +++ b/_player/states/on_wall.gd @@ -0,0 +1,34 @@ +extends LimboHSM + +@onready var root: Normal = %Normal + +func _setup() -> void: + self.add_event_handler(&"trigger_jump",_handler_trigger_jump) + self.add_event_handler(root.climb_state.EVENT_FINISHED,_handler_climb_state_finished) + self.add_event_handler(root.climb_jump_state.EVENT_FINISHED,_handler_climb_state_finished) + + self.add_transition(root.climb_state,root.climb_jump_state,&"want_to_climb_jump") + +func _enter() -> void: + if agent.is_on_wall():##如果已经在Wall上,则什么都不做 + return + + var compensaton_velocity = Player.get_direction_vector(agent.direction) * 1000 + agent.velocity = compensaton_velocity + agent.move_and_slide() + +func _handler_climb_state_finished() -> bool: + if agent.is_on_floor(): + self.dispatch(&"exit_on_ground") + else: + self.dispatch(&"exit_on_air") + + return true + +func _handler_trigger_jump() -> bool: + if self.get_active_state() == root.climb_state: + self.dispatch(&"want_to_climb_jump") + return true + +func _handler_climb_jump_state_finished() -> bool: + return true diff --git a/_player/states/on_wall.gd.uid b/_player/states/on_wall.gd.uid new file mode 100644 index 0000000..64b4aa6 --- /dev/null +++ b/_player/states/on_wall.gd.uid @@ -0,0 +1 @@ +uid://fpfkas0s46xq diff --git a/_player/states/player_hsm.gd b/_player/states/player_hsm.gd new file mode 100644 index 0000000..d130cf0 --- /dev/null +++ b/_player/states/player_hsm.gd @@ -0,0 +1,16 @@ +extends LimboHSM + +@onready var normal_state: LimboHSM = %Normal +@onready var dead_state: LimboState = %Dead + +func _setup() -> void: + _init_trans() + +func _ready() -> void: + await owner.ready + + self.initialize(self.owner) + self.set_active(true) + +func _init_trans() -> void: + self.add_transition(normal_state,dead_state,&"try_enter_dead") diff --git a/_player/states/player_hsm.gd.uid b/_player/states/player_hsm.gd.uid new file mode 100644 index 0000000..e648dd1 --- /dev/null +++ b/_player/states/player_hsm.gd.uid @@ -0,0 +1 @@ +uid://bpd54nf8oxwsb diff --git a/_player/states/wall_jump.gd b/_player/states/wall_jump.gd new file mode 100644 index 0000000..7bcf2e5 --- /dev/null +++ b/_player/states/wall_jump.gd @@ -0,0 +1,39 @@ +extends LimboState + +@export var wall_jump_force_time: float = .24 +var wall_jump_force_timer: float + +func _setup() -> void: + self.add_event_handler(&"completed_jump",_handler_completed_jump) + +func _enter() -> void: + agent.locomotion_comp.wall_jump() + wall_jump_force_timer = wall_jump_force_time + + get_root().blackboard.set_var(&"lock_direction_changed",true) + +func _exit() -> void: + #这里强制重置一下 + agent.locomotion_comp.stop_jump() + get_root().blackboard.set_var(&"lock_direction_changed",false) + +func _update(delta: float) -> void: + if agent.velocity.y >= 0: + get_root().dispatch(self.EVENT_FINISHED) + + + var move_dir : float + move_dir = Input.get_axis(&"move_left",&"move_right") + + #这里执行一个额外的忽略输入的逻辑,在墙跳的开始阶段,玩家如果存在移动输入,则会被强制归为沿墙壁法向的输入 + if wall_jump_force_timer > 0: + wall_jump_force_timer -= delta + #这里的行为是,如果当前存在输入,则不管是什么方向的,都归为法向,否则就是0 + move_dir = agent.get_wall_normal().x if Input.get_axis(&"move_left",&"move_right") != 0 else 0 + + agent.locomotion_comp.add_movement_input(move_dir) + + +func _handler_completed_jump() -> bool: + agent.locomotion_comp.stop_jump() + return true diff --git a/_player/states/wall_jump.gd.uid b/_player/states/wall_jump.gd.uid new file mode 100644 index 0000000..ae7bb96 --- /dev/null +++ b/_player/states/wall_jump.gd.uid @@ -0,0 +1 @@ +uid://dhlg4ct8al76c diff --git a/_sfx/player/jump.tres b/_sfx/player/jump.tres new file mode 100644 index 0000000..c311233 --- /dev/null +++ b/_sfx/player/jump.tres @@ -0,0 +1,8 @@ +[gd_resource type="AudioStreamRandomizer" load_steps=2 format=3 uid="uid://b4moh3s41xi44"] + +[ext_resource type="AudioStream" uid="uid://bbdeag44ynd4" path="res://_asset/sound/jump/ai_jump_dirt.wav" id="1_53qno"] + +[resource] +playback_mode = 1 +streams_count = 1 +stream_0/stream = ExtResource("1_53qno") diff --git a/_shared/CameraSystem.tscn b/_shared/CameraSystem.tscn new file mode 100644 index 0000000..5329af7 --- /dev/null +++ b/_shared/CameraSystem.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=3 format=3 uid="uid://b8pv5wtbo0y20"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_tvldw"] +[ext_resource type="Script" uid="uid://lpenhftmjj4o" path="res://_shared/camera_system.gd" id="1_vo3bs"] + +[node name="CameraSystem" type="Node"] +script = ExtResource("1_vo3bs") + +[node name="Camera2D" type="Camera2D" parent="."] + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_tvldw") +metadata/_custom_type_script = "uid://bd046eokvcnu2" diff --git a/_shared/camera_room.gd b/_shared/camera_room.gd new file mode 100644 index 0000000..e118797 --- /dev/null +++ b/_shared/camera_room.gd @@ -0,0 +1,33 @@ +class_name CameraRoom extends Node2D + +@onready var phantom_camera2d: PhantomCamera2D = $PhantomCamera2D +@onready var default_start_point: Node2D = $PlayerStartPoint + +@export var _room_id : int = -1 + +func _ready() -> void: + #room_entrance.body_entered.connect(_handle_body_enter_room) + RoomSystem.room_changed.connect(_handle_global_room_changed) + + ##绑定一个Room下面的room entrance到进入这个房间 + for r in self.get_children(): + if r is RoomEntrance: + r.body_entered.connect(_handle_body_enter_room) + r.init_room_entrance(self) + +func _handle_body_enter_room(body: Node2D) -> void: + if RoomSystem.current_room_id == self._room_id: + return + if body != null: + RoomSystem.update_current_room_id(self._room_id) + return + +func _handle_global_room_changed(room_id: int) -> void: + if room_id == self._room_id: + _update_room_to_self() + +func reset_priority() -> void: + phantom_camera2d.priority = 0 + +func _update_room_to_self() -> void: + phantom_camera2d.priority = 99 diff --git a/_shared/camera_room.gd.uid b/_shared/camera_room.gd.uid new file mode 100644 index 0000000..9b01b3b --- /dev/null +++ b/_shared/camera_room.gd.uid @@ -0,0 +1 @@ +uid://c7fditim2t1c1 diff --git a/_shared/camera_system.gd b/_shared/camera_system.gd new file mode 100644 index 0000000..8f26ddc --- /dev/null +++ b/_shared/camera_system.gd @@ -0,0 +1,11 @@ +'''全局的相机管理器 + + ======= 外部调用函数 ======= + force_change_camera(camera : ReedCamera) 切换相机 + + func camera_room_enterd(camear : ReedCamera) Camera Room 进入时手动调用 + func camera_room_exited(camera_room : ReedCameraRoom) Camera Room 离开时手动调用 + +''' + +extends Node diff --git a/_shared/camera_system.gd.uid b/_shared/camera_system.gd.uid new file mode 100644 index 0000000..34e143e --- /dev/null +++ b/_shared/camera_system.gd.uid @@ -0,0 +1 @@ +uid://lpenhftmjj4o diff --git a/_shared/global_event.gd b/_shared/global_event.gd new file mode 100644 index 0000000..3841eb7 --- /dev/null +++ b/_shared/global_event.gd @@ -0,0 +1,6 @@ +extends Node + +signal player_dead + +func boradcast_player_dead_event() -> void: + player_dead.emit() diff --git a/_shared/global_event.gd.uid b/_shared/global_event.gd.uid new file mode 100644 index 0000000..55f986c --- /dev/null +++ b/_shared/global_event.gd.uid @@ -0,0 +1 @@ +uid://ch4y284a78f6m diff --git a/_shared/room.tscn b/_shared/room.tscn new file mode 100644 index 0000000..26f8a34 --- /dev/null +++ b/_shared/room.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=5 format=3 uid="uid://byf5lgbkjk52y"] + +[ext_resource type="Script" uid="uid://c7fditim2t1c1" path="res://_shared/camera_room.gd" id="1_yrcw7"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="2_bdhnx"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_p25y8"] + +[sub_resource type="Resource" id="Resource_y58mf"] +script = ExtResource("3_p25y8") + +[node name="Room" type="Node2D" groups=["ROOM"]] +script = ExtResource("1_yrcw7") +_room_id = 10001 + +[node name="PhantomCamera2D" type="Node2D" parent="."] +script = ExtResource("2_bdhnx") +zoom = Vector2(0.8, 0.8) +tween_resource = SubResource("Resource_y58mf") +tween_on_load = false +metadata/_custom_type_script = "uid://bhexx6mj1xv3q" + +[node name="PlayerStartPoint" type="Marker2D" parent="."] diff --git a/_shared/room_entrance.gd b/_shared/room_entrance.gd new file mode 100644 index 0000000..f29b1a3 --- /dev/null +++ b/_shared/room_entrance.gd @@ -0,0 +1,9 @@ +@tool +class_name RoomEntrance extends Area2D + +@export var restart_node: Node2D + +##如果没有手动绑定Start节点,则自动绑定到Room的default +func init_room_entrance(room: CameraRoom) -> void: + if restart_node == null: + restart_node = room.default_start_point diff --git a/_shared/room_entrance.gd.uid b/_shared/room_entrance.gd.uid new file mode 100644 index 0000000..b8c4a78 --- /dev/null +++ b/_shared/room_entrance.gd.uid @@ -0,0 +1 @@ +uid://ir0fur783tru diff --git a/_shared/room_entrance.tscn b/_shared/room_entrance.tscn new file mode 100644 index 0000000..6eda79e --- /dev/null +++ b/_shared/room_entrance.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://d1mnkm2uv857q"] + +[ext_resource type="Script" uid="uid://ir0fur783tru" path="res://_shared/room_entrance.gd" id="1_nlirq"] + +[node name="RoomEntrance" type="Area2D"] +script = ExtResource("1_nlirq") diff --git a/_shared/room_system.gd b/_shared/room_system.gd new file mode 100644 index 0000000..6260c95 --- /dev/null +++ b/_shared/room_system.gd @@ -0,0 +1,35 @@ +extends Node + +var current_room_id: int = 0 + +var defalut_room_id: int = 10001 +signal room_changed(room_id: int) + +func _ready() -> void: + init_room() + +##更新房间id +func update_current_room_id(room_id: int) -> bool: + if room_id == current_room_id: + return false + + reset_all_room_camera_property() + current_room_id = room_id + room_changed.emit(room_id) + return true + +##重置所有房间的room property +func reset_all_room_camera_property() -> void: + get_tree().call_group(&"ROOM",&"reset_priority") + +##初始化相机房间 +func init_room() -> void: + for r in get_tree().get_nodes_in_group(&"ROOM"): + if r._room_id == defalut_room_id: + if r.is_node_ready(): + update_current_room_id(defalut_room_id) + break + else: + await r.ready + update_current_room_id(defalut_room_id) + break diff --git a/_shared/room_system.gd.uid b/_shared/room_system.gd.uid new file mode 100644 index 0000000..e8575e2 --- /dev/null +++ b/_shared/room_system.gd.uid @@ -0,0 +1 @@ +uid://bnl485emckxmh diff --git a/_tileset/test.tres b/_tileset/test.tres new file mode 100644 index 0000000..738f8bc --- /dev/null +++ b/_tileset/test.tres @@ -0,0 +1,21 @@ +[gd_resource type="TileSet" load_steps=3 format=3 uid="uid://doepkfp83k0lb"] + +[ext_resource type="Texture2D" uid="uid://doxhsab56pe50" path="res://_asset/all.png" id="1_26tvm"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_s5wqu"] +texture = ExtResource("1_26tvm") +0:0/0 = 0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +1:0/0 = 0 +1:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(-3.7656374, -0.297287, 0.19819069, 8, 4.0629234, -0.099095345, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +0:2/0 = 0 +1:2/0 = 0 + +[resource] +physics_layer_0/collision_layer = 4 +physics_layer_0/collision_mask = 0 +physics_layer_1/collision_layer = 8 +physics_layer_1/collision_mask = 0 +sources/0 = SubResource("TileSetAtlasSource_s5wqu") diff --git a/_tools/limbo_state_helper.gd b/_tools/limbo_state_helper.gd new file mode 100644 index 0000000..e6a34ce --- /dev/null +++ b/_tools/limbo_state_helper.gd @@ -0,0 +1,26 @@ +extends Node2D + +@export var state_root : LimboHSM +@export var draw_offset : Vector2 +@export var font : Font = ThemeDB.fallback_font + +func _draw() -> void: + if state_root: + draw_string(font,draw_offset,_get_deepest_substate(state_root).name) + +func _process(delta: float) -> void: + queue_redraw() + +func _get_deepest_substate(state : LimboState) -> LimboState: + var active_substate : LimboState = null + + # 如果这个状态有 get_active_state() 方法,就调用 + if state.has_method("get_active_state"): + active_substate = state.get_active_state() + + # 如果没有子状态,返回自己 + if active_substate == null: + return state + + # 如果有子状态,继续递归 + return _get_deepest_substate(active_substate) diff --git a/_tools/limbo_state_helper.gd.uid b/_tools/limbo_state_helper.gd.uid new file mode 100644 index 0000000..9991368 --- /dev/null +++ b/_tools/limbo_state_helper.gd.uid @@ -0,0 +1 @@ +uid://cjf7kds0cipkw diff --git a/_vfx/dust/jump_dust.tscn b/_vfx/dust/jump_dust.tscn new file mode 100644 index 0000000..eac7e80 --- /dev/null +++ b/_vfx/dust/jump_dust.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=3 format=3 uid="uid://yjdrytj3x71v"] + +[ext_resource type="Script" uid="uid://cpuc3qq7pd7lk" path="res://addons/reedfx/vfx/CPUVFXTemplate.gd" id="1_4t5ie"] + +[sub_resource type="Curve" id="Curve_wpir5"] +_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), -3.764854, 0.0, 0, 0] +point_count = 2 + +[node name="LandDust" type="CPUParticles2D"] +z_index = 1 +lifetime = 0.5 +explosiveness = 0.9 +emission_shape = 3 +emission_rect_extents = Vector2(2, 1) +direction = Vector2(0, -1) +spread = 75.0 +gravity = Vector2(0, 5) +initial_velocity_max = 16.0 +damping_min = 21.6 +damping_max = 22.6 +scale_amount_min = 3.0 +scale_amount_max = 6.0 +scale_amount_curve = SubResource("Curve_wpir5") +script = ExtResource("1_4t5ie") +metadata/_custom_type_script = "uid://cpuc3qq7pd7lk" diff --git a/_vfx/dust/land_dust.tscn b/_vfx/dust/land_dust.tscn new file mode 100644 index 0000000..125cacb --- /dev/null +++ b/_vfx/dust/land_dust.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=3 format=3 uid="uid://bs14s8ox4tk0i"] + +[ext_resource type="Script" uid="uid://cpuc3qq7pd7lk" path="res://addons/reedfx/vfx/CPUVFXTemplate.gd" id="1_c1nxr"] + +[sub_resource type="Curve" id="Curve_wpir5"] +_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), -3.764854, 0.0, 0, 0] +point_count = 2 + +[node name="LandDust" type="CPUParticles2D"] +z_index = 1 +lifetime = 0.5 +explosiveness = 0.9 +emission_shape = 3 +emission_rect_extents = Vector2(2, 1) +direction = Vector2(0, -1) +spread = 75.0 +gravity = Vector2(0, 5) +initial_velocity_max = 16.0 +damping_min = 21.6 +damping_max = 22.6 +scale_amount_min = 3.0 +scale_amount_max = 6.0 +scale_amount_curve = SubResource("Curve_wpir5") +script = ExtResource("1_c1nxr") +metadata/_custom_type_script = "uid://cpuc3qq7pd7lk" diff --git a/_vfx/dust/run_dust.tscn b/_vfx/dust/run_dust.tscn new file mode 100644 index 0000000..b710fc0 --- /dev/null +++ b/_vfx/dust/run_dust.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=3 format=3 uid="uid://lrf3gwgkmh06"] + +[ext_resource type="Script" uid="uid://cpuc3qq7pd7lk" path="res://addons/reedfx/vfx/CPUVFXTemplate.gd" id="1_jcsrh"] + +[sub_resource type="Curve" id="Curve_wpir5"] +_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), -3.764854, 0.0, 0, 0] +point_count = 2 + +[node name="LandDust" type="CPUParticles2D"] +z_index = 1 +lifetime = 0.5 +explosiveness = 0.9 +emission_shape = 3 +emission_rect_extents = Vector2(2, 1) +direction = Vector2(0, -1) +spread = 75.0 +gravity = Vector2(0, 5) +initial_velocity_max = 16.0 +damping_min = 21.6 +damping_max = 22.6 +scale_amount_min = 3.0 +scale_amount_max = 6.0 +scale_amount_curve = SubResource("Curve_wpir5") +script = ExtResource("1_jcsrh") +metadata/_custom_type_script = "uid://cpuc3qq7pd7lk" diff --git a/addons/limboai/LICENSE.md b/addons/limboai/LICENSE.md new file mode 100644 index 0000000..07c690f --- /dev/null +++ b/addons/limboai/LICENSE.md @@ -0,0 +1,7 @@ +Copyright (c) 2023-2025 Serhii Snitsaruk and the LimboAI contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/addons/limboai/LOGO_LICENSE.md b/addons/limboai/LOGO_LICENSE.md new file mode 100644 index 0000000..cd0de07 --- /dev/null +++ b/addons/limboai/LOGO_LICENSE.md @@ -0,0 +1,5 @@ +LimboAI Logo +Copyright (c) 2023 Aleksandra Snitsaruk + +This work is licensed under the Creative Commons Attribution 4.0 International +license (CC BY 4.0 International): https://creativecommons.org/licenses/by/4.0/ \ No newline at end of file diff --git a/addons/limboai/README.md b/addons/limboai/README.md new file mode 100644 index 0000000..a90ceae --- /dev/null +++ b/addons/limboai/README.md @@ -0,0 +1,155 @@ +

+ LimboAI logo +

+ +# LimboAI - Behavior Trees & State Machines for Godot 4 + + +[![🔎 Unit Tests](https://github.com/limbonaut/limboai/actions/workflows/test_builds.yml/badge.svg)](https://github.com/limbonaut/limboai/actions/workflows/test_builds.yml) +[![Documentation Status](https://readthedocs.org/projects/limboai/badge/?version=latest)](https://limboai.readthedocs.io/en/latest/?badge=latest) +[![GitHub License](https://img.shields.io/github/license/limbonaut/limboai)](https://github.com/limbonaut/limboai/blob/master/LICENSE.md) +[![Discord](https://img.shields.io/discord/1185664967379267774?logo=discord&link=https%3A%2F%2Fdiscord.gg%2FN5MGC95GpP)](https://discord.gg/N5MGC95GpP) +[![Mastodon Follow](https://img.shields.io/mastodon/follow/109346796150895359?domain=https%3A%2F%2Fmastodon.gamedev.place)](https://mastodon.gamedev.place/@limbo) + +>**Supported Godot Engine:** **4.4 - 4.5** +> *(see below for older versions)* + + +**LimboAI** is an open-source C++ plugin for **Godot Engine 4** providing a combination of +**Behavior Trees** and **State Machines**, which can be used together to create complex AI behaviors. +It comes with a behavior tree editor, built-in documentation, visual debugger, extensive demo project with a tutorial, and more! +While it is implemented in C++, it fully supports GDScript for [creating your own tasks](https://limboai.readthedocs.io/en/stable/behavior-trees/custom-tasks.html) and [states](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html). + +If you enjoy using LimboAI, please **consider supporting** my efforts with a donation on Ko-fi 😊 Your contribution will help me continue developing and improving it. + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/Y8Y2TCNH0) + +![Textured screenshot](doc/images/behavior-tree-editor-debugger.png) + +Behavior Trees are powerful hierarchical structures used to model and control the behavior of agents in a game (e.g., characters, enemies). They are designed to make it easier to create rich and highly modular behaviors for your games. To learn more about behavior trees, check out [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/stable/behavior-trees/introduction.html) and our demo project, which includes a tutorial. + +## Demonstration + +![Charger from Demo](doc/images/demo_charger.gif) + +> [!NOTE] +> **Demo project** lives in the `demo` folder, and is available separately in [**Releases**](https://github.com/limbonaut/limboai/releases). +> Run `demo/scenes/showcase.tscn` to get started. +> It also includes a tutorial that introduces behavior trees through illustrative examples. + +### Videos + +> YouTube videos produced by various creators + + + + + + + + +## Supported Godot versions + +| Plugin Version | GDExtension/AssetLib | Module | +|--------------------------|------------------------|-----------| +| `1.5.x` releases | Godot 4.4 or later | Godot 4.5 | +| `1.4.x` releases | Godot 4.4 or later | Godot 4.4 | +| `1.2.0`-`1.3.x` releases | Godot 4.3 or later | Godot 4.3 | +| `1.1.x` releases | Godot 4.2 or later | Godot 4.2 | + +## Features + +- **Behavior Trees (BT):** + - Easily create, edit, and save `BehaviorTree` resources in the editor. + - Execute `BehaviorTree` resources using the `BTPlayer` node. + - Create complex behaviors by combining and nesting tasks in a hierarchy. + - Control execution flow using composite, decorator, and condition tasks. + - [Create custom tasks](https://limboai.readthedocs.io/en/stable/behavior-trees/custom-tasks.html) by extending core classes: `BTAction`, `BTCondition`, `BTDecorator`, and `BTComposite`. + - Built-in class documentation. + - Blackboard system: Share data seamlessly between tasks using the `Blackboard`. + - Blackboard plans: Define variables in the BehaviorTree resource and override their values in the BTPlayer node. + - Plan editor: Manage variables, their data types and property hints. + - Blackboard scopes: Prevent name conflicts and enable advanced techniques like [sharing data between several agents](https://limboai.readthedocs.io/en/stable/behavior-trees/using-blackboard.html#sharing-data-between-several-agents). + - Blackboard parameters: [Export a BB parameter](https://limboai.readthedocs.io/en/stable/behavior-trees/using-blackboard.html#task-parameters), for which user can provide a value or bind it to a blackboard variable (can be used in custom tasks). + - Inspector support for specifying blackboard variables (custom editor for exported `StringName` properties ending with "_var"). + - Use the `BTSubtree` task to execute a tree from a different resource file, promoting organization and reusability. + - Visual Debugger: Inspect the execution of any BT in a running scene to identify and troubleshoot issues. + - Visualize BT in-game using `BehaviorTreeView` node (for custom in-game tools). + - Monitor tree performance with custom performance monitors. + +- **Hierarchical State Machines (HSM):** + - Extend the `LimboState` class to implement state logic. + - `LimboHSM` node serves as a state machine that manages `LimboState` instances and transitions. + - `LimboHSM` is a state itself and can be nested within other `LimboHSM` instances. + - [Event-based](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html#events-and-transitions): Transitions are associated with events and are triggered by the state machine when the relevant event is dispatched, allowing for better decoupling of transitions from state logic. + - Combine state machines with behavior trees using `BTState` for advanced reactive AI. + - Delegation Option: Using the vanilla `LimboState`, [delegate the implementation](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html#single-file-state-machine-setup) to your callback functions, making it perfect for rapid prototyping and game jams. + - Note: State machine setup and initialization require code; there is no GUI editor. + +- **Tested:** Behavior tree tasks and HSM are covered by unit tests. + +- **GDExtension:** LimboAI can be [used as extension](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html#get-gdextension-version). Custom engine builds are not necessary. + +- **Demo + Tutorial:** Check out our extensive demo project, which includes an introduction to behavior trees using examples. + +## First steps + +Follow the [Getting started](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html) guide to learn how to get started with LimboAI and the demo project. + +## Getting LimboAI + +LimboAI can be used as either a C++ module or as a GDExtension shared library. GDExtension version is more convenient to use but somewhat limited in features. Whichever you choose to use, your project will stay compatible with both and you can switch from one to the other any time. See [Using GDExtension](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html#get-gdextension-version). + +### Precompiled builds + +- For the most recent builds, navigate to **Actions** → [**All Builds**](https://github.com/limbonaut/limboai/actions/workflows/all_builds.yml), select a build from the list, and scroll down until you find the **Artifacts** section. +- For release builds, check [**Releases**](https://github.com/limbonaut/limboai/releases). + +### Compiling from source + +- Download the Godot Engine source code and put this module source into the `modules/limboai` directory. +- Consult the Godot Engine documentation for instructions on [how to build from source code](https://docs.godotengine.org/en/stable/engine_details/development/compiling/index.html). +- If you plan to export a game utilizing the LimboAI module, you'll also need to build export templates. +- To execute unit tests, compile the engine with `tests=yes` and run it with `--test --tc="*[LimboAI]*"`. + +#### For GDExtension + +- You'll need SCons build tool and a C++ compiler. See also [Compiling](https://docs.godotengine.org/en/stable/contributing/development/compiling/index.html). +- Run `scons target=editor` to build the plugin library for your current platform. + - SCons will automatically clone the godot-cpp/ repository if it doesn't already exist in the `limboai/godot-cpp` directory. + - By default, built targets are placed in the demo project: `demo/addons/limboai/bin/` +- Check `scons -h` for other options and targets. + +## Using the plugin + +- Online Documentation: [stable](https://limboai.readthedocs.io/en/stable/index.html), [latest](https://limboai.readthedocs.io/en/latest/index.html) +- [Getting started](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html) +- [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/stable/behavior-trees/introduction.html) +- [Creating custom tasks in GDScript](https://limboai.readthedocs.io/en/stable/behavior-trees/custom-tasks.html) +- [Sharing data using Blackboard](https://limboai.readthedocs.io/en/stable/behavior-trees/using-blackboard.html) +- [Accessing nodes in the scene tree](https://limboai.readthedocs.io/en/stable/behavior-trees/accessing-nodes.html) +- [State machines](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html) +- [Using GDExtension](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html#get-gdextension-version) +- [Using LimboAI with C#](https://limboai.readthedocs.io/en/stable/getting-started/c-sharp.html) +- [Class reference](https://limboai.readthedocs.io/en/stable/classes/featured-classes.html) + +## Contributing + +Contributions are welcome! Please open issues for bug reports, feature requests, or code changes. +For detailed guidelines on contributing to code or documentation, check out our [Contributing](https://limboai.readthedocs.io/en/latest/getting-started/contributing.html) page. + +If you have an idea for a behavior tree task or a feature that could be useful in a variety of projects, open an issue to discuss it. + +## Social + +Need help? We have a Discord server: https://discord.gg/N5MGC95GpP + +I write about LimboAI development on Mastodon: https://mastodon.gamedev.place/@limbo. + +## License + +Use of this source code is governed by an MIT-style license that can be found in the LICENSE file or at https://opensource.org/licenses/MIT + +LimboAI logo and demo project art assets are licensed under the Creative Commons Attribution 4.0 International license that can be found at https://creativecommons.org/licenses/by/4.0/ diff --git a/addons/limboai/bin/liblimboai.android.editor.arm32.so b/addons/limboai/bin/liblimboai.android.editor.arm32.so new file mode 100644 index 0000000..d277325 Binary files /dev/null and b/addons/limboai/bin/liblimboai.android.editor.arm32.so differ diff --git a/addons/limboai/bin/liblimboai.android.editor.arm64.so b/addons/limboai/bin/liblimboai.android.editor.arm64.so new file mode 100644 index 0000000..753819d Binary files /dev/null and b/addons/limboai/bin/liblimboai.android.editor.arm64.so differ diff --git a/addons/limboai/bin/liblimboai.android.editor.x86_32.so b/addons/limboai/bin/liblimboai.android.editor.x86_32.so new file mode 100644 index 0000000..68a637e Binary files /dev/null and b/addons/limboai/bin/liblimboai.android.editor.x86_32.so differ diff --git a/addons/limboai/bin/liblimboai.android.editor.x86_64.so b/addons/limboai/bin/liblimboai.android.editor.x86_64.so new file mode 100644 index 0000000..53c3023 Binary files /dev/null and b/addons/limboai/bin/liblimboai.android.editor.x86_64.so differ diff --git a/addons/limboai/bin/liblimboai.android.template_release.arm32.so b/addons/limboai/bin/liblimboai.android.template_release.arm32.so new file mode 100644 index 0000000..71c0d26 Binary files /dev/null and b/addons/limboai/bin/liblimboai.android.template_release.arm32.so differ diff --git a/addons/limboai/bin/liblimboai.android.template_release.arm64.so b/addons/limboai/bin/liblimboai.android.template_release.arm64.so new file mode 100644 index 0000000..f71e055 Binary files /dev/null and b/addons/limboai/bin/liblimboai.android.template_release.arm64.so differ diff --git a/addons/limboai/bin/liblimboai.android.template_release.x86_32.so b/addons/limboai/bin/liblimboai.android.template_release.x86_32.so new file mode 100644 index 0000000..ac006e7 Binary files /dev/null and b/addons/limboai/bin/liblimboai.android.template_release.x86_32.so differ diff --git a/addons/limboai/bin/liblimboai.android.template_release.x86_64.so b/addons/limboai/bin/liblimboai.android.template_release.x86_64.so new file mode 100644 index 0000000..788be0c Binary files /dev/null and b/addons/limboai/bin/liblimboai.android.template_release.x86_64.so differ diff --git a/addons/limboai/bin/liblimboai.ios.editor.arm64.dylib b/addons/limboai/bin/liblimboai.ios.editor.arm64.dylib new file mode 100644 index 0000000..f4c195c Binary files /dev/null and b/addons/limboai/bin/liblimboai.ios.editor.arm64.dylib differ diff --git a/addons/limboai/bin/liblimboai.ios.editor.universal.simulator.dylib b/addons/limboai/bin/liblimboai.ios.editor.universal.simulator.dylib new file mode 100644 index 0000000..c7858e3 Binary files /dev/null and b/addons/limboai/bin/liblimboai.ios.editor.universal.simulator.dylib differ diff --git a/addons/limboai/bin/liblimboai.ios.template_release.arm64.dylib b/addons/limboai/bin/liblimboai.ios.template_release.arm64.dylib new file mode 100644 index 0000000..f5cece9 Binary files /dev/null and b/addons/limboai/bin/liblimboai.ios.template_release.arm64.dylib differ diff --git a/addons/limboai/bin/liblimboai.ios.template_release.universal.simulator.dylib b/addons/limboai/bin/liblimboai.ios.template_release.universal.simulator.dylib new file mode 100644 index 0000000..178e675 Binary files /dev/null and b/addons/limboai/bin/liblimboai.ios.template_release.universal.simulator.dylib differ diff --git a/addons/limboai/bin/liblimboai.linux.editor.arm64.so b/addons/limboai/bin/liblimboai.linux.editor.arm64.so new file mode 100644 index 0000000..7a74457 Binary files /dev/null and b/addons/limboai/bin/liblimboai.linux.editor.arm64.so differ diff --git a/addons/limboai/bin/liblimboai.linux.editor.x86_64.so b/addons/limboai/bin/liblimboai.linux.editor.x86_64.so new file mode 100644 index 0000000..b9bbcd9 Binary files /dev/null and b/addons/limboai/bin/liblimboai.linux.editor.x86_64.so differ diff --git a/addons/limboai/bin/liblimboai.linux.template_release.arm64.so b/addons/limboai/bin/liblimboai.linux.template_release.arm64.so new file mode 100644 index 0000000..c6c9112 Binary files /dev/null and b/addons/limboai/bin/liblimboai.linux.template_release.arm64.so differ diff --git a/addons/limboai/bin/liblimboai.linux.template_release.x86_64.so b/addons/limboai/bin/liblimboai.linux.template_release.x86_64.so new file mode 100644 index 0000000..485d7e3 Binary files /dev/null and b/addons/limboai/bin/liblimboai.linux.template_release.x86_64.so differ diff --git a/addons/limboai/bin/liblimboai.macos.editor.framework/liblimboai.macos.editor b/addons/limboai/bin/liblimboai.macos.editor.framework/liblimboai.macos.editor new file mode 100644 index 0000000..c4b2480 Binary files /dev/null and b/addons/limboai/bin/liblimboai.macos.editor.framework/liblimboai.macos.editor differ diff --git a/addons/limboai/bin/liblimboai.macos.template_release.framework/liblimboai.macos.template_release b/addons/limboai/bin/liblimboai.macos.template_release.framework/liblimboai.macos.template_release new file mode 100644 index 0000000..8bdb14c Binary files /dev/null and b/addons/limboai/bin/liblimboai.macos.template_release.framework/liblimboai.macos.template_release differ diff --git a/addons/limboai/bin/liblimboai.web.editor.wasm32.nothreads.wasm b/addons/limboai/bin/liblimboai.web.editor.wasm32.nothreads.wasm new file mode 100644 index 0000000..5d07cf1 Binary files /dev/null and b/addons/limboai/bin/liblimboai.web.editor.wasm32.nothreads.wasm differ diff --git a/addons/limboai/bin/liblimboai.web.editor.wasm32.wasm b/addons/limboai/bin/liblimboai.web.editor.wasm32.wasm new file mode 100644 index 0000000..f236b42 Binary files /dev/null and b/addons/limboai/bin/liblimboai.web.editor.wasm32.wasm differ diff --git a/addons/limboai/bin/liblimboai.web.template_release.wasm32.nothreads.wasm b/addons/limboai/bin/liblimboai.web.template_release.wasm32.nothreads.wasm new file mode 100644 index 0000000..4ae4489 Binary files /dev/null and b/addons/limboai/bin/liblimboai.web.template_release.wasm32.nothreads.wasm differ diff --git a/addons/limboai/bin/liblimboai.web.template_release.wasm32.wasm b/addons/limboai/bin/liblimboai.web.template_release.wasm32.wasm new file mode 100644 index 0000000..1a245a4 Binary files /dev/null and b/addons/limboai/bin/liblimboai.web.template_release.wasm32.wasm differ diff --git a/addons/limboai/bin/liblimboai.windows.editor.x86_64.dll b/addons/limboai/bin/liblimboai.windows.editor.x86_64.dll new file mode 100644 index 0000000..7131bab Binary files /dev/null and b/addons/limboai/bin/liblimboai.windows.editor.x86_64.dll differ diff --git a/addons/limboai/bin/liblimboai.windows.template_release.x86_64.dll b/addons/limboai/bin/liblimboai.windows.template_release.x86_64.dll new file mode 100644 index 0000000..e5ab82c Binary files /dev/null and b/addons/limboai/bin/liblimboai.windows.template_release.x86_64.dll differ diff --git a/addons/limboai/bin/limboai.gdextension b/addons/limboai/bin/limboai.gdextension new file mode 100644 index 0000000..fe0e7c9 --- /dev/null +++ b/addons/limboai/bin/limboai.gdextension @@ -0,0 +1,102 @@ +[configuration] + +entry_symbol = "limboai_init" +compatibility_minimum = "4.2" + +[libraries] + +macos.debug = "res://addons/limboai/bin/liblimboai.macos.editor.framework" +macos.release = "res://addons/limboai/bin/liblimboai.macos.template_release.framework" +windows.debug.x86_32 = "res://addons/limboai/bin/liblimboai.windows.editor.x86_32.dll" +windows.release.x86_32 = "res://addons/limboai/bin/liblimboai.windows.template_release.x86_32.dll" +windows.debug.x86_64 = "res://addons/limboai/bin/liblimboai.windows.editor.x86_64.dll" +windows.release.x86_64 = "res://addons/limboai/bin/liblimboai.windows.template_release.x86_64.dll" +linux.debug.x86_64 = "res://addons/limboai/bin/liblimboai.linux.editor.x86_64.so" +linux.release.x86_64 = "res://addons/limboai/bin/liblimboai.linux.template_release.x86_64.so" +linux.debug.arm64 = "res://addons/limboai/bin/liblimboai.linux.editor.arm64.so" +linux.release.arm64 = "res://addons/limboai/bin/liblimboai.linux.template_release.arm64.so" +linux.debug.rv64 = "res://addons/limboai/bin/liblimboai.linux.editor.rv64.so" +linux.release.rv64 = "res://addons/limboai/bin/liblimboai.linux.template_release.rv64.so" +android.debug.arm64 = "res://addons/limboai/bin/liblimboai.android.editor.arm64.so" +android.release.arm64 = "res://addons/limboai/bin/liblimboai.android.template_release.arm64.so" +android.debug.arm32 = "res://addons/limboai/bin/liblimboai.android.editor.arm32.so" +android.release.arm32 = "res://addons/limboai/bin/liblimboai.android.template_release.arm32.so" +android.debug.x86_64 = "res://addons/limboai/bin/liblimboai.android.editor.x86_64.so" +android.release.x86_64 = "res://addons/limboai/bin/liblimboai.android.template_release.x86_64.so" +android.debug.x86_32 = "res://addons/limboai/bin/liblimboai.android.editor.x86_32.so" +android.release.x86_32 = "res://addons/limboai/bin/liblimboai.android.template_release.x86_32.so" +ios.debug.arm64 = "res://addons/limboai/bin/liblimboai.ios.editor.arm64.dylib" +ios.release.arm64 = "res://addons/limboai/bin/liblimboai.ios.template_release.arm64.dylib" +ios.debug.simulator = "res://addons/limboai/bin/liblimboai.ios.editor.universal.dylib" +ios.release.simulator = "res://addons/limboai/bin/liblimboai.ios.template_release.universal.dylib" +web.debug.wasm32 = "res://addons/limboai/bin/liblimboai.web.editor.wasm32.nothreads.wasm" +web.release.wasm32 = "res://addons/limboai/bin/liblimboai.web.template_release.wasm32.nothreads.wasm" +web.debug.threads.wasm32 = "res://addons/limboai/bin/liblimboai.web.editor.wasm32.wasm" +web.release.threads.wasm32 = "res://addons/limboai/bin/liblimboai.web.template_release.wasm32.wasm" + +[icons] + +BTAction = "res://addons/limboai/icons/BTAction.svg" +BTAlwaysFail = "res://addons/limboai/icons/BTAlwaysFail.svg" +BTAlwaysSucceed = "res://addons/limboai/icons/BTAlwaysSucceed.svg" +BTAwaitAnimation = "res://addons/limboai/icons/BTAwaitAnimation.svg" +BTCallMethod = "res://addons/limboai/icons/BTCallMethod.svg" +BTCheckAgentProperty = "res://addons/limboai/icons/BTCheckAgentProperty.svg" +BTCheckTrigger = "res://addons/limboai/icons/BTCheckTrigger.svg" +BTCheckVar = "res://addons/limboai/icons/BTCheckVar.svg" +BTComment = "res://addons/limboai/icons/BTComment.svg" +BTCondition = "res://addons/limboai/icons/BTCondition.svg" +BTConsolePrint = "res://addons/limboai/icons/BTConsolePrint.svg" +BTCooldown = "res://addons/limboai/icons/BTCooldown.svg" +BTDecorator = "res://addons/limboai/icons/BTDecorator.svg" +BTDelay = "res://addons/limboai/icons/BTDelay.svg" +BTDynamicSelector = "res://addons/limboai/icons/BTDynamicSelector.svg" +BTDynamicSequence = "res://addons/limboai/icons/BTDynamicSequence.svg" +BTEvaluateExpression = "res://addons/limboai/icons/BTEvaluateExpression.svg" +BTFail = "res://addons/limboai/icons/BTFail.svg" +BTForEach = "res://addons/limboai/icons/BTForEach.svg" +BTInvert = "res://addons/limboai/icons/BTInvert.svg" +BTNewScope = "res://addons/limboai/icons/BTNewScope.svg" +BTParallel = "res://addons/limboai/icons/BTParallel.svg" +BTPauseAnimation = "res://addons/limboai/icons/BTPauseAnimation.svg" +BTPlayAnimation = "res://addons/limboai/icons/BTPlayAnimation.svg" +BTPlayer = "res://addons/limboai/icons/BTPlayer.svg" +BTProbability = "res://addons/limboai/icons/BTProbability.svg" +BTProbabilitySelector = "res://addons/limboai/icons/BTProbabilitySelector.svg" +BTRandomSelector = "res://addons/limboai/icons/BTRandomSelector.svg" +BTRandomSequence = "res://addons/limboai/icons/BTRandomSequence.svg" +BTRandomWait = "res://addons/limboai/icons/BTRandomWait.svg" +BTRepeat = "res://addons/limboai/icons/BTRepeat.svg" +BTRepeatUntilFailure = "res://addons/limboai/icons/BTRepeatUntilFailure.svg" +BTRepeatUntilSuccess = "res://addons/limboai/icons/BTRepeatUntilSuccess.svg" +BTRunLimit = "res://addons/limboai/icons/BTRunLimit.svg" +BTSelector = "res://addons/limboai/icons/BTSelector.svg" +BTSequence = "res://addons/limboai/icons/BTSequence.svg" +BTSetAgentProperty = "res://addons/limboai/icons/BTSetAgentProperty.svg" +BTSetVar = "res://addons/limboai/icons/BTSetVar.svg" +BTState = "res://addons/limboai/icons/BTState.svg" +BTStopAnimation = "res://addons/limboai/icons/BTStopAnimation.svg" +BTSubtree = "res://addons/limboai/icons/BTSubtree.svg" +BTTimeLimit = "res://addons/limboai/icons/BTTimeLimit.svg" +BTWait = "res://addons/limboai/icons/BTWait.svg" +BTWaitTicks = "res://addons/limboai/icons/BTWaitTicks.svg" +BehaviorTree = "res://addons/limboai/icons/BehaviorTree.svg" +BehaviorTreeView = "res://addons/limboai/icons/BehaviorTreeView.svg" +BlackboardPlan = "res://addons/limboai/icons/BlackboardPlan.svg" +LimboAI = "res://addons/limboai/icons/LimboAI.svg" +LimboDeselectAll = "res://addons/limboai/icons/LimboDeselectAll.svg" +LimboEditBlackboard = "res://addons/limboai/icons/LimboEditBlackboard.svg" +LimboExtraBlackboard = "res://addons/limboai/icons/LimboExtraBlackboard.svg" +LimboExtraClock = "res://addons/limboai/icons/LimboExtraClock.svg" +LimboExtraVariable = "res://addons/limboai/icons/LimboExtraVariable.svg" +LimboExtractSubtree = "res://addons/limboai/icons/LimboExtractSubtree.svg" +LimboHSM = "res://addons/limboai/icons/LimboHSM.svg" +LimboPercent = "res://addons/limboai/icons/LimboPercent.svg" +LimboSelectAll = "res://addons/limboai/icons/LimboSelectAll.svg" +LimboState = "res://addons/limboai/icons/LimboState.svg" +LimboVarAdd = "res://addons/limboai/icons/LimboVarAdd.svg" +LimboVarEmpty = "res://addons/limboai/icons/LimboVarEmpty.svg" +LimboVarError = "res://addons/limboai/icons/LimboVarError.svg" +LimboVarExists = "res://addons/limboai/icons/LimboVarExists.svg" +LimboVarNotFound = "res://addons/limboai/icons/LimboVarNotFound.svg" +LimboVarPrivate = "res://addons/limboai/icons/LimboVarPrivate.svg" diff --git a/addons/limboai/bin/limboai.gdextension.uid b/addons/limboai/bin/limboai.gdextension.uid new file mode 100644 index 0000000..b3e01af --- /dev/null +++ b/addons/limboai/bin/limboai.gdextension.uid @@ -0,0 +1 @@ +uid://b1tb4lh0tnm7p diff --git a/addons/limboai/bin/~liblimboai.windows.editor.x86_64.dll b/addons/limboai/bin/~liblimboai.windows.editor.x86_64.dll new file mode 100644 index 0000000..7131bab Binary files /dev/null and b/addons/limboai/bin/~liblimboai.windows.editor.x86_64.dll differ diff --git a/addons/limboai/icons/BTAction.svg b/addons/limboai/icons/BTAction.svg new file mode 100644 index 0000000..997ebbc --- /dev/null +++ b/addons/limboai/icons/BTAction.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTAction.svg.import b/addons/limboai/icons/BTAction.svg.import new file mode 100644 index 0000000..ef51b02 --- /dev/null +++ b/addons/limboai/icons/BTAction.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cl3bliu5qbndc" +path="res://.godot/imported/BTAction.svg-a43c04a25802778fc1e8d98b5915e67c.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTAction.svg" +dest_files=["res://.godot/imported/BTAction.svg-a43c04a25802778fc1e8d98b5915e67c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTAlwaysFail.svg b/addons/limboai/icons/BTAlwaysFail.svg new file mode 100644 index 0000000..7be2920 --- /dev/null +++ b/addons/limboai/icons/BTAlwaysFail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTAlwaysFail.svg.import b/addons/limboai/icons/BTAlwaysFail.svg.import new file mode 100644 index 0000000..5f4ea52 --- /dev/null +++ b/addons/limboai/icons/BTAlwaysFail.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cav3nbhn6ll7r" +path="res://.godot/imported/BTAlwaysFail.svg-9a4e083bd8ff0d6d8240b50ae0d4cea0.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTAlwaysFail.svg" +dest_files=["res://.godot/imported/BTAlwaysFail.svg-9a4e083bd8ff0d6d8240b50ae0d4cea0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTAlwaysSucceed.svg b/addons/limboai/icons/BTAlwaysSucceed.svg new file mode 100644 index 0000000..248882f --- /dev/null +++ b/addons/limboai/icons/BTAlwaysSucceed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTAlwaysSucceed.svg.import b/addons/limboai/icons/BTAlwaysSucceed.svg.import new file mode 100644 index 0000000..0c393c4 --- /dev/null +++ b/addons/limboai/icons/BTAlwaysSucceed.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cfbm7me5gsyv" +path="res://.godot/imported/BTAlwaysSucceed.svg-c8181e2fd85d1e2ad00a6c8e813e7a94.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTAlwaysSucceed.svg" +dest_files=["res://.godot/imported/BTAlwaysSucceed.svg-c8181e2fd85d1e2ad00a6c8e813e7a94.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTAwaitAnimation.svg b/addons/limboai/icons/BTAwaitAnimation.svg new file mode 100644 index 0000000..6bb4cd1 --- /dev/null +++ b/addons/limboai/icons/BTAwaitAnimation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTAwaitAnimation.svg.import b/addons/limboai/icons/BTAwaitAnimation.svg.import new file mode 100644 index 0000000..ecf2311 --- /dev/null +++ b/addons/limboai/icons/BTAwaitAnimation.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dh2ffq5lq41tu" +path="res://.godot/imported/BTAwaitAnimation.svg-d8d736b3e349e2f77119fde575996909.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTAwaitAnimation.svg" +dest_files=["res://.godot/imported/BTAwaitAnimation.svg-d8d736b3e349e2f77119fde575996909.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTCallMethod.svg b/addons/limboai/icons/BTCallMethod.svg new file mode 100644 index 0000000..8ed7e65 --- /dev/null +++ b/addons/limboai/icons/BTCallMethod.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTCallMethod.svg.import b/addons/limboai/icons/BTCallMethod.svg.import new file mode 100644 index 0000000..766ac0b --- /dev/null +++ b/addons/limboai/icons/BTCallMethod.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b41ancns3b8fb" +path="res://.godot/imported/BTCallMethod.svg-f41bac2a2119be3591af9424d2c32d9a.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTCallMethod.svg" +dest_files=["res://.godot/imported/BTCallMethod.svg-f41bac2a2119be3591af9424d2c32d9a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTCheckAgentProperty.svg b/addons/limboai/icons/BTCheckAgentProperty.svg new file mode 100644 index 0000000..6c869c3 --- /dev/null +++ b/addons/limboai/icons/BTCheckAgentProperty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTCheckAgentProperty.svg.import b/addons/limboai/icons/BTCheckAgentProperty.svg.import new file mode 100644 index 0000000..542a5b5 --- /dev/null +++ b/addons/limboai/icons/BTCheckAgentProperty.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://gigarlolggtj" +path="res://.godot/imported/BTCheckAgentProperty.svg-2ed4c1d109d23a5287ed6f1262e23f15.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTCheckAgentProperty.svg" +dest_files=["res://.godot/imported/BTCheckAgentProperty.svg-2ed4c1d109d23a5287ed6f1262e23f15.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTCheckTrigger.svg b/addons/limboai/icons/BTCheckTrigger.svg new file mode 100644 index 0000000..2a59673 --- /dev/null +++ b/addons/limboai/icons/BTCheckTrigger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTCheckTrigger.svg.import b/addons/limboai/icons/BTCheckTrigger.svg.import new file mode 100644 index 0000000..563d622 --- /dev/null +++ b/addons/limboai/icons/BTCheckTrigger.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ch7d3e4c0jwn4" +path="res://.godot/imported/BTCheckTrigger.svg-79349468c66ee41b0a126720f8ecda55.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTCheckTrigger.svg" +dest_files=["res://.godot/imported/BTCheckTrigger.svg-79349468c66ee41b0a126720f8ecda55.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTCheckVar.svg b/addons/limboai/icons/BTCheckVar.svg new file mode 100644 index 0000000..150a4f2 --- /dev/null +++ b/addons/limboai/icons/BTCheckVar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTCheckVar.svg.import b/addons/limboai/icons/BTCheckVar.svg.import new file mode 100644 index 0000000..66a68a8 --- /dev/null +++ b/addons/limboai/icons/BTCheckVar.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bqt4u78o3y2oq" +path="res://.godot/imported/BTCheckVar.svg-7b3af543bb4450e9a6d56df48f06064e.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTCheckVar.svg" +dest_files=["res://.godot/imported/BTCheckVar.svg-7b3af543bb4450e9a6d56df48f06064e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTComment.svg b/addons/limboai/icons/BTComment.svg new file mode 100644 index 0000000..66699d4 --- /dev/null +++ b/addons/limboai/icons/BTComment.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTComment.svg.import b/addons/limboai/icons/BTComment.svg.import new file mode 100644 index 0000000..cfb98b5 --- /dev/null +++ b/addons/limboai/icons/BTComment.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b6no5nvdnclh0" +path="res://.godot/imported/BTComment.svg-84a811fb1f7563bc02c1f584b4085d5c.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTComment.svg" +dest_files=["res://.godot/imported/BTComment.svg-84a811fb1f7563bc02c1f584b4085d5c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTCondition.svg b/addons/limboai/icons/BTCondition.svg new file mode 100644 index 0000000..7c00015 --- /dev/null +++ b/addons/limboai/icons/BTCondition.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTCondition.svg.import b/addons/limboai/icons/BTCondition.svg.import new file mode 100644 index 0000000..84aa6be --- /dev/null +++ b/addons/limboai/icons/BTCondition.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dx7ocg2eem40s" +path="res://.godot/imported/BTCondition.svg-546aa4361ccfe650098b5f6867299d1a.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTCondition.svg" +dest_files=["res://.godot/imported/BTCondition.svg-546aa4361ccfe650098b5f6867299d1a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTConsolePrint.svg b/addons/limboai/icons/BTConsolePrint.svg new file mode 100644 index 0000000..cee42eb --- /dev/null +++ b/addons/limboai/icons/BTConsolePrint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTConsolePrint.svg.import b/addons/limboai/icons/BTConsolePrint.svg.import new file mode 100644 index 0000000..c8bf9ef --- /dev/null +++ b/addons/limboai/icons/BTConsolePrint.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://34m1r17qnkls" +path="res://.godot/imported/BTConsolePrint.svg-4190426bb73da16c143878c233af4bc3.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTConsolePrint.svg" +dest_files=["res://.godot/imported/BTConsolePrint.svg-4190426bb73da16c143878c233af4bc3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTCooldown.svg b/addons/limboai/icons/BTCooldown.svg new file mode 100644 index 0000000..2c6a237 --- /dev/null +++ b/addons/limboai/icons/BTCooldown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTCooldown.svg.import b/addons/limboai/icons/BTCooldown.svg.import new file mode 100644 index 0000000..d2dad50 --- /dev/null +++ b/addons/limboai/icons/BTCooldown.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cvaiorxaif1v6" +path="res://.godot/imported/BTCooldown.svg-b168adee5e8762abc08102408ea327d5.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTCooldown.svg" +dest_files=["res://.godot/imported/BTCooldown.svg-b168adee5e8762abc08102408ea327d5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTDecorator.svg b/addons/limboai/icons/BTDecorator.svg new file mode 100644 index 0000000..faac1ab --- /dev/null +++ b/addons/limboai/icons/BTDecorator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTDecorator.svg.import b/addons/limboai/icons/BTDecorator.svg.import new file mode 100644 index 0000000..5428d58 --- /dev/null +++ b/addons/limboai/icons/BTDecorator.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cah8aky4n5x1c" +path="res://.godot/imported/BTDecorator.svg-dae9ebd6f4667ba4d2ac62518ef141d6.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTDecorator.svg" +dest_files=["res://.godot/imported/BTDecorator.svg-dae9ebd6f4667ba4d2ac62518ef141d6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTDelay.svg b/addons/limboai/icons/BTDelay.svg new file mode 100644 index 0000000..2c6a237 --- /dev/null +++ b/addons/limboai/icons/BTDelay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTDelay.svg.import b/addons/limboai/icons/BTDelay.svg.import new file mode 100644 index 0000000..b79513d --- /dev/null +++ b/addons/limboai/icons/BTDelay.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bflu2rtive24h" +path="res://.godot/imported/BTDelay.svg-1eb814224ebee27c668e10a73d85b845.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTDelay.svg" +dest_files=["res://.godot/imported/BTDelay.svg-1eb814224ebee27c668e10a73d85b845.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTDynamicSelector.svg b/addons/limboai/icons/BTDynamicSelector.svg new file mode 100644 index 0000000..b9c8f02 --- /dev/null +++ b/addons/limboai/icons/BTDynamicSelector.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTDynamicSelector.svg.import b/addons/limboai/icons/BTDynamicSelector.svg.import new file mode 100644 index 0000000..7106b4f --- /dev/null +++ b/addons/limboai/icons/BTDynamicSelector.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cvsga8pnhfa5q" +path="res://.godot/imported/BTDynamicSelector.svg-d88a1aa9fb8d8826b74e69dad4c99f54.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTDynamicSelector.svg" +dest_files=["res://.godot/imported/BTDynamicSelector.svg-d88a1aa9fb8d8826b74e69dad4c99f54.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTDynamicSequence.svg b/addons/limboai/icons/BTDynamicSequence.svg new file mode 100644 index 0000000..86c8f54 --- /dev/null +++ b/addons/limboai/icons/BTDynamicSequence.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTDynamicSequence.svg.import b/addons/limboai/icons/BTDynamicSequence.svg.import new file mode 100644 index 0000000..efc5532 --- /dev/null +++ b/addons/limboai/icons/BTDynamicSequence.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cltqkvxpmprya" +path="res://.godot/imported/BTDynamicSequence.svg-d2b6a83c37a1553bc168a9837ae0cb1d.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTDynamicSequence.svg" +dest_files=["res://.godot/imported/BTDynamicSequence.svg-d2b6a83c37a1553bc168a9837ae0cb1d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTEvaluateExpression.svg b/addons/limboai/icons/BTEvaluateExpression.svg new file mode 100644 index 0000000..d1cf36f --- /dev/null +++ b/addons/limboai/icons/BTEvaluateExpression.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTEvaluateExpression.svg.import b/addons/limboai/icons/BTEvaluateExpression.svg.import new file mode 100644 index 0000000..ba1ef29 --- /dev/null +++ b/addons/limboai/icons/BTEvaluateExpression.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b24ibj6n71phs" +path="res://.godot/imported/BTEvaluateExpression.svg-d9edc0d3cf9dd54c6a34ffc8a23bf8e3.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTEvaluateExpression.svg" +dest_files=["res://.godot/imported/BTEvaluateExpression.svg-d9edc0d3cf9dd54c6a34ffc8a23bf8e3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTFail.svg b/addons/limboai/icons/BTFail.svg new file mode 100644 index 0000000..7be2920 --- /dev/null +++ b/addons/limboai/icons/BTFail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTFail.svg.import b/addons/limboai/icons/BTFail.svg.import new file mode 100644 index 0000000..d24eada --- /dev/null +++ b/addons/limboai/icons/BTFail.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c6ufqwnhl4w4u" +path="res://.godot/imported/BTFail.svg-0440819265455ee47b2cf2ca8f1b8018.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTFail.svg" +dest_files=["res://.godot/imported/BTFail.svg-0440819265455ee47b2cf2ca8f1b8018.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTForEach.svg b/addons/limboai/icons/BTForEach.svg new file mode 100644 index 0000000..819c0ed --- /dev/null +++ b/addons/limboai/icons/BTForEach.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTForEach.svg.import b/addons/limboai/icons/BTForEach.svg.import new file mode 100644 index 0000000..fe74f09 --- /dev/null +++ b/addons/limboai/icons/BTForEach.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bwy3w0n10getv" +path="res://.godot/imported/BTForEach.svg-4ca6daee422cda100144e3414286df7f.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTForEach.svg" +dest_files=["res://.godot/imported/BTForEach.svg-4ca6daee422cda100144e3414286df7f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTInvert.svg b/addons/limboai/icons/BTInvert.svg new file mode 100644 index 0000000..31be0d5 --- /dev/null +++ b/addons/limboai/icons/BTInvert.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTInvert.svg.import b/addons/limboai/icons/BTInvert.svg.import new file mode 100644 index 0000000..c05f3f2 --- /dev/null +++ b/addons/limboai/icons/BTInvert.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://deaes4fdskgff" +path="res://.godot/imported/BTInvert.svg-19687b5c798f968b9610763066baa2a0.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTInvert.svg" +dest_files=["res://.godot/imported/BTInvert.svg-19687b5c798f968b9610763066baa2a0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTNewScope.svg b/addons/limboai/icons/BTNewScope.svg new file mode 100644 index 0000000..598d39b --- /dev/null +++ b/addons/limboai/icons/BTNewScope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTNewScope.svg.import b/addons/limboai/icons/BTNewScope.svg.import new file mode 100644 index 0000000..3bf547a --- /dev/null +++ b/addons/limboai/icons/BTNewScope.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ci87mypgwfhuj" +path="res://.godot/imported/BTNewScope.svg-d536a90c30773badb76653d8c928cfe0.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTNewScope.svg" +dest_files=["res://.godot/imported/BTNewScope.svg-d536a90c30773badb76653d8c928cfe0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTParallel.svg b/addons/limboai/icons/BTParallel.svg new file mode 100644 index 0000000..7ee727a --- /dev/null +++ b/addons/limboai/icons/BTParallel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTParallel.svg.import b/addons/limboai/icons/BTParallel.svg.import new file mode 100644 index 0000000..32cb4f2 --- /dev/null +++ b/addons/limboai/icons/BTParallel.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cl5vdniq6b5fw" +path="res://.godot/imported/BTParallel.svg-54126e7f374b26a890ddd82c580db45c.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTParallel.svg" +dest_files=["res://.godot/imported/BTParallel.svg-54126e7f374b26a890ddd82c580db45c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTPauseAnimation.svg b/addons/limboai/icons/BTPauseAnimation.svg new file mode 100644 index 0000000..d0878cd --- /dev/null +++ b/addons/limboai/icons/BTPauseAnimation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTPauseAnimation.svg.import b/addons/limboai/icons/BTPauseAnimation.svg.import new file mode 100644 index 0000000..81a8c24 --- /dev/null +++ b/addons/limboai/icons/BTPauseAnimation.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c46rr3t22bh8j" +path="res://.godot/imported/BTPauseAnimation.svg-e1bc0cf7bcd45a0faa047192242d174b.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTPauseAnimation.svg" +dest_files=["res://.godot/imported/BTPauseAnimation.svg-e1bc0cf7bcd45a0faa047192242d174b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTPlayAnimation.svg b/addons/limboai/icons/BTPlayAnimation.svg new file mode 100644 index 0000000..d387bf6 --- /dev/null +++ b/addons/limboai/icons/BTPlayAnimation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTPlayAnimation.svg.import b/addons/limboai/icons/BTPlayAnimation.svg.import new file mode 100644 index 0000000..40dee4d --- /dev/null +++ b/addons/limboai/icons/BTPlayAnimation.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://q4eoa63565ff" +path="res://.godot/imported/BTPlayAnimation.svg-8821f3b3413b9b328414add0e843468c.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTPlayAnimation.svg" +dest_files=["res://.godot/imported/BTPlayAnimation.svg-8821f3b3413b9b328414add0e843468c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTPlayer.svg b/addons/limboai/icons/BTPlayer.svg new file mode 100644 index 0000000..7a874c7 --- /dev/null +++ b/addons/limboai/icons/BTPlayer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTPlayer.svg.import b/addons/limboai/icons/BTPlayer.svg.import new file mode 100644 index 0000000..7685027 --- /dev/null +++ b/addons/limboai/icons/BTPlayer.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dw41q013u2yrs" +path="res://.godot/imported/BTPlayer.svg-ed7adc3cf4a0f3daa1e17a1a77e9a3a2.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTPlayer.svg" +dest_files=["res://.godot/imported/BTPlayer.svg-ed7adc3cf4a0f3daa1e17a1a77e9a3a2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTProbability.svg b/addons/limboai/icons/BTProbability.svg new file mode 100644 index 0000000..b1a90d9 --- /dev/null +++ b/addons/limboai/icons/BTProbability.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTProbability.svg.import b/addons/limboai/icons/BTProbability.svg.import new file mode 100644 index 0000000..e08d8a8 --- /dev/null +++ b/addons/limboai/icons/BTProbability.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dxkfh007b555m" +path="res://.godot/imported/BTProbability.svg-f691fbf51ca49bc268a17742b1e04985.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTProbability.svg" +dest_files=["res://.godot/imported/BTProbability.svg-f691fbf51ca49bc268a17742b1e04985.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTProbabilitySelector.svg b/addons/limboai/icons/BTProbabilitySelector.svg new file mode 100644 index 0000000..f9516a1 --- /dev/null +++ b/addons/limboai/icons/BTProbabilitySelector.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTProbabilitySelector.svg.import b/addons/limboai/icons/BTProbabilitySelector.svg.import new file mode 100644 index 0000000..f2915ae --- /dev/null +++ b/addons/limboai/icons/BTProbabilitySelector.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cbvb5ssq8ew60" +path="res://.godot/imported/BTProbabilitySelector.svg-30f59f4e802f72a701d9d31f605a64f2.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTProbabilitySelector.svg" +dest_files=["res://.godot/imported/BTProbabilitySelector.svg-30f59f4e802f72a701d9d31f605a64f2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTRandomSelector.svg b/addons/limboai/icons/BTRandomSelector.svg new file mode 100644 index 0000000..6dd87d1 --- /dev/null +++ b/addons/limboai/icons/BTRandomSelector.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTRandomSelector.svg.import b/addons/limboai/icons/BTRandomSelector.svg.import new file mode 100644 index 0000000..0eed4cc --- /dev/null +++ b/addons/limboai/icons/BTRandomSelector.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bnvroi7s23207" +path="res://.godot/imported/BTRandomSelector.svg-4bae5a6e3e1affdd4952e8bff4c018ff.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTRandomSelector.svg" +dest_files=["res://.godot/imported/BTRandomSelector.svg-4bae5a6e3e1affdd4952e8bff4c018ff.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTRandomSequence.svg b/addons/limboai/icons/BTRandomSequence.svg new file mode 100644 index 0000000..ff21602 --- /dev/null +++ b/addons/limboai/icons/BTRandomSequence.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTRandomSequence.svg.import b/addons/limboai/icons/BTRandomSequence.svg.import new file mode 100644 index 0000000..4d8c317 --- /dev/null +++ b/addons/limboai/icons/BTRandomSequence.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b27286s6wk13h" +path="res://.godot/imported/BTRandomSequence.svg-85ce4b080ec904d340a807de2669110d.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTRandomSequence.svg" +dest_files=["res://.godot/imported/BTRandomSequence.svg-85ce4b080ec904d340a807de2669110d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTRandomWait.svg b/addons/limboai/icons/BTRandomWait.svg new file mode 100644 index 0000000..8174e2a --- /dev/null +++ b/addons/limboai/icons/BTRandomWait.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTRandomWait.svg.import b/addons/limboai/icons/BTRandomWait.svg.import new file mode 100644 index 0000000..8c7d3a8 --- /dev/null +++ b/addons/limboai/icons/BTRandomWait.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bjvaeggxauloi" +path="res://.godot/imported/BTRandomWait.svg-14f03a0fb52c993ec1cdbb780d9dfea3.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTRandomWait.svg" +dest_files=["res://.godot/imported/BTRandomWait.svg-14f03a0fb52c993ec1cdbb780d9dfea3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTRepeat.svg b/addons/limboai/icons/BTRepeat.svg new file mode 100644 index 0000000..d937bcf --- /dev/null +++ b/addons/limboai/icons/BTRepeat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTRepeat.svg.import b/addons/limboai/icons/BTRepeat.svg.import new file mode 100644 index 0000000..6743429 --- /dev/null +++ b/addons/limboai/icons/BTRepeat.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c2uooxg4hsjq2" +path="res://.godot/imported/BTRepeat.svg-ca1efcf8bdef890d4575f2bf66ba0a8d.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTRepeat.svg" +dest_files=["res://.godot/imported/BTRepeat.svg-ca1efcf8bdef890d4575f2bf66ba0a8d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTRepeatUntilFailure.svg b/addons/limboai/icons/BTRepeatUntilFailure.svg new file mode 100644 index 0000000..88b1261 --- /dev/null +++ b/addons/limboai/icons/BTRepeatUntilFailure.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTRepeatUntilFailure.svg.import b/addons/limboai/icons/BTRepeatUntilFailure.svg.import new file mode 100644 index 0000000..c7b5d00 --- /dev/null +++ b/addons/limboai/icons/BTRepeatUntilFailure.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bymecgi7wfbwg" +path="res://.godot/imported/BTRepeatUntilFailure.svg-97ff99132cb6b229bb78050959a89118.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTRepeatUntilFailure.svg" +dest_files=["res://.godot/imported/BTRepeatUntilFailure.svg-97ff99132cb6b229bb78050959a89118.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTRepeatUntilSuccess.svg b/addons/limboai/icons/BTRepeatUntilSuccess.svg new file mode 100644 index 0000000..9087ce4 --- /dev/null +++ b/addons/limboai/icons/BTRepeatUntilSuccess.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTRepeatUntilSuccess.svg.import b/addons/limboai/icons/BTRepeatUntilSuccess.svg.import new file mode 100644 index 0000000..76c3894 --- /dev/null +++ b/addons/limboai/icons/BTRepeatUntilSuccess.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cslwhy5a8i8x7" +path="res://.godot/imported/BTRepeatUntilSuccess.svg-160e74b6885a57a745db349d6f7004a8.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTRepeatUntilSuccess.svg" +dest_files=["res://.godot/imported/BTRepeatUntilSuccess.svg-160e74b6885a57a745db349d6f7004a8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTRunLimit.svg b/addons/limboai/icons/BTRunLimit.svg new file mode 100644 index 0000000..1ac7fa1 --- /dev/null +++ b/addons/limboai/icons/BTRunLimit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTRunLimit.svg.import b/addons/limboai/icons/BTRunLimit.svg.import new file mode 100644 index 0000000..22e6597 --- /dev/null +++ b/addons/limboai/icons/BTRunLimit.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://uiwnwsqdtwnl" +path="res://.godot/imported/BTRunLimit.svg-eb80a597bf9102a626f8c0e9663703d1.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTRunLimit.svg" +dest_files=["res://.godot/imported/BTRunLimit.svg-eb80a597bf9102a626f8c0e9663703d1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTSelector.svg b/addons/limboai/icons/BTSelector.svg new file mode 100644 index 0000000..d7cafe5 --- /dev/null +++ b/addons/limboai/icons/BTSelector.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTSelector.svg.import b/addons/limboai/icons/BTSelector.svg.import new file mode 100644 index 0000000..bdc8aa0 --- /dev/null +++ b/addons/limboai/icons/BTSelector.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d6och7wyxh7v" +path="res://.godot/imported/BTSelector.svg-859c7746bc77c632d2a60052d2e96cf0.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTSelector.svg" +dest_files=["res://.godot/imported/BTSelector.svg-859c7746bc77c632d2a60052d2e96cf0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTSequence.svg b/addons/limboai/icons/BTSequence.svg new file mode 100644 index 0000000..7eb8f6f --- /dev/null +++ b/addons/limboai/icons/BTSequence.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTSequence.svg.import b/addons/limboai/icons/BTSequence.svg.import new file mode 100644 index 0000000..8fc4968 --- /dev/null +++ b/addons/limboai/icons/BTSequence.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://v7w2pw2ssnfl" +path="res://.godot/imported/BTSequence.svg-3dfd257b3424273ac1ea2f8a48dab7b6.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTSequence.svg" +dest_files=["res://.godot/imported/BTSequence.svg-3dfd257b3424273ac1ea2f8a48dab7b6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTSetAgentProperty.svg b/addons/limboai/icons/BTSetAgentProperty.svg new file mode 100644 index 0000000..c92a710 --- /dev/null +++ b/addons/limboai/icons/BTSetAgentProperty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTSetAgentProperty.svg.import b/addons/limboai/icons/BTSetAgentProperty.svg.import new file mode 100644 index 0000000..24fac4f --- /dev/null +++ b/addons/limboai/icons/BTSetAgentProperty.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dblph7y56drmx" +path="res://.godot/imported/BTSetAgentProperty.svg-8183ecffb47d990ae67daaad34563dc5.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTSetAgentProperty.svg" +dest_files=["res://.godot/imported/BTSetAgentProperty.svg-8183ecffb47d990ae67daaad34563dc5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTSetVar.svg b/addons/limboai/icons/BTSetVar.svg new file mode 100644 index 0000000..09f6822 --- /dev/null +++ b/addons/limboai/icons/BTSetVar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTSetVar.svg.import b/addons/limboai/icons/BTSetVar.svg.import new file mode 100644 index 0000000..9d11ef6 --- /dev/null +++ b/addons/limboai/icons/BTSetVar.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dgcxavcpf0gec" +path="res://.godot/imported/BTSetVar.svg-a8c4f135c2df6bc3f587cbd9f1fe2d95.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTSetVar.svg" +dest_files=["res://.godot/imported/BTSetVar.svg-a8c4f135c2df6bc3f587cbd9f1fe2d95.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTState.svg b/addons/limboai/icons/BTState.svg new file mode 100644 index 0000000..7a874c7 --- /dev/null +++ b/addons/limboai/icons/BTState.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTState.svg.import b/addons/limboai/icons/BTState.svg.import new file mode 100644 index 0000000..1a43483 --- /dev/null +++ b/addons/limboai/icons/BTState.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bh85x65wnv1m0" +path="res://.godot/imported/BTState.svg-71220d904fcc42cc20dd0af8145f86a0.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTState.svg" +dest_files=["res://.godot/imported/BTState.svg-71220d904fcc42cc20dd0af8145f86a0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTStopAnimation.svg b/addons/limboai/icons/BTStopAnimation.svg new file mode 100644 index 0000000..973b542 --- /dev/null +++ b/addons/limboai/icons/BTStopAnimation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTStopAnimation.svg.import b/addons/limboai/icons/BTStopAnimation.svg.import new file mode 100644 index 0000000..31686c9 --- /dev/null +++ b/addons/limboai/icons/BTStopAnimation.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cb7kwptfn68gu" +path="res://.godot/imported/BTStopAnimation.svg-ea88498cd747a6218f7853f6be3ded34.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTStopAnimation.svg" +dest_files=["res://.godot/imported/BTStopAnimation.svg-ea88498cd747a6218f7853f6be3ded34.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTSubtree.svg b/addons/limboai/icons/BTSubtree.svg new file mode 100644 index 0000000..e95ffee --- /dev/null +++ b/addons/limboai/icons/BTSubtree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTSubtree.svg.import b/addons/limboai/icons/BTSubtree.svg.import new file mode 100644 index 0000000..a6f14ee --- /dev/null +++ b/addons/limboai/icons/BTSubtree.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://daegjodbi3n0o" +path="res://.godot/imported/BTSubtree.svg-aa8f2ece5e71aca9132a08c7af1c1ce5.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTSubtree.svg" +dest_files=["res://.godot/imported/BTSubtree.svg-aa8f2ece5e71aca9132a08c7af1c1ce5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTTimeLimit.svg b/addons/limboai/icons/BTTimeLimit.svg new file mode 100644 index 0000000..2c6a237 --- /dev/null +++ b/addons/limboai/icons/BTTimeLimit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTTimeLimit.svg.import b/addons/limboai/icons/BTTimeLimit.svg.import new file mode 100644 index 0000000..c66ac8c --- /dev/null +++ b/addons/limboai/icons/BTTimeLimit.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://qq8tymh6q7kl" +path="res://.godot/imported/BTTimeLimit.svg-ea3ca26eeb5c2b59f3fdb6e806985f3b.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTTimeLimit.svg" +dest_files=["res://.godot/imported/BTTimeLimit.svg-ea3ca26eeb5c2b59f3fdb6e806985f3b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTWait.svg b/addons/limboai/icons/BTWait.svg new file mode 100644 index 0000000..8174e2a --- /dev/null +++ b/addons/limboai/icons/BTWait.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTWait.svg.import b/addons/limboai/icons/BTWait.svg.import new file mode 100644 index 0000000..68b3b78 --- /dev/null +++ b/addons/limboai/icons/BTWait.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://co5hxnc0fxb5s" +path="res://.godot/imported/BTWait.svg-2a5d27d0c617861f027b2e66516aa5bf.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTWait.svg" +dest_files=["res://.godot/imported/BTWait.svg-2a5d27d0c617861f027b2e66516aa5bf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BTWaitTicks.svg b/addons/limboai/icons/BTWaitTicks.svg new file mode 100644 index 0000000..8174e2a --- /dev/null +++ b/addons/limboai/icons/BTWaitTicks.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BTWaitTicks.svg.import b/addons/limboai/icons/BTWaitTicks.svg.import new file mode 100644 index 0000000..6e35dd7 --- /dev/null +++ b/addons/limboai/icons/BTWaitTicks.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1v60pxjfeqss" +path="res://.godot/imported/BTWaitTicks.svg-85a005f86874f6811423163f3f5673b2.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BTWaitTicks.svg" +dest_files=["res://.godot/imported/BTWaitTicks.svg-85a005f86874f6811423163f3f5673b2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BehaviorTree.svg b/addons/limboai/icons/BehaviorTree.svg new file mode 100644 index 0000000..e95ffee --- /dev/null +++ b/addons/limboai/icons/BehaviorTree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BehaviorTree.svg.import b/addons/limboai/icons/BehaviorTree.svg.import new file mode 100644 index 0000000..e3e23f8 --- /dev/null +++ b/addons/limboai/icons/BehaviorTree.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b54spcny26t08" +path="res://.godot/imported/BehaviorTree.svg-9b40a8b5e1feb368d9f11b0fb1785cca.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BehaviorTree.svg" +dest_files=["res://.godot/imported/BehaviorTree.svg-9b40a8b5e1feb368d9f11b0fb1785cca.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BehaviorTreeView.svg b/addons/limboai/icons/BehaviorTreeView.svg new file mode 100644 index 0000000..8deff60 --- /dev/null +++ b/addons/limboai/icons/BehaviorTreeView.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BehaviorTreeView.svg.import b/addons/limboai/icons/BehaviorTreeView.svg.import new file mode 100644 index 0000000..01a4a30 --- /dev/null +++ b/addons/limboai/icons/BehaviorTreeView.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://pkfadcfdou43" +path="res://.godot/imported/BehaviorTreeView.svg-15f9bfa321ed4a264ed8404fd13b53fc.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BehaviorTreeView.svg" +dest_files=["res://.godot/imported/BehaviorTreeView.svg-15f9bfa321ed4a264ed8404fd13b53fc.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/BlackboardPlan.svg b/addons/limboai/icons/BlackboardPlan.svg new file mode 100644 index 0000000..958fba3 --- /dev/null +++ b/addons/limboai/icons/BlackboardPlan.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/BlackboardPlan.svg.import b/addons/limboai/icons/BlackboardPlan.svg.import new file mode 100644 index 0000000..65225fc --- /dev/null +++ b/addons/limboai/icons/BlackboardPlan.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://djme8mnddu22c" +path="res://.godot/imported/BlackboardPlan.svg-9029b7aa87de8b935d9cad63480a6a16.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/BlackboardPlan.svg" +dest_files=["res://.godot/imported/BlackboardPlan.svg-9029b7aa87de8b935d9cad63480a6a16.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboAI.svg b/addons/limboai/icons/LimboAI.svg new file mode 100644 index 0000000..54b042a --- /dev/null +++ b/addons/limboai/icons/LimboAI.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboAI.svg.import b/addons/limboai/icons/LimboAI.svg.import new file mode 100644 index 0000000..c6060b7 --- /dev/null +++ b/addons/limboai/icons/LimboAI.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cinq8lndmk7t" +path="res://.godot/imported/LimboAI.svg-06efe3b51f2fc280e33c37672e174b5e.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboAI.svg" +dest_files=["res://.godot/imported/LimboAI.svg-06efe3b51f2fc280e33c37672e174b5e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboDeselectAll.svg b/addons/limboai/icons/LimboDeselectAll.svg new file mode 100644 index 0000000..2047080 --- /dev/null +++ b/addons/limboai/icons/LimboDeselectAll.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboDeselectAll.svg.import b/addons/limboai/icons/LimboDeselectAll.svg.import new file mode 100644 index 0000000..9c9ed53 --- /dev/null +++ b/addons/limboai/icons/LimboDeselectAll.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cqudkxetsegdl" +path="res://.godot/imported/LimboDeselectAll.svg-72ebb41c0238cae163a7bf3fc821e6ad.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboDeselectAll.svg" +dest_files=["res://.godot/imported/LimboDeselectAll.svg-72ebb41c0238cae163a7bf3fc821e6ad.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboEditBlackboard.svg b/addons/limboai/icons/LimboEditBlackboard.svg new file mode 100644 index 0000000..45ffb92 --- /dev/null +++ b/addons/limboai/icons/LimboEditBlackboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboEditBlackboard.svg.import b/addons/limboai/icons/LimboEditBlackboard.svg.import new file mode 100644 index 0000000..6124fe4 --- /dev/null +++ b/addons/limboai/icons/LimboEditBlackboard.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b40xlkluup7fs" +path="res://.godot/imported/LimboEditBlackboard.svg-eacd7cf985d654974a99a4009ffcc125.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboEditBlackboard.svg" +dest_files=["res://.godot/imported/LimboEditBlackboard.svg-eacd7cf985d654974a99a4009ffcc125.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboExtraBlackboard.svg b/addons/limboai/icons/LimboExtraBlackboard.svg new file mode 100644 index 0000000..09f6822 --- /dev/null +++ b/addons/limboai/icons/LimboExtraBlackboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboExtraBlackboard.svg.import b/addons/limboai/icons/LimboExtraBlackboard.svg.import new file mode 100644 index 0000000..ee9f394 --- /dev/null +++ b/addons/limboai/icons/LimboExtraBlackboard.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dh7npx14vnu5t" +path="res://.godot/imported/LimboExtraBlackboard.svg-45ef3f1dea682b1da438186cfcc0f47b.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboExtraBlackboard.svg" +dest_files=["res://.godot/imported/LimboExtraBlackboard.svg-45ef3f1dea682b1da438186cfcc0f47b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboExtraClock.svg b/addons/limboai/icons/LimboExtraClock.svg new file mode 100644 index 0000000..a3f536a --- /dev/null +++ b/addons/limboai/icons/LimboExtraClock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboExtraClock.svg.import b/addons/limboai/icons/LimboExtraClock.svg.import new file mode 100644 index 0000000..b3c9073 --- /dev/null +++ b/addons/limboai/icons/LimboExtraClock.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bom83qcjfnscn" +path="res://.godot/imported/LimboExtraClock.svg-840321103249948265bce58e6fb69483.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboExtraClock.svg" +dest_files=["res://.godot/imported/LimboExtraClock.svg-840321103249948265bce58e6fb69483.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboExtraVariable.svg b/addons/limboai/icons/LimboExtraVariable.svg new file mode 100644 index 0000000..06780f0 --- /dev/null +++ b/addons/limboai/icons/LimboExtraVariable.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboExtraVariable.svg.import b/addons/limboai/icons/LimboExtraVariable.svg.import new file mode 100644 index 0000000..77ff954 --- /dev/null +++ b/addons/limboai/icons/LimboExtraVariable.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d08u2egb871sr" +path="res://.godot/imported/LimboExtraVariable.svg-dc718672cf9e469886aa48452fdda7b0.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboExtraVariable.svg" +dest_files=["res://.godot/imported/LimboExtraVariable.svg-dc718672cf9e469886aa48452fdda7b0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboExtractSubtree.svg b/addons/limboai/icons/LimboExtractSubtree.svg new file mode 100644 index 0000000..c3c83a2 --- /dev/null +++ b/addons/limboai/icons/LimboExtractSubtree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboExtractSubtree.svg.import b/addons/limboai/icons/LimboExtractSubtree.svg.import new file mode 100644 index 0000000..2aea501 --- /dev/null +++ b/addons/limboai/icons/LimboExtractSubtree.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dmlyswjyycts4" +path="res://.godot/imported/LimboExtractSubtree.svg-84e8d198d3be4b2b8d625d3621368079.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboExtractSubtree.svg" +dest_files=["res://.godot/imported/LimboExtractSubtree.svg-84e8d198d3be4b2b8d625d3621368079.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboHSM.svg b/addons/limboai/icons/LimboHSM.svg new file mode 100644 index 0000000..095cfd4 --- /dev/null +++ b/addons/limboai/icons/LimboHSM.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboHSM.svg.import b/addons/limboai/icons/LimboHSM.svg.import new file mode 100644 index 0000000..3617c4b --- /dev/null +++ b/addons/limboai/icons/LimboHSM.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cwb1ke3ivi10b" +path="res://.godot/imported/LimboHSM.svg-28cca67d246d589dd15402abd78a1ec2.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboHSM.svg" +dest_files=["res://.godot/imported/LimboHSM.svg-28cca67d246d589dd15402abd78a1ec2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboPercent.svg b/addons/limboai/icons/LimboPercent.svg new file mode 100644 index 0000000..8f60917 --- /dev/null +++ b/addons/limboai/icons/LimboPercent.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboPercent.svg.import b/addons/limboai/icons/LimboPercent.svg.import new file mode 100644 index 0000000..f40c31f --- /dev/null +++ b/addons/limboai/icons/LimboPercent.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dpati0wm6ig5x" +path="res://.godot/imported/LimboPercent.svg-00733fc19fb3bbe7f8396b1f07a89da0.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboPercent.svg" +dest_files=["res://.godot/imported/LimboPercent.svg-00733fc19fb3bbe7f8396b1f07a89da0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboSelectAll.svg b/addons/limboai/icons/LimboSelectAll.svg new file mode 100644 index 0000000..fd3df37 --- /dev/null +++ b/addons/limboai/icons/LimboSelectAll.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboSelectAll.svg.import b/addons/limboai/icons/LimboSelectAll.svg.import new file mode 100644 index 0000000..0c88170 --- /dev/null +++ b/addons/limboai/icons/LimboSelectAll.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c4ichdesgey33" +path="res://.godot/imported/LimboSelectAll.svg-db7b91d0d0b530b8e41c9d3772e60fab.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboSelectAll.svg" +dest_files=["res://.godot/imported/LimboSelectAll.svg-db7b91d0d0b530b8e41c9d3772e60fab.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboState.svg b/addons/limboai/icons/LimboState.svg new file mode 100644 index 0000000..dd8e765 --- /dev/null +++ b/addons/limboai/icons/LimboState.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboState.svg.import b/addons/limboai/icons/LimboState.svg.import new file mode 100644 index 0000000..62db662 --- /dev/null +++ b/addons/limboai/icons/LimboState.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dp21dvmq1clx3" +path="res://.godot/imported/LimboState.svg-b1db06d5ed3101ee6256deae4330f6b7.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboState.svg" +dest_files=["res://.godot/imported/LimboState.svg-b1db06d5ed3101ee6256deae4330f6b7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboVarAdd.svg b/addons/limboai/icons/LimboVarAdd.svg new file mode 100644 index 0000000..b2910a0 --- /dev/null +++ b/addons/limboai/icons/LimboVarAdd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboVarAdd.svg.import b/addons/limboai/icons/LimboVarAdd.svg.import new file mode 100644 index 0000000..9a713ca --- /dev/null +++ b/addons/limboai/icons/LimboVarAdd.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://pogdtwd2nlq7" +path="res://.godot/imported/LimboVarAdd.svg-101bcdd036315254e4b61e13747c0788.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboVarAdd.svg" +dest_files=["res://.godot/imported/LimboVarAdd.svg-101bcdd036315254e4b61e13747c0788.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboVarEmpty.svg b/addons/limboai/icons/LimboVarEmpty.svg new file mode 100644 index 0000000..24f5088 --- /dev/null +++ b/addons/limboai/icons/LimboVarEmpty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboVarEmpty.svg.import b/addons/limboai/icons/LimboVarEmpty.svg.import new file mode 100644 index 0000000..3ecf95a --- /dev/null +++ b/addons/limboai/icons/LimboVarEmpty.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1eq87xr1nmkn" +path="res://.godot/imported/LimboVarEmpty.svg-3014256fb5cd566cab45b3327d98988d.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboVarEmpty.svg" +dest_files=["res://.godot/imported/LimboVarEmpty.svg-3014256fb5cd566cab45b3327d98988d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboVarError.svg b/addons/limboai/icons/LimboVarError.svg new file mode 100644 index 0000000..563d762 --- /dev/null +++ b/addons/limboai/icons/LimboVarError.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboVarError.svg.import b/addons/limboai/icons/LimboVarError.svg.import new file mode 100644 index 0000000..f4bf50a --- /dev/null +++ b/addons/limboai/icons/LimboVarError.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c3cbo6v3yc76k" +path="res://.godot/imported/LimboVarError.svg-d9f1ab3e5b2cbb6e0013b65ddb23c1cf.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboVarError.svg" +dest_files=["res://.godot/imported/LimboVarError.svg-d9f1ab3e5b2cbb6e0013b65ddb23c1cf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboVarExists.svg b/addons/limboai/icons/LimboVarExists.svg new file mode 100644 index 0000000..3509c64 --- /dev/null +++ b/addons/limboai/icons/LimboVarExists.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboVarExists.svg.import b/addons/limboai/icons/LimboVarExists.svg.import new file mode 100644 index 0000000..3bca5ea --- /dev/null +++ b/addons/limboai/icons/LimboVarExists.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://crpyglqyq7uri" +path="res://.godot/imported/LimboVarExists.svg-20d2e0b4a7a064b9c6d2cc44711570dd.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboVarExists.svg" +dest_files=["res://.godot/imported/LimboVarExists.svg-20d2e0b4a7a064b9c6d2cc44711570dd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboVarNotFound.svg b/addons/limboai/icons/LimboVarNotFound.svg new file mode 100644 index 0000000..049f6cf --- /dev/null +++ b/addons/limboai/icons/LimboVarNotFound.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboVarNotFound.svg.import b/addons/limboai/icons/LimboVarNotFound.svg.import new file mode 100644 index 0000000..1ad2e95 --- /dev/null +++ b/addons/limboai/icons/LimboVarNotFound.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dyclyhueh30qp" +path="res://.godot/imported/LimboVarNotFound.svg-fce88dc2c01e17a54455124e43955f9d.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboVarNotFound.svg" +dest_files=["res://.godot/imported/LimboVarNotFound.svg-fce88dc2c01e17a54455124e43955f9d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/icons/LimboVarPrivate.svg b/addons/limboai/icons/LimboVarPrivate.svg new file mode 100644 index 0000000..87b2c0f --- /dev/null +++ b/addons/limboai/icons/LimboVarPrivate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/limboai/icons/LimboVarPrivate.svg.import b/addons/limboai/icons/LimboVarPrivate.svg.import new file mode 100644 index 0000000..023f425 --- /dev/null +++ b/addons/limboai/icons/LimboVarPrivate.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://eq2xp8at5jie" +path="res://.godot/imported/LimboVarPrivate.svg-99b4229567f7f98cdabf892099c91da2.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/limboai/icons/LimboVarPrivate.svg" +dest_files=["res://.godot/imported/LimboVarPrivate.svg-99b4229567f7f98cdabf892099c91da2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=true +editor/convert_colors_with_editor_theme=true diff --git a/addons/limboai/version.txt b/addons/limboai/version.txt new file mode 100644 index 0000000..53b5bbb --- /dev/null +++ b/addons/limboai/version.txt @@ -0,0 +1 @@ +v1.5.1 diff --git a/addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png b/addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png new file mode 100644 index 0000000..3082789 Binary files /dev/null and b/addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png differ diff --git a/addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png.import b/addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png.import new file mode 100644 index 0000000..6582ece --- /dev/null +++ b/addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://censw3w53gldn" +path="res://.godot/imported/PhantomCameraBtnPrimaryDefault.png-fcf3696b583a82b1078609a5bfd648f5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png" +dest_files=["res://.godot/imported/PhantomCameraBtnPrimaryDefault.png-fcf3696b583a82b1078609a5bfd648f5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/phantom_camera/assets/PhantomCameraBtnPrimaryHover.png b/addons/phantom_camera/assets/PhantomCameraBtnPrimaryHover.png new file mode 100644 index 0000000..1e0c31a Binary files /dev/null and b/addons/phantom_camera/assets/PhantomCameraBtnPrimaryHover.png differ diff --git a/addons/phantom_camera/assets/PhantomCameraBtnPrimaryHover.png.import b/addons/phantom_camera/assets/PhantomCameraBtnPrimaryHover.png.import new file mode 100644 index 0000000..a9b1fa8 --- /dev/null +++ b/addons/phantom_camera/assets/PhantomCameraBtnPrimaryHover.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://pvr8mbvl1onm" +path="res://.godot/imported/PhantomCameraBtnPrimaryHover.png-3d2e4d225f6a86ce8a9c981ee7926a16.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/assets/PhantomCameraBtnPrimaryHover.png" +dest_files=["res://.godot/imported/PhantomCameraBtnPrimaryHover.png-3d2e4d225f6a86ce8a9c981ee7926a16.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/phantom_camera/examples/credits.txt b/addons/phantom_camera/examples/credits.txt new file mode 100644 index 0000000..d5e949a --- /dev/null +++ b/addons/phantom_camera/examples/credits.txt @@ -0,0 +1,7 @@ +##################### +EXAMPLE ASSET CREDITS +##################### + +# level_spritesheet +https://opengameart.org/content/a-platformer-in-the-forest +https://opengameart.org/users/buch diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_example_scene.tscn new file mode 100644 index 0000000..beca1b9 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_example_scene.tscn @@ -0,0 +1,249 @@ +[gd_scene load_steps=12 format=4 uid="uid://ohwjxojqcj63"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_foq54"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_kmt5y"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_1cmgi"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="4_4dx73"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_gcww2"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_i3g4f"] +[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="7_j2i8l"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_ytjsp"] +[ext_resource type="Script" uid="uid://cnnaky2ns2pn4" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_o4c4h"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_yx3lp"] +texture = ExtResource("1_foq54") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_nawqc"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_yx3lp") + +[node name="Root" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="Pillar" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAAAAPr/AAAKAAIAAAAAAPv/AAAKAAMAAAAAAPz/AAAKAAMAAAAAAP3/AAAKAAMAAAAAAP7/AAAKAAMAAAAAAP//AAAKAAMAAAABAPr/AAALAAIAAAABAPv/AAALAAEAAAABAPz/AAALAAEAAAABAP3/AAALAAEAAAABAP7/AAALAAEAAAABAP//AAALAAEAAAACAPr/AAAMAAIAAAACAPv/AAAMAAMAAAACAPz/AAAMAAMAAAACAP3/AAAMAAMAAAACAP7/AAAMAAMAAAACAP//AAAMAAMAAAA=") +tile_set = SubResource("TileSet_nawqc") +collision_enabled = false +navigation_enabled = false + +[node name="Terrain" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAABAAAAAAALAAAAAAACAAAAAAALAAAAAAADAAAAAAALAAAAAAAEAAAAAAALAAAAAAAFAAAAAAALAAAAAAAGAAAAAAALAAAAAAAHAAAAAAALAAAAAAAIAAAAAAALAAAAAAAJAAAAAAAMAAAAAAAJAAEAAAAMAAEAAAAJAAIAAAAMAAEAAAAJAAMAAAAMAAEAAAAJAAQAAAAMAAEAAAAJAAUAAAAMAAEAAAAJAAYAAAAMAAEAAAABAAEAAAALAAEAAAABAAIAAAALAAEAAAABAAMAAAALAAEAAAABAAQAAAAHAAEAAAABAAUAAAALAAEAAAABAAYAAAALAAEAAAACAAEAAAALAAEAAAACAAIAAAALAAEAAAACAAMAAAALAAEAAAACAAQAAAALAAEAAAACAAUAAAALAAEAAAACAAYAAAALAAEAAAADAAEAAAALAAEAAAADAAIAAAALAAEAAAADAAMAAAALAAEAAAADAAQAAAALAAEAAAADAAUAAAALAAEAAAADAAYAAAALAAEAAAAEAAEAAAAHAAEAAAAEAAIAAAALAAEAAAAEAAMAAAALAAEAAAAEAAQAAAALAAEAAAAEAAUAAAALAAEAAAAEAAYAAAALAAEAAAAFAAEAAAALAAEAAAAFAAIAAAALAAEAAAAFAAMAAAALAAEAAAAFAAQAAAAHAAEAAAAFAAUAAAALAAEAAAAFAAYAAAALAAEAAAAGAAEAAAALAAEAAAAGAAIAAAALAAEAAAAGAAMAAAALAAEAAAAGAAQAAAALAAEAAAAGAAUAAAALAAEAAAAGAAYAAAALAAEAAAAHAAEAAAALAAEAAAAHAAIAAAALAAEAAAAHAAMAAAALAAEAAAAHAAQAAAALAAEAAAAHAAUAAAALAAEAAAAHAAYAAAAHAAEAAAAIAAEAAAALAAEAAAAIAAIAAAALAAEAAAAIAAMAAAAHAAEAAAAIAAQAAAALAAEAAAAIAAUAAAALAAEAAAAIAAYAAAALAAEAAAAKAAEAAAAIAAUAAAALAAEAAAAIAAUAAAAMAAEAAAAIAAUAAAANAAEAAAAIAAUAAAAKAAIAAAAIAAYAAAALAAIAAAAIAAYAAAAMAAIAAAAIAAYAAAANAAIAAAAIAAYAAAAKAAMAAAALAAEAAAAKAAQAAAALAAEAAAALAAMAAAALAAEAAAALAAQAAAALAAEAAAAMAAMAAAALAAEAAAAMAAQAAAALAAEAAAANAAMAAAALAAEAAAANAAQAAAALAAEAAAAOAAEAAAAIAAUAAAAPAAEAAAAIAAUAAAAQAAEAAAAIAAUAAAAOAAIAAAAIAAYAAAAPAAIAAAAIAAYAAAAQAAIAAAAIAAYAAAAOAAMAAAALAAEAAAAPAAMAAAALAAEAAAAPAAQAAAALAAEAAAAQAAQAAAALAAEAAAAQAAMAAAALAAEAAAAOAAQAAAALAAEAAAARAAAAAAALAAQAAAARAAEAAAALAAUAAAARAAIAAAALAAUAAAARAAMAAAALAAUAAAARAAQAAAALAAUAAAASAAAAAAAMAAQAAAATAAAAAAAMAAQAAAAUAAAAAAAMAAQAAAAVAAAAAAAMAAQAAAAWAAAAAAAMAAQAAAAXAAAAAAAMAAQAAAASAAEAAAAMAAUAAAASAAIAAAAMAAUAAAASAAMAAAAMAAUAAAASAAQAAAAMAAUAAAATAAEAAAAMAAUAAAATAAIAAAAJAAYAAAATAAMAAAAMAAUAAAATAAQAAAAMAAUAAAAUAAEAAAAMAAUAAAAUAAIAAAAMAAUAAAAUAAMAAAAMAAUAAAAUAAQAAAAMAAUAAAAVAAEAAAAMAAUAAAAVAAIAAAAMAAUAAAAVAAMAAAAMAAUAAAAVAAQAAAAMAAUAAAAWAAEAAAAMAAUAAAAWAAIAAAAMAAUAAAAWAAMAAAAMAAUAAAAWAAQAAAAKAAYAAAAXAAEAAAAMAAUAAAAXAAIAAAAMAAUAAAAXAAMAAAAMAAUAAAAXAAQAAAAMAAUAAAARAAUAAAALAAUAAAARAAYAAAALAAUAAAASAAUAAAAJAAYAAAASAAYAAAAMAAUAAAATAAUAAAAMAAUAAAATAAYAAAAMAAUAAAAUAAUAAAAMAAUAAAAUAAYAAAAMAAUAAAAVAAUAAAAMAAUAAAAVAAYAAAAMAAUAAAAWAAUAAAAMAAUAAAAWAAYAAAAMAAUAAAAXAAUAAAAMAAUAAAAXAAYAAAAMAAUAAAAKAP7/AAALAAQAAAALAP7/AAAMAAQAAAAMAP7/AAAMAAQAAAAKAP//AAALAAYAAAALAP//AAAMAAYAAAAMAP//AAAMAAYAAAAQAP7/AAANAAQAAAAQAP//AAANAAYAAAANAP7/AAAMAAQAAAAOAP7/AAAMAAQAAAAPAP7/AAAMAAQAAAANAP//AAAMAAYAAAAOAP//AAAMAAYAAAAPAP//AAAMAAYAAAAMAP3/AAAOAAAAAAADAP//AAAOAAIAAAAEAP//AAAPAAIAAAAFAP//AAAQAAIAAAAGAP//AAAOAAIAAAAHAP//AAAPAAIAAAAIAP//AAAQAAIAAAD//wAAAAAKAAAAAAD//wEAAAAKAAEAAAD//wIAAAAKAAEAAAD//wMAAAAKAAEAAAD//wQAAAAKAAEAAAD//wUAAAAKAAEAAAD//wYAAAAKAAEAAAD//wcAAAAKAAEAAAD//wgAAAAKAAEAAAAAAAAAAAALAAAAAAAAAAEAAAALAAEAAAAAAAIAAAALAAEAAAAAAAMAAAALAAEAAAAAAAQAAAALAAEAAAAAAAUAAAALAAEAAAAAAAYAAAALAAEAAAAAAAcAAAALAAEAAAAAAAgAAAALAAEAAAABAAgAAAALAAEAAAACAAgAAAALAAEAAAADAAgAAAALAAEAAAAEAAgAAAALAAEAAAAFAAgAAAALAAEAAAAGAAgAAAALAAEAAAAHAAgAAAALAAEAAAAIAAgAAAALAAEAAAAJAAgAAAAMAAEAAAAJAAcAAAAMAAEAAAAIAAcAAAALAAEAAAAHAAcAAAALAAEAAAAGAAcAAAAHAAEAAAAFAAcAAAALAAEAAAAEAAcAAAALAAEAAAADAAcAAAALAAEAAAACAAcAAAALAAEAAAABAAcAAAALAAEAAAD///v/AAANAAQAAAD///z/AAANAAUAAAD///3/AAANAAUAAAD///7/AAANAAUAAAD/////AAANAAYAAAD+//v/AAAMAAQAAAD9//v/AAAMAAQAAAD+//z/AAAJAAYAAAD9//z/AAAMAAUAAAD6////AAAMAAUAAAD7////AAAMAAUAAAD8////AAAMAAUAAAD9////AAAMAAUAAAD+////AAAMAAUAAAD+//7/AAAMAAUAAAD+//3/AAAMAAUAAAD9//3/AAAMAAUAAAD9//7/AAAKAAYAAAD+/wAAAAANAAUAAAD+/wEAAAANAAUAAAD+/wIAAAANAAUAAAD+/wMAAAANAAUAAAD+/wQAAAANAAUAAAD+/wUAAAANAAUAAAD+/wYAAAANAAUAAAD9/wAAAAAMAAUAAAD8/wAAAAAMAAUAAAD7/wAAAAAMAAUAAAD6/wAAAAAMAAUAAAD5/wAAAAALAAUAAAD6/wEAAAAMAAUAAAD6/wIAAAAMAAUAAAD6/wMAAAAMAAUAAAD7/wMAAAAMAAUAAAD7/wQAAAAMAAUAAAD8/wEAAAAMAAUAAAD9/wEAAAAMAAUAAAD9/wIAAAAMAAUAAAD9/wMAAAAMAAUAAAD9/wQAAAAMAAUAAAD9/wUAAAAMAAUAAAD9/wYAAAAMAAUAAAD8/wUAAAAMAAUAAAD7/wUAAAAMAAUAAAD8/wYAAAAMAAUAAAD8/wQAAAAKAAYAAAD8/wMAAAAMAAUAAAD8/wIAAAAMAAUAAAD7/wEAAAAMAAUAAAD7/wIAAAAJAAYAAAD7/wYAAAAMAAUAAAD6/wYAAAAMAAUAAAD6/wUAAAAMAAUAAAD6/wQAAAAMAAUAAAD5////AAALAAUAAAD5/wEAAAALAAUAAAD5/wIAAAALAAUAAAD5/wMAAAALAAUAAAD5/wQAAAALAAUAAAD5/wUAAAALAAUAAAD5/wYAAAALAAUAAAD8//r/AAALAAMAAAAOAP3/AAALAAMAAAALAP3/AAALAAMAAAASAP//AAALAAMAAAAUAP//AAALAAMAAAD6//r/AAAQAAUAAAD7//r/AAALAAMAAAANAP3/AAAOAAYAAAAWAP//AAAPAAYAAAD9//r/AAAPAAUAAAAXAP//AAAQAAUAAAD5//v/AAALAAQAAAD5//z/AAALAAUAAAD5//3/AAALAAUAAAD5//7/AAALAAUAAAD6//v/AAAMAAQAAAD6//z/AAAKAAYAAAD6//3/AAAMAAUAAAD6//7/AAAMAAUAAAD7//v/AAAMAAQAAAD7//z/AAAMAAUAAAD7//3/AAAMAAUAAAD7//7/AAAMAAUAAAD8//v/AAAMAAQAAAD8//z/AAAMAAUAAAD8//3/AAAMAAUAAAD8//7/AAAMAAUAAAARAAcAAAALAAUAAAARAAgAAAALAAYAAAAXAAcAAAAMAAUAAAAWAAcAAAAMAAUAAAAVAAcAAAAMAAUAAAAUAAcAAAAMAAUAAAATAAcAAAAMAAUAAAASAAcAAAAMAAUAAAASAAgAAAAMAAYAAAATAAgAAAAMAAYAAAAUAAgAAAAMAAYAAAAVAAgAAAAMAAYAAAAWAAgAAAAMAAYAAAAXAAgAAAAMAAYAAAAKAAUAAAALAAEAAAAKAAYAAAALAAEAAAAKAAcAAAALAAEAAAAKAAgAAAALAAEAAAALAAUAAAALAAEAAAALAAYAAAALAAEAAAALAAcAAAALAAEAAAALAAgAAAALAAEAAAAMAAUAAAALAAEAAAAMAAYAAAALAAEAAAAMAAcAAAALAAEAAAAMAAgAAAALAAEAAAANAAUAAAALAAEAAAANAAYAAAALAAEAAAANAAcAAAALAAEAAAANAAgAAAALAAEAAAAOAAUAAAALAAEAAAAOAAYAAAALAAEAAAAOAAcAAAALAAEAAAAOAAgAAAALAAEAAAAPAAUAAAALAAEAAAAPAAYAAAALAAEAAAAPAAcAAAALAAEAAAAPAAgAAAALAAEAAAAQAAUAAAALAAEAAAAQAAYAAAALAAEAAAAQAAcAAAALAAEAAAAQAAgAAAALAAEAAAAdAAAAAAANAAQAAAAdAAEAAAANAAUAAAAdAAIAAAANAAUAAAAdAAMAAAANAAUAAAAdAAQAAAANAAUAAAAdAAUAAAANAAUAAAAdAAYAAAANAAUAAAAdAAcAAAANAAUAAAAdAAgAAAANAAYAAAAZAP//AAAOAAQAAAAYAAAAAAAMAAQAAAAZAAAAAAAMAAQAAAAaAAAAAAAMAAQAAAAbAAAAAAAMAAQAAAAcAAAAAAAMAAQAAAAYAAEAAAAMAAUAAAAZAAEAAAAMAAUAAAAaAAEAAAAMAAUAAAAbAAEAAAAMAAUAAAAcAAEAAAAMAAUAAAAcAAIAAAAMAAUAAAAcAAMAAAAJAAYAAAAbAAIAAAAMAAUAAAAaAAIAAAAMAAUAAAAZAAIAAAAMAAUAAAAYAAIAAAAMAAUAAAAYAAMAAAAMAAUAAAAYAAQAAAAMAAUAAAAYAAUAAAAMAAUAAAAYAAYAAAAMAAUAAAAYAAcAAAAMAAUAAAAYAAgAAAAMAAYAAAAZAAMAAAAMAAUAAAAZAAQAAAAMAAUAAAAZAAUAAAAMAAUAAAAZAAYAAAAMAAUAAAAZAAcAAAAMAAUAAAAZAAgAAAAMAAYAAAAaAAMAAAAMAAUAAAAaAAQAAAAMAAUAAAAaAAUAAAAMAAUAAAAaAAYAAAAKAAYAAAAaAAcAAAAMAAUAAAAaAAgAAAAMAAYAAAAbAAMAAAAMAAUAAAAbAAQAAAAMAAUAAAAbAAUAAAAMAAUAAAAbAAYAAAAMAAUAAAAbAAcAAAAMAAUAAAAbAAgAAAAMAAYAAAAcAAQAAAAMAAUAAAAcAAUAAAAMAAUAAAAcAAYAAAAMAAUAAAAcAAcAAAAMAAUAAAAcAAgAAAAMAAYAAAAPAP3/AAAQAAYAAAAiAPr/AAAQAAYAAAAfAPr/AAAOAAYAAAAkAPr/AAAPAAYAAAAgAPr/AAAPAAUAAAAbAP//AAALAAMAAAAaAP//AAALAAMAAAAjAPr/AAALAAMAAAAhAPr/AAALAAMAAAATAP//AAALAAMAAAAVAP//AAALAAMAAAAeAPv/AAALAAQAAAAeAPz/AAALAAUAAAAeAP3/AAALAAUAAAAeAP7/AAALAAUAAAAeAP//AAALAAUAAAAmAP//AAANAAUAAAAmAP7/AAANAAUAAAAmAP3/AAANAAUAAAAmAPv/AAANAAQAAAAfAPv/AAAMAAQAAAAgAPv/AAAMAAQAAAAhAPv/AAAMAAQAAAAiAPv/AAAMAAQAAAAjAPv/AAAMAAQAAAAkAPv/AAAMAAQAAAAlAPv/AAAMAAQAAAAmAPz/AAANAAUAAAAlAP//AAAMAAUAAAAlAP7/AAAMAAUAAAAlAP3/AAAMAAUAAAAlAPz/AAAMAAUAAAAkAPz/AAAMAAUAAAAjAPz/AAAMAAUAAAAiAPz/AAAMAAUAAAAhAPz/AAAMAAUAAAAgAPz/AAAMAAUAAAAfAPz/AAAMAAUAAAAfAP3/AAAKAAYAAAAfAP7/AAAMAAUAAAAfAP//AAAMAAUAAAAkAP//AAAKAAYAAAAkAP7/AAAJAAYAAAAkAP3/AAAMAAUAAAAjAP3/AAAMAAUAAAAiAP3/AAAMAAUAAAAhAP3/AAAMAAUAAAAgAP3/AAAMAAUAAAAgAP7/AAAJAAYAAAAgAP//AAAMAAUAAAAjAP//AAAMAAUAAAAjAP7/AAAMAAUAAAAiAP7/AAAMAAUAAAAhAP7/AAAMAAUAAAAhAP//AAAMAAUAAAAiAP//AAAMAAUAAAAeAAgAAAALAAYAAAAeAAcAAAALAAUAAAAeAAYAAAALAAUAAAAeAAUAAAALAAUAAAAeAAQAAAALAAUAAAAeAAMAAAALAAUAAAAeAAIAAAALAAUAAAAeAAEAAAALAAUAAAAeAAAAAAALAAUAAAAfAAgAAAAMAAYAAAAgAAgAAAAMAAYAAAAhAAgAAAAMAAYAAAAiAAgAAAAMAAYAAAAjAAgAAAAMAAYAAAAkAAgAAAAMAAYAAAAlAAgAAAAMAAYAAAAmAAgAAAANAAYAAAAmAAAAAAANAAUAAAAmAAEAAAANAAUAAAAmAAIAAAANAAUAAAAmAAMAAAANAAUAAAAmAAQAAAANAAUAAAAmAAUAAAANAAUAAAAmAAYAAAANAAUAAAAmAAcAAAANAAUAAAAfAAAAAAAMAAUAAAAfAAEAAAAMAAUAAAAfAAIAAAAMAAUAAAAfAAMAAAAMAAUAAAAfAAQAAAAMAAUAAAAfAAUAAAAMAAUAAAAfAAYAAAAKAAYAAAAfAAcAAAAMAAUAAAAgAAAAAAAMAAUAAAAgAAEAAAAMAAUAAAAgAAIAAAAMAAUAAAAgAAMAAAAMAAUAAAAgAAQAAAAMAAUAAAAgAAUAAAAMAAUAAAAgAAYAAAAMAAUAAAAgAAcAAAAMAAUAAAAhAAAAAAAMAAUAAAAhAAEAAAAMAAUAAAAhAAIAAAAKAAYAAAAhAAMAAAAMAAUAAAAhAAQAAAAMAAUAAAAhAAUAAAAMAAUAAAAhAAYAAAAMAAUAAAAhAAcAAAAMAAUAAAAiAAAAAAAMAAUAAAAiAAEAAAAMAAUAAAAiAAIAAAAMAAUAAAAiAAMAAAAMAAUAAAAiAAQAAAAKAAYAAAAiAAUAAAAKAAYAAAAiAAYAAAAMAAUAAAAiAAcAAAAMAAUAAAAjAAAAAAAMAAUAAAAjAAEAAAAMAAUAAAAjAAIAAAAMAAUAAAAjAAMAAAAMAAUAAAAjAAQAAAAMAAUAAAAjAAUAAAAMAAUAAAAjAAYAAAAMAAUAAAAjAAcAAAAMAAUAAAAkAAAAAAAKAAYAAAAkAAEAAAAMAAUAAAAkAAIAAAAMAAUAAAAkAAMAAAAMAAUAAAAkAAQAAAAMAAUAAAAkAAUAAAAMAAUAAAAkAAYAAAAMAAUAAAAkAAcAAAAKAAYAAAAlAAAAAAAMAAUAAAAlAAEAAAAMAAUAAAAlAAIAAAAMAAUAAAAlAAMAAAAMAAUAAAAlAAQAAAAMAAUAAAAlAAUAAAAMAAUAAAAlAAYAAAAMAAUAAAAlAAcAAAAMAAUAAAD6/wcAAAAMAAUAAAD7/wcAAAAMAAUAAAD8/wcAAAAMAAUAAAD9/wcAAAAMAAUAAAD5/wcAAAALAAUAAAD+/wcAAAANAAUAAAD5/wgAAAALAAYAAAD6/wgAAAAMAAYAAAD7/wgAAAAMAAYAAAD8/wgAAAAMAAYAAAD9/wgAAAAMAAYAAAD+/wgAAAANAAYAAAA=") +tile_set = SubResource("TileSet_nawqc") + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_kmt5y")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_1cmgi")] +unique_name_in_owner = true +visible = false + +[node name="Controls" type="Label" parent="."] +offset_left = 167.0 +offset_top = -145.0 +offset_right = 332.0 +offset_bottom = -81.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("4_4dx73") +text = "[WASD] to move +[Space] to jump" + +[node name="Camera2D" type="Camera2D" parent="."] +physics_interpolation_mode = 1 +position = Vector2(227, -28) +zoom = Vector2(1.5, 1.5) +process_callback = 0 +editor_draw_limits = true + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("5_gcww2") + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera2D" type="Node2D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +process_priority = -1 +top_level = true +position = Vector2(227, -28) +script = ExtResource("6_i3g4f") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../CharacterBody2D") +zoom = Vector2(1.5, 1.5) +frame_preview = false +tween_resource = ExtResource("7_j2i8l") +tween_on_load = false +follow_damping = true +draw_limits = true + +[node name="CharacterBody2D" parent="Player" instance=ExtResource("8_ytjsp")] +position = Vector2(227, -28) +script = ExtResource("9_o4c4h") diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_framed_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_framed_example_scene.tscn new file mode 100644 index 0000000..9b9cc88 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_framed_example_scene.tscn @@ -0,0 +1,251 @@ +[gd_scene load_steps=12 format=4 uid="uid://dg1tuoxd3b4tw"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_nf5bo"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_5oggv"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_aku7q"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_j3ux0"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_uwr6r"] +[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_4l0c3"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_briql"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_i4m1d"] +[ext_resource type="Script" uid="uid://cnnaky2ns2pn4" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_m3lnd"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_dpuou"] +texture = ExtResource("1_nf5bo") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_kxirl"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_dpuou") + +[node name="Root" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -345.0 +offset_top = -143.0 +offset_right = 947.0 +offset_bottom = 578.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="Pillar" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAAAAPr/AAAKAAIAAAAAAPv/AAAKAAMAAAAAAPz/AAAKAAMAAAAAAP3/AAAKAAMAAAAAAP7/AAAKAAMAAAAAAP//AAAKAAMAAAABAPr/AAALAAIAAAABAPv/AAALAAEAAAABAPz/AAALAAEAAAABAP3/AAALAAEAAAABAP7/AAALAAEAAAABAP//AAALAAEAAAACAPr/AAAMAAIAAAACAPv/AAAMAAMAAAACAPz/AAAMAAMAAAACAP3/AAAMAAMAAAACAP7/AAAMAAMAAAACAP//AAAMAAMAAAA=") +tile_set = SubResource("TileSet_kxirl") +collision_enabled = false +navigation_enabled = false + +[node name="Terrain" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAABAAAAAAALAAAAAAACAAAAAAALAAAAAAADAAAAAAALAAAAAAAEAAAAAAALAAAAAAAFAAAAAAALAAAAAAAGAAAAAAALAAAAAAAHAAAAAAALAAAAAAAIAAAAAAALAAAAAAAJAAAAAAAMAAAAAAAJAAEAAAAMAAEAAAAJAAIAAAAMAAEAAAAJAAMAAAAMAAEAAAAJAAQAAAAMAAEAAAAJAAUAAAAMAAEAAAAJAAYAAAAMAAEAAAABAAEAAAALAAEAAAABAAIAAAALAAEAAAABAAMAAAALAAEAAAABAAQAAAAHAAEAAAABAAUAAAALAAEAAAABAAYAAAALAAEAAAACAAEAAAALAAEAAAACAAIAAAALAAEAAAACAAMAAAALAAEAAAACAAQAAAALAAEAAAACAAUAAAALAAEAAAACAAYAAAALAAEAAAADAAEAAAALAAEAAAADAAIAAAALAAEAAAADAAMAAAALAAEAAAADAAQAAAALAAEAAAADAAUAAAALAAEAAAADAAYAAAALAAEAAAAEAAEAAAAHAAEAAAAEAAIAAAALAAEAAAAEAAMAAAALAAEAAAAEAAQAAAALAAEAAAAEAAUAAAALAAEAAAAEAAYAAAALAAEAAAAFAAEAAAALAAEAAAAFAAIAAAALAAEAAAAFAAMAAAALAAEAAAAFAAQAAAAHAAEAAAAFAAUAAAALAAEAAAAFAAYAAAALAAEAAAAGAAEAAAALAAEAAAAGAAIAAAALAAEAAAAGAAMAAAALAAEAAAAGAAQAAAALAAEAAAAGAAUAAAALAAEAAAAGAAYAAAALAAEAAAAHAAEAAAALAAEAAAAHAAIAAAALAAEAAAAHAAMAAAALAAEAAAAHAAQAAAALAAEAAAAHAAUAAAALAAEAAAAHAAYAAAAHAAEAAAAIAAEAAAALAAEAAAAIAAIAAAALAAEAAAAIAAMAAAAHAAEAAAAIAAQAAAALAAEAAAAIAAUAAAALAAEAAAAIAAYAAAALAAEAAAAKAAEAAAAIAAUAAAALAAEAAAAIAAUAAAAMAAEAAAAIAAUAAAANAAEAAAAIAAUAAAAKAAIAAAAIAAYAAAALAAIAAAAIAAYAAAAMAAIAAAAIAAYAAAANAAIAAAAIAAYAAAAKAAMAAAALAAEAAAAKAAQAAAALAAEAAAALAAMAAAALAAEAAAALAAQAAAALAAEAAAAMAAMAAAALAAEAAAAMAAQAAAALAAEAAAANAAMAAAALAAEAAAANAAQAAAALAAEAAAAOAAEAAAAIAAUAAAAPAAEAAAAIAAUAAAAQAAEAAAAIAAUAAAAOAAIAAAAIAAYAAAAPAAIAAAAIAAYAAAAQAAIAAAAIAAYAAAAOAAMAAAALAAEAAAAPAAMAAAALAAEAAAAPAAQAAAALAAEAAAAQAAQAAAALAAEAAAAQAAMAAAALAAEAAAAOAAQAAAALAAEAAAARAAAAAAALAAQAAAARAAEAAAALAAUAAAARAAIAAAALAAUAAAARAAMAAAALAAUAAAARAAQAAAALAAUAAAASAAAAAAAMAAQAAAATAAAAAAAMAAQAAAAUAAAAAAAMAAQAAAAVAAAAAAAMAAQAAAAWAAAAAAAMAAQAAAAXAAAAAAAMAAQAAAASAAEAAAAMAAUAAAASAAIAAAAMAAUAAAASAAMAAAAMAAUAAAASAAQAAAAMAAUAAAATAAEAAAAMAAUAAAATAAIAAAAJAAYAAAATAAMAAAAMAAUAAAATAAQAAAAMAAUAAAAUAAEAAAAMAAUAAAAUAAIAAAAMAAUAAAAUAAMAAAAMAAUAAAAUAAQAAAAMAAUAAAAVAAEAAAAMAAUAAAAVAAIAAAAMAAUAAAAVAAMAAAAMAAUAAAAVAAQAAAAMAAUAAAAWAAEAAAAMAAUAAAAWAAIAAAAMAAUAAAAWAAMAAAAMAAUAAAAWAAQAAAAKAAYAAAAXAAEAAAAMAAUAAAAXAAIAAAAMAAUAAAAXAAMAAAAMAAUAAAAXAAQAAAAMAAUAAAARAAUAAAALAAUAAAARAAYAAAALAAUAAAASAAUAAAAJAAYAAAASAAYAAAAMAAUAAAATAAUAAAAMAAUAAAATAAYAAAAMAAUAAAAUAAUAAAAMAAUAAAAUAAYAAAAMAAUAAAAVAAUAAAAMAAUAAAAVAAYAAAAMAAUAAAAWAAUAAAAMAAUAAAAWAAYAAAAMAAUAAAAXAAUAAAAMAAUAAAAXAAYAAAAMAAUAAAAKAP7/AAALAAQAAAALAP7/AAAMAAQAAAAMAP7/AAAMAAQAAAAKAP//AAALAAYAAAALAP//AAAMAAYAAAAMAP//AAAMAAYAAAAQAP7/AAANAAQAAAAQAP//AAANAAYAAAANAP7/AAAMAAQAAAAOAP7/AAAMAAQAAAAPAP7/AAAMAAQAAAANAP//AAAMAAYAAAAOAP//AAAMAAYAAAAPAP//AAAMAAYAAAAMAP3/AAAOAAAAAAADAP//AAAOAAIAAAAEAP//AAAPAAIAAAAFAP//AAAQAAIAAAAGAP//AAAOAAIAAAAHAP//AAAPAAIAAAAIAP//AAAQAAIAAAD//wAAAAAKAAAAAAD//wEAAAAKAAEAAAD//wIAAAAKAAEAAAD//wMAAAAKAAEAAAD//wQAAAAKAAEAAAD//wUAAAAKAAEAAAD//wYAAAAKAAEAAAD//wcAAAAKAAEAAAD//wgAAAAKAAEAAAAAAAAAAAALAAAAAAAAAAEAAAALAAEAAAAAAAIAAAALAAEAAAAAAAMAAAALAAEAAAAAAAQAAAALAAEAAAAAAAUAAAALAAEAAAAAAAYAAAALAAEAAAAAAAcAAAALAAEAAAAAAAgAAAALAAEAAAABAAgAAAALAAEAAAACAAgAAAALAAEAAAADAAgAAAALAAEAAAAEAAgAAAALAAEAAAAFAAgAAAALAAEAAAAGAAgAAAALAAEAAAAHAAgAAAALAAEAAAAIAAgAAAALAAEAAAAJAAgAAAAMAAEAAAAJAAcAAAAMAAEAAAAIAAcAAAALAAEAAAAHAAcAAAALAAEAAAAGAAcAAAAHAAEAAAAFAAcAAAALAAEAAAAEAAcAAAALAAEAAAADAAcAAAALAAEAAAACAAcAAAALAAEAAAABAAcAAAALAAEAAAD///v/AAANAAQAAAD///z/AAANAAUAAAD///3/AAANAAUAAAD///7/AAANAAUAAAD/////AAANAAYAAAD+//v/AAAMAAQAAAD9//v/AAAMAAQAAAD+//z/AAAJAAYAAAD9//z/AAAMAAUAAAD6////AAAMAAUAAAD7////AAAMAAUAAAD8////AAAMAAUAAAD9////AAAMAAUAAAD+////AAAMAAUAAAD+//7/AAAMAAUAAAD+//3/AAAMAAUAAAD9//3/AAAMAAUAAAD9//7/AAAKAAYAAAD+/wAAAAANAAUAAAD+/wEAAAANAAUAAAD+/wIAAAANAAUAAAD+/wMAAAANAAUAAAD+/wQAAAANAAUAAAD+/wUAAAANAAUAAAD+/wYAAAANAAUAAAD9/wAAAAAMAAUAAAD8/wAAAAAMAAUAAAD7/wAAAAAMAAUAAAD6/wAAAAAMAAUAAAD5/wAAAAALAAUAAAD6/wEAAAAMAAUAAAD6/wIAAAAMAAUAAAD6/wMAAAAMAAUAAAD7/wMAAAAMAAUAAAD7/wQAAAAMAAUAAAD8/wEAAAAMAAUAAAD9/wEAAAAMAAUAAAD9/wIAAAAMAAUAAAD9/wMAAAAMAAUAAAD9/wQAAAAMAAUAAAD9/wUAAAAMAAUAAAD9/wYAAAAMAAUAAAD8/wUAAAAMAAUAAAD7/wUAAAAMAAUAAAD8/wYAAAAMAAUAAAD8/wQAAAAKAAYAAAD8/wMAAAAMAAUAAAD8/wIAAAAMAAUAAAD7/wEAAAAMAAUAAAD7/wIAAAAJAAYAAAD7/wYAAAAMAAUAAAD6/wYAAAAMAAUAAAD6/wUAAAAMAAUAAAD6/wQAAAAMAAUAAAD5////AAALAAUAAAD5/wEAAAALAAUAAAD5/wIAAAALAAUAAAD5/wMAAAALAAUAAAD5/wQAAAALAAUAAAD5/wUAAAALAAUAAAD5/wYAAAALAAUAAAD8//r/AAALAAMAAAAOAP3/AAALAAMAAAALAP3/AAALAAMAAAASAP//AAALAAMAAAAUAP//AAALAAMAAAD6//r/AAAQAAUAAAD7//r/AAALAAMAAAANAP3/AAAOAAYAAAAWAP//AAAPAAYAAAD9//r/AAAPAAUAAAAXAP//AAAQAAUAAAD5//v/AAALAAQAAAD5//z/AAALAAUAAAD5//3/AAALAAUAAAD5//7/AAALAAUAAAD6//v/AAAMAAQAAAD6//z/AAAKAAYAAAD6//3/AAAMAAUAAAD6//7/AAAMAAUAAAD7//v/AAAMAAQAAAD7//z/AAAMAAUAAAD7//3/AAAMAAUAAAD7//7/AAAMAAUAAAD8//v/AAAMAAQAAAD8//z/AAAMAAUAAAD8//3/AAAMAAUAAAD8//7/AAAMAAUAAAARAAcAAAALAAUAAAARAAgAAAALAAYAAAAXAAcAAAAMAAUAAAAWAAcAAAAMAAUAAAAVAAcAAAAMAAUAAAAUAAcAAAAMAAUAAAATAAcAAAAMAAUAAAASAAcAAAAMAAUAAAASAAgAAAAMAAYAAAATAAgAAAAMAAYAAAAUAAgAAAAMAAYAAAAVAAgAAAAMAAYAAAAWAAgAAAAMAAYAAAAXAAgAAAAMAAYAAAAKAAUAAAALAAEAAAAKAAYAAAALAAEAAAAKAAcAAAALAAEAAAAKAAgAAAALAAEAAAALAAUAAAALAAEAAAALAAYAAAALAAEAAAALAAcAAAALAAEAAAALAAgAAAALAAEAAAAMAAUAAAALAAEAAAAMAAYAAAALAAEAAAAMAAcAAAALAAEAAAAMAAgAAAALAAEAAAANAAUAAAALAAEAAAANAAYAAAALAAEAAAANAAcAAAALAAEAAAANAAgAAAALAAEAAAAOAAUAAAALAAEAAAAOAAYAAAALAAEAAAAOAAcAAAALAAEAAAAOAAgAAAALAAEAAAAPAAUAAAALAAEAAAAPAAYAAAALAAEAAAAPAAcAAAALAAEAAAAPAAgAAAALAAEAAAAQAAUAAAALAAEAAAAQAAYAAAALAAEAAAAQAAcAAAALAAEAAAAQAAgAAAALAAEAAAAdAAAAAAANAAQAAAAdAAEAAAANAAUAAAAdAAIAAAANAAUAAAAdAAMAAAANAAUAAAAdAAQAAAANAAUAAAAdAAUAAAANAAUAAAAdAAYAAAANAAUAAAAdAAcAAAANAAUAAAAdAAgAAAANAAYAAAAZAP//AAAOAAQAAAAYAAAAAAAMAAQAAAAZAAAAAAAMAAQAAAAaAAAAAAAMAAQAAAAbAAAAAAAMAAQAAAAcAAAAAAAMAAQAAAAYAAEAAAAMAAUAAAAZAAEAAAAMAAUAAAAaAAEAAAAMAAUAAAAbAAEAAAAMAAUAAAAcAAEAAAAMAAUAAAAcAAIAAAAMAAUAAAAcAAMAAAAJAAYAAAAbAAIAAAAMAAUAAAAaAAIAAAAMAAUAAAAZAAIAAAAMAAUAAAAYAAIAAAAMAAUAAAAYAAMAAAAMAAUAAAAYAAQAAAAMAAUAAAAYAAUAAAAMAAUAAAAYAAYAAAAMAAUAAAAYAAcAAAAMAAUAAAAYAAgAAAAMAAYAAAAZAAMAAAAMAAUAAAAZAAQAAAAMAAUAAAAZAAUAAAAMAAUAAAAZAAYAAAAMAAUAAAAZAAcAAAAMAAUAAAAZAAgAAAAMAAYAAAAaAAMAAAAMAAUAAAAaAAQAAAAMAAUAAAAaAAUAAAAMAAUAAAAaAAYAAAAKAAYAAAAaAAcAAAAMAAUAAAAaAAgAAAAMAAYAAAAbAAMAAAAMAAUAAAAbAAQAAAAMAAUAAAAbAAUAAAAMAAUAAAAbAAYAAAAMAAUAAAAbAAcAAAAMAAUAAAAbAAgAAAAMAAYAAAAcAAQAAAAMAAUAAAAcAAUAAAAMAAUAAAAcAAYAAAAMAAUAAAAcAAcAAAAMAAUAAAAcAAgAAAAMAAYAAAAPAP3/AAAQAAYAAAAiAPr/AAAQAAYAAAAfAPr/AAAOAAYAAAAkAPr/AAAPAAYAAAAgAPr/AAAPAAUAAAAbAP//AAALAAMAAAAaAP//AAALAAMAAAAjAPr/AAALAAMAAAAhAPr/AAALAAMAAAATAP//AAALAAMAAAAVAP//AAALAAMAAAAeAPv/AAALAAQAAAAeAPz/AAALAAUAAAAeAP3/AAALAAUAAAAeAP7/AAALAAUAAAAeAP//AAALAAUAAAAmAP//AAANAAUAAAAmAP7/AAANAAUAAAAmAP3/AAANAAUAAAAmAPv/AAANAAQAAAAfAPv/AAAMAAQAAAAgAPv/AAAMAAQAAAAhAPv/AAAMAAQAAAAiAPv/AAAMAAQAAAAjAPv/AAAMAAQAAAAkAPv/AAAMAAQAAAAlAPv/AAAMAAQAAAAmAPz/AAANAAUAAAAlAP//AAAMAAUAAAAlAP7/AAAMAAUAAAAlAP3/AAAMAAUAAAAlAPz/AAAMAAUAAAAkAPz/AAAMAAUAAAAjAPz/AAAMAAUAAAAiAPz/AAAMAAUAAAAhAPz/AAAMAAUAAAAgAPz/AAAMAAUAAAAfAPz/AAAMAAUAAAAfAP3/AAAKAAYAAAAfAP7/AAAMAAUAAAAfAP//AAAMAAUAAAAkAP//AAAKAAYAAAAkAP7/AAAJAAYAAAAkAP3/AAAMAAUAAAAjAP3/AAAMAAUAAAAiAP3/AAAMAAUAAAAhAP3/AAAMAAUAAAAgAP3/AAAMAAUAAAAgAP7/AAAJAAYAAAAgAP//AAAMAAUAAAAjAP//AAAMAAUAAAAjAP7/AAAMAAUAAAAiAP7/AAAMAAUAAAAhAP7/AAAMAAUAAAAhAP//AAAMAAUAAAAiAP//AAAMAAUAAAAeAAgAAAALAAYAAAAeAAcAAAALAAUAAAAeAAYAAAALAAUAAAAeAAUAAAALAAUAAAAeAAQAAAALAAUAAAAeAAMAAAALAAUAAAAeAAIAAAALAAUAAAAeAAEAAAALAAUAAAAeAAAAAAALAAUAAAAfAAgAAAAMAAYAAAAgAAgAAAAMAAYAAAAhAAgAAAAMAAYAAAAiAAgAAAAMAAYAAAAjAAgAAAAMAAYAAAAkAAgAAAAMAAYAAAAlAAgAAAAMAAYAAAAmAAgAAAANAAYAAAAmAAAAAAANAAUAAAAmAAEAAAANAAUAAAAmAAIAAAANAAUAAAAmAAMAAAANAAUAAAAmAAQAAAANAAUAAAAmAAUAAAANAAUAAAAmAAYAAAANAAUAAAAmAAcAAAANAAUAAAAfAAAAAAAMAAUAAAAfAAEAAAAMAAUAAAAfAAIAAAAMAAUAAAAfAAMAAAAMAAUAAAAfAAQAAAAMAAUAAAAfAAUAAAAMAAUAAAAfAAYAAAAKAAYAAAAfAAcAAAAMAAUAAAAgAAAAAAAMAAUAAAAgAAEAAAAMAAUAAAAgAAIAAAAMAAUAAAAgAAMAAAAMAAUAAAAgAAQAAAAMAAUAAAAgAAUAAAAMAAUAAAAgAAYAAAAMAAUAAAAgAAcAAAAMAAUAAAAhAAAAAAAMAAUAAAAhAAEAAAAMAAUAAAAhAAIAAAAKAAYAAAAhAAMAAAAMAAUAAAAhAAQAAAAMAAUAAAAhAAUAAAAMAAUAAAAhAAYAAAAMAAUAAAAhAAcAAAAMAAUAAAAiAAAAAAAMAAUAAAAiAAEAAAAMAAUAAAAiAAIAAAAMAAUAAAAiAAMAAAAMAAUAAAAiAAQAAAAKAAYAAAAiAAUAAAAKAAYAAAAiAAYAAAAMAAUAAAAiAAcAAAAMAAUAAAAjAAAAAAAMAAUAAAAjAAEAAAAMAAUAAAAjAAIAAAAMAAUAAAAjAAMAAAAMAAUAAAAjAAQAAAAMAAUAAAAjAAUAAAAMAAUAAAAjAAYAAAAMAAUAAAAjAAcAAAAMAAUAAAAkAAAAAAAKAAYAAAAkAAEAAAAMAAUAAAAkAAIAAAAMAAUAAAAkAAMAAAAMAAUAAAAkAAQAAAAMAAUAAAAkAAUAAAAMAAUAAAAkAAYAAAAMAAUAAAAkAAcAAAAKAAYAAAAlAAAAAAAMAAUAAAAlAAEAAAAMAAUAAAAlAAIAAAAMAAUAAAAlAAMAAAAMAAUAAAAlAAQAAAAMAAUAAAAlAAUAAAAMAAUAAAAlAAYAAAAMAAUAAAAlAAcAAAAMAAUAAAD6/wcAAAAMAAUAAAD7/wcAAAAMAAUAAAD8/wcAAAAMAAUAAAD9/wcAAAAMAAUAAAD5/wcAAAALAAUAAAD+/wcAAAANAAUAAAD5/wgAAAALAAYAAAD6/wgAAAAMAAYAAAD7/wgAAAAMAAYAAAD8/wgAAAAMAAYAAAD9/wgAAAAMAAYAAAD+/wgAAAANAAYAAAA=") +tile_set = SubResource("TileSet_kxirl") + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_5oggv")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_aku7q")] +unique_name_in_owner = true +visible = false + +[node name="Camera2D" type="Camera2D" parent="."] +physics_interpolation_mode = 1 +position = Vector2(215, -73) +zoom = Vector2(2, 2) +process_callback = 0 +editor_draw_limits = true + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("4_j3ux0") + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera2D" type="Node2D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +top_level = true +position = Vector2(215, -73) +script = ExtResource("5_uwr6r") +priority = 5 +follow_mode = 5 +follow_target = NodePath("../CharacterBody2D") +zoom = Vector2(2, 2) +tween_resource = ExtResource("6_4l0c3") +tween_on_load = false +follow_offset = Vector2(0, -45) +follow_damping = true +dead_zone_width = 0.25 +dead_zone_height = 0.8 +show_viewfinder_in_play = true +draw_limits = true + +[node name="Label" type="Label" parent="Player"] +offset_left = 167.0 +offset_top = -145.0 +offset_right = 332.0 +offset_bottom = -81.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("7_briql") +text = "[WASD] to move +[Space] to jump" + +[node name="CharacterBody2D" parent="Player" instance=ExtResource("8_i4m1d")] +position = Vector2(215, -28) +script = ExtResource("9_m3lnd") diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_group_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_group_example_scene.tscn new file mode 100644 index 0000000..dd7bcbc --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_group_example_scene.tscn @@ -0,0 +1,261 @@ +[gd_scene load_steps=14 format=4 uid="uid://bio6mao7gtru2"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_8rflf"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_tafwr"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_37c7w"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_dxiro"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="5_gaaip"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_ojk83"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="7_awenl"] +[ext_resource type="Texture2D" uid="uid://cwep0on2tthn7" path="res://addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png" id="8_ys0m4"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="9_witv0"] +[ext_resource type="Script" uid="uid://cnnaky2ns2pn4" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="10_aivri"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_3qxnm"] +texture = ExtResource("1_8rflf") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_14yng"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_3qxnm") + +[sub_resource type="Resource" id="Resource_spy00"] +script = ExtResource("7_awenl") +duration = 0.3 +transition = 4 +ease = 2 + +[node name="Root" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="Pillar" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAAAAPr/AAAKAAIAAAAAAPv/AAAKAAMAAAAAAPz/AAAKAAMAAAAAAP3/AAAKAAMAAAAAAP7/AAAKAAMAAAAAAP//AAAKAAMAAAABAPr/AAALAAIAAAABAPv/AAALAAEAAAABAPz/AAALAAEAAAABAP3/AAALAAEAAAABAP7/AAALAAEAAAABAP//AAALAAEAAAACAPr/AAAMAAIAAAACAPv/AAAMAAMAAAACAPz/AAAMAAMAAAACAP3/AAAMAAMAAAACAP7/AAAMAAMAAAACAP//AAAMAAMAAAA=") +tile_set = SubResource("TileSet_14yng") +collision_enabled = false +navigation_enabled = false + +[node name="Terrain" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAABAAAAAAALAAAAAAACAAAAAAALAAAAAAADAAAAAAALAAAAAAAEAAAAAAALAAAAAAAFAAAAAAALAAAAAAAGAAAAAAALAAAAAAAHAAAAAAALAAAAAAAIAAAAAAALAAAAAAAJAAAAAAAMAAAAAAAJAAEAAAAMAAEAAAAJAAIAAAAMAAEAAAAJAAMAAAAMAAEAAAAJAAQAAAAMAAEAAAAJAAUAAAAMAAEAAAAJAAYAAAAMAAEAAAABAAEAAAALAAEAAAABAAIAAAALAAEAAAABAAMAAAALAAEAAAABAAQAAAAHAAEAAAABAAUAAAALAAEAAAABAAYAAAALAAEAAAACAAEAAAALAAEAAAACAAIAAAALAAEAAAACAAMAAAALAAEAAAACAAQAAAALAAEAAAACAAUAAAALAAEAAAACAAYAAAALAAEAAAADAAEAAAALAAEAAAADAAIAAAALAAEAAAADAAMAAAALAAEAAAADAAQAAAALAAEAAAADAAUAAAALAAEAAAADAAYAAAALAAEAAAAEAAEAAAAHAAEAAAAEAAIAAAALAAEAAAAEAAMAAAALAAEAAAAEAAQAAAALAAEAAAAEAAUAAAALAAEAAAAEAAYAAAALAAEAAAAFAAEAAAALAAEAAAAFAAIAAAALAAEAAAAFAAMAAAALAAEAAAAFAAQAAAAHAAEAAAAFAAUAAAALAAEAAAAFAAYAAAALAAEAAAAGAAEAAAALAAEAAAAGAAIAAAALAAEAAAAGAAMAAAALAAEAAAAGAAQAAAALAAEAAAAGAAUAAAALAAEAAAAGAAYAAAALAAEAAAAHAAEAAAALAAEAAAAHAAIAAAALAAEAAAAHAAMAAAALAAEAAAAHAAQAAAALAAEAAAAHAAUAAAALAAEAAAAHAAYAAAAHAAEAAAAIAAEAAAALAAEAAAAIAAIAAAALAAEAAAAIAAMAAAAHAAEAAAAIAAQAAAALAAEAAAAIAAUAAAALAAEAAAAIAAYAAAALAAEAAAAKAAEAAAAIAAUAAAALAAEAAAAIAAUAAAAMAAEAAAAIAAUAAAANAAEAAAAIAAUAAAAKAAIAAAAIAAYAAAALAAIAAAAIAAYAAAAMAAIAAAAIAAYAAAANAAIAAAAIAAYAAAAKAAMAAAALAAEAAAAKAAQAAAALAAEAAAALAAMAAAALAAEAAAALAAQAAAALAAEAAAAMAAMAAAALAAEAAAAMAAQAAAALAAEAAAANAAMAAAALAAEAAAANAAQAAAALAAEAAAAOAAEAAAAIAAUAAAAPAAEAAAAIAAUAAAAQAAEAAAAIAAUAAAAOAAIAAAAIAAYAAAAPAAIAAAAIAAYAAAAQAAIAAAAIAAYAAAAOAAMAAAALAAEAAAAPAAMAAAALAAEAAAAPAAQAAAALAAEAAAAQAAQAAAALAAEAAAAQAAMAAAALAAEAAAAOAAQAAAALAAEAAAARAAAAAAALAAQAAAARAAEAAAALAAUAAAARAAIAAAALAAUAAAARAAMAAAALAAUAAAARAAQAAAALAAUAAAASAAAAAAAMAAQAAAATAAAAAAAMAAQAAAAUAAAAAAAMAAQAAAAVAAAAAAAMAAQAAAAWAAAAAAAMAAQAAAAXAAAAAAAMAAQAAAASAAEAAAAMAAUAAAASAAIAAAAMAAUAAAASAAMAAAAMAAUAAAASAAQAAAAMAAUAAAATAAEAAAAMAAUAAAATAAIAAAAJAAYAAAATAAMAAAAMAAUAAAATAAQAAAAMAAUAAAAUAAEAAAAMAAUAAAAUAAIAAAAMAAUAAAAUAAMAAAAMAAUAAAAUAAQAAAAMAAUAAAAVAAEAAAAMAAUAAAAVAAIAAAAMAAUAAAAVAAMAAAAMAAUAAAAVAAQAAAAMAAUAAAAWAAEAAAAMAAUAAAAWAAIAAAAMAAUAAAAWAAMAAAAMAAUAAAAWAAQAAAAKAAYAAAAXAAEAAAAMAAUAAAAXAAIAAAAMAAUAAAAXAAMAAAAMAAUAAAAXAAQAAAAMAAUAAAARAAUAAAALAAUAAAARAAYAAAALAAUAAAASAAUAAAAJAAYAAAASAAYAAAAMAAUAAAATAAUAAAAMAAUAAAATAAYAAAAMAAUAAAAUAAUAAAAMAAUAAAAUAAYAAAAMAAUAAAAVAAUAAAAMAAUAAAAVAAYAAAAMAAUAAAAWAAUAAAAMAAUAAAAWAAYAAAAMAAUAAAAXAAUAAAAMAAUAAAAXAAYAAAAMAAUAAAAKAP7/AAALAAQAAAALAP7/AAAMAAQAAAAMAP7/AAAMAAQAAAAKAP//AAALAAYAAAALAP//AAAMAAYAAAAMAP//AAAMAAYAAAAQAP7/AAANAAQAAAAQAP//AAANAAYAAAANAP7/AAAMAAQAAAAOAP7/AAAMAAQAAAAPAP7/AAAMAAQAAAANAP//AAAMAAYAAAAOAP//AAAMAAYAAAAPAP//AAAMAAYAAAAMAP3/AAAOAAAAAAADAP//AAAOAAIAAAAEAP//AAAPAAIAAAAFAP//AAAQAAIAAAAGAP//AAAOAAIAAAAHAP//AAAPAAIAAAAIAP//AAAQAAIAAAD//wAAAAAKAAAAAAD//wEAAAAKAAEAAAD//wIAAAAKAAEAAAD//wMAAAAKAAEAAAD//wQAAAAKAAEAAAD//wUAAAAKAAEAAAD//wYAAAAKAAEAAAD//wcAAAAKAAEAAAD//wgAAAAKAAEAAAAAAAAAAAALAAAAAAAAAAEAAAALAAEAAAAAAAIAAAALAAEAAAAAAAMAAAALAAEAAAAAAAQAAAALAAEAAAAAAAUAAAALAAEAAAAAAAYAAAALAAEAAAAAAAcAAAALAAEAAAAAAAgAAAALAAEAAAABAAgAAAALAAEAAAACAAgAAAALAAEAAAADAAgAAAALAAEAAAAEAAgAAAALAAEAAAAFAAgAAAALAAEAAAAGAAgAAAALAAEAAAAHAAgAAAALAAEAAAAIAAgAAAALAAEAAAAJAAgAAAAMAAEAAAAJAAcAAAAMAAEAAAAIAAcAAAALAAEAAAAHAAcAAAALAAEAAAAGAAcAAAAHAAEAAAAFAAcAAAALAAEAAAAEAAcAAAALAAEAAAADAAcAAAALAAEAAAACAAcAAAALAAEAAAABAAcAAAALAAEAAAD///v/AAANAAQAAAD///z/AAANAAUAAAD///3/AAANAAUAAAD///7/AAANAAUAAAD/////AAANAAYAAAD+//v/AAAMAAQAAAD9//v/AAAMAAQAAAD+//z/AAAJAAYAAAD9//z/AAAMAAUAAAD6////AAAMAAUAAAD7////AAAMAAUAAAD8////AAAMAAUAAAD9////AAAMAAUAAAD+////AAAMAAUAAAD+//7/AAAMAAUAAAD+//3/AAAMAAUAAAD9//3/AAAMAAUAAAD9//7/AAAKAAYAAAD+/wAAAAANAAUAAAD+/wEAAAANAAUAAAD+/wIAAAANAAUAAAD+/wMAAAANAAUAAAD+/wQAAAANAAUAAAD+/wUAAAANAAUAAAD+/wYAAAANAAUAAAD9/wAAAAAMAAUAAAD8/wAAAAAMAAUAAAD7/wAAAAAMAAUAAAD6/wAAAAAMAAUAAAD5/wAAAAALAAUAAAD6/wEAAAAMAAUAAAD6/wIAAAAMAAUAAAD6/wMAAAAMAAUAAAD7/wMAAAAMAAUAAAD7/wQAAAAMAAUAAAD8/wEAAAAMAAUAAAD9/wEAAAAMAAUAAAD9/wIAAAAMAAUAAAD9/wMAAAAMAAUAAAD9/wQAAAAMAAUAAAD9/wUAAAAMAAUAAAD9/wYAAAAMAAUAAAD8/wUAAAAMAAUAAAD7/wUAAAAMAAUAAAD8/wYAAAAMAAUAAAD8/wQAAAAKAAYAAAD8/wMAAAAMAAUAAAD8/wIAAAAMAAUAAAD7/wEAAAAMAAUAAAD7/wIAAAAJAAYAAAD7/wYAAAAMAAUAAAD6/wYAAAAMAAUAAAD6/wUAAAAMAAUAAAD6/wQAAAAMAAUAAAD5////AAALAAUAAAD5/wEAAAALAAUAAAD5/wIAAAALAAUAAAD5/wMAAAALAAUAAAD5/wQAAAALAAUAAAD5/wUAAAALAAUAAAD5/wYAAAALAAUAAAD8//r/AAALAAMAAAAOAP3/AAALAAMAAAALAP3/AAALAAMAAAASAP//AAALAAMAAAAUAP//AAALAAMAAAD6//r/AAAQAAUAAAD7//r/AAALAAMAAAANAP3/AAAOAAYAAAAWAP//AAAPAAYAAAD9//r/AAAPAAUAAAAXAP//AAAQAAUAAAD5//v/AAALAAQAAAD5//z/AAALAAUAAAD5//3/AAALAAUAAAD5//7/AAALAAUAAAD6//v/AAAMAAQAAAD6//z/AAAKAAYAAAD6//3/AAAMAAUAAAD6//7/AAAMAAUAAAD7//v/AAAMAAQAAAD7//z/AAAMAAUAAAD7//3/AAAMAAUAAAD7//7/AAAMAAUAAAD8//v/AAAMAAQAAAD8//z/AAAMAAUAAAD8//3/AAAMAAUAAAD8//7/AAAMAAUAAAARAAcAAAALAAUAAAARAAgAAAALAAYAAAAXAAcAAAAMAAUAAAAWAAcAAAAMAAUAAAAVAAcAAAAMAAUAAAAUAAcAAAAMAAUAAAATAAcAAAAMAAUAAAASAAcAAAAMAAUAAAASAAgAAAAMAAYAAAATAAgAAAAMAAYAAAAUAAgAAAAMAAYAAAAVAAgAAAAMAAYAAAAWAAgAAAAMAAYAAAAXAAgAAAAMAAYAAAAKAAUAAAALAAEAAAAKAAYAAAALAAEAAAAKAAcAAAALAAEAAAAKAAgAAAALAAEAAAALAAUAAAALAAEAAAALAAYAAAALAAEAAAALAAcAAAALAAEAAAALAAgAAAALAAEAAAAMAAUAAAALAAEAAAAMAAYAAAALAAEAAAAMAAcAAAALAAEAAAAMAAgAAAALAAEAAAANAAUAAAALAAEAAAANAAYAAAALAAEAAAANAAcAAAALAAEAAAANAAgAAAALAAEAAAAOAAUAAAALAAEAAAAOAAYAAAALAAEAAAAOAAcAAAALAAEAAAAOAAgAAAALAAEAAAAPAAUAAAALAAEAAAAPAAYAAAALAAEAAAAPAAcAAAALAAEAAAAPAAgAAAALAAEAAAAQAAUAAAALAAEAAAAQAAYAAAALAAEAAAAQAAcAAAALAAEAAAAQAAgAAAALAAEAAAAdAAAAAAANAAQAAAAdAAEAAAANAAUAAAAdAAIAAAANAAUAAAAdAAMAAAANAAUAAAAdAAQAAAANAAUAAAAdAAUAAAANAAUAAAAdAAYAAAANAAUAAAAdAAcAAAANAAUAAAAdAAgAAAANAAYAAAAZAP//AAAOAAQAAAAYAAAAAAAMAAQAAAAZAAAAAAAMAAQAAAAaAAAAAAAMAAQAAAAbAAAAAAAMAAQAAAAcAAAAAAAMAAQAAAAYAAEAAAAMAAUAAAAZAAEAAAAMAAUAAAAaAAEAAAAMAAUAAAAbAAEAAAAMAAUAAAAcAAEAAAAMAAUAAAAcAAIAAAAMAAUAAAAcAAMAAAAJAAYAAAAbAAIAAAAMAAUAAAAaAAIAAAAMAAUAAAAZAAIAAAAMAAUAAAAYAAIAAAAMAAUAAAAYAAMAAAAMAAUAAAAYAAQAAAAMAAUAAAAYAAUAAAAMAAUAAAAYAAYAAAAMAAUAAAAYAAcAAAAMAAUAAAAYAAgAAAAMAAYAAAAZAAMAAAAMAAUAAAAZAAQAAAAMAAUAAAAZAAUAAAAMAAUAAAAZAAYAAAAMAAUAAAAZAAcAAAAMAAUAAAAZAAgAAAAMAAYAAAAaAAMAAAAMAAUAAAAaAAQAAAAMAAUAAAAaAAUAAAAMAAUAAAAaAAYAAAAKAAYAAAAaAAcAAAAMAAUAAAAaAAgAAAAMAAYAAAAbAAMAAAAMAAUAAAAbAAQAAAAMAAUAAAAbAAUAAAAMAAUAAAAbAAYAAAAMAAUAAAAbAAcAAAAMAAUAAAAbAAgAAAAMAAYAAAAcAAQAAAAMAAUAAAAcAAUAAAAMAAUAAAAcAAYAAAAMAAUAAAAcAAcAAAAMAAUAAAAcAAgAAAAMAAYAAAAPAP3/AAAQAAYAAAAiAPr/AAAQAAYAAAAfAPr/AAAOAAYAAAAkAPr/AAAPAAYAAAAgAPr/AAAPAAUAAAAbAP//AAALAAMAAAAaAP//AAALAAMAAAAjAPr/AAALAAMAAAAhAPr/AAALAAMAAAATAP//AAALAAMAAAAVAP//AAALAAMAAAAeAPv/AAALAAQAAAAeAPz/AAALAAUAAAAeAP3/AAALAAUAAAAeAP7/AAALAAUAAAAeAP//AAALAAUAAAAmAP//AAANAAUAAAAmAP7/AAANAAUAAAAmAP3/AAANAAUAAAAmAPv/AAANAAQAAAAfAPv/AAAMAAQAAAAgAPv/AAAMAAQAAAAhAPv/AAAMAAQAAAAiAPv/AAAMAAQAAAAjAPv/AAAMAAQAAAAkAPv/AAAMAAQAAAAlAPv/AAAMAAQAAAAmAPz/AAANAAUAAAAlAP//AAAMAAUAAAAlAP7/AAAMAAUAAAAlAP3/AAAMAAUAAAAlAPz/AAAMAAUAAAAkAPz/AAAMAAUAAAAjAPz/AAAMAAUAAAAiAPz/AAAMAAUAAAAhAPz/AAAMAAUAAAAgAPz/AAAMAAUAAAAfAPz/AAAMAAUAAAAfAP3/AAAKAAYAAAAfAP7/AAAMAAUAAAAfAP//AAAMAAUAAAAkAP//AAAKAAYAAAAkAP7/AAAJAAYAAAAkAP3/AAAMAAUAAAAjAP3/AAAMAAUAAAAiAP3/AAAMAAUAAAAhAP3/AAAMAAUAAAAgAP3/AAAMAAUAAAAgAP7/AAAJAAYAAAAgAP//AAAMAAUAAAAjAP//AAAMAAUAAAAjAP7/AAAMAAUAAAAiAP7/AAAMAAUAAAAhAP7/AAAMAAUAAAAhAP//AAAMAAUAAAAiAP//AAAMAAUAAAAeAAgAAAALAAYAAAAeAAcAAAALAAUAAAAeAAYAAAALAAUAAAAeAAUAAAALAAUAAAAeAAQAAAALAAUAAAAeAAMAAAALAAUAAAAeAAIAAAALAAUAAAAeAAEAAAALAAUAAAAeAAAAAAALAAUAAAAfAAgAAAAMAAYAAAAgAAgAAAAMAAYAAAAhAAgAAAAMAAYAAAAiAAgAAAAMAAYAAAAjAAgAAAAMAAYAAAAkAAgAAAAMAAYAAAAlAAgAAAAMAAYAAAAmAAgAAAANAAYAAAAmAAAAAAANAAUAAAAmAAEAAAANAAUAAAAmAAIAAAANAAUAAAAmAAMAAAANAAUAAAAmAAQAAAANAAUAAAAmAAUAAAANAAUAAAAmAAYAAAANAAUAAAAmAAcAAAANAAUAAAAfAAAAAAAMAAUAAAAfAAEAAAAMAAUAAAAfAAIAAAAMAAUAAAAfAAMAAAAMAAUAAAAfAAQAAAAMAAUAAAAfAAUAAAAMAAUAAAAfAAYAAAAKAAYAAAAfAAcAAAAMAAUAAAAgAAAAAAAMAAUAAAAgAAEAAAAMAAUAAAAgAAIAAAAMAAUAAAAgAAMAAAAMAAUAAAAgAAQAAAAMAAUAAAAgAAUAAAAMAAUAAAAgAAYAAAAMAAUAAAAgAAcAAAAMAAUAAAAhAAAAAAAMAAUAAAAhAAEAAAAMAAUAAAAhAAIAAAAKAAYAAAAhAAMAAAAMAAUAAAAhAAQAAAAMAAUAAAAhAAUAAAAMAAUAAAAhAAYAAAAMAAUAAAAhAAcAAAAMAAUAAAAiAAAAAAAMAAUAAAAiAAEAAAAMAAUAAAAiAAIAAAAMAAUAAAAiAAMAAAAMAAUAAAAiAAQAAAAKAAYAAAAiAAUAAAAKAAYAAAAiAAYAAAAMAAUAAAAiAAcAAAAMAAUAAAAjAAAAAAAMAAUAAAAjAAEAAAAMAAUAAAAjAAIAAAAMAAUAAAAjAAMAAAAMAAUAAAAjAAQAAAAMAAUAAAAjAAUAAAAMAAUAAAAjAAYAAAAMAAUAAAAjAAcAAAAMAAUAAAAkAAAAAAAKAAYAAAAkAAEAAAAMAAUAAAAkAAIAAAAMAAUAAAAkAAMAAAAMAAUAAAAkAAQAAAAMAAUAAAAkAAUAAAAMAAUAAAAkAAYAAAAMAAUAAAAkAAcAAAAKAAYAAAAlAAAAAAAMAAUAAAAlAAEAAAAMAAUAAAAlAAIAAAAMAAUAAAAlAAMAAAAMAAUAAAAlAAQAAAAMAAUAAAAlAAUAAAAMAAUAAAAlAAYAAAAMAAUAAAAlAAcAAAAMAAUAAAD6/wcAAAAMAAUAAAD7/wcAAAAMAAUAAAD8/wcAAAAMAAUAAAD9/wcAAAAMAAUAAAD5/wcAAAALAAUAAAD+/wcAAAANAAUAAAD5/wgAAAALAAYAAAD6/wgAAAAMAAYAAAD7/wgAAAAMAAYAAAD8/wgAAAAMAAYAAAD9/wgAAAAMAAYAAAD+/wgAAAANAAYAAAA=") +tile_set = SubResource("TileSet_14yng") + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_tafwr")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_37c7w")] +unique_name_in_owner = true +visible = false + +[node name="Camera2D" type="Camera2D" parent="."] +physics_interpolation_mode = 1 +position = Vector2(186, -172.5) +zoom = Vector2(1.5, 1.5) +process_callback = 0 +position_smoothing_speed = 8.0 +editor_draw_limits = true + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("4_dxiro") + +[node name="Label" type="Label" parent="."] +offset_left = 167.0 +offset_top = -133.0 +offset_right = 332.0 +offset_bottom = -69.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("5_gaaip") +text = "[WASD] to move +[Space] to jump" + +[node name="PhantomCamera2D" type="Node2D" parent="." node_paths=PackedStringArray("follow_targets")] +top_level = true +position = Vector2(186, -172.5) +script = ExtResource("6_ojk83") +priority = 10 +follow_mode = 3 +follow_targets = [NodePath("../CharacterBody2D"), NodePath("../GroupNPCSprite")] +zoom = Vector2(1.5, 1.5) +tween_resource = SubResource("Resource_spy00") +tween_on_load = false +follow_damping = true +auto_zoom = true +auto_zoom_min = 0.5 +auto_zoom_max = 1.5 +auto_zoom_margin = Vector4(200, 0, 200, 0) +draw_limits = true + +[node name="GroupNPCSprite" type="Sprite2D" parent="."] +unique_name_in_owner = true +position = Vector2(107, -316) +texture = ExtResource("8_ys0m4") + +[node name="CharacterBody2D" parent="." instance=ExtResource("9_witv0")] +position = Vector2(265, -29) +script = ExtResource("10_aivri") diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_path_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_path_example_scene.tscn new file mode 100644 index 0000000..60342a2 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_follow_path_example_scene.tscn @@ -0,0 +1,269 @@ +[gd_scene load_steps=13 format=4 uid="uid://b75giavcvh1mv"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_t003o"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_4ncqd"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_tpji3"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_w0rat"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="5_q77r4"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_y6hoa"] +[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="7_wd55r"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_fy81j"] +[ext_resource type="Script" uid="uid://cnnaky2ns2pn4" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_u6ygl"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_nivvc"] +texture = ExtResource("1_t003o") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_eyojy"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_nivvc") + +[sub_resource type="Curve2D" id="Curve2D_usrhf"] +_data = { +"points": PackedVector2Array(-96.4111, 42.3785, 0, 0, 222, 0, 0, 0, 0, 0, 1580.53, 0) +} +point_count = 2 + +[node name="Root" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="Pillar" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAAAAPr/AAAKAAIAAAAAAPv/AAAKAAMAAAAAAPz/AAAKAAMAAAAAAP3/AAAKAAMAAAAAAP7/AAAKAAMAAAAAAP//AAAKAAMAAAABAPr/AAALAAIAAAABAPv/AAALAAEAAAABAPz/AAALAAEAAAABAP3/AAALAAEAAAABAP7/AAALAAEAAAABAP//AAALAAEAAAACAPr/AAAMAAIAAAACAPv/AAAMAAMAAAACAPz/AAAMAAMAAAACAP3/AAAMAAMAAAACAP7/AAAMAAMAAAACAP//AAAMAAMAAAA=") +tile_set = SubResource("TileSet_eyojy") +collision_enabled = false +navigation_enabled = false + +[node name="Terrain" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAABAAAAAAALAAAAAAACAAAAAAALAAAAAAADAAAAAAALAAAAAAAEAAAAAAALAAAAAAAFAAAAAAALAAAAAAAGAAAAAAALAAAAAAAHAAAAAAALAAAAAAAIAAAAAAALAAAAAAAJAAAAAAAMAAAAAAAJAAEAAAAMAAEAAAAJAAIAAAAMAAEAAAAJAAMAAAAMAAEAAAAJAAQAAAAMAAEAAAAJAAUAAAAMAAEAAAAJAAYAAAAMAAEAAAABAAEAAAALAAEAAAABAAIAAAALAAEAAAABAAMAAAALAAEAAAABAAQAAAAHAAEAAAABAAUAAAALAAEAAAABAAYAAAALAAEAAAACAAEAAAALAAEAAAACAAIAAAALAAEAAAACAAMAAAALAAEAAAACAAQAAAALAAEAAAACAAUAAAALAAEAAAACAAYAAAALAAEAAAADAAEAAAALAAEAAAADAAIAAAALAAEAAAADAAMAAAALAAEAAAADAAQAAAALAAEAAAADAAUAAAALAAEAAAADAAYAAAALAAEAAAAEAAEAAAAHAAEAAAAEAAIAAAALAAEAAAAEAAMAAAALAAEAAAAEAAQAAAALAAEAAAAEAAUAAAALAAEAAAAEAAYAAAALAAEAAAAFAAEAAAALAAEAAAAFAAIAAAALAAEAAAAFAAMAAAALAAEAAAAFAAQAAAAHAAEAAAAFAAUAAAALAAEAAAAFAAYAAAALAAEAAAAGAAEAAAALAAEAAAAGAAIAAAALAAEAAAAGAAMAAAALAAEAAAAGAAQAAAALAAEAAAAGAAUAAAALAAEAAAAGAAYAAAALAAEAAAAHAAEAAAALAAEAAAAHAAIAAAALAAEAAAAHAAMAAAALAAEAAAAHAAQAAAALAAEAAAAHAAUAAAALAAEAAAAHAAYAAAAHAAEAAAAIAAEAAAALAAEAAAAIAAIAAAALAAEAAAAIAAMAAAAHAAEAAAAIAAQAAAALAAEAAAAIAAUAAAALAAEAAAAIAAYAAAALAAEAAAAKAAEAAAAIAAUAAAALAAEAAAAIAAUAAAAMAAEAAAAIAAUAAAANAAEAAAAIAAUAAAAKAAIAAAAIAAYAAAALAAIAAAAIAAYAAAAMAAIAAAAIAAYAAAANAAIAAAAIAAYAAAAKAAMAAAALAAEAAAAKAAQAAAALAAEAAAALAAMAAAALAAEAAAALAAQAAAALAAEAAAAMAAMAAAALAAEAAAAMAAQAAAALAAEAAAANAAMAAAALAAEAAAANAAQAAAALAAEAAAAOAAEAAAAIAAUAAAAPAAEAAAAIAAUAAAAQAAEAAAAIAAUAAAAOAAIAAAAIAAYAAAAPAAIAAAAIAAYAAAAQAAIAAAAIAAYAAAAOAAMAAAALAAEAAAAPAAMAAAALAAEAAAAPAAQAAAALAAEAAAAQAAQAAAALAAEAAAAQAAMAAAALAAEAAAAOAAQAAAALAAEAAAARAAAAAAALAAQAAAARAAEAAAALAAUAAAARAAIAAAALAAUAAAARAAMAAAALAAUAAAARAAQAAAALAAUAAAASAAAAAAAMAAQAAAATAAAAAAAMAAQAAAAUAAAAAAAMAAQAAAAVAAAAAAAMAAQAAAAWAAAAAAAMAAQAAAAXAAAAAAAMAAQAAAASAAEAAAAMAAUAAAASAAIAAAAMAAUAAAASAAMAAAAMAAUAAAASAAQAAAAMAAUAAAATAAEAAAAMAAUAAAATAAIAAAAJAAYAAAATAAMAAAAMAAUAAAATAAQAAAAMAAUAAAAUAAEAAAAMAAUAAAAUAAIAAAAMAAUAAAAUAAMAAAAMAAUAAAAUAAQAAAAMAAUAAAAVAAEAAAAMAAUAAAAVAAIAAAAMAAUAAAAVAAMAAAAMAAUAAAAVAAQAAAAMAAUAAAAWAAEAAAAMAAUAAAAWAAIAAAAMAAUAAAAWAAMAAAAMAAUAAAAWAAQAAAAKAAYAAAAXAAEAAAAMAAUAAAAXAAIAAAAMAAUAAAAXAAMAAAAMAAUAAAAXAAQAAAAMAAUAAAARAAUAAAALAAUAAAARAAYAAAALAAUAAAASAAUAAAAJAAYAAAASAAYAAAAMAAUAAAATAAUAAAAMAAUAAAATAAYAAAAMAAUAAAAUAAUAAAAMAAUAAAAUAAYAAAAMAAUAAAAVAAUAAAAMAAUAAAAVAAYAAAAMAAUAAAAWAAUAAAAMAAUAAAAWAAYAAAAMAAUAAAAXAAUAAAAMAAUAAAAXAAYAAAAMAAUAAAAKAP7/AAALAAQAAAALAP7/AAAMAAQAAAAMAP7/AAAMAAQAAAAKAP//AAALAAYAAAALAP//AAAMAAYAAAAMAP//AAAMAAYAAAAQAP7/AAANAAQAAAAQAP//AAANAAYAAAANAP7/AAAMAAQAAAAOAP7/AAAMAAQAAAAPAP7/AAAMAAQAAAANAP//AAAMAAYAAAAOAP//AAAMAAYAAAAPAP//AAAMAAYAAAAMAP3/AAAOAAAAAAADAP//AAAOAAIAAAAEAP//AAAPAAIAAAAFAP//AAAQAAIAAAAGAP//AAAOAAIAAAAHAP//AAAPAAIAAAAIAP//AAAQAAIAAAD//wAAAAAKAAAAAAD//wEAAAAKAAEAAAD//wIAAAAKAAEAAAD//wMAAAAKAAEAAAD//wQAAAAKAAEAAAD//wUAAAAKAAEAAAD//wYAAAAKAAEAAAD//wcAAAAKAAEAAAD//wgAAAAKAAEAAAAAAAAAAAALAAAAAAAAAAEAAAALAAEAAAAAAAIAAAALAAEAAAAAAAMAAAALAAEAAAAAAAQAAAALAAEAAAAAAAUAAAALAAEAAAAAAAYAAAALAAEAAAAAAAcAAAALAAEAAAAAAAgAAAALAAEAAAABAAgAAAALAAEAAAACAAgAAAALAAEAAAADAAgAAAALAAEAAAAEAAgAAAALAAEAAAAFAAgAAAALAAEAAAAGAAgAAAALAAEAAAAHAAgAAAALAAEAAAAIAAgAAAALAAEAAAAJAAgAAAAMAAEAAAAJAAcAAAAMAAEAAAAIAAcAAAALAAEAAAAHAAcAAAALAAEAAAAGAAcAAAAHAAEAAAAFAAcAAAALAAEAAAAEAAcAAAALAAEAAAADAAcAAAALAAEAAAACAAcAAAALAAEAAAABAAcAAAALAAEAAAD///v/AAANAAQAAAD///z/AAANAAUAAAD///3/AAANAAUAAAD///7/AAANAAUAAAD/////AAANAAYAAAD+//v/AAAMAAQAAAD9//v/AAAMAAQAAAD+//z/AAAJAAYAAAD9//z/AAAMAAUAAAD6////AAAMAAUAAAD7////AAAMAAUAAAD8////AAAMAAUAAAD9////AAAMAAUAAAD+////AAAMAAUAAAD+//7/AAAMAAUAAAD+//3/AAAMAAUAAAD9//3/AAAMAAUAAAD9//7/AAAKAAYAAAD+/wAAAAANAAUAAAD+/wEAAAANAAUAAAD+/wIAAAANAAUAAAD+/wMAAAANAAUAAAD+/wQAAAANAAUAAAD+/wUAAAANAAUAAAD+/wYAAAANAAUAAAD9/wAAAAAMAAUAAAD8/wAAAAAMAAUAAAD7/wAAAAAMAAUAAAD6/wAAAAAMAAUAAAD5/wAAAAALAAUAAAD6/wEAAAAMAAUAAAD6/wIAAAAMAAUAAAD6/wMAAAAMAAUAAAD7/wMAAAAMAAUAAAD7/wQAAAAMAAUAAAD8/wEAAAAMAAUAAAD9/wEAAAAMAAUAAAD9/wIAAAAMAAUAAAD9/wMAAAAMAAUAAAD9/wQAAAAMAAUAAAD9/wUAAAAMAAUAAAD9/wYAAAAMAAUAAAD8/wUAAAAMAAUAAAD7/wUAAAAMAAUAAAD8/wYAAAAMAAUAAAD8/wQAAAAKAAYAAAD8/wMAAAAMAAUAAAD8/wIAAAAMAAUAAAD7/wEAAAAMAAUAAAD7/wIAAAAJAAYAAAD7/wYAAAAMAAUAAAD6/wYAAAAMAAUAAAD6/wUAAAAMAAUAAAD6/wQAAAAMAAUAAAD5////AAALAAUAAAD5/wEAAAALAAUAAAD5/wIAAAALAAUAAAD5/wMAAAALAAUAAAD5/wQAAAALAAUAAAD5/wUAAAALAAUAAAD5/wYAAAALAAUAAAD8//r/AAALAAMAAAAOAP3/AAALAAMAAAALAP3/AAALAAMAAAASAP//AAALAAMAAAAUAP//AAALAAMAAAD6//r/AAAQAAUAAAD7//r/AAALAAMAAAANAP3/AAAOAAYAAAAWAP//AAAPAAYAAAD9//r/AAAPAAUAAAAXAP//AAAQAAUAAAD5//v/AAALAAQAAAD5//z/AAALAAUAAAD5//3/AAALAAUAAAD5//7/AAALAAUAAAD6//v/AAAMAAQAAAD6//z/AAAKAAYAAAD6//3/AAAMAAUAAAD6//7/AAAMAAUAAAD7//v/AAAMAAQAAAD7//z/AAAMAAUAAAD7//3/AAAMAAUAAAD7//7/AAAMAAUAAAD8//v/AAAMAAQAAAD8//z/AAAMAAUAAAD8//3/AAAMAAUAAAD8//7/AAAMAAUAAAARAAcAAAALAAUAAAARAAgAAAALAAYAAAAXAAcAAAAMAAUAAAAWAAcAAAAMAAUAAAAVAAcAAAAMAAUAAAAUAAcAAAAMAAUAAAATAAcAAAAMAAUAAAASAAcAAAAMAAUAAAASAAgAAAAMAAYAAAATAAgAAAAMAAYAAAAUAAgAAAAMAAYAAAAVAAgAAAAMAAYAAAAWAAgAAAAMAAYAAAAXAAgAAAAMAAYAAAAKAAUAAAALAAEAAAAKAAYAAAALAAEAAAAKAAcAAAALAAEAAAAKAAgAAAALAAEAAAALAAUAAAALAAEAAAALAAYAAAALAAEAAAALAAcAAAALAAEAAAALAAgAAAALAAEAAAAMAAUAAAALAAEAAAAMAAYAAAALAAEAAAAMAAcAAAALAAEAAAAMAAgAAAALAAEAAAANAAUAAAALAAEAAAANAAYAAAALAAEAAAANAAcAAAALAAEAAAANAAgAAAALAAEAAAAOAAUAAAALAAEAAAAOAAYAAAALAAEAAAAOAAcAAAALAAEAAAAOAAgAAAALAAEAAAAPAAUAAAALAAEAAAAPAAYAAAALAAEAAAAPAAcAAAALAAEAAAAPAAgAAAALAAEAAAAQAAUAAAALAAEAAAAQAAYAAAALAAEAAAAQAAcAAAALAAEAAAAQAAgAAAALAAEAAAAdAAAAAAANAAQAAAAdAAEAAAANAAUAAAAdAAIAAAANAAUAAAAdAAMAAAANAAUAAAAdAAQAAAANAAUAAAAdAAUAAAANAAUAAAAdAAYAAAANAAUAAAAdAAcAAAANAAUAAAAdAAgAAAANAAYAAAAZAP//AAAOAAQAAAAYAAAAAAAMAAQAAAAZAAAAAAAMAAQAAAAaAAAAAAAMAAQAAAAbAAAAAAAMAAQAAAAcAAAAAAAMAAQAAAAYAAEAAAAMAAUAAAAZAAEAAAAMAAUAAAAaAAEAAAAMAAUAAAAbAAEAAAAMAAUAAAAcAAEAAAAMAAUAAAAcAAIAAAAMAAUAAAAcAAMAAAAJAAYAAAAbAAIAAAAMAAUAAAAaAAIAAAAMAAUAAAAZAAIAAAAMAAUAAAAYAAIAAAAMAAUAAAAYAAMAAAAMAAUAAAAYAAQAAAAMAAUAAAAYAAUAAAAMAAUAAAAYAAYAAAAMAAUAAAAYAAcAAAAMAAUAAAAYAAgAAAAMAAYAAAAZAAMAAAAMAAUAAAAZAAQAAAAMAAUAAAAZAAUAAAAMAAUAAAAZAAYAAAAMAAUAAAAZAAcAAAAMAAUAAAAZAAgAAAAMAAYAAAAaAAMAAAAMAAUAAAAaAAQAAAAMAAUAAAAaAAUAAAAMAAUAAAAaAAYAAAAKAAYAAAAaAAcAAAAMAAUAAAAaAAgAAAAMAAYAAAAbAAMAAAAMAAUAAAAbAAQAAAAMAAUAAAAbAAUAAAAMAAUAAAAbAAYAAAAMAAUAAAAbAAcAAAAMAAUAAAAbAAgAAAAMAAYAAAAcAAQAAAAMAAUAAAAcAAUAAAAMAAUAAAAcAAYAAAAMAAUAAAAcAAcAAAAMAAUAAAAcAAgAAAAMAAYAAAAPAP3/AAAQAAYAAAAbAP//AAALAAMAAAAaAP//AAALAAMAAAATAP//AAALAAMAAAAVAP//AAALAAMAAAD6/wcAAAAMAAUAAAD7/wcAAAAMAAUAAAD8/wcAAAAMAAUAAAD9/wcAAAAMAAUAAAD5/wcAAAALAAUAAAD+/wcAAAANAAUAAAD5/wgAAAALAAYAAAD6/wgAAAAMAAYAAAD7/wgAAAAMAAYAAAD8/wgAAAAMAAYAAAD9/wgAAAAMAAYAAAD+/wgAAAANAAYAAAAeAP//AAALAAQAAAAeAAAAAAALAAUAAAAeAAEAAAALAAUAAAAeAAIAAAALAAUAAAAeAAMAAAALAAUAAAAeAAQAAAALAAUAAAAeAAUAAAALAAUAAAAeAAYAAAALAAUAAAAeAAcAAAALAAUAAAAeAAgAAAALAAUAAAAeAAkAAAALAAUAAAAeAAoAAAALAAUAAAAeAAsAAAALAAUAAAAeAAwAAAALAAYAAAAfAP//AAAMAAQAAAAfAAAAAAAMAAUAAAAfAAEAAAAKAAYAAAAfAAIAAAAMAAUAAAAfAAMAAAAMAAUAAAAfAAQAAAAMAAUAAAAfAAUAAAAMAAUAAAAfAAYAAAAMAAUAAAAfAAcAAAAMAAUAAAAfAAgAAAAMAAUAAAAfAAkAAAAMAAUAAAAfAAoAAAAKAAYAAAAfAAsAAAAMAAUAAAAfAAwAAAAMAAYAAAAgAP//AAAMAAQAAAAgAAAAAAAMAAUAAAAgAAEAAAAMAAUAAAAgAAIAAAAJAAYAAAAgAAMAAAAMAAUAAAAgAAQAAAAMAAUAAAAgAAUAAAAMAAUAAAAgAAYAAAAMAAUAAAAgAAcAAAAMAAUAAAAgAAgAAAAMAAUAAAAgAAkAAAAMAAUAAAAgAAoAAAAMAAUAAAAgAAsAAAAMAAUAAAAgAAwAAAAMAAYAAAAhAP//AAAMAAQAAAAhAAAAAAAMAAUAAAAhAAEAAAAMAAUAAAAhAAIAAAAMAAUAAAAhAAMAAAAMAAUAAAAhAAQAAAAMAAUAAAAhAAUAAAAMAAUAAAAhAAYAAAAKAAYAAAAhAAcAAAAMAAUAAAAhAAgAAAAMAAUAAAAhAAkAAAAMAAUAAAAhAAoAAAAMAAUAAAAhAAsAAAAMAAUAAAAhAAwAAAAMAAYAAAAiAP//AAAMAAQAAAAiAAAAAAAMAAUAAAAiAAEAAAAMAAUAAAAiAAIAAAAMAAUAAAAiAAMAAAAMAAUAAAAiAAQAAAAMAAUAAAAiAAUAAAAMAAUAAAAiAAYAAAAMAAUAAAAiAAcAAAAMAAUAAAAiAAgAAAAKAAYAAAAiAAkAAAAKAAYAAAAiAAoAAAAMAAUAAAAiAAsAAAAMAAUAAAAiAAwAAAAMAAYAAAAjAP//AAAMAAQAAAAjAAAAAAAMAAUAAAAjAAEAAAAMAAUAAAAjAAIAAAAMAAUAAAAjAAMAAAAMAAUAAAAjAAQAAAAMAAUAAAAjAAUAAAAMAAUAAAAjAAYAAAAMAAUAAAAjAAcAAAAMAAUAAAAjAAgAAAAMAAUAAAAjAAkAAAAMAAUAAAAjAAoAAAAMAAUAAAAjAAsAAAAMAAUAAAAjAAwAAAAMAAYAAAAkAP//AAAMAAQAAAAkAAAAAAAMAAUAAAAkAAEAAAAMAAUAAAAkAAIAAAAJAAYAAAAkAAMAAAAKAAYAAAAkAAQAAAAKAAYAAAAkAAUAAAAMAAUAAAAkAAYAAAAMAAUAAAAkAAcAAAAMAAUAAAAkAAgAAAAMAAUAAAAkAAkAAAAMAAUAAAAkAAoAAAAMAAUAAAAkAAsAAAAKAAYAAAAkAAwAAAAMAAYAAAAlAP//AAAMAAQAAAAlAAAAAAAMAAUAAAAlAAEAAAAMAAUAAAAlAAIAAAAMAAUAAAAlAAMAAAAMAAUAAAAlAAQAAAAMAAUAAAAlAAUAAAAMAAUAAAAlAAYAAAAMAAUAAAAlAAcAAAAMAAUAAAAlAAgAAAAMAAUAAAAlAAkAAAAMAAUAAAAlAAoAAAAMAAUAAAAlAAsAAAAMAAUAAAAlAAwAAAAMAAYAAAAmAP//AAANAAQAAAAmAAAAAAANAAUAAAAmAAEAAAANAAUAAAAmAAIAAAANAAUAAAAmAAMAAAANAAUAAAAmAAQAAAANAAUAAAAmAAUAAAANAAUAAAAmAAYAAAANAAUAAAAmAAcAAAANAAUAAAAmAAgAAAANAAUAAAAmAAkAAAANAAUAAAAmAAoAAAANAAUAAAAmAAsAAAANAAUAAAAmAAwAAAANAAYAAAAnAP7/AAALAAQAAAAnAP//AAALAAUAAAAnAAAAAAALAAUAAAAnAAEAAAALAAUAAAAnAAIAAAALAAUAAAAnAAMAAAALAAUAAAAnAAQAAAALAAUAAAAnAAUAAAALAAUAAAAnAAYAAAALAAUAAAAnAAcAAAALAAUAAAAnAAgAAAALAAUAAAAnAAkAAAALAAUAAAAnAAoAAAALAAUAAAAnAAsAAAALAAYAAAAoAP7/AAAMAAQAAAAoAP//AAAMAAUAAAAoAAAAAAAKAAYAAAAoAAEAAAAMAAUAAAAoAAIAAAAMAAUAAAAoAAMAAAAMAAUAAAAoAAQAAAAMAAUAAAAoAAUAAAAMAAUAAAAoAAYAAAAMAAUAAAAoAAcAAAAMAAUAAAAoAAgAAAAMAAUAAAAoAAkAAAAKAAYAAAAoAAoAAAAMAAUAAAAoAAsAAAAMAAYAAAApAP7/AAAMAAQAAAApAP//AAAMAAUAAAApAAAAAAAMAAUAAAApAAEAAAAMAAUAAAApAAIAAAAMAAUAAAApAAMAAAAMAAUAAAApAAQAAAAMAAUAAAApAAUAAAAMAAUAAAApAAYAAAAMAAUAAAApAAcAAAAMAAUAAAApAAgAAAAMAAUAAAApAAkAAAAMAAUAAAApAAoAAAAMAAUAAAApAAsAAAAMAAYAAAAqAP7/AAAMAAQAAAAqAP//AAAMAAUAAAAqAAAAAAAMAAUAAAAqAAEAAAAJAAYAAAAqAAIAAAAKAAYAAAAqAAMAAAAKAAYAAAAqAAQAAAAMAAUAAAAqAAUAAAAMAAUAAAAqAAYAAAAMAAUAAAAqAAcAAAAMAAUAAAAqAAgAAAAMAAUAAAAqAAkAAAAMAAUAAAAqAAoAAAAKAAYAAAAqAAsAAAAMAAYAAAArAPb/AAALAAQAAAArAPf/AAALAAUAAAArAPj/AAALAAUAAAArAPn/AAALAAUAAAArAPr/AAALAAUAAAArAPv/AAALAAUAAAArAPz/AAALAAUAAAArAP3/AAALAAYAAAAsAPb/AAAMAAQAAAAsAPf/AAAMAAUAAAAsAPj/AAAKAAYAAAAsAPn/AAAMAAUAAAAsAPr/AAAMAAUAAAAsAPv/AAAMAAUAAAAsAPz/AAAMAAUAAAAsAP3/AAAMAAYAAAAtAPb/AAAMAAQAAAAtAPf/AAAMAAUAAAAtAPj/AAAMAAUAAAAtAPn/AAAJAAYAAAAtAPr/AAAMAAUAAAAtAPv/AAAMAAUAAAAtAPz/AAAMAAUAAAAtAP3/AAAMAAYAAAAuAPb/AAAMAAQAAAAuAPf/AAAMAAUAAAAuAPj/AAAMAAUAAAAuAPn/AAAMAAUAAAAuAPr/AAAMAAUAAAAuAPv/AAAMAAUAAAAuAPz/AAAMAAUAAAAuAP3/AAAMAAYAAAAvAPb/AAAMAAQAAAAvAPf/AAAMAAUAAAAvAPj/AAAMAAUAAAAvAPn/AAAMAAUAAAAvAPr/AAAMAAUAAAAvAPv/AAAMAAUAAAAvAPz/AAAMAAUAAAAvAP3/AAAMAAYAAAAwAPb/AAAMAAQAAAAwAPf/AAAMAAUAAAAwAPj/AAAMAAUAAAAwAPn/AAAMAAUAAAAwAPr/AAAMAAUAAAAwAPv/AAAMAAUAAAAwAPz/AAAMAAUAAAAwAP3/AAAMAAYAAAAxAPb/AAAMAAQAAAAxAPf/AAAMAAUAAAAxAPj/AAAMAAUAAAAxAPn/AAAMAAUAAAAxAPr/AAAMAAUAAAAxAPv/AAAMAAUAAAAxAPz/AAAMAAUAAAAxAP3/AAAMAAYAAAAyAPb/AAAMAAQAAAAyAPf/AAAMAAUAAAAyAPj/AAAMAAUAAAAyAPn/AAAMAAUAAAAyAPr/AAAMAAUAAAAyAPv/AAAMAAUAAAAyAPz/AAAMAAUAAAAyAP3/AAAMAAUAAAArAP7/AAANAAQAAAArAP//AAANAAUAAAArAAAAAAANAAUAAAArAAEAAAANAAUAAAArAAIAAAANAAUAAAArAAMAAAANAAUAAAArAAQAAAANAAUAAAArAAUAAAANAAUAAAArAAYAAAANAAUAAAArAAcAAAANAAUAAAArAAgAAAANAAUAAAArAAkAAAANAAUAAAArAAoAAAANAAUAAAArAAsAAAANAAYAAAA=") +tile_set = SubResource("TileSet_eyojy") + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_4ncqd")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_tpji3")] +unique_name_in_owner = true +visible = false + +[node name="Camera2D" type="Camera2D" parent="."] +physics_interpolation_mode = 1 +position = Vector2(374, -190) +zoom = Vector2(1.5, 1.5) +process_callback = 0 +editor_draw_limits = true + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("4_w0rat") + +[node name="Label" type="Label" parent="."] +offset_left = 167.0 +offset_top = -133.0 +offset_right = 332.0 +offset_bottom = -69.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("5_q77r4") +text = "[WASD] to move +[Space] to jump" + +[node name="Player" type="Node" parent="."] + +[node name="Label" type="Label" parent="Player"] +visible = false +offset_left = 167.0 +offset_top = -145.0 +offset_right = 332.0 +offset_bottom = -81.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("5_q77r4") +text = "[WASD] to move +[Space] to jump" + +[node name="PlayerPhantomCamera2D" type="Node2D" parent="." node_paths=PackedStringArray("follow_target", "follow_path")] +unique_name_in_owner = true +top_level = true +position = Vector2(374, -190) +script = ExtResource("6_y6hoa") +priority = 10 +follow_mode = 4 +follow_target = NodePath("../CharacterBody2D") +follow_path = NodePath("../Path2D") +zoom = Vector2(1.5, 1.5) +tween_resource = ExtResource("7_wd55r") +tween_on_load = false +follow_damping = true +draw_limits = true + +[node name="Path2D" type="Path2D" parent="."] +position = Vector2(152, -190) +curve = SubResource("Curve2D_usrhf") + +[node name="CharacterBody2D" parent="." instance=ExtResource("8_fy81j")] +position = Vector2(225, -28) +script = ExtResource("9_u6ygl") diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_limit_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_limit_example_scene.tscn new file mode 100644 index 0000000..35538eb --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_limit_example_scene.tscn @@ -0,0 +1,319 @@ +[gd_scene load_steps=17 format=4 uid="uid://0ox7hgdpwpqp"] + +[ext_resource type="Script" uid="uid://dtcuvut1eklnd" path="res://addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd" id="1_bwr3f"] +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="2_f03of"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="3_cysy4"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="4_qqut6"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="5_yv8tn"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_2n5r1"] +[ext_resource type="Script" uid="uid://cnnaky2ns2pn4" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="6_68ewj"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="7_ne05h"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="8_hulu3"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"] +texture = ExtResource("2_f03of") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_kf7eg"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_easgx") + +[sub_resource type="Resource" id="Resource_ct1eh"] +script = ExtResource("7_ne05h") +duration = 0.9 +transition = 2 +ease = 2 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_xmxri"] +size = Vector2(790, 410) + +[sub_resource type="Resource" id="Resource_exr3j"] +script = ExtResource("7_ne05h") +duration = 0.9 +transition = 2 +ease = 2 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_wtfjw"] +size = Vector2(1530, 700) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_daeuh"] +size = Vector2(1027.5, 610.5) + +[node name="ExampleScene2D" type="Node2D"] +script = ExtResource("1_bwr3f") + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) +metadata/_edit_lock_ = true + +[node name="StartingTerrain" type="TileMapLayer" parent="."] +z_index = 1 +use_parent_material = true +position = Vector2(-97, 0) +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAD9/wAAAAALAAAAAAD+/wAAAAALAAAAAAD//wAAAAALAAAAAAAAAAAAAAALAAAAAAABAAAAAAALAAAAAAACAAAAAAALAAAAAAADAAAAAAALAAAAAAAEAAAAAAALAAAAAAAFAAAAAAALAAAAAAAGAAAAAAALAAAAAAAHAAAAAAALAAAAAAAIAAAAAAALAAAAAAAJAAAAAAAMAAAAAAD8/wAAAAALAAAAAAD7/wAAAAAKAAAAAAD7/wEAAAAKAAEAAAD7/wIAAAAKAAEAAAD7/wMAAAAKAAEAAAD7/wQAAAAKAAEAAAD7/wUAAAAKAAEAAAD8/wEAAAALAAEAAAD8/wIAAAALAAEAAAD8/wMAAAALAAEAAAD8/wQAAAALAAEAAAD8/wUAAAALAAEAAAD9/wEAAAALAAEAAAD9/wIAAAALAAEAAAD9/wMAAAALAAEAAAD9/wQAAAALAAEAAAD9/wUAAAALAAEAAAD+/wEAAAALAAEAAAD+/wIAAAALAAEAAAD+/wMAAAALAAEAAAD+/wQAAAALAAEAAAD+/wUAAAALAAEAAAD//wEAAAALAAEAAAD//wIAAAALAAEAAAD//wMAAAALAAEAAAD//wQAAAALAAEAAAD//wUAAAALAAEAAAAAAAEAAAALAAEAAAAAAAIAAAALAAEAAAAAAAMAAAALAAEAAAAAAAQAAAALAAEAAAAAAAUAAAALAAEAAAABAAEAAAALAAEAAAABAAIAAAALAAEAAAABAAMAAAALAAEAAAABAAQAAAALAAEAAAABAAUAAAALAAEAAAACAAEAAAALAAEAAAACAAIAAAALAAEAAAACAAMAAAALAAEAAAACAAQAAAALAAEAAAACAAUAAAALAAEAAAADAAEAAAALAAEAAAADAAIAAAALAAEAAAADAAMAAAALAAEAAAADAAQAAAALAAEAAAADAAUAAAALAAEAAAAEAAEAAAALAAEAAAAEAAIAAAALAAEAAAAEAAMAAAALAAEAAAAEAAQAAAALAAEAAAAEAAUAAAALAAEAAAAFAAEAAAALAAEAAAAFAAIAAAALAAEAAAAFAAMAAAALAAEAAAAFAAQAAAALAAEAAAAFAAUAAAALAAEAAAAGAAEAAAALAAEAAAAGAAIAAAALAAEAAAAGAAMAAAALAAEAAAAGAAQAAAALAAEAAAAGAAUAAAALAAEAAAAHAAEAAAALAAEAAAAHAAIAAAALAAEAAAAHAAMAAAALAAEAAAAHAAQAAAALAAEAAAAHAAUAAAALAAEAAAAIAAEAAAALAAEAAAAIAAIAAAALAAEAAAAIAAMAAAALAAEAAAAIAAQAAAALAAEAAAAIAAUAAAALAAEAAAAJAAEAAAAMAAEAAAAJAAIAAAAMAAEAAAAJAAMAAAAMAAEAAAAJAAQAAAAMAAEAAAAJAAUAAAAMAAEAAAD7//n/AAALAAYAAAD7//j/AAALAAUAAAD7//f/AAALAAUAAAD7//b/AAALAAUAAAD7//X/AAALAAQAAAD8//n/AAAMAAYAAAD9//n/AAAMAAYAAAD+//n/AAAMAAYAAAD///n/AAAMAAYAAAAAAPn/AAAMAAYAAAABAPn/AAAMAAYAAAACAPn/AAAMAAYAAAADAPn/AAAMAAYAAAAEAPn/AAAMAAYAAAAFAPn/AAAMAAYAAAAGAPn/AAAMAAYAAAAHAPn/AAAMAAYAAAAIAPn/AAAMAAYAAAD8//X/AAAMAAQAAAD9//X/AAAMAAQAAAD+//X/AAAMAAQAAAD///X/AAAMAAQAAAAAAPX/AAAMAAQAAAABAPX/AAAMAAQAAAACAPX/AAAMAAQAAAADAPX/AAAMAAQAAAAEAPX/AAAMAAQAAAAFAPX/AAAMAAQAAAAGAPX/AAAMAAQAAAAHAPX/AAAMAAQAAAAIAPX/AAAMAAQAAAAJAPX/AAANAAQAAAAJAPb/AAANAAUAAAAJAPf/AAANAAUAAAAJAPj/AAANAAUAAAAJAPn/AAANAAYAAAD8//b/AAAMAAUAAAD8//f/AAAMAAUAAAD8//j/AAAMAAUAAAD9//b/AAAMAAUAAAD9//f/AAAMAAUAAAD9//j/AAAMAAUAAAD+//b/AAAMAAUAAAD+//f/AAAMAAUAAAD+//j/AAAMAAUAAAD///b/AAAMAAUAAAD///f/AAAMAAUAAAD///j/AAAMAAUAAAAAAPb/AAAMAAUAAAAAAPf/AAAMAAUAAAAAAPj/AAAMAAUAAAABAPb/AAAMAAUAAAABAPf/AAAMAAUAAAABAPj/AAAMAAUAAAACAPb/AAAMAAUAAAACAPf/AAAMAAUAAAACAPj/AAAMAAUAAAADAPb/AAAMAAUAAAADAPf/AAAMAAUAAAADAPj/AAAMAAUAAAAEAPb/AAAMAAUAAAAEAPf/AAAMAAUAAAAEAPj/AAAMAAUAAAAFAPb/AAAMAAUAAAAFAPf/AAAMAAUAAAAFAPj/AAAMAAUAAAAGAPb/AAAMAAUAAAAGAPf/AAAMAAUAAAAGAPj/AAAMAAUAAAAHAPb/AAAMAAUAAAAHAPf/AAAMAAUAAAAHAPj/AAAMAAUAAAAIAPb/AAAMAAUAAAAIAPf/AAAMAAUAAAAIAPj/AAAMAAUAAAA=") +tile_set = SubResource("TileSet_kf7eg") + +[node name="OtherTerrain" type="TileMapLayer" parent="."] +z_index = 1 +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAAIAAAAAAAMAAQAAAAJAAAAAAAMAAQAAAAKAAAAAAAMAAQAAAALAAAAAAAMAAQAAAAMAAAAAAAMAAQAAAANAAAAAAAMAAQAAAAOAAAAAAAMAAQAAAD4/wAAAAANAAUAAAD3/wAAAAAMAAUAAAD2/wAAAAAMAAUAAAD1/wAAAAAMAAUAAAD0/wAAAAAMAAUAAADz/wAAAAAMAAUAAAAIAAEAAAAMAAUAAAAIAAIAAAAMAAUAAAAIAAMAAAAMAAUAAAAIAAQAAAAMAAUAAAAJAAEAAAAMAAUAAAAJAAIAAAAMAAUAAAAJAAMAAAAMAAUAAAAJAAQAAAAMAAUAAAAKAAEAAAAMAAUAAAAKAAIAAAAMAAUAAAAKAAMAAAAMAAUAAAAKAAQAAAAMAAUAAAALAAEAAAAMAAUAAAALAAIAAAAMAAUAAAALAAMAAAAMAAUAAAALAAQAAAAMAAUAAAAMAAEAAAAMAAUAAAAMAAIAAAAMAAUAAAAMAAMAAAAMAAUAAAAMAAQAAAAMAAUAAAANAAEAAAAMAAUAAAANAAIAAAAMAAUAAAANAAMAAAAMAAUAAAANAAQAAAAMAAUAAAAOAAEAAAAMAAUAAAAOAAIAAAAMAAUAAAAOAAMAAAAMAAUAAAAOAAQAAAAMAAUAAAAOAAUAAAAMAAUAAAANAAUAAAAMAAUAAAAMAAUAAAAMAAUAAAALAAUAAAAMAAUAAAAKAAUAAAAMAAUAAAAJAAUAAAAMAAUAAAAIAAUAAAAMAAUAAADv//3/AAALAAUAAADv//7/AAALAAUAAADv////AAALAAUAAADv/wAAAAALAAYAAADw//3/AAAMAAUAAADw//7/AAAMAAUAAADw////AAAMAAUAAADw/wAAAAAMAAUAAADx//3/AAAMAAUAAADx//7/AAAMAAUAAADx////AAAMAAUAAADx/wAAAAAMAAUAAADy//3/AAAMAAUAAADy//7/AAAMAAUAAADy////AAAMAAUAAADy/wAAAAAMAAUAAADz//3/AAAMAAUAAADz//7/AAAMAAUAAADz////AAAMAAUAAAD0//3/AAAMAAUAAAD0//7/AAAMAAUAAAD0////AAAMAAUAAAD1//3/AAAMAAUAAAD1//7/AAAMAAUAAAD1////AAAMAAUAAAD2//3/AAAMAAUAAAD2//7/AAAMAAUAAAD2////AAAMAAUAAAD3//3/AAAMAAUAAAD3//7/AAAMAAUAAAD3////AAAMAAUAAAD4//3/AAANAAUAAAD4//7/AAANAAUAAAD4////AAANAAUAAAD4/wEAAAANAAUAAAD4/wIAAAANAAUAAAD4/wMAAAANAAUAAAD4/wQAAAANAAUAAAD4/wUAAAANAAUAAADw/wEAAAAMAAUAAADw/wIAAAAMAAUAAADw/wMAAAAMAAUAAADw/wQAAAAMAAUAAADw/wUAAAAMAAUAAADx/wEAAAAMAAUAAADx/wIAAAAMAAUAAADx/wMAAAAMAAUAAADx/wQAAAAMAAUAAADx/wUAAAAMAAUAAADy/wEAAAAMAAUAAADy/wIAAAAMAAUAAADy/wMAAAAMAAUAAADy/wQAAAAMAAUAAADy/wUAAAAMAAUAAADz/wEAAAAMAAUAAADz/wIAAAAMAAUAAADz/wMAAAAMAAUAAADz/wQAAAAMAAUAAADz/wUAAAAMAAUAAAD0/wEAAAAMAAUAAAD0/wIAAAAMAAUAAAD0/wMAAAAMAAUAAAD0/wQAAAAMAAUAAAD0/wUAAAAMAAUAAAD1/wEAAAAMAAUAAAD1/wIAAAAMAAUAAAD1/wMAAAAMAAUAAAD1/wQAAAAMAAUAAAD1/wUAAAAMAAUAAAD2/wEAAAAMAAUAAAD2/wIAAAAMAAUAAAD2/wMAAAAMAAUAAAD2/wQAAAAMAAUAAAD2/wUAAAAMAAUAAAD3/wEAAAAMAAUAAAD3/wIAAAAMAAUAAAD3/wMAAAAMAAUAAAD3/wQAAAAMAAUAAAD3/wUAAAAMAAUAAAARAAAAAAAMAAQAAAARAAEAAAAMAAUAAAARAAIAAAAMAAUAAAARAAMAAAAMAAUAAAARAAQAAAAMAAUAAAARAAUAAAAMAAUAAAASAAAAAAAMAAQAAAASAAEAAAAMAAUAAAASAAIAAAAMAAUAAAASAAMAAAAMAAUAAAASAAQAAAAMAAUAAAASAAUAAAAMAAUAAAAPAAAAAAAMAAQAAAAPAAEAAAAMAAUAAAAPAAIAAAAMAAUAAAAPAAMAAAAMAAUAAAAPAAQAAAAMAAUAAAAPAAUAAAAMAAUAAAAQAAAAAAAMAAQAAAAQAAEAAAAMAAUAAAAQAAIAAAAMAAUAAAAQAAMAAAAMAAUAAAAQAAQAAAAMAAUAAAAQAAUAAAAMAAUAAAATAAAAAAAMAAQAAAATAAEAAAAMAAUAAAATAAIAAAAMAAUAAAATAAMAAAAMAAUAAAATAAQAAAAMAAUAAAATAAUAAAAMAAUAAADv//j/AAALAAUAAADv//n/AAALAAUAAADw//j/AAAMAAUAAADw//n/AAAMAAUAAADx//j/AAAMAAUAAADx//n/AAAMAAUAAADy//j/AAAMAAUAAADy//n/AAAMAAUAAADz//j/AAAMAAUAAADz//n/AAAMAAUAAAD0//j/AAAMAAUAAAD0//n/AAAMAAUAAAD1//j/AAAMAAUAAAD1//n/AAAMAAUAAAD2//j/AAAMAAUAAAD2//n/AAAMAAUAAAD3//j/AAAMAAUAAAD3//n/AAAMAAUAAAD4//j/AAANAAUAAAD4//n/AAANAAUAAADv//X/AAALAAQAAADv//b/AAALAAUAAADv//f/AAALAAUAAADw//X/AAAMAAQAAADw//b/AAAMAAUAAADw//f/AAAMAAUAAADx//X/AAAMAAQAAADx//b/AAAMAAUAAADx//f/AAAMAAUAAADy//X/AAAMAAQAAADy//b/AAAMAAUAAADy//f/AAAMAAUAAADz//X/AAAMAAQAAADz//b/AAAMAAUAAADz//f/AAAMAAUAAAD0//X/AAAMAAQAAAD0//b/AAAMAAUAAAD0//f/AAAMAAUAAAD1//X/AAAMAAQAAAD1//b/AAAMAAUAAAD1//f/AAAMAAUAAAD2//X/AAAMAAQAAAD2//b/AAAMAAUAAAD2//f/AAAMAAUAAAD3//X/AAAMAAQAAAD3//b/AAAMAAUAAAD3//f/AAAMAAUAAAD4//X/AAANAAQAAAD4//b/AAANAAUAAAD4//f/AAANAAUAAADv//r/AAALAAUAAADw//r/AAAMAAUAAADx//r/AAAMAAUAAADy//r/AAAMAAUAAADz//r/AAAMAAUAAAD0//r/AAAMAAUAAAD1//r/AAAMAAUAAAD2//r/AAAMAAUAAAD3//r/AAAMAAUAAAD4//r/AAANAAUAAADv//v/AAALAAUAAADw//v/AAAMAAUAAADx//v/AAAMAAUAAADy//v/AAAMAAUAAADz//v/AAAMAAUAAAD0//v/AAAMAAUAAAD1//v/AAAMAAUAAAD2//v/AAAMAAUAAAD3//v/AAAMAAUAAAD4//v/AAANAAUAAADv//z/AAALAAUAAADw//z/AAAMAAUAAADx//z/AAAMAAUAAADy//z/AAAMAAUAAADz//z/AAAMAAUAAAD0//z/AAAMAAUAAAD1//z/AAAMAAUAAAD2//z/AAAMAAUAAAD3//z/AAAMAAUAAAD4//z/AAANAAUAAAAUAAAAAAAMAAQAAAAUAAEAAAAMAAUAAAAUAAIAAAAMAAUAAAAUAAMAAAAMAAUAAAAUAAQAAAAMAAUAAAAUAAUAAAAMAAUAAAAVAAAAAAAMAAQAAAAVAAEAAAAMAAUAAAAVAAIAAAAMAAUAAAAVAAMAAAAMAAUAAAAVAAQAAAAMAAUAAAAVAAUAAAAMAAUAAAAWAAAAAAAMAAQAAAAWAAEAAAAMAAUAAAAWAAIAAAAMAAUAAAAWAAMAAAAMAAUAAAAWAAQAAAAMAAUAAAAWAAUAAAAMAAUAAAAXAAAAAAAMAAQAAAAXAAEAAAAMAAUAAAAXAAIAAAAMAAUAAAAXAAMAAAAMAAUAAAAXAAQAAAAMAAUAAAAXAAUAAAAMAAUAAAAYAAAAAAAMAAQAAAAYAAEAAAAMAAUAAAAYAAIAAAAMAAUAAAAYAAMAAAAMAAUAAAAYAAQAAAAMAAUAAAAYAAUAAAAMAAUAAAAZAAAAAAAMAAQAAAAZAAEAAAAMAAUAAAAZAAIAAAAMAAUAAAAZAAMAAAAMAAUAAAAZAAQAAAAMAAUAAAAZAAUAAAAMAAUAAAAaAAAAAAAMAAQAAAAaAAEAAAAMAAUAAAAaAAIAAAAMAAUAAAAaAAMAAAAMAAUAAAAaAAQAAAAMAAUAAAAaAAUAAAAMAAUAAAAbAAAAAAAMAAQAAAAbAAEAAAAMAAUAAAAbAAIAAAAMAAUAAAAbAAMAAAAMAAUAAAAbAAQAAAAMAAUAAAAbAAUAAAAMAAUAAAAmAAAAAAAMAAQAAAAmAAEAAAAMAAUAAAAmAAIAAAAMAAUAAAAmAAMAAAAMAAUAAAAmAAQAAAAMAAUAAAAmAAUAAAAMAAUAAAAnAAAAAAAMAAQAAAAnAAEAAAAMAAUAAAAnAAIAAAAMAAUAAAAnAAMAAAAMAAUAAAAnAAQAAAAMAAUAAAAnAAUAAAAMAAUAAAAoAAAAAAAMAAQAAAAoAAEAAAAMAAUAAAAoAAIAAAAMAAUAAAAoAAMAAAAMAAUAAAAoAAQAAAAMAAUAAAAoAAUAAAAMAAUAAAApAAAAAAAMAAQAAAApAAEAAAAMAAUAAAApAAIAAAAMAAUAAAApAAMAAAAMAAUAAAApAAQAAAAMAAUAAAApAAUAAAAMAAUAAAAqAAAAAAAMAAQAAAAqAAEAAAAMAAUAAAAqAAIAAAAMAAUAAAAqAAMAAAAMAAUAAAAqAAQAAAAMAAUAAAAqAAUAAAAMAAUAAAArAAAAAAAMAAQAAAArAAEAAAAMAAUAAAArAAIAAAAMAAUAAAArAAMAAAAMAAUAAAArAAQAAAAMAAUAAAArAAUAAAAMAAUAAAAsAAAAAAAMAAQAAAAsAAEAAAAMAAUAAAAsAAIAAAAMAAUAAAAsAAMAAAAMAAUAAAAsAAQAAAAMAAUAAAAsAAUAAAAMAAUAAAAtAAAAAAAMAAQAAAAtAAEAAAAMAAUAAAAtAAIAAAAMAAUAAAAtAAMAAAAMAAUAAAAtAAQAAAAMAAUAAAAtAAUAAAAMAAUAAAAuAAAAAAAMAAQAAAAuAAEAAAAMAAUAAAAuAAIAAAAMAAUAAAAuAAMAAAAMAAUAAAAuAAQAAAAMAAUAAAAuAAUAAAAMAAUAAAAvAAAAAAAMAAQAAAAvAAEAAAAMAAUAAAAvAAIAAAAMAAUAAAAvAAMAAAAMAAUAAAAvAAQAAAAMAAUAAAAvAAUAAAAMAAUAAAAwAAAAAAAMAAQAAAAwAAEAAAAMAAUAAAAwAAIAAAAMAAUAAAAwAAMAAAAMAAUAAAAwAAQAAAAMAAUAAAAwAAUAAAAMAAUAAAAxAAAAAAANAAQAAAAxAAEAAAANAAUAAAAxAAIAAAANAAUAAAAxAAMAAAANAAUAAAAxAAQAAAANAAUAAAAxAAUAAAANAAUAAAAyAPf/AAALAAQAAAAyAPj/AAALAAUAAAAyAPn/AAALAAUAAAAyAPr/AAALAAUAAAAyAPv/AAALAAUAAAAyAPz/AAALAAUAAAAyAP3/AAALAAUAAAAyAP7/AAALAAUAAAAyAP//AAALAAUAAAAyAAAAAAALAAUAAAAyAAEAAAALAAUAAAAyAAIAAAALAAUAAAAyAAMAAAALAAUAAAAyAAQAAAALAAUAAAAyAAUAAAALAAUAAAAzAPf/AAAMAAQAAAAzAPj/AAAMAAUAAAAzAPn/AAAMAAUAAAAzAPr/AAAMAAUAAAAzAPv/AAAMAAUAAAAzAPz/AAAMAAUAAAAzAP3/AAAMAAUAAAAzAP7/AAAMAAUAAAAzAP//AAAMAAUAAAAzAAAAAAAMAAUAAAAzAAEAAAAMAAUAAAAzAAIAAAAMAAUAAAAzAAMAAAAMAAUAAAAzAAQAAAAMAAUAAAAzAAUAAAAMAAUAAAA0APf/AAAMAAQAAAA0APj/AAAMAAUAAAA0APn/AAAMAAUAAAA0APr/AAAMAAUAAAA0APv/AAAMAAUAAAA0APz/AAAMAAUAAAA0AP3/AAAMAAUAAAA0AP7/AAAMAAUAAAA0AP//AAAMAAUAAAA0AAAAAAAMAAUAAAA0AAEAAAAMAAUAAAA0AAIAAAAMAAUAAAA0AAMAAAAMAAUAAAA0AAQAAAAMAAUAAAA0AAUAAAAMAAUAAAA1APf/AAAMAAQAAAA1APj/AAAMAAUAAAA1APn/AAAMAAUAAAA1APr/AAAMAAUAAAA1APv/AAAMAAUAAAA1APz/AAAMAAUAAAA1AP3/AAAMAAUAAAA1AP7/AAAMAAUAAAA1AP//AAAMAAUAAAA1AAAAAAAMAAUAAAA1AAEAAAAMAAUAAAA1AAIAAAAMAAUAAAA1AAMAAAAMAAUAAAA1AAQAAAAMAAUAAAA1AAUAAAAMAAUAAAA2APf/AAAMAAQAAAA2APj/AAAMAAUAAAA2APn/AAAMAAUAAAA2APr/AAAMAAUAAAA2APv/AAAMAAUAAAA2APz/AAAMAAUAAAA2AP3/AAAMAAUAAAA2AP7/AAAMAAUAAAA2AP//AAAMAAUAAAA2AAAAAAAMAAUAAAA2AAEAAAAMAAUAAAA2AAIAAAAMAAUAAAA2AAMAAAAMAAUAAAA2AAQAAAAMAAUAAAA2AAUAAAAMAAUAAAA3APf/AAAMAAQAAAA3APj/AAAMAAUAAAA3APn/AAAMAAUAAAA3APr/AAAMAAUAAAA3APv/AAAMAAUAAAA3APz/AAAMAAUAAAA3AP3/AAAMAAUAAAA3AP7/AAAMAAUAAAA3AP//AAAMAAUAAAA3AAAAAAAMAAUAAAA3AAEAAAAMAAUAAAA3AAIAAAAMAAUAAAA3AAMAAAAMAAUAAAA3AAQAAAAMAAUAAAA3AAUAAAAMAAUAAAA4APf/AAAMAAQAAAA4APj/AAAMAAUAAAA4APn/AAAMAAUAAAA4APr/AAAMAAUAAAA4APv/AAAMAAUAAAA4APz/AAAMAAUAAAA4AP3/AAAMAAUAAAA4AP7/AAAMAAUAAAA4AP//AAAMAAUAAAA4AAAAAAAMAAUAAAA4AAEAAAAMAAUAAAA4AAIAAAAMAAUAAAA4AAMAAAAMAAUAAAA4AAQAAAAMAAUAAAA4AAUAAAAMAAUAAAA5APf/AAAMAAQAAAA5APj/AAAMAAUAAAA5APn/AAAMAAUAAAA5APr/AAAMAAUAAAA5APv/AAAMAAUAAAA5APz/AAAMAAUAAAA5AP3/AAAMAAUAAAA5AP7/AAAMAAUAAAA5AP//AAAMAAUAAAA5AAAAAAAMAAUAAAA5AAEAAAAMAAUAAAA5AAIAAAAMAAUAAAA5AAMAAAAMAAUAAAA5AAQAAAAMAAUAAAA5AAUAAAAMAAUAAAA6APf/AAAMAAQAAAA6APj/AAAMAAUAAAA6APn/AAAMAAUAAAA6APr/AAAMAAUAAAA6APv/AAAMAAUAAAA6APz/AAAMAAUAAAA6AP3/AAAMAAUAAAA6AP7/AAAMAAUAAAA6AP//AAAMAAUAAAA6AAAAAAAMAAUAAAA6AAEAAAAMAAUAAAA6AAIAAAAMAAUAAAA6AAMAAAAMAAUAAAA6AAQAAAAMAAUAAAA6AAUAAAAMAAUAAAA7APf/AAANAAQAAAA7APj/AAANAAUAAAA7APn/AAANAAUAAAA7APr/AAANAAUAAAA7APv/AAANAAUAAAA7APz/AAANAAUAAAA7AP3/AAANAAUAAAA7AP7/AAANAAUAAAA7AP//AAANAAUAAAA7AAAAAAANAAUAAAA7AAEAAAANAAUAAAA7AAIAAAANAAUAAAA7AAMAAAANAAUAAAA7AAQAAAANAAUAAAA7AAUAAAANAAUAAAAcAAAAAAAMAAQAAAAcAAEAAAAMAAUAAAAcAAIAAAAMAAUAAAAcAAMAAAAMAAUAAAAcAAQAAAAMAAUAAAAcAAUAAAAMAAUAAAAdAAAAAAAMAAQAAAAdAAEAAAAMAAUAAAAdAAIAAAAMAAUAAAAdAAMAAAAMAAUAAAAdAAQAAAAMAAUAAAAdAAUAAAAMAAUAAAAeAAAAAAAMAAQAAAAeAAEAAAAMAAUAAAAeAAIAAAAMAAUAAAAeAAMAAAAMAAUAAAAeAAQAAAAMAAUAAAAeAAUAAAAMAAUAAAAfAAAAAAAMAAQAAAAfAAEAAAAMAAUAAAAfAAIAAAAMAAUAAAAfAAMAAAAMAAUAAAAfAAQAAAAMAAUAAAAfAAUAAAAMAAUAAAAgAAAAAAAMAAQAAAAgAAEAAAAMAAUAAAAgAAIAAAAMAAUAAAAgAAMAAAAMAAUAAAAgAAQAAAAMAAUAAAAgAAUAAAAMAAUAAAAhAAAAAAAMAAQAAAAhAAEAAAAMAAUAAAAhAAIAAAAMAAUAAAAhAAMAAAAMAAUAAAAhAAQAAAAMAAUAAAAhAAUAAAAMAAUAAAAiAAAAAAAMAAQAAAAiAAEAAAAMAAUAAAAiAAIAAAAMAAUAAAAiAAMAAAAMAAUAAAAiAAQAAAAMAAUAAAAiAAUAAAAMAAUAAAAjAAAAAAAMAAQAAAAjAAEAAAAMAAUAAAAjAAIAAAAMAAUAAAAjAAMAAAAMAAUAAAAjAAQAAAAMAAUAAAAjAAUAAAAMAAUAAAAkAAAAAAAMAAQAAAAkAAEAAAAMAAUAAAAkAAIAAAAMAAUAAAAkAAMAAAAMAAUAAAAkAAQAAAAMAAUAAAAkAAUAAAAMAAUAAAAlAAAAAAAMAAQAAAAlAAEAAAAMAAUAAAAlAAIAAAAMAAUAAAAlAAMAAAAMAAUAAAAlAAQAAAAMAAUAAAAlAAUAAAAMAAUAAAAmAP//AAAOAAMAAAAnAP//AAAPAAMAAAAoAP//AAAPAAMAAAApAP//AAAPAAMAAAAqAP//AAAPAAMAAAArAP//AAAPAAMAAAAsAP//AAAPAAMAAAAtAP//AAAPAAMAAAAuAP//AAAPAAMAAAAvAP//AAAPAAMAAAAwAP//AAAQAAMAAAAxAPf/AAAHAAQAAAAxAPj/AAAHAAUAAAAxAPn/AAAHAAUAAAAxAPr/AAAHAAUAAAAxAPv/AAAHAAUAAAAxAPz/AAAHAAUAAAAxAP3/AAAHAAUAAAAxAP7/AAAHAAUAAAAxAP//AAAHAAYAAAA=") +tile_set = SubResource("TileSet_kf7eg") + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("3_cysy4")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("4_qqut6")] +unique_name_in_owner = true +visible = false + +[node name="CharacterBody2D" parent="." instance=ExtResource("5_yv8tn")] +unique_name_in_owner = true +z_index = 1 +position = Vector2(66, -28) +script = ExtResource("6_68ewj") + +[node name="RoomLeftPhantomCamera2D" type="Node2D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +top_level = true +position = Vector2(141, -91.205) +script = ExtResource("6_2n5r1") +priority = 5 +follow_mode = 2 +follow_target = NodePath("../CharacterBody2D") +zoom = Vector2(2, 2) +tween_resource = SubResource("Resource_ct1eh") +follow_offset = Vector2(0, -63.205) +follow_damping = true +draw_limits = true +limit_target = NodePath("../StartingTerrain") +limit_margin = Vector4i(-50, 0, -50, 0) + +[node name="RoomLeftArea2D" type="Area2D" parent="."] +unique_name_in_owner = true +position = Vector2(117, -174) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomLeftArea2D"] +position = Vector2(-79, 43) +shape = SubResource("RectangleShape2D_xmxri") +debug_color = Color(0, 0.6, 0.701961, 0.0313726) + +[node name="RoomCentrePhantomCamera2D" type="Node2D" parent="."] +unique_name_in_owner = true +top_level = true +position = Vector2(1218, -217) +script = ExtResource("6_2n5r1") +follow_mode = 2 +zoom = Vector2(1.5, 1.5) +tween_resource = SubResource("Resource_exr3j") +follow_damping = true +draw_limits = true +limit_target = NodePath("../RoomCentreArea2D/CollisionShape2D") + +[node name="RoomCentreArea2D" type="Area2D" parent="."] +unique_name_in_owner = true +position = Vector2(755, -179) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomCentreArea2D"] +position = Vector2(338, -28) +shape = SubResource("RectangleShape2D_wtfjw") +debug_color = Color(0, 0.6, 0.701961, 0) + +[node name="RoomRightArea2D" type="Area2D" parent="."] +unique_name_in_owner = true +position = Vector2(2065, -160) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomRightArea2D"] +position = Vector2(255.75, -3.25) +shape = SubResource("RectangleShape2D_daeuh") +debug_color = Color(0, 0.6, 0.701961, 0) + +[node name="RoomRightPhantomCamera2D" type="Node2D" parent="."] +unique_name_in_owner = true +top_level = true +position = Vector2(2347, -156) +scale = Vector2(1.0024, 1) +script = ExtResource("6_2n5r1") +follow_mode = 2 +zoom = Vector2(2, 2) +tween_resource = SubResource("Resource_exr3j") +follow_damping = true +draw_limits = true + +[node name="Camera2D" type="Camera2D" parent="."] +physics_interpolation_mode = 1 +position = Vector2(141, -91.205) +zoom = Vector2(2, 2) +process_callback = 0 +limit_left = -147 +limit_top = -528 +limit_right = 673 +limit_bottom = 288 +position_smoothing_speed = 10.0 +editor_draw_limits = true + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("8_hulu3") diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_noise_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_noise_example_scene.tscn new file mode 100644 index 0000000..68e792e --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_noise_example_scene.tscn @@ -0,0 +1,289 @@ +[gd_scene load_steps=16 format=4 uid="uid://chw6g32u86uve"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_2m0x8"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_4bfy0"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_vdqsb"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="4_w2gh7"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_d6fcf"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_bdmii"] +[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="7_dpnkg"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_u5o87"] +[ext_resource type="Script" uid="uid://cnnaky2ns2pn4" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_suxld"] +[ext_resource type="Script" uid="uid://bhd4nuiu23e7l" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd" id="10_p43w0"] +[ext_resource type="Script" uid="uid://dimvdouy8g0sv" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd" id="11_d6abr"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_lvmak"] +texture = ExtResource("1_2m0x8") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_kf7eg"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_lvmak") + +[sub_resource type="Resource" id="Resource_87ddr"] +script = ExtResource("11_d6abr") +amplitude = 30.0 +frequency = 0.5 +randomize_noise_seed = 1 +noise_seed = 0 +positional_noise = true +rotational_noise = false +positional_multiplier_x = 1.0 +positional_multiplier_y = 1.0 +rotational_multiplier = 1.0 + +[sub_resource type="Resource" id="Resource_rmnw1"] +script = ExtResource("11_d6abr") +amplitude = 40.0 +frequency = 30.0 +randomize_noise_seed = 1 +noise_seed = 96 +positional_noise = true +rotational_noise = true +positional_multiplier_x = 1.0 +positional_multiplier_y = 1.0 +rotational_multiplier = 1.0 + +[node name="Root" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="Pillar" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAAAAPr/AAAKAAIAAAAAAPv/AAAKAAMAAAAAAPz/AAAKAAMAAAAAAP3/AAAKAAMAAAAAAP7/AAAKAAMAAAAAAP//AAAKAAMAAAABAPr/AAALAAIAAAABAPv/AAALAAEAAAABAPz/AAALAAEAAAABAP3/AAALAAEAAAABAP7/AAALAAEAAAABAP//AAALAAEAAAACAPr/AAAMAAIAAAACAPv/AAAMAAMAAAACAPz/AAAMAAMAAAACAP3/AAAMAAMAAAACAP7/AAAMAAMAAAACAP//AAAMAAMAAAA=") +tile_set = SubResource("TileSet_kf7eg") +collision_enabled = false +navigation_enabled = false + +[node name="Terrain" type="TileMapLayer" parent="."] +z_index = 1 +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAABAAAAAAALAAAAAAACAAAAAAALAAAAAAADAAAAAAALAAAAAAAEAAAAAAALAAAAAAAFAAAAAAALAAAAAAAGAAAAAAALAAAAAAAHAAAAAAALAAAAAAAIAAAAAAALAAAAAAAJAAAAAAAMAAAAAAAJAAEAAAAMAAEAAAAJAAIAAAAMAAEAAAAJAAMAAAAMAAEAAAAJAAQAAAAMAAEAAAAJAAUAAAAMAAEAAAAJAAYAAAAMAAEAAAABAAEAAAALAAEAAAABAAIAAAALAAEAAAABAAMAAAALAAEAAAABAAQAAAAHAAEAAAABAAUAAAALAAEAAAABAAYAAAALAAEAAAACAAEAAAALAAEAAAACAAIAAAALAAEAAAACAAMAAAALAAEAAAACAAQAAAALAAEAAAACAAUAAAALAAEAAAACAAYAAAALAAEAAAADAAEAAAALAAEAAAADAAIAAAALAAEAAAADAAMAAAALAAEAAAADAAQAAAALAAEAAAADAAUAAAALAAEAAAADAAYAAAALAAEAAAAEAAEAAAAHAAEAAAAEAAIAAAALAAEAAAAEAAMAAAALAAEAAAAEAAQAAAALAAEAAAAEAAUAAAALAAEAAAAEAAYAAAALAAEAAAAFAAEAAAALAAEAAAAFAAIAAAALAAEAAAAFAAMAAAALAAEAAAAFAAQAAAAHAAEAAAAFAAUAAAALAAEAAAAFAAYAAAALAAEAAAAGAAEAAAALAAEAAAAGAAIAAAALAAEAAAAGAAMAAAALAAEAAAAGAAQAAAALAAEAAAAGAAUAAAALAAEAAAAGAAYAAAALAAEAAAAHAAEAAAALAAEAAAAHAAIAAAALAAEAAAAHAAMAAAALAAEAAAAHAAQAAAALAAEAAAAHAAUAAAALAAEAAAAHAAYAAAAHAAEAAAAIAAEAAAALAAEAAAAIAAIAAAALAAEAAAAIAAMAAAAHAAEAAAAIAAQAAAALAAEAAAAIAAUAAAALAAEAAAAIAAYAAAALAAEAAAAKAAEAAAAIAAUAAAALAAEAAAAIAAUAAAAMAAEAAAAIAAUAAAANAAEAAAAIAAUAAAAKAAIAAAAIAAYAAAALAAIAAAAIAAYAAAAMAAIAAAAIAAYAAAANAAIAAAAIAAYAAAAKAAMAAAALAAEAAAAKAAQAAAALAAEAAAALAAMAAAALAAEAAAALAAQAAAALAAEAAAAMAAMAAAALAAEAAAAMAAQAAAALAAEAAAANAAMAAAALAAEAAAANAAQAAAALAAEAAAAOAAEAAAAIAAUAAAAPAAEAAAAIAAUAAAAQAAEAAAAIAAUAAAAOAAIAAAAIAAYAAAAPAAIAAAAIAAYAAAAQAAIAAAAIAAYAAAAOAAMAAAALAAEAAAAPAAMAAAALAAEAAAAPAAQAAAALAAEAAAAQAAQAAAALAAEAAAAQAAMAAAALAAEAAAAOAAQAAAALAAEAAAARAAAAAAALAAQAAAARAAEAAAALAAUAAAARAAIAAAALAAUAAAARAAMAAAALAAUAAAARAAQAAAALAAUAAAASAAAAAAAMAAQAAAATAAAAAAAMAAQAAAAUAAAAAAAMAAQAAAAVAAAAAAAMAAQAAAAWAAAAAAAMAAQAAAAXAAAAAAAMAAQAAAASAAEAAAAMAAUAAAASAAIAAAAMAAUAAAASAAMAAAAMAAUAAAASAAQAAAAMAAUAAAATAAEAAAAMAAUAAAATAAIAAAAJAAYAAAATAAMAAAAMAAUAAAATAAQAAAAMAAUAAAAUAAEAAAAMAAUAAAAUAAIAAAAMAAUAAAAUAAMAAAAMAAUAAAAUAAQAAAAMAAUAAAAVAAEAAAAMAAUAAAAVAAIAAAAMAAUAAAAVAAMAAAAMAAUAAAAVAAQAAAAMAAUAAAAWAAEAAAAMAAUAAAAWAAIAAAAMAAUAAAAWAAMAAAAMAAUAAAAWAAQAAAAKAAYAAAAXAAEAAAAMAAUAAAAXAAIAAAAMAAUAAAAXAAMAAAAMAAUAAAAXAAQAAAAMAAUAAAARAAUAAAALAAUAAAARAAYAAAALAAUAAAASAAUAAAAJAAYAAAASAAYAAAAMAAUAAAATAAUAAAAMAAUAAAATAAYAAAAMAAUAAAAUAAUAAAAMAAUAAAAUAAYAAAAMAAUAAAAVAAUAAAAMAAUAAAAVAAYAAAAMAAUAAAAWAAUAAAAMAAUAAAAWAAYAAAAMAAUAAAAXAAUAAAAMAAUAAAAXAAYAAAAMAAUAAAAKAP7/AAALAAQAAAALAP7/AAAMAAQAAAAMAP7/AAAMAAQAAAAKAP//AAALAAYAAAALAP//AAAMAAYAAAAMAP//AAAMAAYAAAAQAP7/AAANAAQAAAAQAP//AAANAAYAAAANAP7/AAAMAAQAAAAOAP7/AAAMAAQAAAAPAP7/AAAMAAQAAAANAP//AAAMAAYAAAAOAP//AAAMAAYAAAAPAP//AAAMAAYAAAAMAP3/AAAOAAAAAAADAP//AAAOAAIAAAAEAP//AAAPAAIAAAAFAP//AAAQAAIAAAAGAP//AAAOAAIAAAAHAP//AAAPAAIAAAAIAP//AAAQAAIAAAD//wAAAAAKAAAAAAD//wEAAAAKAAEAAAD//wIAAAAKAAEAAAD//wMAAAAKAAEAAAD//wQAAAAKAAEAAAD//wUAAAAKAAEAAAD//wYAAAAKAAEAAAD//wcAAAAKAAEAAAD//wgAAAAKAAEAAAAAAAAAAAALAAAAAAAAAAEAAAALAAEAAAAAAAIAAAALAAEAAAAAAAMAAAALAAEAAAAAAAQAAAALAAEAAAAAAAUAAAALAAEAAAAAAAYAAAALAAEAAAAAAAcAAAALAAEAAAAAAAgAAAALAAEAAAABAAgAAAALAAEAAAACAAgAAAALAAEAAAADAAgAAAALAAEAAAAEAAgAAAALAAEAAAAFAAgAAAALAAEAAAAGAAgAAAALAAEAAAAHAAgAAAALAAEAAAAIAAgAAAALAAEAAAAJAAgAAAAMAAEAAAAJAAcAAAAMAAEAAAAIAAcAAAALAAEAAAAHAAcAAAALAAEAAAAGAAcAAAAHAAEAAAAFAAcAAAALAAEAAAAEAAcAAAALAAEAAAADAAcAAAALAAEAAAACAAcAAAALAAEAAAABAAcAAAALAAEAAAD///v/AAANAAQAAAD///z/AAANAAUAAAD///3/AAANAAUAAAD///7/AAANAAUAAAD/////AAANAAYAAAD+//v/AAAMAAQAAAD9//v/AAAMAAQAAAD+//z/AAAJAAYAAAD9//z/AAAMAAUAAAD6////AAAMAAUAAAD7////AAAMAAUAAAD8////AAAMAAUAAAD9////AAAMAAUAAAD+////AAAMAAUAAAD+//7/AAAMAAUAAAD+//3/AAAMAAUAAAD9//3/AAAMAAUAAAD9//7/AAAKAAYAAAD+/wAAAAANAAUAAAD+/wEAAAANAAUAAAD+/wIAAAANAAUAAAD+/wMAAAANAAUAAAD+/wQAAAANAAUAAAD+/wUAAAANAAUAAAD+/wYAAAANAAUAAAD9/wAAAAAMAAUAAAD8/wAAAAAMAAUAAAD7/wAAAAAMAAUAAAD6/wAAAAAMAAUAAAD5/wAAAAALAAUAAAD6/wEAAAAMAAUAAAD6/wIAAAAMAAUAAAD6/wMAAAAMAAUAAAD7/wMAAAAMAAUAAAD7/wQAAAAMAAUAAAD8/wEAAAAMAAUAAAD9/wEAAAAMAAUAAAD9/wIAAAAMAAUAAAD9/wMAAAAMAAUAAAD9/wQAAAAMAAUAAAD9/wUAAAAMAAUAAAD9/wYAAAAMAAUAAAD8/wUAAAAMAAUAAAD7/wUAAAAMAAUAAAD8/wYAAAAMAAUAAAD8/wQAAAAKAAYAAAD8/wMAAAAMAAUAAAD8/wIAAAAMAAUAAAD7/wEAAAAMAAUAAAD7/wIAAAAJAAYAAAD7/wYAAAAMAAUAAAD6/wYAAAAMAAUAAAD6/wUAAAAMAAUAAAD6/wQAAAAMAAUAAAD5////AAALAAUAAAD5/wEAAAALAAUAAAD5/wIAAAALAAUAAAD5/wMAAAALAAUAAAD5/wQAAAALAAUAAAD5/wUAAAALAAUAAAD5/wYAAAALAAUAAAD8//r/AAALAAMAAAAOAP3/AAALAAMAAAALAP3/AAALAAMAAAASAP//AAALAAMAAAAUAP//AAALAAMAAAD6//r/AAAQAAUAAAD7//r/AAALAAMAAAANAP3/AAAOAAYAAAAWAP//AAAPAAYAAAD9//r/AAAPAAUAAAAXAP//AAAQAAUAAAD5//v/AAALAAQAAAD5//z/AAALAAUAAAD5//3/AAALAAUAAAD5//7/AAALAAUAAAD6//v/AAAMAAQAAAD6//z/AAAKAAYAAAD6//3/AAAMAAUAAAD6//7/AAAMAAUAAAD7//v/AAAMAAQAAAD7//z/AAAMAAUAAAD7//3/AAAMAAUAAAD7//7/AAAMAAUAAAD8//v/AAAMAAQAAAD8//z/AAAMAAUAAAD8//3/AAAMAAUAAAD8//7/AAAMAAUAAAARAAcAAAALAAUAAAARAAgAAAALAAYAAAAXAAcAAAAMAAUAAAAWAAcAAAAMAAUAAAAVAAcAAAAMAAUAAAAUAAcAAAAMAAUAAAATAAcAAAAMAAUAAAASAAcAAAAMAAUAAAASAAgAAAAMAAYAAAATAAgAAAAMAAYAAAAUAAgAAAAMAAYAAAAVAAgAAAAMAAYAAAAWAAgAAAAMAAYAAAAXAAgAAAAMAAYAAAAKAAUAAAALAAEAAAAKAAYAAAALAAEAAAAKAAcAAAALAAEAAAAKAAgAAAALAAEAAAALAAUAAAALAAEAAAALAAYAAAALAAEAAAALAAcAAAALAAEAAAALAAgAAAALAAEAAAAMAAUAAAALAAEAAAAMAAYAAAALAAEAAAAMAAcAAAALAAEAAAAMAAgAAAALAAEAAAANAAUAAAALAAEAAAANAAYAAAALAAEAAAANAAcAAAALAAEAAAANAAgAAAALAAEAAAAOAAUAAAALAAEAAAAOAAYAAAALAAEAAAAOAAcAAAALAAEAAAAOAAgAAAALAAEAAAAPAAUAAAALAAEAAAAPAAYAAAALAAEAAAAPAAcAAAALAAEAAAAPAAgAAAALAAEAAAAQAAUAAAALAAEAAAAQAAYAAAALAAEAAAAQAAcAAAALAAEAAAAQAAgAAAALAAEAAAAdAAAAAAANAAQAAAAdAAEAAAANAAUAAAAdAAIAAAANAAUAAAAdAAMAAAANAAUAAAAdAAQAAAANAAUAAAAdAAUAAAANAAUAAAAdAAYAAAANAAUAAAAdAAcAAAANAAUAAAAdAAgAAAANAAYAAAAZAP//AAAOAAQAAAAYAAAAAAAMAAQAAAAZAAAAAAAMAAQAAAAaAAAAAAAMAAQAAAAbAAAAAAAMAAQAAAAcAAAAAAAMAAQAAAAYAAEAAAAMAAUAAAAZAAEAAAAMAAUAAAAaAAEAAAAMAAUAAAAbAAEAAAAMAAUAAAAcAAEAAAAMAAUAAAAcAAIAAAAMAAUAAAAcAAMAAAAJAAYAAAAbAAIAAAAMAAUAAAAaAAIAAAAMAAUAAAAZAAIAAAAMAAUAAAAYAAIAAAAMAAUAAAAYAAMAAAAMAAUAAAAYAAQAAAAMAAUAAAAYAAUAAAAMAAUAAAAYAAYAAAAMAAUAAAAYAAcAAAAMAAUAAAAYAAgAAAAMAAYAAAAZAAMAAAAMAAUAAAAZAAQAAAAMAAUAAAAZAAUAAAAMAAUAAAAZAAYAAAAMAAUAAAAZAAcAAAAMAAUAAAAZAAgAAAAMAAYAAAAaAAMAAAAMAAUAAAAaAAQAAAAMAAUAAAAaAAUAAAAMAAUAAAAaAAYAAAAKAAYAAAAaAAcAAAAMAAUAAAAaAAgAAAAMAAYAAAAbAAMAAAAMAAUAAAAbAAQAAAAMAAUAAAAbAAUAAAAMAAUAAAAbAAYAAAAMAAUAAAAbAAcAAAAMAAUAAAAbAAgAAAAMAAYAAAAcAAQAAAAMAAUAAAAcAAUAAAAMAAUAAAAcAAYAAAAMAAUAAAAcAAcAAAAMAAUAAAAcAAgAAAAMAAYAAAAPAP3/AAAQAAYAAAAiAPr/AAAQAAYAAAAfAPr/AAAOAAYAAAAkAPr/AAAPAAYAAAAgAPr/AAAPAAUAAAAbAP//AAALAAMAAAAaAP//AAALAAMAAAAjAPr/AAALAAMAAAAhAPr/AAALAAMAAAATAP//AAALAAMAAAAVAP//AAALAAMAAAAeAPv/AAALAAQAAAAeAPz/AAALAAUAAAAeAP3/AAALAAUAAAAeAP7/AAALAAUAAAAeAP//AAALAAUAAAAmAP//AAANAAUAAAAmAP7/AAANAAUAAAAmAP3/AAANAAUAAAAmAPv/AAANAAQAAAAfAPv/AAAMAAQAAAAgAPv/AAAMAAQAAAAhAPv/AAAMAAQAAAAiAPv/AAAMAAQAAAAjAPv/AAAMAAQAAAAkAPv/AAAMAAQAAAAlAPv/AAAMAAQAAAAmAPz/AAANAAUAAAAlAP//AAAMAAUAAAAlAP7/AAAMAAUAAAAlAP3/AAAMAAUAAAAlAPz/AAAMAAUAAAAkAPz/AAAMAAUAAAAjAPz/AAAMAAUAAAAiAPz/AAAMAAUAAAAhAPz/AAAMAAUAAAAgAPz/AAAMAAUAAAAfAPz/AAAMAAUAAAAfAP3/AAAKAAYAAAAfAP7/AAAMAAUAAAAfAP//AAAMAAUAAAAkAP//AAAKAAYAAAAkAP7/AAAJAAYAAAAkAP3/AAAMAAUAAAAjAP3/AAAMAAUAAAAiAP3/AAAMAAUAAAAhAP3/AAAMAAUAAAAgAP3/AAAMAAUAAAAgAP7/AAAJAAYAAAAgAP//AAAMAAUAAAAjAP//AAAMAAUAAAAjAP7/AAAMAAUAAAAiAP7/AAAMAAUAAAAhAP7/AAAMAAUAAAAhAP//AAAMAAUAAAAiAP//AAAMAAUAAAAeAAgAAAALAAYAAAAeAAcAAAALAAUAAAAeAAYAAAALAAUAAAAeAAUAAAALAAUAAAAeAAQAAAALAAUAAAAeAAMAAAALAAUAAAAeAAIAAAALAAUAAAAeAAEAAAALAAUAAAAeAAAAAAALAAUAAAAfAAgAAAAMAAYAAAAgAAgAAAAMAAYAAAAhAAgAAAAMAAYAAAAiAAgAAAAMAAYAAAAjAAgAAAAMAAYAAAAkAAgAAAAMAAYAAAAlAAgAAAAMAAYAAAAmAAgAAAANAAYAAAAmAAAAAAANAAUAAAAmAAEAAAANAAUAAAAmAAIAAAANAAUAAAAmAAMAAAANAAUAAAAmAAQAAAANAAUAAAAmAAUAAAANAAUAAAAmAAYAAAANAAUAAAAmAAcAAAANAAUAAAAfAAAAAAAMAAUAAAAfAAEAAAAMAAUAAAAfAAIAAAAMAAUAAAAfAAMAAAAMAAUAAAAfAAQAAAAMAAUAAAAfAAUAAAAMAAUAAAAfAAYAAAAKAAYAAAAfAAcAAAAMAAUAAAAgAAAAAAAMAAUAAAAgAAEAAAAMAAUAAAAgAAIAAAAMAAUAAAAgAAMAAAAMAAUAAAAgAAQAAAAMAAUAAAAgAAUAAAAMAAUAAAAgAAYAAAAMAAUAAAAgAAcAAAAMAAUAAAAhAAAAAAAMAAUAAAAhAAEAAAAMAAUAAAAhAAIAAAAKAAYAAAAhAAMAAAAMAAUAAAAhAAQAAAAMAAUAAAAhAAUAAAAMAAUAAAAhAAYAAAAMAAUAAAAhAAcAAAAMAAUAAAAiAAAAAAAMAAUAAAAiAAEAAAAMAAUAAAAiAAIAAAAMAAUAAAAiAAMAAAAMAAUAAAAiAAQAAAAKAAYAAAAiAAUAAAAKAAYAAAAiAAYAAAAMAAUAAAAiAAcAAAAMAAUAAAAjAAAAAAAMAAUAAAAjAAEAAAAMAAUAAAAjAAIAAAAMAAUAAAAjAAMAAAAMAAUAAAAjAAQAAAAMAAUAAAAjAAUAAAAMAAUAAAAjAAYAAAAMAAUAAAAjAAcAAAAMAAUAAAAkAAAAAAAKAAYAAAAkAAEAAAAMAAUAAAAkAAIAAAAMAAUAAAAkAAMAAAAMAAUAAAAkAAQAAAAMAAUAAAAkAAUAAAAMAAUAAAAkAAYAAAAMAAUAAAAkAAcAAAAKAAYAAAAlAAAAAAAMAAUAAAAlAAEAAAAMAAUAAAAlAAIAAAAMAAUAAAAlAAMAAAAMAAUAAAAlAAQAAAAMAAUAAAAlAAUAAAAMAAUAAAAlAAYAAAAMAAUAAAAlAAcAAAAMAAUAAAD6/wcAAAAMAAUAAAD7/wcAAAAMAAUAAAD8/wcAAAAMAAUAAAD9/wcAAAAMAAUAAAD5/wcAAAALAAUAAAD+/wcAAAANAAUAAAD5/wgAAAALAAYAAAD6/wgAAAAMAAYAAAD7/wgAAAAMAAYAAAD8/wgAAAAMAAYAAAD9/wgAAAAMAAYAAAD+/wgAAAANAAYAAAA=") +tile_set = SubResource("TileSet_kf7eg") + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_4bfy0")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_vdqsb")] +unique_name_in_owner = true +visible = false + +[node name="Controls" type="Label" parent="."] +offset_left = 167.0 +offset_top = -145.0 +offset_right = 332.0 +offset_bottom = -81.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("4_w2gh7") +text = "[WASD] to move +[Space] to jump +[Q] to trigger Noise Emitter" + +[node name="Camera2D" type="Camera2D" parent="."] +physics_interpolation_mode = 1 +position = Vector2(227, -28) +offset = Vector2(2.3068, -7.8485) +ignore_rotation = false +zoom = Vector2(1.5, 1.5) +process_callback = 0 +editor_draw_limits = true + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("5_d6fcf") + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera2D" type="Node2D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +process_priority = -1 +top_level = true +position = Vector2(227, -28) +script = ExtResource("6_bdmii") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../CharacterBody2D") +zoom = Vector2(1.5, 1.5) +frame_preview = false +tween_resource = ExtResource("7_dpnkg") +tween_on_load = false +follow_damping = true +draw_limits = true +noise = SubResource("Resource_87ddr") +noise_emitter_layer = 1 + +[node name="PlayerPhantomCameraNoiseEmitter2D" type="Node2D" parent="Player"] +unique_name_in_owner = true +script = ExtResource("10_p43w0") +noise = SubResource("Resource_rmnw1") +duration = 0.1 +decay_time = 0.1 + +[node name="CharacterBody2D" parent="Player" instance=ExtResource("8_u5o87")] +z_index = 2 +position = Vector2(227, -28) +script = ExtResource("9_suxld") diff --git a/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_tweening_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_tweening_example_scene.tscn new file mode 100644 index 0000000..523b72c --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D-4.3/2d_tweening_example_scene.tscn @@ -0,0 +1,402 @@ +[gd_scene load_steps=20 format=4 uid="uid://bvpp5na5054jd"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_h1rbo"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_1f2t2"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_o6nri"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_j7670"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_gvv7r"] +[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_rwobr"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_ylx0h"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_ytsgf"] +[ext_resource type="Script" uid="uid://t8wa4e5y5hcf" path="res://addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd" id="9_3r1pw"] +[ext_resource type="Script" uid="uid://cnnaky2ns2pn4" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd" id="9_5jy5e"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="10_guf2v"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_cvmao"] +texture = ExtResource("1_h1rbo") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_na7gm"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_cvmao") + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_tgk1y"] +size = Vector2(140, 160) + +[sub_resource type="Resource" id="Resource_mtp70"] +script = ExtResource("10_guf2v") +duration = 0.6 +transition = 1 +ease = 2 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_clm0y"] +size = Vector2(104, 160) + +[sub_resource type="Resource" id="Resource_8jg5c"] +script = ExtResource("10_guf2v") +duration = 0.3 +transition = 8 +ease = 2 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_uka0w"] +size = Vector2(560, 160) + +[sub_resource type="Resource" id="Resource_e4e41"] +script = ExtResource("10_guf2v") +duration = 1.2 +transition = 10 +ease = 2 + +[node name="Root" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="Pillar" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAAAAPr/AAAKAAIAAAAAAPv/AAAKAAMAAAAAAPz/AAAKAAMAAAAAAP3/AAAKAAMAAAAAAP7/AAAKAAMAAAAAAP//AAAKAAMAAAABAPr/AAALAAIAAAABAPv/AAALAAEAAAABAPz/AAALAAEAAAABAP3/AAALAAEAAAABAP7/AAALAAEAAAABAP//AAALAAEAAAACAPr/AAAMAAIAAAACAPv/AAAMAAMAAAACAPz/AAAMAAMAAAACAP3/AAAMAAMAAAACAP7/AAAMAAMAAAACAP//AAAMAAMAAAA=") +tile_set = SubResource("TileSet_na7gm") +collision_enabled = false +navigation_enabled = false + +[node name="Terrain" type="TileMapLayer" parent="."] +use_parent_material = true +scale = Vector2(3, 3) +tile_map_data = PackedByteArray("AAABAAAAAAALAAAAAAACAAAAAAALAAAAAAADAAAAAAALAAAAAAAEAAAAAAALAAAAAAAFAAAAAAALAAAAAAAGAAAAAAALAAAAAAAHAAAAAAALAAAAAAAIAAAAAAALAAAAAAAJAAAAAAAMAAAAAAAJAAEAAAAMAAEAAAAJAAIAAAAMAAEAAAAJAAMAAAAMAAEAAAAJAAQAAAAMAAEAAAAJAAUAAAAMAAEAAAAJAAYAAAAMAAEAAAABAAEAAAALAAEAAAABAAIAAAALAAEAAAABAAMAAAALAAEAAAABAAQAAAAHAAEAAAABAAUAAAALAAEAAAABAAYAAAALAAEAAAACAAEAAAALAAEAAAACAAIAAAALAAEAAAACAAMAAAALAAEAAAACAAQAAAALAAEAAAACAAUAAAALAAEAAAACAAYAAAALAAEAAAADAAEAAAALAAEAAAADAAIAAAALAAEAAAADAAMAAAALAAEAAAADAAQAAAALAAEAAAADAAUAAAALAAEAAAADAAYAAAALAAEAAAAEAAEAAAAHAAEAAAAEAAIAAAALAAEAAAAEAAMAAAALAAEAAAAEAAQAAAALAAEAAAAEAAUAAAALAAEAAAAEAAYAAAALAAEAAAAFAAEAAAALAAEAAAAFAAIAAAALAAEAAAAFAAMAAAALAAEAAAAFAAQAAAAHAAEAAAAFAAUAAAALAAEAAAAFAAYAAAALAAEAAAAGAAEAAAALAAEAAAAGAAIAAAALAAEAAAAGAAMAAAALAAEAAAAGAAQAAAALAAEAAAAGAAUAAAALAAEAAAAGAAYAAAALAAEAAAAHAAEAAAALAAEAAAAHAAIAAAALAAEAAAAHAAMAAAALAAEAAAAHAAQAAAALAAEAAAAHAAUAAAALAAEAAAAHAAYAAAAHAAEAAAAIAAEAAAALAAEAAAAIAAIAAAALAAEAAAAIAAMAAAAHAAEAAAAIAAQAAAALAAEAAAAIAAUAAAALAAEAAAAIAAYAAAALAAEAAAAKAAEAAAAIAAUAAAALAAEAAAAIAAUAAAAMAAEAAAAIAAUAAAANAAEAAAAIAAUAAAAKAAIAAAAIAAYAAAALAAIAAAAIAAYAAAAMAAIAAAAIAAYAAAANAAIAAAAIAAYAAAAKAAMAAAALAAEAAAAKAAQAAAALAAEAAAALAAMAAAALAAEAAAALAAQAAAALAAEAAAAMAAMAAAALAAEAAAAMAAQAAAALAAEAAAANAAMAAAALAAEAAAANAAQAAAALAAEAAAAOAAEAAAAIAAUAAAAPAAEAAAAIAAUAAAAQAAEAAAAIAAUAAAAOAAIAAAAIAAYAAAAPAAIAAAAIAAYAAAAQAAIAAAAIAAYAAAAOAAMAAAALAAEAAAAPAAMAAAALAAEAAAAPAAQAAAALAAEAAAAQAAQAAAALAAEAAAAQAAMAAAALAAEAAAAOAAQAAAALAAEAAAARAAAAAAALAAQAAAARAAEAAAALAAUAAAARAAIAAAALAAUAAAARAAMAAAALAAUAAAARAAQAAAALAAUAAAASAAAAAAAMAAQAAAATAAAAAAAMAAQAAAAUAAAAAAAMAAQAAAAVAAAAAAAMAAQAAAAWAAAAAAAMAAQAAAAXAAAAAAAMAAQAAAASAAEAAAAMAAUAAAASAAIAAAAMAAUAAAASAAMAAAAMAAUAAAASAAQAAAAMAAUAAAATAAEAAAAMAAUAAAATAAIAAAAJAAYAAAATAAMAAAAMAAUAAAATAAQAAAAMAAUAAAAUAAEAAAAMAAUAAAAUAAIAAAAMAAUAAAAUAAMAAAAMAAUAAAAUAAQAAAAMAAUAAAAVAAEAAAAMAAUAAAAVAAIAAAAMAAUAAAAVAAMAAAAMAAUAAAAVAAQAAAAMAAUAAAAWAAEAAAAMAAUAAAAWAAIAAAAMAAUAAAAWAAMAAAAMAAUAAAAWAAQAAAAKAAYAAAAXAAEAAAAMAAUAAAAXAAIAAAAMAAUAAAAXAAMAAAAMAAUAAAAXAAQAAAAMAAUAAAARAAUAAAALAAUAAAARAAYAAAALAAUAAAASAAUAAAAJAAYAAAASAAYAAAAMAAUAAAATAAUAAAAMAAUAAAATAAYAAAAMAAUAAAAUAAUAAAAMAAUAAAAUAAYAAAAMAAUAAAAVAAUAAAAMAAUAAAAVAAYAAAAMAAUAAAAWAAUAAAAMAAUAAAAWAAYAAAAMAAUAAAAXAAUAAAAMAAUAAAAXAAYAAAAMAAUAAAAKAP7/AAALAAQAAAALAP7/AAAMAAQAAAAMAP7/AAAMAAQAAAAKAP//AAALAAYAAAALAP//AAAMAAYAAAAMAP//AAAMAAYAAAAQAP7/AAANAAQAAAAQAP//AAANAAYAAAANAP7/AAAMAAQAAAAOAP7/AAAMAAQAAAAPAP7/AAAMAAQAAAANAP//AAAMAAYAAAAOAP//AAAMAAYAAAAPAP//AAAMAAYAAAADAP//AAAOAAIAAAAEAP//AAAPAAIAAAAFAP//AAAQAAIAAAAGAP//AAAOAAIAAAAHAP//AAAPAAIAAAAIAP//AAAQAAIAAAD//wAAAAAKAAAAAAD//wEAAAAKAAEAAAD//wIAAAAKAAEAAAD//wMAAAAKAAEAAAD//wQAAAAKAAEAAAD//wUAAAAKAAEAAAD//wYAAAAKAAEAAAD//wcAAAAKAAEAAAD//wgAAAAKAAEAAAAAAAAAAAALAAAAAAAAAAEAAAALAAEAAAAAAAIAAAALAAEAAAAAAAMAAAALAAEAAAAAAAQAAAALAAEAAAAAAAUAAAALAAEAAAAAAAYAAAALAAEAAAAAAAcAAAALAAEAAAAAAAgAAAALAAEAAAABAAgAAAALAAEAAAACAAgAAAALAAEAAAADAAgAAAALAAEAAAAEAAgAAAALAAEAAAAFAAgAAAALAAEAAAAGAAgAAAALAAEAAAAHAAgAAAALAAEAAAAIAAgAAAALAAEAAAAJAAgAAAAMAAEAAAAJAAcAAAAMAAEAAAAIAAcAAAALAAEAAAAHAAcAAAALAAEAAAAGAAcAAAAHAAEAAAAFAAcAAAALAAEAAAAEAAcAAAALAAEAAAADAAcAAAALAAEAAAACAAcAAAALAAEAAAABAAcAAAALAAEAAAD///v/AAANAAQAAAD///z/AAANAAUAAAD///3/AAANAAUAAAD///7/AAANAAUAAAD/////AAANAAYAAAD+//v/AAAMAAQAAAD9//v/AAAMAAQAAAD+//z/AAAJAAYAAAD9//z/AAAMAAUAAAD6////AAAMAAUAAAD7////AAAMAAUAAAD8////AAAMAAUAAAD9////AAAMAAUAAAD+////AAAMAAUAAAD+//7/AAAMAAUAAAD+//3/AAAMAAUAAAD9//3/AAAMAAUAAAD9//7/AAAKAAYAAAD+/wAAAAANAAUAAAD+/wEAAAANAAUAAAD+/wIAAAANAAUAAAD+/wMAAAANAAUAAAD+/wQAAAANAAUAAAD+/wUAAAANAAUAAAD+/wYAAAANAAUAAAD9/wAAAAAMAAUAAAD8/wAAAAAMAAUAAAD7/wAAAAAMAAUAAAD6/wAAAAAMAAUAAAD5/wAAAAALAAUAAAD6/wEAAAAMAAUAAAD6/wIAAAAMAAUAAAD6/wMAAAAMAAUAAAD7/wMAAAAMAAUAAAD7/wQAAAAMAAUAAAD8/wEAAAAMAAUAAAD9/wEAAAAMAAUAAAD9/wIAAAAMAAUAAAD9/wMAAAAMAAUAAAD9/wQAAAAMAAUAAAD9/wUAAAAMAAUAAAD9/wYAAAAMAAUAAAD8/wUAAAAMAAUAAAD7/wUAAAAMAAUAAAD8/wYAAAAMAAUAAAD8/wQAAAAKAAYAAAD8/wMAAAAMAAUAAAD8/wIAAAAMAAUAAAD7/wEAAAAMAAUAAAD7/wIAAAAJAAYAAAD7/wYAAAAMAAUAAAD6/wYAAAAMAAUAAAD6/wUAAAAMAAUAAAD6/wQAAAAMAAUAAAD5////AAALAAUAAAD5/wEAAAALAAUAAAD5/wIAAAALAAUAAAD5/wMAAAALAAUAAAD5/wQAAAALAAUAAAD5/wUAAAALAAUAAAD5/wYAAAALAAUAAAD8//r/AAALAAMAAAAOAP3/AAALAAMAAAALAP3/AAALAAMAAAASAP//AAALAAMAAAAUAP//AAALAAMAAAD6//r/AAAQAAUAAAD7//r/AAALAAMAAAANAP3/AAAOAAYAAAAWAP//AAAPAAYAAAD9//r/AAAPAAUAAAAXAP//AAAQAAUAAAD5//v/AAALAAQAAAD5//z/AAALAAUAAAD5//3/AAALAAUAAAD5//7/AAALAAUAAAD6//v/AAAMAAQAAAD6//z/AAAKAAYAAAD6//3/AAAMAAUAAAD6//7/AAAMAAUAAAD7//v/AAAMAAQAAAD7//z/AAAMAAUAAAD7//3/AAAMAAUAAAD7//7/AAAMAAUAAAD8//v/AAAMAAQAAAD8//z/AAAMAAUAAAD8//3/AAAMAAUAAAD8//7/AAAMAAUAAAARAAcAAAALAAUAAAARAAgAAAALAAYAAAAXAAcAAAAMAAUAAAAWAAcAAAAMAAUAAAAVAAcAAAAMAAUAAAAUAAcAAAAMAAUAAAATAAcAAAAMAAUAAAASAAcAAAAMAAUAAAASAAgAAAAMAAYAAAATAAgAAAAMAAYAAAAUAAgAAAAMAAYAAAAVAAgAAAAMAAYAAAAWAAgAAAAMAAYAAAAXAAgAAAAMAAYAAAAKAAUAAAALAAEAAAAKAAYAAAALAAEAAAAKAAcAAAALAAEAAAAKAAgAAAALAAEAAAALAAUAAAALAAEAAAALAAYAAAALAAEAAAALAAcAAAALAAEAAAALAAgAAAALAAEAAAAMAAUAAAALAAEAAAAMAAYAAAALAAEAAAAMAAcAAAALAAEAAAAMAAgAAAALAAEAAAANAAUAAAALAAEAAAANAAYAAAALAAEAAAANAAcAAAALAAEAAAANAAgAAAALAAEAAAAOAAUAAAALAAEAAAAOAAYAAAALAAEAAAAOAAcAAAALAAEAAAAOAAgAAAALAAEAAAAPAAUAAAALAAEAAAAPAAYAAAALAAEAAAAPAAcAAAALAAEAAAAPAAgAAAALAAEAAAAQAAUAAAALAAEAAAAQAAYAAAALAAEAAAAQAAcAAAALAAEAAAAQAAgAAAALAAEAAAAdAAAAAAANAAQAAAAdAAEAAAANAAUAAAAdAAIAAAANAAUAAAAdAAMAAAANAAUAAAAdAAQAAAANAAUAAAAdAAUAAAANAAUAAAAdAAYAAAANAAUAAAAdAAcAAAANAAUAAAAdAAgAAAANAAYAAAAYAAAAAAAMAAQAAAAZAAAAAAAMAAQAAAAaAAAAAAAMAAQAAAAbAAAAAAAMAAQAAAAcAAAAAAAMAAQAAAAYAAEAAAAMAAUAAAAZAAEAAAAMAAUAAAAaAAEAAAAMAAUAAAAbAAEAAAAMAAUAAAAcAAEAAAAMAAUAAAAcAAIAAAAMAAUAAAAcAAMAAAAJAAYAAAAbAAIAAAAMAAUAAAAaAAIAAAAMAAUAAAAZAAIAAAAMAAUAAAAYAAIAAAAMAAUAAAAYAAMAAAAMAAUAAAAYAAQAAAAMAAUAAAAYAAUAAAAMAAUAAAAYAAYAAAAMAAUAAAAYAAcAAAAMAAUAAAAYAAgAAAAMAAYAAAAZAAMAAAAMAAUAAAAZAAQAAAAMAAUAAAAZAAUAAAAMAAUAAAAZAAYAAAAMAAUAAAAZAAcAAAAMAAUAAAAZAAgAAAAMAAYAAAAaAAMAAAAMAAUAAAAaAAQAAAAMAAUAAAAaAAUAAAAMAAUAAAAaAAYAAAAKAAYAAAAaAAcAAAAMAAUAAAAaAAgAAAAMAAYAAAAbAAMAAAAMAAUAAAAbAAQAAAAMAAUAAAAbAAUAAAAMAAUAAAAbAAYAAAAMAAUAAAAbAAcAAAAMAAUAAAAbAAgAAAAMAAYAAAAcAAQAAAAMAAUAAAAcAAUAAAAMAAUAAAAcAAYAAAAMAAUAAAAcAAcAAAAMAAUAAAAcAAgAAAAMAAYAAAAPAP3/AAAQAAYAAAAiAPr/AAAQAAYAAAAfAPr/AAAOAAYAAAAkAPr/AAAPAAYAAAAgAPr/AAAPAAUAAAAbAP//AAALAAMAAAAaAP//AAALAAMAAAAjAPr/AAALAAMAAAAhAPr/AAALAAMAAAATAP//AAALAAMAAAAVAP//AAALAAMAAAAeAPv/AAALAAQAAAAeAPz/AAALAAUAAAAeAP3/AAALAAUAAAAeAP7/AAALAAUAAAAeAP//AAALAAUAAAAmAP//AAANAAUAAAAmAP7/AAANAAUAAAAmAP3/AAANAAUAAAAmAPv/AAANAAQAAAAfAPv/AAAMAAQAAAAgAPv/AAAMAAQAAAAhAPv/AAAMAAQAAAAiAPv/AAAMAAQAAAAjAPv/AAAMAAQAAAAkAPv/AAAMAAQAAAAlAPv/AAAMAAQAAAAmAPz/AAANAAUAAAAlAP//AAAMAAUAAAAlAP7/AAAMAAUAAAAlAP3/AAAMAAUAAAAlAPz/AAAMAAUAAAAkAPz/AAAMAAUAAAAjAPz/AAAMAAUAAAAiAPz/AAAMAAUAAAAhAPz/AAAMAAUAAAAgAPz/AAAMAAUAAAAfAPz/AAAMAAUAAAAfAP3/AAAKAAYAAAAfAP7/AAAMAAUAAAAfAP//AAAMAAUAAAAkAP//AAAKAAYAAAAkAP7/AAAJAAYAAAAkAP3/AAAMAAUAAAAjAP3/AAAMAAUAAAAiAP3/AAAMAAUAAAAhAP3/AAAMAAUAAAAgAP3/AAAMAAUAAAAgAP7/AAAJAAYAAAAgAP//AAAMAAUAAAAjAP//AAAMAAUAAAAjAP7/AAAMAAUAAAAiAP7/AAAMAAUAAAAhAP7/AAAMAAUAAAAhAP//AAAMAAUAAAAiAP//AAAMAAUAAAAeAAgAAAALAAYAAAAeAAcAAAALAAUAAAAeAAYAAAALAAUAAAAeAAUAAAALAAUAAAAeAAQAAAALAAUAAAAeAAMAAAALAAUAAAAeAAIAAAALAAUAAAAeAAEAAAALAAUAAAAeAAAAAAALAAUAAAAfAAgAAAAMAAYAAAAgAAgAAAAMAAYAAAAhAAgAAAAMAAYAAAAiAAgAAAAMAAYAAAAjAAgAAAAMAAYAAAAkAAgAAAAMAAYAAAAlAAgAAAAMAAYAAAAmAAgAAAANAAYAAAAmAAAAAAANAAUAAAAmAAEAAAANAAUAAAAmAAIAAAANAAUAAAAmAAMAAAANAAUAAAAmAAQAAAANAAUAAAAmAAUAAAANAAUAAAAmAAYAAAANAAUAAAAmAAcAAAANAAUAAAAfAAAAAAAMAAUAAAAfAAEAAAAMAAUAAAAfAAIAAAAMAAUAAAAfAAMAAAAMAAUAAAAfAAQAAAAMAAUAAAAfAAUAAAAMAAUAAAAfAAYAAAAKAAYAAAAfAAcAAAAMAAUAAAAgAAAAAAAMAAUAAAAgAAEAAAAMAAUAAAAgAAIAAAAMAAUAAAAgAAMAAAAMAAUAAAAgAAQAAAAMAAUAAAAgAAUAAAAMAAUAAAAgAAYAAAAMAAUAAAAgAAcAAAAMAAUAAAAhAAAAAAAMAAUAAAAhAAEAAAAMAAUAAAAhAAIAAAAKAAYAAAAhAAMAAAAMAAUAAAAhAAQAAAAMAAUAAAAhAAUAAAAMAAUAAAAhAAYAAAAMAAUAAAAhAAcAAAAMAAUAAAAiAAAAAAAMAAUAAAAiAAEAAAAMAAUAAAAiAAIAAAAMAAUAAAAiAAMAAAAMAAUAAAAiAAQAAAAKAAYAAAAiAAUAAAAKAAYAAAAiAAYAAAAMAAUAAAAiAAcAAAAMAAUAAAAjAAAAAAAMAAUAAAAjAAEAAAAMAAUAAAAjAAIAAAAMAAUAAAAjAAMAAAAMAAUAAAAjAAQAAAAMAAUAAAAjAAUAAAAMAAUAAAAjAAYAAAAMAAUAAAAjAAcAAAAMAAUAAAAkAAAAAAAKAAYAAAAkAAEAAAAMAAUAAAAkAAIAAAAMAAUAAAAkAAMAAAAMAAUAAAAkAAQAAAAMAAUAAAAkAAUAAAAMAAUAAAAkAAYAAAAMAAUAAAAkAAcAAAAKAAYAAAAlAAAAAAAMAAUAAAAlAAEAAAAMAAUAAAAlAAIAAAAMAAUAAAAlAAMAAAAMAAUAAAAlAAQAAAAMAAUAAAAlAAUAAAAMAAUAAAAlAAYAAAAMAAUAAAAlAAcAAAAMAAUAAAD6/wcAAAAMAAUAAAD7/wcAAAAMAAUAAAD8/wcAAAAMAAUAAAD9/wcAAAAMAAUAAAD5/wcAAAALAAUAAAD+/wcAAAANAAUAAAD5/wgAAAALAAYAAAD6/wgAAAAMAAYAAAD7/wgAAAAMAAYAAAD8/wgAAAAMAAYAAAD9/wgAAAAMAAYAAAD+/wgAAAANAAYAAAA=") +tile_set = SubResource("TileSet_na7gm") + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_1f2t2")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_o6nri")] +unique_name_in_owner = true +visible = false + +[node name="Camera2D" type="Camera2D" parent="."] +physics_interpolation_mode = 1 +position = Vector2(227, -28) +process_callback = 0 +position_smoothing_speed = 10.0 +editor_draw_limits = true + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("4_j7670") + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera2D" type="Node2D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +top_level = true +position = Vector2(227, -28) +script = ExtResource("5_gvv7r") +priority = 5 +follow_mode = 2 +follow_target = NodePath("../CharacterBody2D") +tween_resource = ExtResource("6_rwobr") +tween_on_load = false +follow_damping = true +draw_limits = true + +[node name="Label" type="Label" parent="Player"] +offset_left = 167.0 +offset_top = -132.0 +offset_right = 332.0 +offset_bottom = -68.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("7_ylx0h") +text = "[WASD] to move +[Space] to jump" + +[node name="CharacterBody2D" parent="Player" instance=ExtResource("8_ytsgf")] +position = Vector2(227, -28) +script = ExtResource("9_5jy5e") + +[node name="WideArea" type="Area2D" parent="." node_paths=PackedStringArray("area_pcam")] +position = Vector2(393, -40) +collision_layer = 2 +collision_mask = 2 +script = ExtResource("9_3r1pw") +area_pcam = NodePath("PhantomCamera2D") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="WideArea"] +position = Vector2(0, -40) +shape = SubResource("RectangleShape2D_tgk1y") + +[node name="ColorRect" type="ColorRect" parent="WideArea"] +offset_left = -70.0 +offset_top = -120.0 +offset_right = 70.0 +offset_bottom = 40.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +color = Color(0.556863, 0.447059, 0.545098, 0.698039) + +[node name="Label" type="Label" parent="WideArea"] +offset_left = -77.0 +offset_top = -250.0 +offset_right = 76.0 +offset_bottom = -120.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("7_ylx0h") +text = "Transition Type: +Sine + +Duration: +0.6s" +horizontal_alignment = 1 + +[node name="PhantomCamera2D" type="Node2D" parent="WideArea"] +position = Vector2(4, -100) +script = ExtResource("5_gvv7r") +zoom = Vector2(0.8, 0.8) +tween_resource = SubResource("Resource_mtp70") +draw_limits = true + +[node name="UpperZoomArea" type="Area2D" parent="." node_paths=PackedStringArray("area_pcam")] +position = Vector2(649, -135) +collision_layer = 2 +collision_mask = 2 +script = ExtResource("9_3r1pw") +area_pcam = NodePath("PhantomCamera2D") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="UpperZoomArea"] +position = Vector2(0, -40) +shape = SubResource("RectangleShape2D_clm0y") + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="UpperZoomArea"] +position = Vector2(0, -40) +shape = SubResource("RectangleShape2D_clm0y") + +[node name="ColorRect" type="ColorRect" parent="UpperZoomArea"] +offset_left = -52.0 +offset_top = -120.0 +offset_right = 52.0 +offset_bottom = 40.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +color = Color(0.556863, 0.447059, 0.545098, 0.698039) + +[node name="Label" type="Label" parent="UpperZoomArea"] +offset_left = -74.0 +offset_top = -251.0 +offset_right = 79.0 +offset_bottom = -121.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("7_ylx0h") +text = "Transition Type: +Circ + +Duration: +0.3s" +horizontal_alignment = 1 + +[node name="PhantomCamera2D" type="Node2D" parent="UpperZoomArea"] +position = Vector2(2, -83) +script = ExtResource("5_gvv7r") +zoom = Vector2(2, 2) +tween_resource = SubResource("Resource_8jg5c") +draw_limits = true + +[node name="ForwardArea" type="Area2D" parent="." node_paths=PackedStringArray("area_pcam")] +position = Vector2(1136, -38) +collision_layer = 2 +collision_mask = 2 +script = ExtResource("9_3r1pw") +area_pcam = NodePath("PhantomCamera2D") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="ForwardArea"] +position = Vector2(0, -42) +shape = SubResource("RectangleShape2D_uka0w") + +[node name="ColorRect" type="ColorRect" parent="ForwardArea"] +offset_left = -280.0 +offset_top = -122.0 +offset_right = 280.0 +offset_bottom = 38.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +color = Color(0.556863, 0.447059, 0.545098, 0.698039) + +[node name="Label" type="Label" parent="ForwardArea"] +offset_left = -76.0 +offset_top = -252.0 +offset_right = 77.0 +offset_bottom = -122.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("7_ylx0h") +text = "Transition Type: +Back + +Duration: +1.2s" +horizontal_alignment = 1 + +[node name="PhantomCamera2D" type="Node2D" parent="ForwardArea"] +position = Vector2(344, -46) +script = ExtResource("5_gvv7r") +zoom = Vector2(0.9, 0.9) +tween_resource = SubResource("Resource_e4e41") +draw_limits = true diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_example_scene.tscn new file mode 100644 index 0000000..7729dbb --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D/2d_example_scene.tscn @@ -0,0 +1,245 @@ +[gd_scene load_steps=11 format=3 uid="uid://drvexsp2t0nfy"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_1utlo"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="2_mgsut"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_54fc4"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="6_kqt1v"] +[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_pxbym"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="7_62i3t"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="7_fdx1s"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="12_k4p0h"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"] +texture = ExtResource("1_1utlo") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_kf7eg"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_easgx") + +[node name="ExampleScene2D2" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="TileMap" type="TileMap" parent="."] +z_index = -1 +scale = Vector2(3, 3) +tile_set = SubResource("TileSet_kf7eg") +format = 2 +layer_0/name = "Background" +layer_0/tile_data = PackedInt32Array(-393216, 655360, 2, -327680, 655360, 3, -262144, 655360, 3, -196608, 655360, 3, -131072, 655360, 3, -65536, 655360, 3, -393215, 720896, 2, -327679, 720896, 1, -262143, 720896, 1, -196607, 720896, 1, -131071, 720896, 1, -65535, 720896, 1, -393214, 786432, 2, -327678, 786432, 3, -262142, 786432, 3, -196606, 786432, 3, -131070, 786432, 3, -65534, 786432, 3) +layer_1/name = "Terrain" +layer_1/z_index = 1 +layer_1/tile_data = PackedInt32Array(1, 720896, 0, 2, 720896, 0, 3, 720896, 0, 4, 720896, 0, 5, 720896, 0, 6, 720896, 0, 7, 720896, 0, 8, 720896, 0, 9, 786432, 0, 65545, 786432, 1, 131081, 786432, 1, 196617, 786432, 1, 262153, 786432, 1, 327689, 786432, 1, 393225, 786432, 1, 65537, 720896, 1, 131073, 720896, 1, 196609, 720896, 1, 262145, 458752, 1, 327681, 720896, 1, 393217, 720896, 1, 65538, 720896, 1, 131074, 720896, 1, 196610, 720896, 1, 262146, 720896, 1, 327682, 720896, 1, 393218, 720896, 1, 65539, 720896, 1, 131075, 720896, 1, 196611, 720896, 1, 262147, 720896, 1, 327683, 720896, 1, 393219, 720896, 1, 65540, 458752, 1, 131076, 720896, 1, 196612, 720896, 1, 262148, 720896, 1, 327684, 720896, 1, 393220, 720896, 1, 65541, 720896, 1, 131077, 720896, 1, 196613, 720896, 1, 262149, 458752, 1, 327685, 720896, 1, 393221, 720896, 1, 65542, 720896, 1, 131078, 720896, 1, 196614, 720896, 1, 262150, 720896, 1, 327686, 720896, 1, 393222, 720896, 1, 65543, 720896, 1, 131079, 720896, 1, 196615, 720896, 1, 262151, 720896, 1, 327687, 720896, 1, 393223, 458752, 1, 65544, 720896, 1, 131080, 720896, 1, 196616, 458752, 1, 262152, 720896, 1, 327688, 720896, 1, 393224, 720896, 1, 65546, 524288, 5, 65547, 524288, 5, 65548, 524288, 5, 65549, 524288, 5, 131082, 524288, 6, 131083, 524288, 6, 131084, 524288, 6, 131085, 524288, 6, 196618, 720896, 1, 262154, 720896, 1, 196619, 720896, 1, 262155, 720896, 1, 196620, 720896, 1, 262156, 720896, 1, 196621, 720896, 1, 262157, 720896, 1, 65550, 524288, 5, 65551, 524288, 5, 65552, 524288, 5, 131086, 524288, 6, 131087, 524288, 6, 131088, 524288, 6, 196622, 720896, 1, 196623, 720896, 1, 262159, 720896, 1, 262160, 720896, 1, 196624, 720896, 1, 262158, 720896, 1, 17, 720896, 4, 65553, 720896, 5, 131089, 720896, 5, 196625, 720896, 5, 262161, 720896, 5, 18, 786432, 4, 19, 786432, 4, 20, 786432, 4, 21, 786432, 4, 22, 786432, 4, 23, 786432, 4, 65554, 786432, 5, 131090, 786432, 5, 196626, 786432, 5, 262162, 786432, 5, 65555, 786432, 5, 131091, 589824, 6, 196627, 786432, 5, 262163, 786432, 5, 65556, 786432, 5, 131092, 786432, 5, 196628, 786432, 5, 262164, 786432, 5, 65557, 786432, 5, 131093, 786432, 5, 196629, 786432, 5, 262165, 786432, 5, 65558, 786432, 5, 131094, 786432, 5, 196630, 786432, 5, 262166, 655360, 6, 65559, 786432, 5, 131095, 786432, 5, 196631, 786432, 5, 262167, 786432, 5, 327697, 720896, 5, 393233, 720896, 5, 327698, 589824, 6, 393234, 786432, 5, 327699, 786432, 5, 393235, 786432, 5, 327700, 786432, 5, 393236, 786432, 5, 327701, 786432, 5, 393237, 786432, 5, 327702, 786432, 5, 393238, 786432, 5, 327703, 786432, 5, 393239, 786432, 5, -131062, 720896, 4, -131061, 786432, 4, -131060, 786432, 4, -65526, 720896, 6, -65525, 786432, 6, -65524, 786432, 6, -131056, 851968, 4, -65520, 851968, 6, -131059, 786432, 4, -131058, 786432, 4, -131057, 786432, 4, -65523, 786432, 6, -65522, 786432, 6, -65521, 786432, 6, -65536, 917504, 2, -65535, 983040, 2, -65534, 1048576, 2, -65533, 917504, 2, -65532, 983040, 2, -65531, 1048576, 2, -65530, 917504, 2, -65529, 983040, 2, -65528, 1048576, 2, 65535, 655360, 0, 131071, 655360, 1, 196607, 655360, 1, 262143, 655360, 1, 327679, 655360, 1, 393215, 655360, 1, 458751, 655360, 1, 524287, 655360, 1, 589823, 655360, 1, 0, 720896, 0, 65536, 720896, 1, 131072, 720896, 1, 196608, 720896, 1, 262144, 720896, 1, 327680, 720896, 1, 393216, 720896, 1, 458752, 720896, 1, 524288, 720896, 1, 524289, 720896, 1, 524290, 720896, 1, 524291, 720896, 1, 524292, 720896, 1, 524293, 720896, 1, 524294, 720896, 1, 524295, 720896, 1, 524296, 720896, 1, 524297, 786432, 1, 458761, 786432, 1, 458760, 720896, 1, 458759, 720896, 1, 458758, 458752, 1, 458757, 720896, 1, 458756, 720896, 1, 458755, 720896, 1, 458754, 720896, 1, 458753, 720896, 1, -262145, 851968, 4, -196609, 851968, 5, -131073, 851968, 5, -65537, 851968, 5, -1, 851968, 6, -262146, 786432, 4, -262147, 786432, 4, -196610, 589824, 6, -196611, 786432, 5, -6, 786432, 5, -5, 786432, 5, -4, 786432, 5, -3, 786432, 5, -2, 786432, 5, -65538, 786432, 5, -131074, 786432, 5, -131075, 786432, 5, -65539, 655360, 6, 65534, 851968, 5, 131070, 851968, 5, 196606, 851968, 5, 262142, 851968, 5, 327678, 851968, 5, 393214, 851968, 5, 458750, 851968, 5, 65533, 786432, 5, 65532, 786432, 5, 65531, 786432, 5, 65530, 786432, 5, 65529, 720896, 5, 131066, 786432, 5, 196602, 786432, 5, 262138, 786432, 5, 262139, 786432, 5, 327675, 786432, 5, 131068, 786432, 5, 131069, 786432, 5, 196605, 786432, 5, 262141, 786432, 5, 327677, 786432, 5, 393213, 786432, 5, 458749, 786432, 5, 393212, 786432, 5, 393211, 786432, 5, 458748, 786432, 5, 327676, 655360, 6, 262140, 786432, 5, 196604, 786432, 5, 131067, 786432, 5, 196603, 589824, 6, 458747, 786432, 5, 458746, 786432, 5, 393210, 786432, 5, 327674, 786432, 5, -7, 720896, 5, 131065, 720896, 5, 196601, 720896, 5, 262137, 720896, 5, 327673, 720896, 5, 393209, 720896, 5, 458745, 720896, 5, -327684, 720896, 3, -196594, 720896, 3, -196597, 720896, 3, -65518, 720896, 3, -65516, 720896, 3, -327686, 1048576, 5, -327685, 720896, 3, -196595, 917504, 6, -65514, 983040, 6, -327683, 983040, 5, -65513, 1048576, 5, -262151, 720896, 4, -196615, 720896, 5, -131079, 720896, 5, -65543, 720896, 5, -262150, 786432, 4, -196614, 655360, 6, -131078, 786432, 5, -65542, 786432, 5, -262149, 786432, 4, -196613, 786432, 5, -131077, 786432, 5, -65541, 786432, 5, -262148, 786432, 4, -196612, 786432, 5, -131076, 786432, 5, -65540, 786432, 5, 458769, 720896, 5, 524305, 720896, 6, 458775, 786432, 5, 458774, 786432, 5, 458773, 786432, 5, 458772, 786432, 5, 458771, 786432, 5, 458770, 786432, 5, 524306, 786432, 6, 524307, 786432, 6, 524308, 786432, 6, 524309, 786432, 6, 524310, 786432, 6, 524311, 786432, 6, 327690, 720896, 1, 393226, 720896, 1, 458762, 720896, 1, 524298, 720896, 1, 327691, 720896, 1, 393227, 720896, 1, 458763, 720896, 1, 524299, 720896, 1, 327692, 720896, 1, 393228, 720896, 1, 458764, 720896, 1, 524300, 720896, 1, 327693, 720896, 1, 393229, 720896, 1, 458765, 720896, 1, 524301, 720896, 1, 327694, 720896, 1, 393230, 720896, 1, 458766, 720896, 1, 524302, 720896, 1, 327695, 720896, 1, 393231, 720896, 1, 458767, 720896, 1, 524303, 720896, 1, 327696, 720896, 1, 393232, 720896, 1, 458768, 720896, 1, 524304, 720896, 1, 29, 851968, 4, 65565, 851968, 5, 131101, 851968, 5, 196637, 851968, 5, 262173, 851968, 5, 327709, 851968, 5, 393245, 851968, 5, 458781, 851968, 5, 524317, 851968, 6, -65511, 917504, 4, 24, 786432, 4, 25, 786432, 4, 26, 786432, 4, 27, 786432, 4, 28, 786432, 4, 65560, 786432, 5, 65561, 786432, 5, 65562, 786432, 5, 65563, 786432, 5, 65564, 786432, 5, 131100, 786432, 5, 196636, 589824, 6, 131099, 786432, 5, 131098, 786432, 5, 131097, 786432, 5, 131096, 786432, 5, 196632, 786432, 5, 262168, 786432, 5, 327704, 786432, 5, 393240, 786432, 5, 458776, 786432, 5, 524312, 786432, 6, 196633, 786432, 5, 262169, 786432, 5, 327705, 786432, 5, 393241, 786432, 5, 458777, 786432, 5, 524313, 786432, 6, 196634, 786432, 5, 262170, 786432, 5, 327706, 786432, 5, 393242, 655360, 6, 458778, 786432, 5, 524314, 786432, 6, 196635, 786432, 5, 262171, 786432, 5, 327707, 786432, 5, 393243, 786432, 5, 458779, 786432, 5, 524315, 786432, 6, 262172, 786432, 5, 327708, 786432, 5, 393244, 786432, 5, 458780, 786432, 5, 524316, 786432, 6, -196593, 1048576, 6, -393182, 1048576, 6, -393185, 917504, 6, -393180, 983040, 6, -393184, 983040, 5, -65509, 720896, 3, -65510, 720896, 3, -393181, 720896, 3, -393183, 720896, 3, -65517, 720896, 3, -65515, 720896, 3, -327650, 720896, 4, -262114, 720896, 5, -196578, 720896, 5, -131042, 720896, 5, -65506, 720896, 5, -65498, 851968, 5, -131034, 851968, 5, -196570, 851968, 5, -327642, 851968, 4, -327649, 786432, 4, -327648, 786432, 4, -327647, 786432, 4, -327646, 786432, 4, -327645, 786432, 4, -327644, 786432, 4, -327643, 786432, 4, -262106, 851968, 5, -65499, 786432, 5, -131035, 786432, 5, -196571, 786432, 5, -262107, 786432, 5, -262108, 786432, 5, -262109, 786432, 5, -262110, 786432, 5, -262111, 786432, 5, -262112, 786432, 5, -262113, 786432, 5, -196577, 655360, 6, -131041, 786432, 5, -65505, 786432, 5, -65500, 655360, 6, -131036, 589824, 6, -196572, 786432, 5, -196573, 786432, 5, -196574, 786432, 5, -196575, 786432, 5, -196576, 786432, 5, -131040, 589824, 6, -65504, 786432, 5, -65501, 786432, 5, -131037, 786432, 5, -131038, 786432, 5, -131039, 786432, 5, -65503, 786432, 5, -65502, 786432, 5, 524318, 720896, 6, 458782, 720896, 5, 393246, 720896, 5, 327710, 720896, 5, 262174, 720896, 5, 196638, 720896, 5, 131102, 720896, 5, 65566, 720896, 5, 30, 720896, 5, 524319, 786432, 6, 524320, 786432, 6, 524321, 786432, 6, 524322, 786432, 6, 524323, 786432, 6, 524324, 786432, 6, 524325, 786432, 6, 524326, 851968, 6, 38, 851968, 5, 65574, 851968, 5, 131110, 851968, 5, 196646, 851968, 5, 262182, 851968, 5, 327718, 851968, 5, 393254, 851968, 5, 458790, 851968, 5, 31, 786432, 5, 65567, 786432, 5, 131103, 786432, 5, 196639, 786432, 5, 262175, 786432, 5, 327711, 786432, 5, 393247, 655360, 6, 458783, 786432, 5, 32, 786432, 5, 65568, 786432, 5, 131104, 786432, 5, 196640, 786432, 5, 262176, 786432, 5, 327712, 786432, 5, 393248, 786432, 5, 458784, 786432, 5, 33, 786432, 5, 65569, 786432, 5, 131105, 655360, 6, 196641, 786432, 5, 262177, 786432, 5, 327713, 786432, 5, 393249, 786432, 5, 458785, 786432, 5, 34, 786432, 5, 65570, 786432, 5, 131106, 786432, 5, 196642, 786432, 5, 262178, 655360, 6, 327714, 655360, 6, 393250, 786432, 5, 458786, 786432, 5, 35, 786432, 5, 65571, 786432, 5, 131107, 786432, 5, 196643, 786432, 5, 262179, 786432, 5, 327715, 786432, 5, 393251, 786432, 5, 458787, 786432, 5, 36, 655360, 6, 65572, 786432, 5, 131108, 786432, 5, 196644, 786432, 5, 262180, 786432, 5, 327716, 786432, 5, 393252, 786432, 5, 458788, 655360, 6, 37, 786432, 5, 65573, 786432, 5, 131109, 786432, 5, 196645, 786432, 5, 262181, 786432, 5, 327717, 786432, 5, 393253, 786432, 5, 458789, 786432, 5, 524282, 786432, 5, 524283, 786432, 5, 524284, 786432, 5, 524285, 786432, 5, 524281, 720896, 5, 524286, 851968, 5, 589817, 720896, 6, 589818, 786432, 6, 589819, 786432, 6, 589820, 786432, 6, 589821, 786432, 6, 589822, 851968, 6, -196596, 917504, 0) + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("7_fdx1s")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("6_kqt1v")] +unique_name_in_owner = true +visible = false + +[node name="Controls" type="Label" parent="."] +offset_left = 167.0 +offset_top = -145.0 +offset_right = 332.0 +offset_bottom = -81.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("12_k4p0h") +text = "[WASD] to move +[Space] to jump" + +[node name="Camera2D" type="Camera2D" parent="."] +position = Vector2(227, -28) +zoom = Vector2(1.5, 1.5) +process_callback = 0 +editor_draw_limits = true + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("4_54fc4") + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera2D" type="Node2D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +process_priority = -1 +top_level = true +position = Vector2(227, -28) +script = ExtResource("2_mgsut") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../CharacterBody2D/PlayerVisuals") +zoom = Vector2(1.5, 1.5) +frame_preview = false +tween_resource = ExtResource("6_pxbym") +tween_on_load = false +follow_damping = true +draw_limits = true + +[node name="CharacterBody2D" parent="Player" instance=ExtResource("7_62i3t")] +position = Vector2(227, -28) + +[editable path="Player/CharacterBody2D"] diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_follow_framed_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_framed_example_scene.tscn new file mode 100644 index 0000000..98a54c2 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_framed_example_scene.tscn @@ -0,0 +1,245 @@ +[gd_scene load_steps=11 format=3 uid="uid://bxtsl6qlpq1ar"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_27o77"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_1tbys"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_1kfnp"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_mylkx"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_lwx5e"] +[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_tju6r"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="8_bo8m7"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_wlikg"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"] +texture = ExtResource("1_27o77") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_kf7eg"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_easgx") + +[node name="ExampleScene2D" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -345.0 +offset_top = -143.0 +offset_right = 947.0 +offset_bottom = 578.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="TileMap" type="TileMap" parent="."] +z_index = -1 +scale = Vector2(3, 3) +tile_set = SubResource("TileSet_kf7eg") +format = 2 +layer_0/name = "Background" +layer_0/tile_data = PackedInt32Array(-393216, 655360, 2, -327680, 655360, 3, -262144, 655360, 3, -196608, 655360, 3, -131072, 655360, 3, -65536, 655360, 3, -393215, 720896, 2, -327679, 720896, 1, -262143, 720896, 1, -196607, 720896, 1, -131071, 720896, 1, -65535, 720896, 1, -393214, 786432, 2, -327678, 786432, 3, -262142, 786432, 3, -196606, 786432, 3, -131070, 786432, 3, -65534, 786432, 3) +layer_1/name = "Terrain" +layer_1/z_index = 1 +layer_1/tile_data = PackedInt32Array(1, 720896, 0, 2, 720896, 0, 3, 720896, 0, 4, 720896, 0, 5, 720896, 0, 6, 720896, 0, 7, 720896, 0, 8, 720896, 0, 9, 786432, 0, 65545, 786432, 1, 131081, 786432, 1, 196617, 786432, 1, 262153, 786432, 1, 327689, 786432, 1, 393225, 786432, 1, 65537, 720896, 1, 131073, 720896, 1, 196609, 720896, 1, 262145, 458752, 1, 327681, 720896, 1, 393217, 720896, 1, 65538, 720896, 1, 131074, 720896, 1, 196610, 720896, 1, 262146, 720896, 1, 327682, 720896, 1, 393218, 720896, 1, 65539, 720896, 1, 131075, 720896, 1, 196611, 720896, 1, 262147, 720896, 1, 327683, 720896, 1, 393219, 720896, 1, 65540, 458752, 1, 131076, 720896, 1, 196612, 720896, 1, 262148, 720896, 1, 327684, 720896, 1, 393220, 720896, 1, 65541, 720896, 1, 131077, 720896, 1, 196613, 720896, 1, 262149, 458752, 1, 327685, 720896, 1, 393221, 720896, 1, 65542, 720896, 1, 131078, 720896, 1, 196614, 720896, 1, 262150, 720896, 1, 327686, 720896, 1, 393222, 720896, 1, 65543, 720896, 1, 131079, 720896, 1, 196615, 720896, 1, 262151, 720896, 1, 327687, 720896, 1, 393223, 458752, 1, 65544, 720896, 1, 131080, 720896, 1, 196616, 458752, 1, 262152, 720896, 1, 327688, 720896, 1, 393224, 720896, 1, 65546, 524288, 5, 65547, 524288, 5, 65548, 524288, 5, 65549, 524288, 5, 131082, 524288, 6, 131083, 524288, 6, 131084, 524288, 6, 131085, 524288, 6, 196618, 720896, 1, 262154, 720896, 1, 196619, 720896, 1, 262155, 720896, 1, 196620, 720896, 1, 262156, 720896, 1, 196621, 720896, 1, 262157, 720896, 1, 65550, 524288, 5, 65551, 524288, 5, 65552, 524288, 5, 131086, 524288, 6, 131087, 524288, 6, 131088, 524288, 6, 196622, 720896, 1, 196623, 720896, 1, 262159, 720896, 1, 262160, 720896, 1, 196624, 720896, 1, 262158, 720896, 1, 17, 720896, 4, 65553, 720896, 5, 131089, 720896, 5, 196625, 720896, 5, 262161, 720896, 5, 18, 786432, 4, 19, 786432, 4, 20, 786432, 4, 21, 786432, 4, 22, 786432, 4, 23, 786432, 4, 65554, 786432, 5, 131090, 786432, 5, 196626, 786432, 5, 262162, 786432, 5, 65555, 786432, 5, 131091, 589824, 6, 196627, 786432, 5, 262163, 786432, 5, 65556, 786432, 5, 131092, 786432, 5, 196628, 786432, 5, 262164, 786432, 5, 65557, 786432, 5, 131093, 786432, 5, 196629, 786432, 5, 262165, 786432, 5, 65558, 786432, 5, 131094, 786432, 5, 196630, 786432, 5, 262166, 655360, 6, 65559, 786432, 5, 131095, 786432, 5, 196631, 786432, 5, 262167, 786432, 5, 327697, 720896, 5, 393233, 720896, 5, 327698, 589824, 6, 393234, 786432, 5, 327699, 786432, 5, 393235, 786432, 5, 327700, 786432, 5, 393236, 786432, 5, 327701, 786432, 5, 393237, 786432, 5, 327702, 786432, 5, 393238, 786432, 5, 327703, 786432, 5, 393239, 786432, 5, -131062, 720896, 4, -131061, 786432, 4, -131060, 786432, 4, -65526, 720896, 6, -65525, 786432, 6, -65524, 786432, 6, -131056, 851968, 4, -65520, 851968, 6, -131059, 786432, 4, -131058, 786432, 4, -131057, 786432, 4, -65523, 786432, 6, -65522, 786432, 6, -65521, 786432, 6, -196596, 917504, 0, -65536, 917504, 2, -65535, 983040, 2, -65534, 1048576, 2, -65533, 917504, 2, -65532, 983040, 2, -65531, 1048576, 2, -65530, 917504, 2, -65529, 983040, 2, -65528, 1048576, 2, 65535, 655360, 0, 131071, 655360, 1, 196607, 655360, 1, 262143, 655360, 1, 327679, 655360, 1, 393215, 655360, 1, 458751, 655360, 1, 524287, 655360, 1, 589823, 655360, 1, 0, 720896, 0, 65536, 720896, 1, 131072, 720896, 1, 196608, 720896, 1, 262144, 720896, 1, 327680, 720896, 1, 393216, 720896, 1, 458752, 720896, 1, 524288, 720896, 1, 524289, 720896, 1, 524290, 720896, 1, 524291, 720896, 1, 524292, 720896, 1, 524293, 720896, 1, 524294, 720896, 1, 524295, 720896, 1, 524296, 720896, 1, 524297, 786432, 1, 458761, 786432, 1, 458760, 720896, 1, 458759, 720896, 1, 458758, 458752, 1, 458757, 720896, 1, 458756, 720896, 1, 458755, 720896, 1, 458754, 720896, 1, 458753, 720896, 1, -262145, 851968, 4, -196609, 851968, 5, -131073, 851968, 5, -65537, 851968, 5, -1, 851968, 6, -262146, 786432, 4, -262147, 786432, 4, -196610, 589824, 6, -196611, 786432, 5, -6, 786432, 5, -5, 786432, 5, -4, 786432, 5, -3, 786432, 5, -2, 786432, 5, -65538, 786432, 5, -131074, 786432, 5, -131075, 786432, 5, -65539, 655360, 6, 65534, 851968, 5, 131070, 851968, 5, 196606, 851968, 5, 262142, 851968, 5, 327678, 851968, 5, 393214, 851968, 5, 458750, 851968, 5, 65533, 786432, 5, 65532, 786432, 5, 65531, 786432, 5, 65530, 786432, 5, 65529, 720896, 5, 131066, 786432, 5, 196602, 786432, 5, 262138, 786432, 5, 262139, 786432, 5, 327675, 786432, 5, 131068, 786432, 5, 131069, 786432, 5, 196605, 786432, 5, 262141, 786432, 5, 327677, 786432, 5, 393213, 786432, 5, 458749, 786432, 5, 393212, 786432, 5, 393211, 786432, 5, 458748, 786432, 5, 327676, 655360, 6, 262140, 786432, 5, 196604, 786432, 5, 131067, 786432, 5, 196603, 589824, 6, 458747, 786432, 5, 458746, 786432, 5, 393210, 786432, 5, 327674, 786432, 5, -7, 720896, 5, 131065, 720896, 5, 196601, 720896, 5, 262137, 720896, 5, 327673, 720896, 5, 393209, 720896, 5, 458745, 720896, 5, -327684, 720896, 3, -196594, 720896, 3, -196597, 720896, 3, -65518, 720896, 3, -65516, 720896, 3, -327686, 1048576, 5, -327685, 720896, 3, -196595, 917504, 6, -65514, 983040, 6, -327683, 983040, 5, -65513, 1048576, 5, -262151, 720896, 4, -196615, 720896, 5, -131079, 720896, 5, -65543, 720896, 5, -262150, 786432, 4, -196614, 655360, 6, -131078, 786432, 5, -65542, 786432, 5, -262149, 786432, 4, -196613, 786432, 5, -131077, 786432, 5, -65541, 786432, 5, -262148, 786432, 4, -196612, 786432, 5, -131076, 786432, 5, -65540, 786432, 5, 458769, 720896, 5, 524305, 720896, 6, 458775, 786432, 5, 458774, 786432, 5, 458773, 786432, 5, 458772, 786432, 5, 458771, 786432, 5, 458770, 786432, 5, 524306, 786432, 6, 524307, 786432, 6, 524308, 786432, 6, 524309, 786432, 6, 524310, 786432, 6, 524311, 786432, 6, 327690, 720896, 1, 393226, 720896, 1, 458762, 720896, 1, 524298, 720896, 1, 327691, 720896, 1, 393227, 720896, 1, 458763, 720896, 1, 524299, 720896, 1, 327692, 720896, 1, 393228, 720896, 1, 458764, 720896, 1, 524300, 720896, 1, 327693, 720896, 1, 393229, 720896, 1, 458765, 720896, 1, 524301, 720896, 1, 327694, 720896, 1, 393230, 720896, 1, 458766, 720896, 1, 524302, 720896, 1, 327695, 720896, 1, 393231, 720896, 1, 458767, 720896, 1, 524303, 720896, 1, 327696, 720896, 1, 393232, 720896, 1, 458768, 720896, 1, 524304, 720896, 1, 29, 851968, 4, 65565, 851968, 5, 131101, 851968, 5, 196637, 851968, 5, 262173, 851968, 5, 327709, 851968, 5, 393245, 851968, 5, 458781, 851968, 5, 524317, 851968, 6, -65511, 917504, 4, 24, 786432, 4, 25, 786432, 4, 26, 786432, 4, 27, 786432, 4, 28, 786432, 4, 65560, 786432, 5, 65561, 786432, 5, 65562, 786432, 5, 65563, 786432, 5, 65564, 786432, 5, 131100, 786432, 5, 196636, 589824, 6, 131099, 786432, 5, 131098, 786432, 5, 131097, 786432, 5, 131096, 786432, 5, 196632, 786432, 5, 262168, 786432, 5, 327704, 786432, 5, 393240, 786432, 5, 458776, 786432, 5, 524312, 786432, 6, 196633, 786432, 5, 262169, 786432, 5, 327705, 786432, 5, 393241, 786432, 5, 458777, 786432, 5, 524313, 786432, 6, 196634, 786432, 5, 262170, 786432, 5, 327706, 786432, 5, 393242, 655360, 6, 458778, 786432, 5, 524314, 786432, 6, 196635, 786432, 5, 262171, 786432, 5, 327707, 786432, 5, 393243, 786432, 5, 458779, 786432, 5, 524315, 786432, 6, 262172, 786432, 5, 327708, 786432, 5, 393244, 786432, 5, 458780, 786432, 5, 524316, 786432, 6, -196593, 1048576, 6, -393182, 1048576, 6, -393185, 917504, 6, -393180, 983040, 6, -393184, 983040, 5, -65509, 720896, 3, -65510, 720896, 3, -393181, 720896, 3, -393183, 720896, 3, -65517, 720896, 3, -65515, 720896, 3, -327650, 720896, 4, -262114, 720896, 5, -196578, 720896, 5, -131042, 720896, 5, -65506, 720896, 5, -65498, 851968, 5, -131034, 851968, 5, -196570, 851968, 5, -327642, 851968, 4, -327649, 786432, 4, -327648, 786432, 4, -327647, 786432, 4, -327646, 786432, 4, -327645, 786432, 4, -327644, 786432, 4, -327643, 786432, 4, -262106, 851968, 5, -65499, 786432, 5, -131035, 786432, 5, -196571, 786432, 5, -262107, 786432, 5, -262108, 786432, 5, -262109, 786432, 5, -262110, 786432, 5, -262111, 786432, 5, -262112, 786432, 5, -262113, 786432, 5, -196577, 655360, 6, -131041, 786432, 5, -65505, 786432, 5, -65500, 655360, 6, -131036, 589824, 6, -196572, 786432, 5, -196573, 786432, 5, -196574, 786432, 5, -196575, 786432, 5, -196576, 786432, 5, -131040, 589824, 6, -65504, 786432, 5, -65501, 786432, 5, -131037, 786432, 5, -131038, 786432, 5, -131039, 786432, 5, -65503, 786432, 5, -65502, 786432, 5, 524318, 720896, 6, 458782, 720896, 5, 393246, 720896, 5, 327710, 720896, 5, 262174, 720896, 5, 196638, 720896, 5, 131102, 720896, 5, 65566, 720896, 5, 30, 720896, 5, 524319, 786432, 6, 524320, 786432, 6, 524321, 786432, 6, 524322, 786432, 6, 524323, 786432, 6, 524324, 786432, 6, 524325, 786432, 6, 524326, 851968, 6, 38, 851968, 5, 65574, 851968, 5, 131110, 851968, 5, 196646, 851968, 5, 262182, 851968, 5, 327718, 851968, 5, 393254, 851968, 5, 458790, 851968, 5, 31, 786432, 5, 65567, 786432, 5, 131103, 786432, 5, 196639, 786432, 5, 262175, 786432, 5, 327711, 786432, 5, 393247, 655360, 6, 458783, 786432, 5, 32, 786432, 5, 65568, 786432, 5, 131104, 786432, 5, 196640, 786432, 5, 262176, 786432, 5, 327712, 786432, 5, 393248, 786432, 5, 458784, 786432, 5, 33, 786432, 5, 65569, 786432, 5, 131105, 655360, 6, 196641, 786432, 5, 262177, 786432, 5, 327713, 786432, 5, 393249, 786432, 5, 458785, 786432, 5, 34, 786432, 5, 65570, 786432, 5, 131106, 786432, 5, 196642, 786432, 5, 262178, 655360, 6, 327714, 655360, 6, 393250, 786432, 5, 458786, 786432, 5, 35, 786432, 5, 65571, 786432, 5, 131107, 786432, 5, 196643, 786432, 5, 262179, 786432, 5, 327715, 786432, 5, 393251, 786432, 5, 458787, 786432, 5, 36, 655360, 6, 65572, 786432, 5, 131108, 786432, 5, 196644, 786432, 5, 262180, 786432, 5, 327716, 786432, 5, 393252, 786432, 5, 458788, 655360, 6, 37, 786432, 5, 65573, 786432, 5, 131109, 786432, 5, 196645, 786432, 5, 262181, 786432, 5, 327717, 786432, 5, 393253, 786432, 5, 458789, 786432, 5, 524282, 786432, 5, 524283, 786432, 5, 524284, 786432, 5, 524285, 786432, 5, 524281, 720896, 5, 524286, 851968, 5, 589817, 720896, 6, 589818, 786432, 6, 589819, 786432, 6, 589820, 786432, 6, 589821, 786432, 6, 589822, 851968, 6) + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_1tbys")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_1kfnp")] +unique_name_in_owner = true +visible = false + +[node name="Camera2D" type="Camera2D" parent="."] +position = Vector2(282, -29) +zoom = Vector2(2, 2) +process_callback = 0 + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("4_mylkx") + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera2D" type="Node2D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +top_level = true +position = Vector2(282, -29) +script = ExtResource("5_lwx5e") +priority = 5 +follow_mode = 5 +follow_target = NodePath("../CharacterBody2D/PlayerVisuals") +zoom = Vector2(2, 2) +tween_resource = ExtResource("6_tju6r") +tween_on_load = false +follow_damping = true +dead_zone_width = 0.4 +dead_zone_height = 0.8 +show_viewfinder_in_play = true +draw_limits = true + +[node name="Label" type="Label" parent="Player"] +offset_left = 167.0 +offset_top = -145.0 +offset_right = 332.0 +offset_bottom = -81.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("8_bo8m7") +text = "[WASD] to move +[Space] to jump" + +[node name="CharacterBody2D" parent="Player" instance=ExtResource("8_wlikg")] +position = Vector2(282, -29) + +[editable path="Player/CharacterBody2D"] diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_follow_group_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_group_example_scene.tscn new file mode 100644 index 0000000..ba1e261 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_group_example_scene.tscn @@ -0,0 +1,255 @@ +[gd_scene load_steps=13 format=3 uid="uid://brrncnp26lrco"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_5kqbp"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_xmntp"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_8dojy"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_2efwt"] +[ext_resource type="Texture2D" uid="uid://cwep0on2tthn7" path="res://addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png" id="5_0v2cd"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_diuy4"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="7_ybwrw"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="9_wk0p3"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="12_uvcwb"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"] +texture = ExtResource("1_5kqbp") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_kf7eg"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_easgx") + +[sub_resource type="Resource" id="Resource_spy00"] +script = ExtResource("9_wk0p3") +duration = 0.3 +transition = 4 +ease = 2 + +[node name="ExampleScene2D" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="TileMap" type="TileMap" parent="."] +z_index = -1 +scale = Vector2(3, 3) +tile_set = SubResource("TileSet_kf7eg") +format = 2 +layer_0/name = "Background" +layer_0/tile_data = PackedInt32Array(-393216, 655360, 2, -327680, 655360, 3, -262144, 655360, 3, -196608, 655360, 3, -131072, 655360, 3, -65536, 655360, 3, -393215, 720896, 2, -327679, 720896, 1, -262143, 720896, 1, -196607, 720896, 1, -131071, 720896, 1, -65535, 720896, 1, -393214, 786432, 2, -327678, 786432, 3, -262142, 786432, 3, -196606, 786432, 3, -131070, 786432, 3, -65534, 786432, 3) +layer_1/name = "Terrain" +layer_1/z_index = 1 +layer_1/tile_data = PackedInt32Array(1, 720896, 0, 2, 720896, 0, 3, 720896, 0, 4, 720896, 0, 5, 720896, 0, 6, 720896, 0, 7, 720896, 0, 8, 720896, 0, 9, 786432, 0, 65545, 786432, 1, 131081, 786432, 1, 196617, 786432, 1, 262153, 786432, 1, 327689, 786432, 1, 393225, 786432, 1, 65537, 720896, 1, 131073, 720896, 1, 196609, 720896, 1, 262145, 458752, 1, 327681, 720896, 1, 393217, 720896, 1, 65538, 720896, 1, 131074, 720896, 1, 196610, 720896, 1, 262146, 720896, 1, 327682, 720896, 1, 393218, 720896, 1, 65539, 720896, 1, 131075, 720896, 1, 196611, 720896, 1, 262147, 720896, 1, 327683, 720896, 1, 393219, 720896, 1, 65540, 458752, 1, 131076, 720896, 1, 196612, 720896, 1, 262148, 720896, 1, 327684, 720896, 1, 393220, 720896, 1, 65541, 720896, 1, 131077, 720896, 1, 196613, 720896, 1, 262149, 458752, 1, 327685, 720896, 1, 393221, 720896, 1, 65542, 720896, 1, 131078, 720896, 1, 196614, 720896, 1, 262150, 720896, 1, 327686, 720896, 1, 393222, 720896, 1, 65543, 720896, 1, 131079, 720896, 1, 196615, 720896, 1, 262151, 720896, 1, 327687, 720896, 1, 393223, 458752, 1, 65544, 720896, 1, 131080, 720896, 1, 196616, 458752, 1, 262152, 720896, 1, 327688, 720896, 1, 393224, 720896, 1, 65546, 524288, 5, 65547, 524288, 5, 65548, 524288, 5, 65549, 524288, 5, 131082, 524288, 6, 131083, 524288, 6, 131084, 524288, 6, 131085, 524288, 6, 196618, 720896, 1, 262154, 720896, 1, 196619, 720896, 1, 262155, 720896, 1, 196620, 720896, 1, 262156, 720896, 1, 196621, 720896, 1, 262157, 720896, 1, 65550, 524288, 5, 65551, 524288, 5, 65552, 524288, 5, 131086, 524288, 6, 131087, 524288, 6, 131088, 524288, 6, 196622, 720896, 1, 196623, 720896, 1, 262159, 720896, 1, 262160, 720896, 1, 196624, 720896, 1, 262158, 720896, 1, 17, 720896, 4, 65553, 720896, 5, 131089, 720896, 5, 196625, 720896, 5, 262161, 720896, 5, 18, 786432, 4, 19, 786432, 4, 20, 786432, 4, 21, 786432, 4, 22, 786432, 4, 23, 786432, 4, 65554, 786432, 5, 131090, 786432, 5, 196626, 786432, 5, 262162, 786432, 5, 65555, 786432, 5, 131091, 589824, 6, 196627, 786432, 5, 262163, 786432, 5, 65556, 786432, 5, 131092, 786432, 5, 196628, 786432, 5, 262164, 786432, 5, 65557, 786432, 5, 131093, 786432, 5, 196629, 786432, 5, 262165, 786432, 5, 65558, 786432, 5, 131094, 786432, 5, 196630, 786432, 5, 262166, 655360, 6, 65559, 786432, 5, 131095, 786432, 5, 196631, 786432, 5, 262167, 786432, 5, 327697, 720896, 5, 393233, 720896, 5, 327698, 589824, 6, 393234, 786432, 5, 327699, 786432, 5, 393235, 786432, 5, 327700, 786432, 5, 393236, 786432, 5, 327701, 786432, 5, 393237, 786432, 5, 327702, 786432, 5, 393238, 786432, 5, 327703, 786432, 5, 393239, 786432, 5, -131062, 720896, 4, -131061, 786432, 4, -131060, 786432, 4, -65526, 720896, 6, -65525, 786432, 6, -65524, 786432, 6, -131056, 851968, 4, -65520, 851968, 6, -131059, 786432, 4, -131058, 786432, 4, -131057, 786432, 4, -65523, 786432, 6, -65522, 786432, 6, -65521, 786432, 6, -196596, 917504, 0, -65536, 917504, 2, -65535, 983040, 2, -65534, 1048576, 2, -65533, 917504, 2, -65532, 983040, 2, -65531, 1048576, 2, -65530, 917504, 2, -65529, 983040, 2, -65528, 1048576, 2, 65535, 655360, 0, 131071, 655360, 1, 196607, 655360, 1, 262143, 655360, 1, 327679, 655360, 1, 393215, 655360, 1, 458751, 655360, 1, 524287, 655360, 1, 589823, 655360, 1, 0, 720896, 0, 65536, 720896, 1, 131072, 720896, 1, 196608, 720896, 1, 262144, 720896, 1, 327680, 720896, 1, 393216, 720896, 1, 458752, 720896, 1, 524288, 720896, 1, 524289, 720896, 1, 524290, 720896, 1, 524291, 720896, 1, 524292, 720896, 1, 524293, 720896, 1, 524294, 720896, 1, 524295, 720896, 1, 524296, 720896, 1, 524297, 786432, 1, 458761, 786432, 1, 458760, 720896, 1, 458759, 720896, 1, 458758, 458752, 1, 458757, 720896, 1, 458756, 720896, 1, 458755, 720896, 1, 458754, 720896, 1, 458753, 720896, 1, -262145, 851968, 4, -196609, 851968, 5, -131073, 851968, 5, -65537, 851968, 5, -1, 851968, 6, -262146, 786432, 4, -262147, 786432, 4, -196610, 589824, 6, -196611, 786432, 5, -6, 786432, 5, -5, 786432, 5, -4, 786432, 5, -3, 786432, 5, -2, 786432, 5, -65538, 786432, 5, -131074, 786432, 5, -131075, 786432, 5, -65539, 655360, 6, 65534, 851968, 5, 131070, 851968, 5, 196606, 851968, 5, 262142, 851968, 5, 327678, 851968, 5, 393214, 851968, 5, 458750, 851968, 5, 65533, 786432, 5, 65532, 786432, 5, 65531, 786432, 5, 65530, 786432, 5, 65529, 720896, 5, 131066, 786432, 5, 196602, 786432, 5, 262138, 786432, 5, 262139, 786432, 5, 327675, 786432, 5, 131068, 786432, 5, 131069, 786432, 5, 196605, 786432, 5, 262141, 786432, 5, 327677, 786432, 5, 393213, 786432, 5, 458749, 786432, 5, 393212, 786432, 5, 393211, 786432, 5, 458748, 786432, 5, 327676, 655360, 6, 262140, 786432, 5, 196604, 786432, 5, 131067, 786432, 5, 196603, 589824, 6, 458747, 786432, 5, 458746, 786432, 5, 393210, 786432, 5, 327674, 786432, 5, -7, 720896, 5, 131065, 720896, 5, 196601, 720896, 5, 262137, 720896, 5, 327673, 720896, 5, 393209, 720896, 5, 458745, 720896, 5, -327684, 720896, 3, -196594, 720896, 3, -196597, 720896, 3, -65518, 720896, 3, -65516, 720896, 3, -327686, 1048576, 5, -327685, 720896, 3, -196595, 917504, 6, -65514, 983040, 6, -327683, 983040, 5, -65513, 1048576, 5, -262151, 720896, 4, -196615, 720896, 5, -131079, 720896, 5, -65543, 720896, 5, -262150, 786432, 4, -196614, 655360, 6, -131078, 786432, 5, -65542, 786432, 5, -262149, 786432, 4, -196613, 786432, 5, -131077, 786432, 5, -65541, 786432, 5, -262148, 786432, 4, -196612, 786432, 5, -131076, 786432, 5, -65540, 786432, 5, 458769, 720896, 5, 524305, 720896, 6, 458775, 786432, 5, 458774, 786432, 5, 458773, 786432, 5, 458772, 786432, 5, 458771, 786432, 5, 458770, 786432, 5, 524306, 786432, 6, 524307, 786432, 6, 524308, 786432, 6, 524309, 786432, 6, 524310, 786432, 6, 524311, 786432, 6, 327690, 720896, 1, 393226, 720896, 1, 458762, 720896, 1, 524298, 720896, 1, 327691, 720896, 1, 393227, 720896, 1, 458763, 720896, 1, 524299, 720896, 1, 327692, 720896, 1, 393228, 720896, 1, 458764, 720896, 1, 524300, 720896, 1, 327693, 720896, 1, 393229, 720896, 1, 458765, 720896, 1, 524301, 720896, 1, 327694, 720896, 1, 393230, 720896, 1, 458766, 720896, 1, 524302, 720896, 1, 327695, 720896, 1, 393231, 720896, 1, 458767, 720896, 1, 524303, 720896, 1, 327696, 720896, 1, 393232, 720896, 1, 458768, 720896, 1, 524304, 720896, 1, 29, 851968, 4, 65565, 851968, 5, 131101, 851968, 5, 196637, 851968, 5, 262173, 851968, 5, 327709, 851968, 5, 393245, 851968, 5, 458781, 851968, 5, 524317, 851968, 6, -65511, 917504, 4, 24, 786432, 4, 25, 786432, 4, 26, 786432, 4, 27, 786432, 4, 28, 786432, 4, 65560, 786432, 5, 65561, 786432, 5, 65562, 786432, 5, 65563, 786432, 5, 65564, 786432, 5, 131100, 786432, 5, 196636, 589824, 6, 131099, 786432, 5, 131098, 786432, 5, 131097, 786432, 5, 131096, 786432, 5, 196632, 786432, 5, 262168, 786432, 5, 327704, 786432, 5, 393240, 786432, 5, 458776, 786432, 5, 524312, 786432, 6, 196633, 786432, 5, 262169, 786432, 5, 327705, 786432, 5, 393241, 786432, 5, 458777, 786432, 5, 524313, 786432, 6, 196634, 786432, 5, 262170, 786432, 5, 327706, 786432, 5, 393242, 655360, 6, 458778, 786432, 5, 524314, 786432, 6, 196635, 786432, 5, 262171, 786432, 5, 327707, 786432, 5, 393243, 786432, 5, 458779, 786432, 5, 524315, 786432, 6, 262172, 786432, 5, 327708, 786432, 5, 393244, 786432, 5, 458780, 786432, 5, 524316, 786432, 6, -196593, 1048576, 6, -393182, 1048576, 6, -393185, 917504, 6, -393180, 983040, 6, -393184, 983040, 5, -65509, 720896, 3, -65510, 720896, 3, -393181, 720896, 3, -393183, 720896, 3, -65517, 720896, 3, -65515, 720896, 3, -327650, 720896, 4, -262114, 720896, 5, -196578, 720896, 5, -131042, 720896, 5, -65506, 720896, 5, -65498, 851968, 5, -131034, 851968, 5, -196570, 851968, 5, -327642, 851968, 4, -327649, 786432, 4, -327648, 786432, 4, -327647, 786432, 4, -327646, 786432, 4, -327645, 786432, 4, -327644, 786432, 4, -327643, 786432, 4, -262106, 851968, 5, -65499, 786432, 5, -131035, 786432, 5, -196571, 786432, 5, -262107, 786432, 5, -262108, 786432, 5, -262109, 786432, 5, -262110, 786432, 5, -262111, 786432, 5, -262112, 786432, 5, -262113, 786432, 5, -196577, 655360, 6, -131041, 786432, 5, -65505, 786432, 5, -65500, 655360, 6, -131036, 589824, 6, -196572, 786432, 5, -196573, 786432, 5, -196574, 786432, 5, -196575, 786432, 5, -196576, 786432, 5, -131040, 589824, 6, -65504, 786432, 5, -65501, 786432, 5, -131037, 786432, 5, -131038, 786432, 5, -131039, 786432, 5, -65503, 786432, 5, -65502, 786432, 5, 524318, 720896, 6, 458782, 720896, 5, 393246, 720896, 5, 327710, 720896, 5, 262174, 720896, 5, 196638, 720896, 5, 131102, 720896, 5, 65566, 720896, 5, 30, 720896, 5, 524319, 786432, 6, 524320, 786432, 6, 524321, 786432, 6, 524322, 786432, 6, 524323, 786432, 6, 524324, 786432, 6, 524325, 786432, 6, 524326, 851968, 6, 38, 851968, 5, 65574, 851968, 5, 131110, 851968, 5, 196646, 851968, 5, 262182, 851968, 5, 327718, 851968, 5, 393254, 851968, 5, 458790, 851968, 5, 31, 786432, 5, 65567, 786432, 5, 131103, 786432, 5, 196639, 786432, 5, 262175, 786432, 5, 327711, 786432, 5, 393247, 655360, 6, 458783, 786432, 5, 32, 786432, 5, 65568, 786432, 5, 131104, 786432, 5, 196640, 786432, 5, 262176, 786432, 5, 327712, 786432, 5, 393248, 786432, 5, 458784, 786432, 5, 33, 786432, 5, 65569, 786432, 5, 131105, 655360, 6, 196641, 786432, 5, 262177, 786432, 5, 327713, 786432, 5, 393249, 786432, 5, 458785, 786432, 5, 34, 786432, 5, 65570, 786432, 5, 131106, 786432, 5, 196642, 786432, 5, 262178, 655360, 6, 327714, 655360, 6, 393250, 786432, 5, 458786, 786432, 5, 35, 786432, 5, 65571, 786432, 5, 131107, 786432, 5, 196643, 786432, 5, 262179, 786432, 5, 327715, 786432, 5, 393251, 786432, 5, 458787, 786432, 5, 36, 655360, 6, 65572, 786432, 5, 131108, 786432, 5, 196644, 786432, 5, 262180, 786432, 5, 327716, 786432, 5, 393252, 786432, 5, 458788, 655360, 6, 37, 786432, 5, 65573, 786432, 5, 131109, 786432, 5, 196645, 786432, 5, 262181, 786432, 5, 327717, 786432, 5, 393253, 786432, 5, 458789, 786432, 5) + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_xmntp")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_8dojy")] +unique_name_in_owner = true +visible = false + +[node name="Camera2D" type="Camera2D" parent="."] +position = Vector2(186, -172.5) +zoom = Vector2(1.5, 1.5) +position_smoothing_speed = 8.0 + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("4_2efwt") + +[node name="Label" type="Label" parent="."] +offset_left = 167.0 +offset_top = -133.0 +offset_right = 332.0 +offset_bottom = -69.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("12_uvcwb") +text = "[WASD] to move +[Space] to jump" + +[node name="PhantomCamera2D" type="Node2D" parent="." node_paths=PackedStringArray("follow_targets")] +top_level = true +position = Vector2(186, -172.5) +script = ExtResource("6_diuy4") +priority = 10 +follow_mode = 3 +follow_targets = [NodePath("../GroupNPCSprite"), NodePath("../CharacterBody2D/PlayerVisuals")] +zoom = Vector2(1.5, 1.5) +tween_resource = SubResource("Resource_spy00") +tween_on_load = false +follow_damping = true +auto_zoom = true +auto_zoom_min = 0.5 +auto_zoom_max = 1.5 +auto_zoom_margin = Vector4(200, 0, 200, 0) +draw_limits = true + +[node name="GroupNPCSprite" type="Sprite2D" parent="."] +unique_name_in_owner = true +position = Vector2(107, -316) +texture = ExtResource("5_0v2cd") + +[node name="CharacterBody2D" parent="." instance=ExtResource("7_ybwrw")] +position = Vector2(265, -29) + +[editable path="CharacterBody2D"] diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_follow_path_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_path_example_scene.tscn new file mode 100644 index 0000000..b7ebc1c --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D/2d_follow_path_example_scene.tscn @@ -0,0 +1,263 @@ +[gd_scene load_steps=12 format=3 uid="uid://psbaaxnedqmq"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_17ngo"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_whpvu"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_rbo5b"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_yddet"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_x25dj"] +[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_4vtmp"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="8_6pcaf"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_a2pel"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"] +texture = ExtResource("1_17ngo") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_kf7eg"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_easgx") + +[sub_resource type="Curve2D" id="Curve2D_usrhf"] +_data = { +"points": PackedVector2Array(-96.4111, 42.3785, 0, 0, 222, 0, 0, 0, 0, 0, 1550, 0) +} +point_count = 2 + +[node name="ExampleScene2D" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="TileMap" type="TileMap" parent="."] +z_index = -1 +scale = Vector2(3, 3) +tile_set = SubResource("TileSet_kf7eg") +format = 2 +layer_0/name = "Background" +layer_0/tile_data = PackedInt32Array(-393216, 655360, 2, -327680, 655360, 3, -262144, 655360, 3, -196608, 655360, 3, -131072, 655360, 3, -65536, 655360, 3, -393215, 720896, 2, -327679, 720896, 1, -262143, 720896, 1, -196607, 720896, 1, -131071, 720896, 1, -65535, 720896, 1, -393214, 786432, 2, -327678, 786432, 3, -262142, 786432, 3, -196606, 786432, 3, -131070, 786432, 3, -65534, 786432, 3) +layer_1/name = "Terrain" +layer_1/z_index = 1 +layer_1/tile_data = PackedInt32Array(1, 720896, 0, 2, 720896, 0, 3, 720896, 0, 4, 720896, 0, 5, 720896, 0, 6, 720896, 0, 7, 720896, 0, 8, 720896, 0, 9, 786432, 0, 65545, 786432, 1, 131081, 786432, 1, 196617, 786432, 1, 262153, 786432, 1, 327689, 786432, 1, 393225, 786432, 1, 65537, 720896, 1, 131073, 720896, 1, 196609, 720896, 1, 262145, 458752, 1, 327681, 720896, 1, 393217, 720896, 1, 65538, 720896, 1, 131074, 720896, 1, 196610, 720896, 1, 262146, 720896, 1, 327682, 720896, 1, 393218, 720896, 1, 65539, 720896, 1, 131075, 720896, 1, 196611, 720896, 1, 262147, 720896, 1, 327683, 720896, 1, 393219, 720896, 1, 65540, 458752, 1, 131076, 720896, 1, 196612, 720896, 1, 262148, 720896, 1, 327684, 720896, 1, 393220, 720896, 1, 65541, 720896, 1, 131077, 720896, 1, 196613, 720896, 1, 262149, 458752, 1, 327685, 720896, 1, 393221, 720896, 1, 65542, 720896, 1, 131078, 720896, 1, 196614, 720896, 1, 262150, 720896, 1, 327686, 720896, 1, 393222, 720896, 1, 65543, 720896, 1, 131079, 720896, 1, 196615, 720896, 1, 262151, 720896, 1, 327687, 720896, 1, 393223, 458752, 1, 65544, 720896, 1, 131080, 720896, 1, 196616, 458752, 1, 262152, 720896, 1, 327688, 720896, 1, 393224, 720896, 1, 65546, 524288, 5, 65547, 524288, 5, 65548, 524288, 5, 65549, 524288, 5, 131082, 524288, 6, 131083, 524288, 6, 131084, 524288, 6, 131085, 524288, 6, 196618, 720896, 1, 262154, 720896, 1, 196619, 720896, 1, 262155, 720896, 1, 196620, 720896, 1, 262156, 720896, 1, 196621, 720896, 1, 262157, 720896, 1, 65550, 524288, 5, 65551, 524288, 5, 65552, 524288, 5, 131086, 524288, 6, 131087, 524288, 6, 131088, 524288, 6, 196622, 720896, 1, 196623, 720896, 1, 262159, 720896, 1, 262160, 720896, 1, 196624, 720896, 1, 262158, 720896, 1, 17, 720896, 4, 65553, 720896, 5, 131089, 720896, 5, 196625, 720896, 5, 262161, 720896, 5, 18, 786432, 4, 19, 786432, 4, 20, 786432, 4, 21, 786432, 4, 22, 786432, 4, 23, 786432, 4, 65554, 786432, 5, 131090, 786432, 5, 196626, 786432, 5, 262162, 786432, 5, 65555, 786432, 5, 131091, 589824, 6, 196627, 786432, 5, 262163, 786432, 5, 65556, 786432, 5, 131092, 786432, 5, 196628, 786432, 5, 262164, 786432, 5, 65557, 786432, 5, 131093, 786432, 5, 196629, 786432, 5, 262165, 786432, 5, 65558, 786432, 5, 131094, 786432, 5, 196630, 786432, 5, 262166, 655360, 6, 65559, 786432, 5, 131095, 786432, 5, 196631, 786432, 5, 262167, 786432, 5, 327697, 720896, 5, 393233, 720896, 5, 327698, 589824, 6, 393234, 786432, 5, 327699, 786432, 5, 393235, 786432, 5, 327700, 786432, 5, 393236, 786432, 5, 327701, 786432, 5, 393237, 786432, 5, 327702, 786432, 5, 393238, 786432, 5, 327703, 786432, 5, 393239, 786432, 5, -131062, 720896, 4, -131061, 786432, 4, -131060, 786432, 4, -65526, 720896, 6, -65525, 786432, 6, -65524, 786432, 6, -131056, 851968, 4, -65520, 851968, 6, -131059, 786432, 4, -131058, 786432, 4, -131057, 786432, 4, -65523, 786432, 6, -65522, 786432, 6, -65521, 786432, 6, -65536, 917504, 2, -65535, 983040, 2, -65534, 1048576, 2, -65533, 917504, 2, -65532, 983040, 2, -65531, 1048576, 2, -65530, 917504, 2, -65529, 983040, 2, -65528, 1048576, 2, 65535, 655360, 0, 131071, 655360, 1, 196607, 655360, 1, 262143, 655360, 1, 327679, 655360, 1, 393215, 655360, 1, 458751, 655360, 1, 524287, 655360, 1, 589823, 655360, 1, 0, 720896, 0, 65536, 720896, 1, 131072, 720896, 1, 196608, 720896, 1, 262144, 720896, 1, 327680, 720896, 1, 393216, 720896, 1, 458752, 720896, 1, 524288, 720896, 1, 524289, 720896, 1, 524290, 720896, 1, 524291, 720896, 1, 524292, 720896, 1, 524293, 720896, 1, 524294, 720896, 1, 524295, 720896, 1, 524296, 720896, 1, 524297, 786432, 1, 458761, 786432, 1, 458760, 720896, 1, 458759, 720896, 1, 458758, 458752, 1, 458757, 720896, 1, 458756, 720896, 1, 458755, 720896, 1, 458754, 720896, 1, 458753, 720896, 1, -262145, 851968, 4, -196609, 851968, 5, -131073, 851968, 5, -65537, 851968, 5, -1, 851968, 6, -262146, 786432, 4, -262147, 786432, 4, -196610, 589824, 6, -196611, 786432, 5, -6, 786432, 5, -5, 786432, 5, -4, 786432, 5, -3, 786432, 5, -2, 786432, 5, -65538, 786432, 5, -131074, 786432, 5, -131075, 786432, 5, -65539, 655360, 6, 65534, 851968, 5, 131070, 851968, 5, 196606, 851968, 5, 262142, 851968, 5, 327678, 851968, 5, 393214, 851968, 5, 458750, 851968, 5, 65533, 786432, 5, 65532, 786432, 5, 65531, 786432, 5, 65530, 786432, 5, 65529, 720896, 5, 131066, 786432, 5, 196602, 786432, 5, 262138, 786432, 5, 262139, 786432, 5, 327675, 786432, 5, 131068, 786432, 5, 131069, 786432, 5, 196605, 786432, 5, 262141, 786432, 5, 327677, 786432, 5, 393213, 786432, 5, 458749, 786432, 5, 393212, 786432, 5, 393211, 786432, 5, 458748, 786432, 5, 327676, 655360, 6, 262140, 786432, 5, 196604, 786432, 5, 131067, 786432, 5, 196603, 589824, 6, 458747, 786432, 5, 458746, 786432, 5, 393210, 786432, 5, 327674, 786432, 5, -7, 720896, 5, 131065, 720896, 5, 196601, 720896, 5, 262137, 720896, 5, 327673, 720896, 5, 393209, 720896, 5, 458745, 720896, 5, -327684, 720896, 3, -196594, 720896, 3, -196597, 720896, 3, -65518, 720896, 3, -65516, 720896, 3, -327686, 1048576, 5, -327685, 720896, 3, -196595, 917504, 6, -65514, 983040, 6, -327683, 983040, 5, -65513, 1048576, 5, -262151, 720896, 4, -196615, 720896, 5, -131079, 720896, 5, -65543, 720896, 5, -262150, 786432, 4, -196614, 655360, 6, -131078, 786432, 5, -65542, 786432, 5, -262149, 786432, 4, -196613, 786432, 5, -131077, 786432, 5, -65541, 786432, 5, -262148, 786432, 4, -196612, 786432, 5, -131076, 786432, 5, -65540, 786432, 5, 458769, 720896, 5, 524305, 720896, 6, 458775, 786432, 5, 458774, 786432, 5, 458773, 786432, 5, 458772, 786432, 5, 458771, 786432, 5, 458770, 786432, 5, 524306, 786432, 6, 524307, 786432, 6, 524308, 786432, 6, 524309, 786432, 6, 524310, 786432, 6, 524311, 786432, 6, 327690, 720896, 1, 393226, 720896, 1, 458762, 720896, 1, 524298, 720896, 1, 327691, 720896, 1, 393227, 720896, 1, 458763, 720896, 1, 524299, 720896, 1, 327692, 720896, 1, 393228, 720896, 1, 458764, 720896, 1, 524300, 720896, 1, 327693, 720896, 1, 393229, 720896, 1, 458765, 720896, 1, 524301, 720896, 1, 327694, 720896, 1, 393230, 720896, 1, 458766, 720896, 1, 524302, 720896, 1, 327695, 720896, 1, 393231, 720896, 1, 458767, 720896, 1, 524303, 720896, 1, 327696, 720896, 1, 393232, 720896, 1, 458768, 720896, 1, 524304, 720896, 1, 29, 851968, 4, 65565, 851968, 5, 131101, 851968, 5, 196637, 851968, 5, 262173, 851968, 5, 327709, 851968, 5, 393245, 851968, 5, 458781, 851968, 5, 524317, 851968, 6, 24, 786432, 4, 25, 786432, 4, 26, 786432, 4, 27, 786432, 4, 28, 786432, 4, 65560, 786432, 5, 65561, 786432, 5, 65562, 786432, 5, 65563, 786432, 5, 65564, 786432, 5, 131100, 786432, 5, 196636, 589824, 6, 131099, 786432, 5, 131098, 786432, 5, 131097, 786432, 5, 131096, 786432, 5, 196632, 786432, 5, 262168, 786432, 5, 327704, 786432, 5, 393240, 786432, 5, 458776, 786432, 5, 524312, 786432, 6, 196633, 786432, 5, 262169, 786432, 5, 327705, 786432, 5, 393241, 786432, 5, 458777, 786432, 5, 524313, 786432, 6, 196634, 786432, 5, 262170, 786432, 5, 327706, 786432, 5, 393242, 655360, 6, 458778, 786432, 5, 524314, 786432, 6, 196635, 786432, 5, 262171, 786432, 5, 327707, 786432, 5, 393243, 786432, 5, 458779, 786432, 5, 524315, 786432, 6, 262172, 786432, 5, 327708, 786432, 5, 393244, 786432, 5, 458780, 786432, 5, 524316, 786432, 6, -196593, 1048576, 6, -65509, 720896, 3, -65510, 720896, 3, -65517, 720896, 3, -65515, 720896, 3, 524282, 786432, 5, 524283, 786432, 5, 524284, 786432, 5, 524285, 786432, 5, 524281, 720896, 5, 524286, 851968, 5, 589817, 720896, 6, 589818, 786432, 6, 589819, 786432, 6, 589820, 786432, 6, 589821, 786432, 6, 589822, 851968, 6, -196569, 720896, 4, -131033, 720896, 5, -65497, 720896, 5, 39, 720896, 5, 65575, 720896, 5, 131111, 720896, 5, 196647, 720896, 5, 262183, 720896, 5, 327719, 720896, 5, 393255, 720896, 5, 458791, 720896, 5, 524327, 720896, 5, 589863, 720896, 5, 655399, 720896, 6, -262104, 917504, 6, -196568, 786432, 4, -131032, 786432, 5, -65496, 655360, 6, 40, 786432, 5, 65576, 786432, 5, 131112, 786432, 5, 196648, 786432, 5, 262184, 786432, 5, 327720, 786432, 5, 393256, 786432, 5, 458792, 786432, 5, 524328, 655360, 6, 589864, 786432, 5, 655400, 786432, 6, -262103, 983040, 5, -196567, 786432, 4, -131031, 786432, 5, -65495, 786432, 5, 41, 589824, 6, 65577, 786432, 5, 131113, 786432, 5, 196649, 786432, 5, 262185, 786432, 5, 327721, 786432, 5, 393257, 786432, 5, 458793, 786432, 5, 524329, 786432, 5, 589865, 786432, 5, 655401, 786432, 6, -262102, 720896, 3, -196566, 786432, 4, -131030, 786432, 5, -65494, 786432, 5, 42, 786432, 5, 65578, 786432, 5, 131114, 786432, 5, 196650, 786432, 5, 262186, 655360, 6, 327722, 786432, 5, 393258, 786432, 5, 458794, 786432, 5, 524330, 786432, 5, 589866, 786432, 5, 655402, 786432, 6, -262101, 1048576, 6, -196565, 786432, 4, -131029, 786432, 5, -65493, 786432, 5, 43, 786432, 5, 65579, 786432, 5, 131115, 786432, 5, 196651, 786432, 5, 262187, 786432, 5, 327723, 786432, 5, 393259, 655360, 6, 458795, 655360, 6, 524331, 786432, 5, 589867, 786432, 5, 655403, 786432, 6, -262100, 720896, 3, -196564, 786432, 4, -131028, 786432, 5, -65492, 786432, 5, 44, 786432, 5, 65580, 786432, 5, 131116, 786432, 5, 196652, 786432, 5, 262188, 786432, 5, 327724, 786432, 5, 393260, 786432, 5, 458796, 786432, 5, 524332, 786432, 5, 589868, 786432, 5, 655404, 786432, 6, -262099, 983040, 6, -196563, 786432, 4, -131027, 786432, 5, -65491, 786432, 5, 45, 589824, 6, 65581, 655360, 6, 131117, 655360, 6, 196653, 786432, 5, 262189, 786432, 5, 327725, 786432, 5, 393261, 786432, 5, 458797, 786432, 5, 524333, 786432, 5, 589869, 655360, 6, 655405, 786432, 6, -196562, 786432, 4, -131026, 786432, 5, -65490, 786432, 5, 46, 786432, 5, 65582, 786432, 5, 131118, 786432, 5, 196654, 786432, 5, 262190, 786432, 5, 327726, 786432, 5, 393262, 786432, 5, 458798, 786432, 5, 524334, 786432, 5, 589870, 786432, 5, 655406, 786432, 6, -196561, 851968, 4, -131025, 851968, 5, -65489, 851968, 5, 47, 851968, 5, 65583, 851968, 5, 131119, 851968, 5, 196655, 851968, 5, 262191, 851968, 5, 327727, 851968, 5, 393263, 851968, 5, 458799, 851968, 5, 524335, 851968, 5, 589871, 851968, 5, 655407, 851968, 6, -131042, 720896, 4, -65506, 720896, 5, 30, 720896, 5, 65566, 720896, 5, 131102, 720896, 5, 196638, 720896, 5, 262174, 720896, 5, 327710, 720896, 5, 393246, 720896, 5, 458782, 720896, 5, 524318, 720896, 5, -196577, 917504, 6, -131041, 786432, 4, -65505, 786432, 5, 31, 655360, 6, 65567, 786432, 5, 131103, 786432, 5, 196639, 786432, 5, 262175, 786432, 5, 327711, 786432, 5, 393247, 786432, 5, 458783, 786432, 5, 524319, 786432, 5, -196576, 983040, 5, -131040, 786432, 4, -65504, 786432, 5, 32, 786432, 5, 65568, 589824, 6, 131104, 786432, 5, 196640, 786432, 5, 262176, 786432, 5, 327712, 786432, 5, 393248, 786432, 5, 458784, 786432, 5, 524320, 786432, 5, -196575, 720896, 3, -131039, 786432, 4, -65503, 786432, 5, 33, 786432, 5, 65569, 786432, 5, 131105, 786432, 5, 196641, 786432, 5, 262177, 786432, 5, 327713, 655360, 6, 393249, 786432, 5, 458785, 786432, 5, 524321, 786432, 5, -196574, 1048576, 6, -131038, 786432, 4, -65502, 786432, 5, 34, 786432, 5, 65570, 786432, 5, 131106, 786432, 5, 196642, 786432, 5, 262178, 786432, 5, 327714, 786432, 5, 393250, 786432, 5, 458786, 655360, 6, 524322, 655360, 6, -196573, 720896, 3, -131037, 786432, 4, -65501, 786432, 5, 35, 786432, 5, 65571, 786432, 5, 131107, 786432, 5, 196643, 786432, 5, 262179, 786432, 5, 327715, 786432, 5, 393251, 786432, 5, 458787, 786432, 5, 524323, 786432, 5, -196572, 983040, 6, -131036, 786432, 4, -65500, 786432, 5, 36, 786432, 5, 65572, 589824, 6, 131108, 655360, 6, 196644, 655360, 6, 262180, 786432, 5, 327716, 786432, 5, 393252, 786432, 5, 458788, 786432, 5, 524324, 786432, 5, -131035, 786432, 4, -65499, 786432, 5, 37, 786432, 5, 65573, 786432, 5, 131109, 786432, 5, 196645, 786432, 5, 262181, 786432, 5, 327717, 786432, 5, 393253, 786432, 5, 458789, 786432, 5, 524325, 786432, 5, -131034, 851968, 4, -65498, 851968, 5, 38, 851968, 5, 65574, 851968, 5, 131110, 851968, 5, 196646, 851968, 5, 262182, 851968, 5, 327718, 851968, 5, 393254, 851968, 5, 458790, 851968, 5, 524326, 851968, 5, 589854, 720896, 5, 655390, 720896, 5, 720926, 720896, 6, 589855, 655360, 6, 655391, 786432, 5, 720927, 786432, 6, 589856, 786432, 5, 655392, 786432, 5, 720928, 786432, 6, 589857, 786432, 5, 655393, 786432, 5, 720929, 786432, 6, 589858, 786432, 5, 655394, 786432, 5, 720930, 786432, 6, 589859, 786432, 5, 655395, 786432, 5, 720931, 786432, 6, 589860, 786432, 5, 655396, 655360, 6, 720932, 786432, 6, 589861, 786432, 5, 655397, 786432, 5, 720933, 786432, 6, 589862, 851968, 5, 655398, 851968, 5, 720934, 851968, 6, -458704, 720896, 4, -393168, 720896, 5, -327632, 720896, 5, -262096, 720896, 5, -196560, 720896, 5, -131024, 720896, 5, -65488, 720896, 5, 48, 720896, 5, 65584, 720896, 5, 131120, 720896, 5, 196656, 720896, 5, 262192, 720896, 5, 327728, 720896, 5, 393264, 720896, 6, -524239, 917504, 6, -458703, 786432, 4, -393167, 786432, 5, -327631, 655360, 6, -262095, 786432, 5, -196559, 786432, 5, -131023, 786432, 5, -65487, 786432, 5, 49, 786432, 5, 65585, 786432, 5, 131121, 786432, 5, 196657, 786432, 5, 262193, 655360, 6, 327729, 786432, 5, 393265, 786432, 6, -524238, 983040, 5, -458702, 786432, 4, -393166, 786432, 5, -327630, 786432, 5, -262094, 589824, 6, -196558, 786432, 5, -131022, 786432, 5, -65486, 786432, 5, 50, 786432, 5, 65586, 786432, 5, 131122, 786432, 5, 196658, 786432, 5, 262194, 786432, 5, 327730, 786432, 5, 393266, 786432, 6, -524237, 720896, 3, -458701, 786432, 4, -393165, 786432, 5, -327629, 786432, 5, -262093, 786432, 5, -196557, 786432, 5, -131021, 786432, 5, -65485, 786432, 5, 51, 655360, 6, 65587, 786432, 5, 131123, 786432, 5, 196659, 786432, 5, 262195, 786432, 5, 327731, 786432, 5, 393267, 786432, 6, -524236, 1048576, 6, -458700, 786432, 4, -393164, 786432, 5, -327628, 786432, 5, -262092, 786432, 5, -196556, 786432, 5, -131020, 786432, 5, -65484, 786432, 5, 52, 786432, 5, 65588, 786432, 5, 131124, 655360, 6, 196660, 655360, 6, 262196, 786432, 5, 327732, 786432, 5, 393268, 786432, 6, -524235, 720896, 3, -458699, 786432, 4, -393163, 786432, 5, -327627, 786432, 5, -262091, 786432, 5, -196555, 786432, 5, -131019, 786432, 5, -65483, 786432, 5, 53, 786432, 5, 65589, 786432, 5, 131125, 786432, 5, 196661, 786432, 5, 262197, 786432, 5, 327733, 786432, 5, 393269, 786432, 6, -524234, 983040, 6, -458698, 786432, 4, -393162, 786432, 5, -327626, 786432, 5, -262090, 589824, 6, -196554, 655360, 6, -131018, 655360, 6, -65482, 786432, 5, 54, 786432, 5, 65590, 786432, 5, 131126, 786432, 5, 196662, 786432, 5, 262198, 786432, 5, 327734, 655360, 6, 393270, 786432, 6, -458697, 786432, 4, -393161, 786432, 5, -327625, 786432, 5, -262089, 786432, 5, -196553, 786432, 5, -131017, 786432, 5, -65481, 786432, 5, 55, 786432, 5, 65591, 786432, 5, 131127, 786432, 5, 196663, 786432, 5, 262199, 786432, 5, 327735, 786432, 5, 393271, 786432, 6, -458696, 851968, 4, -393160, 851968, 5, -327624, 851968, 5, -262088, 851968, 5, -196552, 851968, 5, -131016, 851968, 5, -65480, 851968, 5, 56, 851968, 5, 65592, 851968, 5, 131128, 851968, 5, 196664, 851968, 5, 262200, 851968, 5, 327736, 851968, 5, 393272, 851968, 6) + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_whpvu")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_rbo5b")] +unique_name_in_owner = true +visible = false + +[node name="Camera2D" type="Camera2D" parent="."] +position = Vector2(374, -216) +zoom = Vector2(1.5, 1.5) +process_callback = 0 + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("4_yddet") + +[node name="Label" type="Label" parent="."] +offset_left = 167.0 +offset_top = -133.0 +offset_right = 332.0 +offset_bottom = -69.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("8_6pcaf") +text = "[WASD] to move +[Space] to jump" + +[node name="Player" type="Node" parent="."] + +[node name="Label" type="Label" parent="Player"] +visible = false +offset_left = 167.0 +offset_top = -145.0 +offset_right = 332.0 +offset_bottom = -81.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("8_6pcaf") +text = "[WASD] to move +[Space] to jump" + +[node name="PlayerPhantomCamera2D" type="Node2D" parent="." node_paths=PackedStringArray("follow_target", "follow_path")] +unique_name_in_owner = true +top_level = true +position = Vector2(374, -216) +script = ExtResource("5_x25dj") +priority = 10 +follow_mode = 4 +follow_target = NodePath("../CharacterBody2D/PlayerVisuals") +follow_path = NodePath("../Path2D") +zoom = Vector2(1.5, 1.5) +tween_resource = ExtResource("6_4vtmp") +tween_on_load = false +draw_limits = true + +[node name="Path2D" type="Path2D" parent="."] +position = Vector2(152, -216) +curve = SubResource("Curve2D_usrhf") + +[node name="CharacterBody2D" parent="." instance=ExtResource("8_a2pel")] +position = Vector2(225, -28) + +[editable path="CharacterBody2D"] diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_limit_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_limit_example_scene.tscn new file mode 100644 index 0000000..7735ec6 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D/2d_limit_example_scene.tscn @@ -0,0 +1,324 @@ +[gd_scene load_steps=16 format=3 uid="uid://w20wokw3ohsq"] + +[ext_resource type="Script" uid="uid://c5yewe1hewu7j" path="res://addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd" id="1_ijqyv"] +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_wmhqb"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_v5qg2"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_oqmwp"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="4_4b648"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="5_pr2x5"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="9_twplb"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="9_w5e16"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"] +texture = ExtResource("1_wmhqb") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 + +[sub_resource type="TileSet" id="TileSet_kf7eg"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_easgx") + +[sub_resource type="Resource" id="Resource_ct1eh"] +script = ExtResource("9_twplb") +duration = 0.9 +transition = 2 +ease = 2 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_xmxri"] +size = Vector2(790, 410) + +[sub_resource type="Resource" id="Resource_exr3j"] +script = ExtResource("9_twplb") +duration = 0.9 +transition = 2 +ease = 2 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_wtfjw"] +size = Vector2(1530, 700) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_daeuh"] +size = Vector2(1027.5, 610.5) + +[node name="ExampleScene2D" type="Node2D"] +script = ExtResource("1_ijqyv") + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) +metadata/_edit_lock_ = true + +[node name="TileMap" type="TileMap" parent="."] +z_index = -1 +position = Vector2(-97, 0) +scale = Vector2(3, 3) +tile_set = SubResource("TileSet_kf7eg") +format = 2 +layer_0/name = "Background" +layer_0/tile_data = PackedInt32Array(-458743, 851968, 6, -458744, 786432, 6, -458745, 786432, 6, -458746, 786432, 6, -458747, 786432, 6, -458748, 786432, 6, -458749, 786432, 6, -458750, 786432, 6, -458751, 786432, 6, -393218, 786432, 6, -393219, 786432, 6, -393220, 786432, 6, -393221, 720896, 6, -458752, 786432, 6, -393217, 786432, 6, -524279, 851968, 5, -589815, 851968, 5, -655351, 851968, 5, -720887, 851968, 4, -720888, 786432, 4, -720889, 786432, 4, -720890, 786432, 4, -720891, 786432, 4, -720892, 786432, 4, -720893, 786432, 4, -720894, 786432, 4, -720895, 786432, 4, -720896, 786432, 4, -655361, 786432, 4, -655362, 786432, 4, -655363, 786432, 4, -655364, 786432, 4, -655365, 720896, 4, -589829, 720896, 5, -524293, 720896, 5, -458757, 720896, 5, -589828, 786432, 5, -524292, 786432, 5, -458756, 786432, 5, -589827, 786432, 5, -524291, 786432, 5, -458755, 786432, 5, -589826, 786432, 5, -524290, 786432, 5, -458754, 786432, 5, -589825, 786432, 5, -524289, 786432, 5, -458753, 786432, 5, -655360, 786432, 5, -589824, 786432, 5, -524288, 786432, 5, -655359, 786432, 5, -589823, 786432, 5, -524287, 786432, 5, -655358, 786432, 5, -589822, 786432, 5, -524286, 786432, 5, -655357, 786432, 5, -589821, 786432, 5, -524285, 786432, 5, -655356, 786432, 5, -589820, 786432, 5, -524284, 786432, 5, -655355, 786432, 5, -589819, 786432, 5, -524283, 786432, 5, -655354, 786432, 5, -589818, 786432, 5, -524282, 786432, 5, -655353, 786432, 5, -589817, 786432, 5, -524281, 786432, 5, -655352, 786432, 5, -589816, 786432, 5, -524280, 786432, 5) +layer_1/name = "Terrain" +layer_1/z_index = 1 +layer_1/tile_data = PackedInt32Array(65533, 720896, 0, 65534, 720896, 0, 65535, 720896, 0, 0, 720896, 0, 1, 720896, 0, 2, 720896, 0, 3, 720896, 0, 4, 720896, 0, 5, 720896, 0, 6, 720896, 0, 7, 720896, 0, 8, 720896, 0, 9, 786432, 0, 65532, 720896, 0, 65531, 655360, 0, 131067, 655360, 1, 196603, 655360, 1, 262139, 655360, 1, 327675, 655360, 1, 393211, 655360, 1, 131068, 720896, 1, 196604, 720896, 1, 262140, 720896, 1, 327676, 720896, 1, 393212, 720896, 1, 131069, 720896, 1, 196605, 720896, 1, 262141, 720896, 1, 327677, 720896, 1, 393213, 720896, 1, 131070, 720896, 1, 196606, 720896, 1, 262142, 720896, 1, 327678, 720896, 1, 393214, 720896, 1, 131071, 720896, 1, 196607, 720896, 1, 262143, 720896, 1, 327679, 720896, 1, 393215, 720896, 1, 65536, 720896, 1, 131072, 720896, 1, 196608, 720896, 1, 262144, 720896, 1, 327680, 720896, 1, 65537, 720896, 1, 131073, 720896, 1, 196609, 720896, 1, 262145, 720896, 1, 327681, 720896, 1, 65538, 720896, 1, 131074, 720896, 1, 196610, 720896, 1, 262146, 720896, 1, 327682, 720896, 1, 65539, 720896, 1, 131075, 720896, 1, 196611, 720896, 1, 262147, 720896, 1, 327683, 720896, 1, 65540, 720896, 1, 131076, 720896, 1, 196612, 720896, 1, 262148, 720896, 1, 327684, 720896, 1, 65541, 720896, 1, 131077, 720896, 1, 196613, 720896, 1, 262149, 720896, 1, 327685, 720896, 1, 65542, 720896, 1, 131078, 720896, 1, 196614, 720896, 1, 262150, 720896, 1, 327686, 720896, 1, 65543, 720896, 1, 131079, 720896, 1, 196615, 720896, 1, 262151, 720896, 1, 327687, 720896, 1, 65544, 720896, 1, 131080, 720896, 1, 196616, 720896, 1, 262152, 720896, 1, 327688, 720896, 1, 65545, 786432, 1, 131081, 786432, 1, 196617, 786432, 1, 262153, 786432, 1, 327689, 786432, 1) + +[node name="TileMap2" type="TileMap" parent="."] +z_index = -1 +scale = Vector2(3, 3) +tile_set = SubResource("TileSet_kf7eg") +format = 2 +layer_0/name = "Background" +layer_1/name = "Terrain" +layer_1/z_index = 1 +layer_1/tile_data = PackedInt32Array(8, 786432, 4, 9, 786432, 4, 10, 786432, 4, 11, 786432, 4, 12, 786432, 4, 13, 786432, 4, 14, 786432, 4, 65528, 851968, 5, 65527, 786432, 5, 65526, 786432, 5, 65525, 786432, 5, 65524, 786432, 5, 65523, 786432, 5, 65544, 786432, 5, 131080, 786432, 5, 196616, 786432, 5, 262152, 786432, 5, 65545, 786432, 5, 131081, 786432, 5, 196617, 786432, 5, 262153, 786432, 5, 65546, 786432, 5, 131082, 786432, 5, 196618, 786432, 5, 262154, 786432, 5, 65547, 786432, 5, 131083, 786432, 5, 196619, 786432, 5, 262155, 786432, 5, 65548, 786432, 5, 131084, 786432, 5, 196620, 786432, 5, 262156, 786432, 5, 65549, 786432, 5, 131085, 786432, 5, 196621, 786432, 5, 262157, 786432, 5, 65550, 786432, 5, 131086, 786432, 5, 196622, 786432, 5, 262158, 786432, 5, 327694, 786432, 5, 327693, 786432, 5, 327692, 786432, 5, 327691, 786432, 5, 327690, 786432, 5, 327689, 786432, 5, 327688, 786432, 5, -131089, 720896, 5, -65553, 720896, 5, -17, 720896, 5, 65519, 720896, 6, -131088, 786432, 5, -65552, 786432, 5, -16, 786432, 5, 65520, 786432, 5, -131087, 786432, 5, -65551, 786432, 5, -15, 786432, 5, 65521, 786432, 5, -131086, 786432, 5, -65550, 786432, 5, -14, 786432, 5, 65522, 786432, 5, -131085, 786432, 5, -65549, 786432, 5, -13, 786432, 5, -131084, 786432, 5, -65548, 786432, 5, -12, 786432, 5, -131083, 786432, 5, -65547, 786432, 5, -11, 786432, 5, -131082, 786432, 5, -65546, 786432, 5, -10, 786432, 5, -131081, 786432, 5, -65545, 786432, 5, -9, 786432, 5, -131080, 851968, 5, -65544, 851968, 5, -8, 851968, 5, 131064, 851968, 5, 196600, 851968, 5, 262136, 851968, 5, 327672, 851968, 5, 393208, 851968, 5, 131056, 786432, 5, 196592, 786432, 5, 262128, 786432, 5, 327664, 786432, 5, 393200, 786432, 5, 131057, 786432, 5, 196593, 786432, 5, 262129, 786432, 5, 327665, 786432, 5, 393201, 786432, 5, 131058, 786432, 5, 196594, 786432, 5, 262130, 786432, 5, 327666, 786432, 5, 393202, 786432, 5, 131059, 786432, 5, 196595, 786432, 5, 262131, 786432, 5, 327667, 786432, 5, 393203, 786432, 5, 131060, 786432, 5, 196596, 786432, 5, 262132, 786432, 5, 327668, 786432, 5, 393204, 786432, 5, 131061, 786432, 5, 196597, 786432, 5, 262133, 786432, 5, 327669, 786432, 5, 393205, 786432, 5, 131062, 786432, 5, 196598, 786432, 5, 262134, 786432, 5, 327670, 786432, 5, 393206, 786432, 5, 131063, 786432, 5, 196599, 786432, 5, 262135, 786432, 5, 327671, 786432, 5, 393207, 786432, 5, 17, 786432, 4, 65553, 786432, 5, 131089, 786432, 5, 196625, 786432, 5, 262161, 786432, 5, 327697, 786432, 5, 18, 786432, 4, 65554, 786432, 5, 131090, 786432, 5, 196626, 786432, 5, 262162, 786432, 5, 327698, 786432, 5, 15, 786432, 4, 65551, 786432, 5, 131087, 786432, 5, 196623, 786432, 5, 262159, 786432, 5, 327695, 786432, 5, 16, 786432, 4, 65552, 786432, 5, 131088, 786432, 5, 196624, 786432, 5, 262160, 786432, 5, 327696, 786432, 5, 19, 786432, 4, 65555, 786432, 5, 131091, 786432, 5, 196627, 786432, 5, 262163, 786432, 5, 327699, 786432, 5, -458769, 720896, 5, -393233, 720896, 5, -458768, 786432, 5, -393232, 786432, 5, -458767, 786432, 5, -393231, 786432, 5, -458766, 786432, 5, -393230, 786432, 5, -458765, 786432, 5, -393229, 786432, 5, -458764, 786432, 5, -393228, 786432, 5, -458763, 786432, 5, -393227, 786432, 5, -458762, 786432, 5, -393226, 786432, 5, -458761, 786432, 5, -393225, 786432, 5, -458760, 851968, 5, -393224, 851968, 5, -655377, 720896, 4, -589841, 720896, 5, -524305, 720896, 5, -655376, 786432, 4, -589840, 786432, 5, -524304, 786432, 5, -655375, 786432, 4, -589839, 786432, 5, -524303, 786432, 5, -655374, 786432, 4, -589838, 786432, 5, -524302, 786432, 5, -655373, 786432, 4, -589837, 786432, 5, -524301, 786432, 5, -655372, 786432, 4, -589836, 786432, 5, -524300, 786432, 5, -655371, 786432, 4, -589835, 786432, 5, -524299, 786432, 5, -655370, 786432, 4, -589834, 786432, 5, -524298, 786432, 5, -655369, 786432, 4, -589833, 786432, 5, -524297, 786432, 5, -655368, 851968, 4, -589832, 851968, 5, -524296, 851968, 5, -327697, 720896, 5, -327696, 786432, 5, -327695, 786432, 5, -327694, 786432, 5, -327693, 786432, 5, -327692, 786432, 5, -327691, 786432, 5, -327690, 786432, 5, -327689, 786432, 5, -327688, 851968, 5, -262161, 720896, 5, -262160, 786432, 5, -262159, 786432, 5, -262158, 786432, 5, -262157, 786432, 5, -262156, 786432, 5, -262155, 786432, 5, -262154, 786432, 5, -262153, 786432, 5, -262152, 851968, 5, -196625, 720896, 5, -196624, 786432, 5, -196623, 786432, 5, -196622, 786432, 5, -196621, 786432, 5, -196620, 786432, 5, -196619, 786432, 5, -196618, 786432, 5, -196617, 786432, 5, -196616, 851968, 5, 20, 786432, 4, 65556, 786432, 5, 131092, 786432, 5, 196628, 786432, 5, 262164, 786432, 5, 327700, 786432, 5, 21, 786432, 4, 65557, 786432, 5, 131093, 786432, 5, 196629, 786432, 5, 262165, 786432, 5, 327701, 786432, 5, 22, 786432, 4, 65558, 786432, 5, 131094, 786432, 5, 196630, 786432, 5, 262166, 786432, 5, 327702, 786432, 5, 23, 786432, 4, 65559, 786432, 5, 131095, 786432, 5, 196631, 786432, 5, 262167, 786432, 5, 327703, 786432, 5, 24, 786432, 4, 65560, 786432, 5, 131096, 786432, 5, 196632, 786432, 5, 262168, 786432, 5, 327704, 786432, 5, 25, 786432, 4, 65561, 786432, 5, 131097, 786432, 5, 196633, 786432, 5, 262169, 786432, 5, 327705, 786432, 5, 26, 786432, 4, 65562, 786432, 5, 131098, 786432, 5, 196634, 786432, 5, 262170, 786432, 5, 327706, 786432, 5, 27, 786432, 4, 65563, 786432, 5, 131099, 786432, 5, 196635, 786432, 5, 262171, 786432, 5, 327707, 786432, 5, -65498, 917504, 3, 38, 786432, 4, 65574, 786432, 5, 131110, 786432, 5, 196646, 786432, 5, 262182, 786432, 5, 327718, 786432, 5, 39, 786432, 4, 65575, 786432, 5, 131111, 786432, 5, 196647, 786432, 5, 262183, 786432, 5, 327719, 786432, 5, -65496, 983040, 3, 40, 786432, 4, 65576, 786432, 5, 131112, 786432, 5, 196648, 786432, 5, 262184, 786432, 5, 327720, 786432, 5, -65495, 983040, 3, 41, 786432, 4, 65577, 786432, 5, 131113, 786432, 5, 196649, 786432, 5, 262185, 786432, 5, 327721, 786432, 5, -65494, 983040, 3, 42, 786432, 4, 65578, 786432, 5, 131114, 786432, 5, 196650, 786432, 5, 262186, 786432, 5, 327722, 786432, 5, -65493, 983040, 3, 43, 786432, 4, 65579, 786432, 5, 131115, 786432, 5, 196651, 786432, 5, 262187, 786432, 5, 327723, 786432, 5, -65492, 983040, 3, 44, 786432, 4, 65580, 786432, 5, 131116, 786432, 5, 196652, 786432, 5, 262188, 786432, 5, 327724, 786432, 5, -65491, 983040, 3, 45, 786432, 4, 65581, 786432, 5, 131117, 786432, 5, 196653, 786432, 5, 262189, 786432, 5, 327725, 786432, 5, -65490, 983040, 3, 46, 786432, 4, 65582, 786432, 5, 131118, 786432, 5, 196654, 786432, 5, 262190, 786432, 5, 327726, 786432, 5, -65489, 983040, 3, 47, 786432, 4, 65583, 786432, 5, 131119, 786432, 5, 196655, 786432, 5, 262191, 786432, 5, 327727, 786432, 5, -65488, 1048576, 3, 48, 786432, 4, 65584, 786432, 5, 131120, 786432, 5, 196656, 786432, 5, 262192, 786432, 5, 327728, 786432, 5, 49, 851968, 4, 65585, 851968, 5, 131121, 851968, 5, 196657, 851968, 5, 262193, 851968, 5, 327729, 851968, 5, -65497, 983040, 3, -589774, 720896, 4, -524238, 720896, 5, -458702, 720896, 5, -393166, 720896, 5, -327630, 720896, 5, -262094, 720896, 5, -196558, 720896, 5, -131022, 720896, 5, -65486, 720896, 5, 50, 720896, 5, 65586, 720896, 5, 131122, 720896, 5, 196658, 720896, 5, 262194, 720896, 5, 327730, 720896, 5, -589773, 786432, 4, -524237, 786432, 5, -458701, 786432, 5, -393165, 786432, 5, -327629, 786432, 5, -262093, 786432, 5, -196557, 786432, 5, -131021, 786432, 5, -65485, 786432, 5, 51, 786432, 5, 65587, 786432, 5, 131123, 786432, 5, 196659, 786432, 5, 262195, 786432, 5, 327731, 786432, 5, -589772, 786432, 4, -524236, 786432, 5, -458700, 786432, 5, -393164, 786432, 5, -327628, 786432, 5, -262092, 786432, 5, -196556, 786432, 5, -131020, 786432, 5, -65484, 786432, 5, 52, 786432, 5, 65588, 786432, 5, 131124, 786432, 5, 196660, 786432, 5, 262196, 786432, 5, 327732, 786432, 5, -589771, 786432, 4, -524235, 786432, 5, -458699, 786432, 5, -393163, 786432, 5, -327627, 786432, 5, -262091, 786432, 5, -196555, 786432, 5, -131019, 786432, 5, -65483, 786432, 5, 53, 786432, 5, 65589, 786432, 5, 131125, 786432, 5, 196661, 786432, 5, 262197, 786432, 5, 327733, 786432, 5, -589770, 786432, 4, -524234, 786432, 5, -458698, 786432, 5, -393162, 786432, 5, -327626, 786432, 5, -262090, 786432, 5, -196554, 786432, 5, -131018, 786432, 5, -65482, 786432, 5, 54, 786432, 5, 65590, 786432, 5, 131126, 786432, 5, 196662, 786432, 5, 262198, 786432, 5, 327734, 786432, 5, -589769, 786432, 4, -524233, 786432, 5, -458697, 786432, 5, -393161, 786432, 5, -327625, 786432, 5, -262089, 786432, 5, -196553, 786432, 5, -131017, 786432, 5, -65481, 786432, 5, 55, 786432, 5, 65591, 786432, 5, 131127, 786432, 5, 196663, 786432, 5, 262199, 786432, 5, 327735, 786432, 5, -589768, 786432, 4, -524232, 786432, 5, -458696, 786432, 5, -393160, 786432, 5, -327624, 786432, 5, -262088, 786432, 5, -196552, 786432, 5, -131016, 786432, 5, -65480, 786432, 5, 56, 786432, 5, 65592, 786432, 5, 131128, 786432, 5, 196664, 786432, 5, 262200, 786432, 5, 327736, 786432, 5, -589767, 786432, 4, -524231, 786432, 5, -458695, 786432, 5, -393159, 786432, 5, -327623, 786432, 5, -262087, 786432, 5, -196551, 786432, 5, -131015, 786432, 5, -65479, 786432, 5, 57, 786432, 5, 65593, 786432, 5, 131129, 786432, 5, 196665, 786432, 5, 262201, 786432, 5, 327737, 786432, 5, -589766, 786432, 4, -524230, 786432, 5, -458694, 786432, 5, -393158, 786432, 5, -327622, 786432, 5, -262086, 786432, 5, -196550, 786432, 5, -131014, 786432, 5, -65478, 786432, 5, 58, 786432, 5, 65594, 786432, 5, 131130, 786432, 5, 196666, 786432, 5, 262202, 786432, 5, 327738, 786432, 5, -589765, 851968, 4, -524229, 851968, 5, -458693, 851968, 5, -393157, 851968, 5, -327621, 851968, 5, -262085, 851968, 5, -196549, 851968, 5, -131013, 851968, 5, -65477, 851968, 5, 59, 851968, 5, 65595, 851968, 5, 131131, 851968, 5, 196667, 851968, 5, 262203, 851968, 5, 327739, 851968, 5, 28, 786432, 4, 65564, 786432, 5, 131100, 786432, 5, 196636, 786432, 5, 262172, 786432, 5, 327708, 786432, 5, 29, 786432, 4, 65565, 786432, 5, 131101, 786432, 5, 196637, 786432, 5, 262173, 786432, 5, 327709, 786432, 5, 30, 786432, 4, 65566, 786432, 5, 131102, 786432, 5, 196638, 786432, 5, 262174, 786432, 5, 327710, 786432, 5, 31, 786432, 4, 65567, 786432, 5, 131103, 786432, 5, 196639, 786432, 5, 262175, 786432, 5, 327711, 786432, 5, 32, 786432, 4, 65568, 786432, 5, 131104, 786432, 5, 196640, 786432, 5, 262176, 786432, 5, 327712, 786432, 5, 33, 786432, 4, 65569, 786432, 5, 131105, 786432, 5, 196641, 786432, 5, 262177, 786432, 5, 327713, 786432, 5, 34, 786432, 4, 65570, 786432, 5, 131106, 786432, 5, 196642, 786432, 5, 262178, 786432, 5, 327714, 786432, 5, 35, 786432, 4, 65571, 786432, 5, 131107, 786432, 5, 196643, 786432, 5, 262179, 786432, 5, 327715, 786432, 5, 36, 786432, 4, 65572, 786432, 5, 131108, 786432, 5, 196644, 786432, 5, 262180, 786432, 5, 327716, 786432, 5, 37, 786432, 4, 65573, 786432, 5, 131109, 786432, 5, 196645, 786432, 5, 262181, 786432, 5, 327717, 786432, 5, -65487, 458752, 6, -131023, 458752, 5, -196559, 458752, 5, -262095, 458752, 5, -327631, 458752, 5, -393167, 458752, 5, -458703, 458752, 5, -524239, 458752, 5, -589775, 458752, 4) + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_v5qg2")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_oqmwp")] +unique_name_in_owner = true +visible = false + +[node name="CharacterBody2D" parent="." instance=ExtResource("5_pr2x5")] +unique_name_in_owner = true +position = Vector2(66, -28) + +[node name="RoomLeftPhantomCamera2D" type="Node2D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +top_level = true +position = Vector2(66, -91.205) +script = ExtResource("4_4b648") +priority = 5 +follow_mode = 2 +follow_target = NodePath("../CharacterBody2D/PlayerVisuals") +zoom = Vector2(2, 2) +tween_resource = SubResource("Resource_ct1eh") +follow_offset = Vector2(0, -63.205) +follow_damping = true +draw_limits = true +limit_target = NodePath("../TileMap") +limit_margin = Vector4i(-50, 0, -50, 0) + +[node name="RoomLeftArea2D" type="Area2D" parent="."] +unique_name_in_owner = true +position = Vector2(117, -174) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomLeftArea2D"] +position = Vector2(-79, 43) +shape = SubResource("RectangleShape2D_xmxri") +debug_color = Color(0, 0.6, 0.701961, 0.0313726) + +[node name="RoomCentrePhantomCamera2D" type="Node2D" parent="."] +unique_name_in_owner = true +top_level = true +position = Vector2(1474, -149) +script = ExtResource("4_4b648") +follow_mode = 2 +zoom = Vector2(1.5, 1.5) +tween_resource = SubResource("Resource_exr3j") +follow_damping = true +draw_limits = true +limit_target = NodePath("../RoomCentreArea2D/CollisionShape2D") + +[node name="RoomCentreArea2D" type="Area2D" parent="."] +unique_name_in_owner = true +position = Vector2(755, -179) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomCentreArea2D"] +position = Vector2(338, -28) +shape = SubResource("RectangleShape2D_wtfjw") +debug_color = Color(0, 0.6, 0.701961, 0) + +[node name="RoomRightArea2D" type="Area2D" parent="."] +unique_name_in_owner = true +position = Vector2(2065, -160) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomRightArea2D"] +position = Vector2(255.75, -3.25) +shape = SubResource("RectangleShape2D_daeuh") +debug_color = Color(0, 0.6, 0.701961, 0) + +[node name="RoomRightPhantomCamera2D" type="Node2D" parent="."] +unique_name_in_owner = true +top_level = true +position = Vector2(2347, -156) +scale = Vector2(1.0024, 1) +script = ExtResource("4_4b648") +follow_mode = 2 +zoom = Vector2(2, 2) +tween_resource = SubResource("Resource_exr3j") +follow_damping = true +draw_limits = true + +[node name="Camera2D" type="Camera2D" parent="."] +position = Vector2(66, -91.205) +zoom = Vector2(2, 2) +process_callback = 0 +limit_left = -387 +limit_top = -528 +limit_right = 433 +limit_bottom = 288 +position_smoothing_speed = 10.0 +editor_draw_limits = true + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("9_w5e16") + +[editable path="CharacterBody2D"] diff --git a/addons/phantom_camera/examples/example_scenes/2D/2d_tweening_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/2D/2d_tweening_example_scene.tscn new file mode 100644 index 0000000..24f2f3b --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D/2d_tweening_example_scene.tscn @@ -0,0 +1,397 @@ +[gd_scene load_steps=19 format=3 uid="uid://cpyb3ucwcqj8l"] + +[ext_resource type="Texture2D" uid="uid://c77npili4pel4" path="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" id="1_oo2bo"] +[ext_resource type="PackedScene" uid="uid://dg7rhrymsrrrm" path="res://addons/phantom_camera/examples/ui/ui_inventory.tscn" id="2_as4e6"] +[ext_resource type="PackedScene" uid="uid://iq5xd1ob1res" path="res://addons/phantom_camera/examples/ui/ui_sign.tscn" id="3_6yi7w"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="4_bb7en"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="5_kikl5"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="6_8u8cj"] +[ext_resource type="Resource" uid="uid://euybd2w0bax" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres" id="6_gu0o0"] +[ext_resource type="PackedScene" uid="uid://7kh0xydx0b1o" path="res://addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn" id="8_g1syc"] +[ext_resource type="Script" uid="uid://t8wa4e5y5hcf" path="res://addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd" id="9_184pu"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="11_myq47"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_easgx"] +texture = ExtResource("1_oo2bo") +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:1/0 = 0 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +7:1/0 = 0 +7:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +7:2/0 = 0 +7:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +4:3/0 = 0 +7:3/0 = 0 +7:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:4/0 = 0 +4:4/0 = 0 +5:4/0 = 0 +7:4/0 = 0 +3:5/0 = 0 +4:5/0 = 0 +7:5/0 = 0 +3:6/0 = 0 +4:6/0 = 0 +7:6/0 = 0 +2:7/0 = 0 +3:7/0 = 0 +4:7/0 = 0 +5:7/0 = 0 +8:0/0 = 0 +8:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:0/0 = 0 +9:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:0/0 = 0 +10:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:0/0 = 0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:0/0 = 0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:0/0 = 0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:0/0 = 0 +14:0/0/physics_layer_1/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8) +14:0/0/custom_data_0 = &"Sign" +15:0/0 = 0 +16:0/0 = 0 +8:1/0 = 0 +8:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:1/0 = 0 +9:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:1/0 = 0 +10:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:1/0 = 0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:1/0 = 0 +12:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:1/0 = 0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:1/0 = 0 +15:1/0 = 0 +16:1/0 = 0 +8:2/0 = 0 +8:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:2/0 = 0 +9:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:2/0 = 0 +10:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:2/0 = 0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:2/0 = 0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:2/0 = 0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:2/0 = 0 +15:2/0 = 0 +16:2/0 = 0 +8:3/0 = 0 +8:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +9:3/0 = 0 +9:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +10:3/0 = 0 +10:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +11:3/0 = 0 +12:3/0 = 0 +12:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:3/0 = 0 +13:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:3/0 = 0 +15:3/0 = 0 +16:3/0 = 0 +8:4/0 = 0 +9:4/0 = 0 +10:4/0 = 0 +11:4/0 = 0 +11:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-7, 2.5, -5, -2, -2.5, -5, 2, -7, 8, -8, 8, 8, -8, 8) +12:4/0 = 0 +12:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:4/0 = 0 +13:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -6, 4, -1.5, 6.5, 1.5, 8, 8, -8, 8) +14:4/0 = 0 +14:4/0/physics_layer_1/polygon_0/points = PackedVector2Array(-8, -8, -8, 8, 8, 8, 8, -8) +14:4/0/custom_data_0 = &"Inventory" +15:4/0 = 0 +16:4/0 = 0 +8:5/0 = 0 +9:5/0 = 0 +10:5/0 = 0 +11:5/0 = 0 +11:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +12:5/0 = 0 +12:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:5/0 = 0 +13:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +14:5/0 = 0 +15:5/0 = 0 +16:5/0 = 0 +8:6/0 = 0 +9:6/0 = 0 +10:6/0 = 0 +11:6/0 = 0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, 1, 6.5, -3, 3, -6.5, -1.5) +12:6/0 = 0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +13:6/0 = 0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 6, -0.5, 3, 3.5, -1.5, 6.5, -8, 8) +14:6/0 = 0 +15:6/0 = 0 +16:6/0 = 0 +5:3/0 = 0 + +[sub_resource type="TileSet" id="TileSet_kf7eg"] +physics_layer_0/collision_layer = 1 +physics_layer_1/collision_layer = 2 +physics_layer_1/collision_mask = 2 +custom_data_layer_0/name = "Type" +custom_data_layer_0/type = 21 +sources/0 = SubResource("TileSetAtlasSource_easgx") + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_tgk1y"] +size = Vector2(140, 160) + +[sub_resource type="Resource" id="Resource_mtp70"] +script = ExtResource("6_8u8cj") +duration = 0.6 +transition = 1 +ease = 2 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_clm0y"] +size = Vector2(104, 160) + +[sub_resource type="Resource" id="Resource_8jg5c"] +script = ExtResource("6_8u8cj") +duration = 0.3 +transition = 8 +ease = 2 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_uka0w"] +size = Vector2(560, 160) + +[sub_resource type="Resource" id="Resource_e4e41"] +script = ExtResource("6_8u8cj") +duration = 1.2 +transition = 10 +ease = 2 + +[node name="ExampleScene2D" type="Node2D"] + +[node name="Background" type="CanvasLayer" parent="."] +layer = -3 + +[node name="ColorRect" type="ColorRect" parent="Background"] +auto_translate_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -311.0 +offset_top = -173.0 +offset_right = 981.0 +offset_bottom = 548.0 +grow_horizontal = 2 +grow_vertical = 2 +localize_numeral_system = false +color = Color(0.137255, 0.14902, 0.196078, 1) + +[node name="TileMap" type="TileMap" parent="."] +z_index = -1 +scale = Vector2(3, 3) +tile_set = SubResource("TileSet_kf7eg") +format = 2 +layer_0/name = "Background" +layer_0/tile_data = PackedInt32Array(-393216, 655360, 2, -327680, 655360, 3, -262144, 655360, 3, -196608, 655360, 3, -131072, 655360, 3, -65536, 655360, 3, -393215, 720896, 2, -327679, 720896, 1, -262143, 720896, 1, -196607, 720896, 1, -131071, 720896, 1, -65535, 720896, 1, -393214, 786432, 2, -327678, 786432, 3, -262142, 786432, 3, -196606, 786432, 3, -131070, 786432, 3, -65534, 786432, 3) +layer_1/name = "Terrain" +layer_1/z_index = 1 +layer_1/tile_data = PackedInt32Array(1, 720896, 0, 2, 720896, 0, 3, 720896, 0, 4, 720896, 0, 5, 720896, 0, 6, 720896, 0, 7, 720896, 0, 8, 720896, 0, 9, 786432, 0, 65545, 786432, 1, 131081, 786432, 1, 196617, 786432, 1, 262153, 786432, 1, 327689, 786432, 1, 393225, 786432, 1, 65537, 720896, 1, 131073, 720896, 1, 196609, 720896, 1, 262145, 458752, 1, 327681, 720896, 1, 393217, 720896, 1, 65538, 720896, 1, 131074, 720896, 1, 196610, 720896, 1, 262146, 720896, 1, 327682, 720896, 1, 393218, 720896, 1, 65539, 720896, 1, 131075, 720896, 1, 196611, 720896, 1, 262147, 720896, 1, 327683, 720896, 1, 393219, 720896, 1, 65540, 458752, 1, 131076, 720896, 1, 196612, 720896, 1, 262148, 720896, 1, 327684, 720896, 1, 393220, 720896, 1, 65541, 720896, 1, 131077, 720896, 1, 196613, 720896, 1, 262149, 458752, 1, 327685, 720896, 1, 393221, 720896, 1, 65542, 720896, 1, 131078, 720896, 1, 196614, 720896, 1, 262150, 720896, 1, 327686, 720896, 1, 393222, 720896, 1, 65543, 720896, 1, 131079, 720896, 1, 196615, 720896, 1, 262151, 720896, 1, 327687, 720896, 1, 393223, 458752, 1, 65544, 720896, 1, 131080, 720896, 1, 196616, 458752, 1, 262152, 720896, 1, 327688, 720896, 1, 393224, 720896, 1, 65546, 524288, 5, 65547, 524288, 5, 65548, 524288, 5, 65549, 524288, 5, 131082, 524288, 6, 131083, 524288, 6, 131084, 524288, 6, 131085, 524288, 6, 196618, 720896, 1, 262154, 720896, 1, 196619, 720896, 1, 262155, 720896, 1, 196620, 720896, 1, 262156, 720896, 1, 196621, 720896, 1, 262157, 720896, 1, 65550, 524288, 5, 65551, 524288, 5, 65552, 524288, 5, 131086, 524288, 6, 131087, 524288, 6, 131088, 524288, 6, 196622, 720896, 1, 196623, 720896, 1, 262159, 720896, 1, 262160, 720896, 1, 196624, 720896, 1, 262158, 720896, 1, 17, 720896, 4, 65553, 720896, 5, 131089, 720896, 5, 196625, 720896, 5, 262161, 720896, 5, 18, 786432, 4, 19, 786432, 4, 20, 786432, 4, 21, 786432, 4, 22, 786432, 4, 23, 786432, 4, 65554, 786432, 5, 131090, 786432, 5, 196626, 786432, 5, 262162, 786432, 5, 65555, 786432, 5, 131091, 589824, 6, 196627, 786432, 5, 262163, 786432, 5, 65556, 786432, 5, 131092, 786432, 5, 196628, 786432, 5, 262164, 786432, 5, 65557, 786432, 5, 131093, 786432, 5, 196629, 786432, 5, 262165, 786432, 5, 65558, 786432, 5, 131094, 786432, 5, 196630, 786432, 5, 262166, 655360, 6, 65559, 786432, 5, 131095, 786432, 5, 196631, 786432, 5, 262167, 786432, 5, 327697, 720896, 5, 393233, 720896, 5, 327698, 589824, 6, 393234, 786432, 5, 327699, 786432, 5, 393235, 786432, 5, 327700, 786432, 5, 393236, 786432, 5, 327701, 786432, 5, 393237, 786432, 5, 327702, 786432, 5, 393238, 786432, 5, 327703, 786432, 5, 393239, 786432, 5, -131062, 720896, 4, -131061, 786432, 4, -131060, 786432, 4, -65526, 720896, 6, -65525, 786432, 6, -65524, 786432, 6, -131056, 851968, 4, -65520, 851968, 6, -131059, 786432, 4, -131058, 786432, 4, -131057, 786432, 4, -65523, 786432, 6, -65522, 786432, 6, -65521, 786432, 6, -65536, 917504, 2, -65535, 983040, 2, -65534, 1048576, 2, -65533, 917504, 2, -65532, 983040, 2, -65531, 1048576, 2, -65530, 917504, 2, -65529, 983040, 2, -65528, 1048576, 2, 65535, 655360, 0, 131071, 655360, 1, 196607, 655360, 1, 262143, 655360, 1, 327679, 655360, 1, 393215, 655360, 1, 458751, 655360, 1, 524287, 655360, 1, 589823, 655360, 1, 0, 720896, 0, 65536, 720896, 1, 131072, 720896, 1, 196608, 720896, 1, 262144, 720896, 1, 327680, 720896, 1, 393216, 720896, 1, 458752, 720896, 1, 524288, 720896, 1, 524289, 720896, 1, 524290, 720896, 1, 524291, 720896, 1, 524292, 720896, 1, 524293, 720896, 1, 524294, 720896, 1, 524295, 720896, 1, 524296, 720896, 1, 524297, 786432, 1, 458761, 786432, 1, 458760, 720896, 1, 458759, 720896, 1, 458758, 458752, 1, 458757, 720896, 1, 458756, 720896, 1, 458755, 720896, 1, 458754, 720896, 1, 458753, 720896, 1, -262145, 851968, 4, -196609, 851968, 5, -131073, 851968, 5, -65537, 851968, 5, -1, 851968, 6, -262146, 786432, 4, -262147, 786432, 4, -196610, 589824, 6, -196611, 786432, 5, -6, 786432, 5, -5, 786432, 5, -4, 786432, 5, -3, 786432, 5, -2, 786432, 5, -65538, 786432, 5, -131074, 786432, 5, -131075, 786432, 5, -65539, 655360, 6, 65534, 851968, 5, 131070, 851968, 5, 196606, 851968, 5, 262142, 851968, 5, 327678, 851968, 5, 393214, 851968, 5, 458750, 851968, 5, 65533, 786432, 5, 65532, 786432, 5, 65531, 786432, 5, 65530, 786432, 5, 65529, 720896, 5, 131066, 786432, 5, 196602, 786432, 5, 262138, 786432, 5, 262139, 786432, 5, 327675, 786432, 5, 131068, 786432, 5, 131069, 786432, 5, 196605, 786432, 5, 262141, 786432, 5, 327677, 786432, 5, 393213, 786432, 5, 458749, 786432, 5, 393212, 786432, 5, 393211, 786432, 5, 458748, 786432, 5, 327676, 655360, 6, 262140, 786432, 5, 196604, 786432, 5, 131067, 786432, 5, 196603, 589824, 6, 458747, 786432, 5, 458746, 786432, 5, 393210, 786432, 5, 327674, 786432, 5, -7, 720896, 5, 131065, 720896, 5, 196601, 720896, 5, 262137, 720896, 5, 327673, 720896, 5, 393209, 720896, 5, 458745, 720896, 5, -327684, 720896, 3, -196594, 720896, 3, -196597, 720896, 3, -65518, 720896, 3, -65516, 720896, 3, -327686, 1048576, 5, -327685, 720896, 3, -196595, 917504, 6, -65514, 983040, 6, -327683, 983040, 5, -65513, 1048576, 5, -262151, 720896, 4, -196615, 720896, 5, -131079, 720896, 5, -65543, 720896, 5, -262150, 786432, 4, -196614, 655360, 6, -131078, 786432, 5, -65542, 786432, 5, -262149, 786432, 4, -196613, 786432, 5, -131077, 786432, 5, -65541, 786432, 5, -262148, 786432, 4, -196612, 786432, 5, -131076, 786432, 5, -65540, 786432, 5, 458769, 720896, 5, 458775, 786432, 5, 458774, 786432, 5, 458773, 786432, 5, 458772, 786432, 5, 458771, 786432, 5, 458770, 786432, 5, 327690, 720896, 1, 393226, 720896, 1, 458762, 720896, 1, 524298, 720896, 1, 327691, 720896, 1, 393227, 720896, 1, 458763, 720896, 1, 524299, 720896, 1, 327692, 720896, 1, 393228, 720896, 1, 458764, 720896, 1, 524300, 720896, 1, 327693, 720896, 1, 393229, 720896, 1, 458765, 720896, 1, 524301, 720896, 1, 327694, 720896, 1, 393230, 720896, 1, 458766, 720896, 1, 524302, 720896, 1, 327695, 720896, 1, 393231, 720896, 1, 458767, 720896, 1, 524303, 720896, 1, 327696, 720896, 1, 393232, 720896, 1, 458768, 720896, 1, 524304, 720896, 1, 29, 851968, 4, 65565, 851968, 5, 131101, 851968, 5, 196637, 851968, 5, 262173, 851968, 5, 327709, 851968, 5, 393245, 851968, 5, 458781, 851968, 5, 24, 786432, 4, 25, 786432, 4, 26, 786432, 4, 27, 786432, 4, 28, 786432, 4, 65560, 786432, 5, 65561, 786432, 5, 65562, 786432, 5, 65563, 786432, 5, 65564, 786432, 5, 131100, 786432, 5, 196636, 589824, 6, 131099, 786432, 5, 131098, 786432, 5, 131097, 786432, 5, 131096, 786432, 5, 196632, 786432, 5, 262168, 786432, 5, 327704, 786432, 5, 393240, 786432, 5, 458776, 786432, 5, 196633, 786432, 5, 262169, 786432, 5, 327705, 786432, 5, 393241, 786432, 5, 458777, 786432, 5, 196634, 786432, 5, 262170, 786432, 5, 327706, 786432, 5, 393242, 655360, 6, 458778, 786432, 5, 196635, 786432, 5, 262171, 786432, 5, 327707, 786432, 5, 393243, 786432, 5, 458779, 786432, 5, 262172, 786432, 5, 327708, 786432, 5, 393244, 786432, 5, 458780, 786432, 5, -196593, 1048576, 6, -393182, 1048576, 6, -393185, 917504, 6, -393180, 983040, 6, -393184, 983040, 5, -65509, 720896, 3, -65510, 720896, 3, -393181, 720896, 3, -393183, 720896, 3, -65517, 720896, 3, -65515, 720896, 3, -327650, 720896, 4, -262114, 720896, 5, -196578, 720896, 5, -131042, 720896, 5, -65506, 720896, 5, -327649, 786432, 4, -327648, 786432, 4, -327647, 786432, 4, -327646, 786432, 4, -327645, 786432, 4, -327644, 786432, 4, -327643, 786432, 4, -65499, 786432, 5, -131035, 786432, 5, -196571, 786432, 5, -262107, 655360, 6, -262108, 786432, 5, -262109, 786432, 5, -262110, 786432, 5, -262111, 786432, 5, -262112, 786432, 5, -262113, 786432, 5, -196577, 655360, 6, -131041, 786432, 5, -65505, 786432, 5, -65500, 655360, 6, -131036, 589824, 6, -196572, 786432, 5, -196573, 786432, 5, -196574, 786432, 5, -196575, 786432, 5, -196576, 786432, 5, -131040, 589824, 6, -65504, 786432, 5, -65501, 786432, 5, -131037, 786432, 5, -131038, 786432, 5, -131039, 786432, 5, -65503, 786432, 5, -65502, 786432, 5, 524318, 720896, 6, 458782, 720896, 5, 393246, 720896, 5, 327710, 720896, 5, 262174, 720896, 5, 196638, 720896, 5, 131102, 720896, 5, 65566, 720896, 5, 30, 720896, 5, 524319, 786432, 6, 524320, 786432, 6, 524321, 786432, 6, 524322, 786432, 6, 524323, 786432, 6, 524324, 786432, 6, 524325, 786432, 6, 31, 786432, 5, 65567, 786432, 5, 131103, 786432, 5, 196639, 786432, 5, 262175, 786432, 5, 327711, 786432, 5, 393247, 655360, 6, 458783, 786432, 5, 32, 786432, 5, 65568, 786432, 5, 131104, 786432, 5, 196640, 786432, 5, 262176, 786432, 5, 327712, 786432, 5, 393248, 786432, 5, 458784, 786432, 5, 33, 786432, 5, 65569, 786432, 5, 131105, 655360, 6, 196641, 786432, 5, 262177, 786432, 5, 327713, 786432, 5, 393249, 786432, 5, 458785, 786432, 5, 34, 786432, 5, 65570, 786432, 5, 131106, 786432, 5, 196642, 786432, 5, 262178, 655360, 6, 327714, 655360, 6, 393250, 786432, 5, 458786, 786432, 5, 35, 786432, 5, 65571, 786432, 5, 131107, 786432, 5, 196643, 786432, 5, 262179, 786432, 5, 327715, 786432, 5, 393251, 786432, 5, 458787, 786432, 5, 36, 655360, 6, 65572, 786432, 5, 131108, 786432, 5, 196644, 786432, 5, 262180, 786432, 5, 327716, 786432, 5, 393252, 786432, 5, 458788, 655360, 6, 37, 786432, 5, 65573, 786432, 5, 131109, 786432, 5, 196645, 786432, 5, 262181, 655360, 6, 327717, 786432, 5, 393253, 786432, 5, 458789, 786432, 5, 524281, 720896, 5, 524285, 786432, 5, 524284, 786432, 5, 524283, 786432, 5, 524282, 786432, 5, 589818, 786432, 5, 589819, 786432, 5, 589820, 786432, 5, 655356, 786432, 5, 655357, 786432, 5, 589821, 786432, 5, 655355, 786432, 5, 655354, 786432, 5, 720890, 786432, 5, 720891, 786432, 5, 720892, 786432, 5, 720893, 786432, 5, 720894, 851968, 5, 786429, 786432, 5, 786428, 786432, 5, 786427, 786432, 5, 786426, 786432, 5, 851962, 786432, 5, 917498, 786432, 5, 917499, 786432, 5, 851964, 786432, 5, 851965, 786432, 5, 917501, 786432, 5, 917500, 786432, 5, 851963, 786432, 5, 589817, 720896, 5, 655353, 720896, 5, 720889, 720896, 5, 786425, 720896, 5, 851961, 720896, 5, 917497, 720896, 5, 524286, 851968, 5, 589822, 851968, 5, 655358, 851968, 5, 786430, 851968, 5, 851966, 851968, 5, 917502, 851968, 5, 589824, 720896, 1, 655360, 720896, 1, 720896, 720896, 1, 786432, 720896, 1, 851968, 720896, 1, 589825, 720896, 1, 655361, 720896, 1, 720897, 720896, 1, 786433, 720896, 1, 851969, 720896, 1, 589826, 720896, 1, 655362, 720896, 1, 720898, 720896, 1, 786434, 720896, 1, 851970, 720896, 1, 589827, 720896, 1, 655363, 720896, 1, 720899, 720896, 1, 786435, 720896, 1, 851971, 720896, 1, 589828, 720896, 1, 655364, 720896, 1, 720900, 720896, 1, 786436, 720896, 1, 851972, 720896, 1, 589829, 720896, 1, 655365, 720896, 1, 720901, 720896, 1, 786437, 720896, 1, 851973, 720896, 1, 589830, 720896, 1, 655366, 720896, 1, 720902, 720896, 1, 786438, 720896, 1, 851974, 720896, 1, 589831, 720896, 1, 655367, 720896, 1, 720903, 720896, 1, 786439, 720896, 1, 851975, 720896, 1, 589832, 720896, 1, 655368, 720896, 1, 720904, 720896, 1, 786440, 720896, 1, 851976, 720896, 1, 589833, 786432, 1, 655369, 786432, 1, 720905, 786432, 1, 786441, 786432, 1, 851977, 786432, 1, 655359, 655360, 1, 720895, 655360, 1, 786431, 655360, 1, 851967, 655360, 1, 917503, 655360, 1, 589834, 720896, 1, 655370, 720896, 1, 720906, 720896, 1, 786442, 720896, 1, 851978, 720896, 1, 589835, 720896, 1, 655371, 720896, 1, 720907, 720896, 1, 786443, 720896, 1, 851979, 720896, 1, 589836, 720896, 1, 655372, 720896, 1, 720908, 720896, 1, 786444, 720896, 1, 851980, 720896, 1, 589837, 720896, 1, 655373, 720896, 1, 720909, 720896, 1, 786445, 720896, 1, 851981, 720896, 1, 589838, 720896, 1, 655374, 720896, 1, 720910, 720896, 1, 786446, 720896, 1, 851982, 720896, 1, 589839, 720896, 1, 655375, 720896, 1, 720911, 720896, 1, 786447, 720896, 1, 851983, 720896, 1, 589840, 720896, 1, 655376, 720896, 1, 720912, 720896, 1, 786448, 720896, 1, 851984, 720896, 1, 851985, 720896, 6, 851986, 786432, 6, 851987, 786432, 6, 851988, 786432, 6, 851989, 786432, 6, 851990, 786432, 6, 851991, 786432, 6, 851992, 786432, 6, 851993, 786432, 6, 851994, 786432, 6, 851995, 786432, 6, 851996, 786432, 6, 851997, 851968, 6, 524306, 786432, 5, 589842, 786432, 5, 655378, 786432, 5, 720914, 786432, 5, 786450, 786432, 5, 524307, 786432, 5, 589843, 786432, 5, 655379, 786432, 5, 720915, 786432, 5, 786451, 786432, 5, 524308, 786432, 5, 589844, 786432, 5, 655380, 786432, 5, 720916, 786432, 5, 786452, 786432, 5, 524309, 786432, 5, 589845, 786432, 5, 655381, 786432, 5, 720917, 786432, 5, 786453, 786432, 5, 524310, 786432, 5, 589846, 786432, 5, 655382, 786432, 5, 720918, 786432, 5, 786454, 786432, 5, 524311, 786432, 5, 589847, 786432, 5, 655383, 786432, 5, 720919, 786432, 5, 786455, 786432, 5, 524312, 786432, 5, 589848, 786432, 5, 655384, 786432, 5, 720920, 786432, 5, 786456, 786432, 5, 524313, 786432, 5, 589849, 786432, 5, 655385, 786432, 5, 720921, 786432, 5, 786457, 786432, 5, 524314, 786432, 5, 589850, 786432, 5, 655386, 786432, 5, 720922, 786432, 5, 786458, 786432, 5, 524315, 786432, 5, 589851, 786432, 5, 655387, 786432, 5, 720923, 786432, 5, 786459, 786432, 5, 524316, 786432, 5, 589852, 786432, 5, 655388, 786432, 5, 720924, 786432, 5, 786460, 786432, 5, 524305, 720896, 5, 589841, 720896, 5, 655377, 720896, 5, 720913, 720896, 5, 786449, 720896, 5, 524317, 851968, 5, 589853, 851968, 5, 655389, 851968, 5, 720925, 851968, 5, 786461, 851968, 5, -262106, 786432, 5, -196570, 786432, 5, -131034, 786432, 5, -65498, 786432, 5, 38, 786432, 5, 65574, 786432, 5, 131110, 655360, 6, 196646, 786432, 5, 262182, 786432, 5, 327718, 786432, 5, 393254, 786432, 5, 458790, 786432, 5, -262105, 786432, 5, -196569, 786432, 5, -131033, 786432, 5, -65497, 786432, 5, 39, 786432, 5, 65575, 786432, 5, 131111, 786432, 5, 196647, 786432, 5, 262183, 786432, 5, 327719, 786432, 5, 393255, 655360, 6, 458791, 786432, 5, -262104, 786432, 5, -196568, 786432, 5, -131032, 786432, 5, -65496, 786432, 5, 40, 655360, 6, 65576, 786432, 5, 131112, 786432, 5, 196648, 786432, 5, 262184, 655360, 6, 327720, 786432, 5, 393256, 786432, 5, 458792, 786432, 5, -262103, 786432, 5, -196567, 655360, 6, -131031, 786432, 5, -65495, 786432, 5, 41, 786432, 5, 65577, 786432, 5, 131113, 786432, 5, 196649, 786432, 5, 262185, 786432, 5, 327721, 786432, 5, 393257, 786432, 5, 458793, 786432, 5, -262102, 786432, 5, -196566, 786432, 5, -131030, 786432, 5, -65494, 786432, 5, 42, 786432, 5, 65578, 786432, 5, 131114, 655360, 6, 196650, 786432, 5, 262186, 786432, 5, 327722, 786432, 5, 393258, 786432, 5, 458794, 655360, 6, 524326, 786432, 6, 524327, 786432, 6, 524328, 786432, 6, 524329, 786432, 6, 524330, 786432, 6, -327642, 786432, 4, -327641, 786432, 4, -327640, 786432, 4, -327639, 786432, 4, -327638, 786432, 4, -327632, 851968, 4, -262096, 851968, 5, -196560, 851968, 5, -131024, 851968, 5, -65488, 851968, 5, 48, 851968, 5, 65584, 851968, 5, 131120, 851968, 5, 196656, 851968, 5, 262192, 851968, 5, 327728, 851968, 5, 393264, 851968, 5, 458800, 851968, 5, 524336, 851968, 6, -327637, 786432, 4, -327636, 786432, 4, -327635, 786432, 4, -327634, 786432, 4, -327633, 786432, 4, -262101, 786432, 5, -196565, 786432, 5, -131029, 655360, 6, -65493, 786432, 5, 43, 786432, 5, 65579, 786432, 5, 131115, 786432, 5, 196651, 786432, 5, 262187, 786432, 5, 327723, 655360, 6, 393259, 786432, 5, 458795, 786432, 5, -262100, 786432, 5, -196564, 786432, 5, -131028, 786432, 5, -65492, 786432, 5, 44, 655360, 6, 65580, 786432, 5, 131116, 786432, 5, 196652, 786432, 5, 262188, 786432, 5, 327724, 786432, 5, 393260, 786432, 5, 458796, 786432, 5, -262099, 786432, 5, -196563, 786432, 5, -131027, 786432, 5, -65491, 786432, 5, 45, 786432, 5, 65581, 655360, 6, 131117, 786432, 5, 196653, 786432, 5, 262189, 786432, 5, 327725, 786432, 5, 393261, 786432, 5, 458797, 786432, 5, -262098, 655360, 6, -196562, 786432, 5, -131026, 786432, 5, -65490, 786432, 5, 46, 786432, 5, 65582, 786432, 5, 131118, 786432, 5, 196654, 655360, 6, 262190, 786432, 5, 327726, 786432, 5, 393262, 786432, 5, 458798, 655360, 6, -262097, 786432, 5, -196561, 786432, 5, -131025, 786432, 5, -65489, 786432, 5, 47, 786432, 5, 65583, 786432, 5, 131119, 786432, 5, 196655, 786432, 5, 262191, 786432, 5, 327727, 786432, 5, 393263, 786432, 5, 458799, 786432, 5, 524331, 786432, 6, 524332, 786432, 6, 524333, 786432, 6, 524334, 786432, 6, 524335, 786432, 6) + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="UIInventory" parent="UI" instance=ExtResource("2_as4e6")] +unique_name_in_owner = true +visible = false + +[node name="UISign" parent="UI" instance=ExtResource("3_6yi7w")] +unique_name_in_owner = true +visible = false + +[node name="Camera2D" type="Camera2D" parent="."] +position = Vector2(227, -28) +process_callback = 0 +position_smoothing_speed = 10.0 + +[node name="PhantomCameraHost" type="Node" parent="Camera2D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("4_bb7en") + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera2D" type="Node2D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +top_level = true +position = Vector2(227, -28) +script = ExtResource("5_kikl5") +priority = 5 +follow_mode = 2 +follow_target = NodePath("../CharacterBody2D/PlayerVisuals") +tween_resource = ExtResource("6_gu0o0") +tween_on_load = false +follow_damping = true +draw_limits = true + +[node name="Label" type="Label" parent="Player"] +offset_left = 167.0 +offset_top = -132.0 +offset_right = 332.0 +offset_bottom = -68.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("11_myq47") +text = "[WASD] to move +[Space] to jump" + +[node name="CharacterBody2D" parent="Player" instance=ExtResource("8_g1syc")] +position = Vector2(227, -28) + +[node name="WideArea" type="Area2D" parent="." node_paths=PackedStringArray("area_pcam")] +position = Vector2(393, -40) +collision_layer = 2 +collision_mask = 2 +script = ExtResource("9_184pu") +area_pcam = NodePath("PhantomCamera2D") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="WideArea"] +position = Vector2(0, -40) +shape = SubResource("RectangleShape2D_tgk1y") + +[node name="ColorRect" type="ColorRect" parent="WideArea"] +offset_left = -70.0 +offset_top = -120.0 +offset_right = 70.0 +offset_bottom = 40.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +color = Color(0.556863, 0.447059, 0.545098, 0.698039) + +[node name="Label" type="Label" parent="WideArea"] +offset_left = -77.0 +offset_top = -250.0 +offset_right = 76.0 +offset_bottom = -120.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("11_myq47") +text = "Transition Type: +Sine + +Duration: +0.6s" +horizontal_alignment = 1 + +[node name="PhantomCamera2D" type="Node2D" parent="WideArea"] +position = Vector2(4, -100) +script = ExtResource("5_kikl5") +zoom = Vector2(0.8, 0.8) +tween_resource = SubResource("Resource_mtp70") +draw_limits = true + +[node name="UpperZoomArea" type="Area2D" parent="." node_paths=PackedStringArray("area_pcam")] +position = Vector2(649, -135) +collision_layer = 2 +collision_mask = 2 +script = ExtResource("9_184pu") +area_pcam = NodePath("PhantomCamera2D") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="UpperZoomArea"] +position = Vector2(0, -40) +shape = SubResource("RectangleShape2D_clm0y") + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="UpperZoomArea"] +position = Vector2(0, -40) +shape = SubResource("RectangleShape2D_clm0y") + +[node name="ColorRect" type="ColorRect" parent="UpperZoomArea"] +offset_left = -52.0 +offset_top = -120.0 +offset_right = 52.0 +offset_bottom = 40.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +color = Color(0.556863, 0.447059, 0.545098, 0.698039) + +[node name="Label" type="Label" parent="UpperZoomArea"] +offset_left = -74.0 +offset_top = -251.0 +offset_right = 79.0 +offset_bottom = -121.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("11_myq47") +text = "Transition Type: +Circ + +Duration: +0.3s" +horizontal_alignment = 1 + +[node name="PhantomCamera2D" type="Node2D" parent="UpperZoomArea"] +position = Vector2(2, -83) +script = ExtResource("5_kikl5") +zoom = Vector2(2, 2) +tween_resource = SubResource("Resource_8jg5c") +draw_limits = true + +[node name="ForwardArea" type="Area2D" parent="." node_paths=PackedStringArray("area_pcam")] +position = Vector2(1136, -38) +collision_layer = 2 +collision_mask = 2 +script = ExtResource("9_184pu") +area_pcam = NodePath("PhantomCamera2D") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="ForwardArea"] +position = Vector2(0, -42) +shape = SubResource("RectangleShape2D_uka0w") + +[node name="ColorRect" type="ColorRect" parent="ForwardArea"] +offset_left = -280.0 +offset_top = -122.0 +offset_right = 280.0 +offset_bottom = 38.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +color = Color(0.556863, 0.447059, 0.545098, 0.698039) + +[node name="Label" type="Label" parent="ForwardArea"] +offset_left = -76.0 +offset_top = -252.0 +offset_right = 77.0 +offset_bottom = -122.0 +theme_override_colors/font_color = Color(0.294118, 1, 0.631373, 1) +theme_override_fonts/font = ExtResource("11_myq47") +text = "Transition Type: +Back + +Duration: +1.2s" +horizontal_alignment = 1 + +[node name="PhantomCamera2D" type="Node2D" parent="ForwardArea"] +position = Vector2(344, -46) +script = ExtResource("5_kikl5") +zoom = Vector2(0.9, 0.9) +tween_resource = SubResource("Resource_e4e41") +draw_limits = true + +[editable path="Player/CharacterBody2D"] diff --git a/addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn b/addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn new file mode 100644 index 0000000..f0dca01 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/2D/sub_scenes/playable_character_2d.tscn @@ -0,0 +1,120 @@ +[gd_scene load_steps=10 format=3 uid="uid://7kh0xydx0b1o"] + +[ext_resource type="Script" uid="uid://cb46ypjv5p72s" path="res://addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd" id="1_jnc14"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="2_62b2n"] +[ext_resource type="Texture2D" uid="uid://cscjjt55iw2cu" path="res://addons/phantom_camera/examples/textures/2D/player_sprite.svg" id="2_yr8cm"] +[ext_resource type="Script" uid="uid://bhexx6mj1xv3q" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="4_rloon"] +[ext_resource type="Resource" uid="uid://cecrnq0wnkexh" path="res://addons/phantom_camera/examples/resources/tween/item_focus_phantom_camera_2d_tween.tres" id="5_4iyk1"] +[ext_resource type="Resource" uid="uid://cllveybboaqk5" path="res://addons/phantom_camera/examples/resources/tween/inventory_phantom_camera_2d_tween.tres" id="6_2h6fv"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5hryl"] +bg_color = Color(0.85098, 0.894118, 0.937255, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.113725, 0.113725, 0.113725, 1) +corner_radius_top_left = 7 +corner_radius_top_right = 7 +corner_radius_bottom_right = 7 +corner_radius_bottom_left = 7 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_xj4ar"] +size = Vector2(64, 57) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_18i13"] +size = Vector2(64, 57) + +[node name="CharacterBody2D" type="CharacterBody2D"] +script = ExtResource("1_jnc14") + +[node name="DarkOverlay" type="ColorRect" parent="."] +unique_name_in_owner = true +visible = false +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -1000.0 +offset_top = -1000.0 +offset_right = 1000.0 +offset_bottom = 1000.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0, 0, 0, 0.615686) + +[node name="PlayerVisuals" type="Node2D" parent="."] +unique_name_in_owner = true + +[node name="PlayerSprite" type="Sprite2D" parent="PlayerVisuals"] +unique_name_in_owner = true +scale = Vector2(0.5, 0.5) +texture = ExtResource("2_yr8cm") + +[node name="InteractionPrompt" type="Panel" parent="PlayerVisuals"] +unique_name_in_owner = true +visible = false +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -16.0 +offset_top = -66.0 +offset_right = 16.0 +offset_bottom = -34.0 +grow_horizontal = 2 +grow_vertical = 0 +size_flags_vertical = 0 +theme_override_styles/panel = SubResource("StyleBoxFlat_5hryl") + +[node name="Label" type="Label" parent="PlayerVisuals/InteractionPrompt"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -3.0 +offset_bottom = 5.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("2_62b2n") +theme_override_font_sizes/font_size = 26 +text = "F" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(0, -0.5) +shape = SubResource("RectangleShape2D_xj4ar") + +[node name="PlayerArea2D" type="Area2D" parent="."] +unique_name_in_owner = true +collision_layer = 2 +collision_mask = 2 +priority = 20 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerArea2D"] +position = Vector2(0, -0.5) +shape = SubResource("RectangleShape2D_18i13") + +[node name="ItemFocusPhantomCamera2D" type="Node2D" parent="."] +unique_name_in_owner = true +position = Vector2(0, -122) +script = ExtResource("4_rloon") +zoom = Vector2(2, 2) +frame_preview = false +tween_resource = ExtResource("5_4iyk1") +follow_damping_value = Vector2(0, 0) +draw_limits = true + +[node name="InventoryPhantomCamera2D" type="Node2D" parent="."] +unique_name_in_owner = true +position = Vector2(-183, -5) +script = ExtResource("4_rloon") +zoom = Vector2(2.5, 2.5) +frame_preview = false +tween_resource = ExtResource("6_2h6fv") +follow_damping_value = Vector2(0, 0) +draw_limits = true diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_example_scene.tscn new file mode 100644 index 0000000..d557c93 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_example_scene.tscn @@ -0,0 +1,413 @@ +[gd_scene load_steps=41 format=3 uid="uid://cypbptekk8etg"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_u86qq"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="2_jl1he"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="3_an0dt"] +[ext_resource type="Script" uid="uid://tgv6xpi88sd0" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="3_yfuq5"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="4_iy6qn"] +[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="5_0ku52"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="6_prr6u"] +[ext_resource type="Script" uid="uid://uvw6pg1ut0ms" path="res://addons/phantom_camera/examples/scripts/3D/npc.gd" id="7_nl3ax"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="8_xvqcg"] +[ext_resource type="Script" uid="uid://bnhxcejvr6wi3" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="9_hqgwi"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="10_cd0kn"] + +[sub_resource type="Resource" id="Resource_jtk1d"] +script = ExtResource("6_prr6u") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_o161n"] +script = ExtResource("6_prr6u") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxMesh" id="BoxMesh_7tjw4"] +size = Vector3(2, 0.5, 4) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_hpllm"] +transparency = 1 +albedo_color = Color(0.988235, 0.478431, 0.905882, 0.0901961) + +[sub_resource type="BoxShape3D" id="BoxShape3D_65o6h"] +size = Vector3(2, 0.5, 4) + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_tpc7d"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_g0eml"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_v5iy7"] +albedo_color = Color(0.988235, 0.478431, 0.905882, 1) + +[sub_resource type="Resource" id="Resource_tpvee"] +script = ExtResource("8_xvqcg") +duration = 0.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_bxbnv"] +script = ExtResource("6_prr6u") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxShape3D" id="BoxShape3D_wcrbb"] +size = Vector3(6.8, 0.1, 5.4) + +[sub_resource type="Resource" id="Resource_7ih0k"] +script = ExtResource("8_xvqcg") +duration = 0.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_4iyps"] +script = ExtResource("6_prr6u") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxShape3D" id="BoxShape3D_ctyr8"] +size = Vector3(7.4, 0.1, 3.6) + +[sub_resource type="Resource" id="Resource_x5y0u"] +script = ExtResource("8_xvqcg") +duration = 0.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_pgiyx"] +script = ExtResource("6_prr6u") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxShape3D" id="BoxShape3D_ua072"] +size = Vector3(6.8, 0.1, 3.6) + +[sub_resource type="BoxMesh" id="BoxMesh_ugc3s"] +size = Vector3(1, 1, 2) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_68thd"] +albedo_color = Color(0.34902, 0.862745, 0.854902, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_wphly"] +size = Vector3(1, 0.5, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_gyp5s"] +size = Vector3(20, 40, 30) + +[sub_resource type="BoxShape3D" id="BoxShape3D_lfaqs"] +size = Vector3(20, 40, 30) + +[sub_resource type="BoxMesh" id="BoxMesh_n70lt"] +size = Vector3(14, 40, 6) + +[sub_resource type="BoxShape3D" id="BoxShape3D_jxmqm"] +size = Vector3(14, 40, 6) + +[sub_resource type="BoxMesh" id="BoxMesh_x0tgm"] +size = Vector3(8, 40, 1) + +[sub_resource type="BoxShape3D" id="BoxShape3D_t67ef"] +size = Vector3(50, 40, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_rmslh"] +size = Vector3(0.5, 6, 13.5) + +[sub_resource type="BoxMesh" id="BoxMesh_242ij"] +size = Vector3(2, 3, 3) + +[sub_resource type="BoxMesh" id="BoxMesh_niuda"] +size = Vector3(8, 6, 0.5) + +[node name="Root" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(1, 0, 0, 0, 0.948876, 0.315649, 0, -0.315649, 0.948876, -2.53871, 2, 9.76232) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_u86qq") + +[node name="PlayerGroup" type="Node" parent="."] + +[node name="PlayerCharacterBody3D" parent="PlayerGroup" instance=ExtResource("2_jl1he")] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.53871, 0.5, 7.26232) +script = ExtResource("3_yfuq5") + +[node name="MovementInstructionsLabel" type="Label3D" parent="PlayerGroup"] +transform = Transform3D(1, 0, 0, 0, 0.866025, 0.5, 0, -0.5, 0.866025, -2.47682, -0.0708016, 7.93048) +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[WASD] to move" +font = ExtResource("3_an0dt") +font_size = 48 + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="PlayerGroup" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999858, 0, 0, 0, 0.94884, 0.315632, 0, -0.315637, 0.948825, -2.53871, 2, 9.76232) +top_level = true +script = ExtResource("4_iy6qn") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = ExtResource("5_0ku52") +tween_on_load = false +camera_3d_resource = SubResource("Resource_jtk1d") +follow_offset = Vector3(0, 1.5, 2.5) +follow_damping = true + +[node name="NPCGroup" type="Node" parent="."] + +[node name="NPCPhantomCamera3D" type="Node3D" parent="NPCGroup"] +unique_name_in_owner = true +transform = Transform3D(0.616596, -0.109786, 0.779587, -2.23517e-08, 0.990229, 0.13945, -0.78728, -0.0859841, 0.610571, -2.98802, 1.50739, 1.19719) +script = ExtResource("4_iy6qn") +tween_resource = ExtResource("5_0ku52") +camera_3d_resource = SubResource("Resource_o161n") + +[node name="NPCDescriptionLabel" type="Label3D" parent="NPCGroup"] +transform = Transform3D(1, 0, 0, 0, 0.866026, 0.5, 0, -0.5, 0.866025, -3.04693, 0.367287, 0.953757) +text = "Input Example" +font = ExtResource("3_an0dt") + +[node name="NPCDialogueExampleLabel" type="Label3D" parent="NPCGroup"] +unique_name_in_owner = true +transform = Transform3D(1, 4.54671e-10, 1.65487e-10, 4.25644e-10, 0.939693, 0.34202, 0, -0.34202, 0.939693, -4.46738, 1.58641, -0.253679) +modulate = Color(1, 0.603922, 0.254902, 1) +text = "Press [ F ] to change camera" +font = ExtResource("3_an0dt") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="NPCGroup"] +transform = Transform3D(0.819152, 4.83851e-10, -0.573576, -3.92481e-09, 1, -6.3473e-09, 0.573576, 7.45058e-09, 0.819152, -3.46138, -0.4, 0.875321) +mesh = SubResource("BoxMesh_7tjw4") +skeleton = NodePath("../..") +surface_material_override/0 = SubResource("StandardMaterial3D_hpllm") +metadata/_edit_group_ = true + +[node name="NPCInteractionArea3D" type="Area3D" parent="NPCGroup/NPCInteractionZoneMesh"] +unique_name_in_owner = true +transform = Transform3D(1, -2.68591e-26, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) +monitorable = false + +[node name="NPCInterationCollisionShape3D" type="CollisionShape3D" parent="NPCGroup/NPCInteractionZoneMesh/NPCInteractionArea3D"] +shape = SubResource("BoxShape3D_65o6h") + +[node name="NPC" type="StaticBody3D" parent="NPCGroup"] +transform = Transform3D(1, 4.83851e-10, 0, 4.25644e-10, 1, -7.45058e-09, 0, 7.45058e-09, 1, -4.56338, 0.5, -0.272679) +script = ExtResource("7_nl3ax") + +[node name="PlayerCollisionShape3D2" type="CollisionShape3D" parent="NPCGroup/NPC"] +transform = Transform3D(1, -2.68591e-26, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_tpc7d") + +[node name="NPCMesh" type="MeshInstance3D" parent="NPCGroup/NPC"] +transform = Transform3D(1, -2.68591e-26, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) +mesh = SubResource("CapsuleMesh_g0eml") +skeleton = NodePath("../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_v5iy7") + +[node name="MoveToLocation" type="Node3D" parent="NPCGroup"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.70084, 0.5, 0.962891) + +[node name="FixedCameraTriggerZone" type="Node" parent="."] + +[node name="FixedCameraLabel" type="Label3D" parent="FixedCameraTriggerZone"] +unique_name_in_owner = true +transform = Transform3D(0.939693, 0.280167, -0.196175, 1.49012e-08, 0.573577, 0.819152, 0.34202, -0.769751, 0.538986, -0.538716, -0.247626, 3.13456) +text = "Fixed Camera +Example" +font = ExtResource("3_an0dt") + +[node name="NorthRoomPhantomCamera3D" type="Node3D" parent="FixedCameraTriggerZone"] +transform = Transform3D(0.38357, -0.555836, 0.737507, -0.105898, 0.766851, 0.633027, -0.917417, -0.320912, 0.235279, 6.89638, 4.73986, 0.115512) +script = ExtResource("4_iy6qn") +tween_resource = SubResource("Resource_tpvee") +camera_3d_resource = SubResource("Resource_bxbnv") + +[node name="NorthRoomTrigger" type="Area3D" parent="FixedCameraTriggerZone" node_paths=PackedStringArray("area_pcam")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, -0.45, -0.9) +priority = 5 +script = ExtResource("9_hqgwi") +area_pcam = NodePath("../NorthRoomPhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="FixedCameraTriggerZone/NorthRoomTrigger"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.6, 0, -0.4) +shape = SubResource("BoxShape3D_wcrbb") + +[node name="EntryRoomPhantomCamera3D" type="Node3D" parent="FixedCameraTriggerZone"] +transform = Transform3D(0.258818, -0.482963, 0.836515, 1.3027e-15, 0.866025, 0.499999, -0.965924, -0.129409, 0.224143, 6.69741, 4.73364, 4.02374) +script = ExtResource("4_iy6qn") +tween_resource = SubResource("Resource_7ih0k") +camera_3d_resource = SubResource("Resource_4iyps") + +[node name="EntryRoomTrigger" type="Area3D" parent="FixedCameraTriggerZone" node_paths=PackedStringArray("area_pcam")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.00003, -0.454982, 3.00572) +priority = 5 +script = ExtResource("9_hqgwi") +area_pcam = NodePath("../EntryRoomPhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="FixedCameraTriggerZone/EntryRoomTrigger"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.3, 0, 0.2) +shape = SubResource("BoxShape3D_ctyr8") + +[node name="SouthRoomPhantomCamera3D" type="Node3D" parent="FixedCameraTriggerZone"] +transform = Transform3D(-0.766043, -0.492403, 0.413175, 0, 0.642787, 0.766043, -0.642786, 0.586825, -0.492403, 6.89741, 4.73364, 5.62374) +script = ExtResource("4_iy6qn") +tween_resource = SubResource("Resource_x5y0u") +camera_3d_resource = SubResource("Resource_pgiyx") + +[node name="SouthRoomTrigger" type="Area3D" parent="FixedCameraTriggerZone" node_paths=PackedStringArray("area_pcam")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, -0.45, 6.7) +priority = 5 +script = ExtResource("9_hqgwi") +area_pcam = NodePath("../SouthRoomPhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="FixedCameraTriggerZone/SouthRoomTrigger"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.6, 0, 0.1) +shape = SubResource("BoxShape3D_ua072") + +[node name="CSGMesh3D" type="CSGMesh3D" parent="FixedCameraTriggerZone"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.14238, 1.82571, 2.88655) +mesh = SubResource("BoxMesh_ugc3s") +material = SubResource("StandardMaterial3D_68thd") + +[node name="CSGMesh3D2" type="CSGMesh3D" parent="FixedCameraTriggerZone/CSGMesh3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00192642, -0.0120339, 0.00494432) +operation = 2 +mesh = SubResource("BoxMesh_wphly") +material = SubResource("StandardMaterial3D_68thd") + +[node name="Environment" type="Node" parent="."] + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Environment" type="Node3D" parent="Environment"] + +[node name="Floor" parent="Environment/Environment" instance=ExtResource("10_cd0kn")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="West Wall" type="StaticBody3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16, 0.5, 0) +metadata/_edit_group_ = true +metadata/_edit_lock_ = true + +[node name="MeshInstance3D2" type="MeshInstance3D" parent="Environment/Environment/West Wall"] +mesh = SubResource("BoxMesh_gyp5s") +skeleton = NodePath("") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Environment/Environment/West Wall"] +shape = SubResource("BoxShape3D_lfaqs") + +[node name="East Wall" type="StaticBody3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16.999, 0.502, 0) +metadata/_edit_group_ = true +metadata/_edit_lock_ = true + +[node name="MeshInstance3D2" type="MeshInstance3D" parent="Environment/Environment/East Wall"] +mesh = SubResource("BoxMesh_gyp5s") +skeleton = NodePath("") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Environment/Environment/East Wall"] +shape = SubResource("BoxShape3D_lfaqs") + +[node name="North Wall" type="StaticBody3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, -6.90828) +metadata/_edit_group_ = true +metadata/_edit_lock_ = true + +[node name="MeshInstance3D2" type="MeshInstance3D" parent="Environment/Environment/North Wall"] +mesh = SubResource("BoxMesh_n70lt") +skeleton = NodePath("") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Environment/Environment/North Wall"] +shape = SubResource("BoxShape3D_jxmqm") + +[node name="South Wall" type="StaticBody3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, 0.5, 9.087) +metadata/_edit_group_ = true + +[node name="MeshInstance3D3" type="MeshInstance3D" parent="Environment/Environment/South Wall"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0, 0) +mesh = SubResource("BoxMesh_x0tgm") +skeleton = NodePath("") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Environment/Environment/South Wall"] +shape = SubResource("BoxShape3D_t67ef") + +[node name="FixedCamOuterWall" type="CSGMesh3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 2) +use_collision = true +mesh = SubResource("BoxMesh_rmslh") + +[node name="FixedCamOuterDoorway" type="CSGMesh3D" parent="Environment/Environment/FixedCamOuterWall"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.5, 1) +operation = 2 +mesh = SubResource("BoxMesh_242ij") + +[node name="FixedCamNorthWall" type="CSGMesh3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 2.5, 1) +use_collision = true +mesh = SubResource("BoxMesh_niuda") + +[node name="FixedCamNorthDoorway" type="CSGMesh3D" parent="Environment/Environment/FixedCamNorthWall"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.5, 0) +operation = 2 +mesh = SubResource("BoxMesh_242ij") + +[node name="FixedCamSouthWall" type="CSGMesh3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 2.5, 5.1) +use_collision = true +mesh = SubResource("BoxMesh_niuda") + +[node name="FixedCamSouthDoorway" type="CSGMesh3D" parent="Environment/Environment/FixedCamSouthWall"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.50541, 1.19209e-07) +operation = 2 +mesh = SubResource("BoxMesh_242ij") diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_framed_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_framed_example_scene.tscn new file mode 100644 index 0000000..b7086c0 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_framed_example_scene.tscn @@ -0,0 +1,158 @@ +[gd_scene load_steps=11 format=3 uid="uid://cx7x48cpi8gcd"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_6uslv"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_5cpe8"] +[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="3_422w7"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_4qurp"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_uw36d"] +[ext_resource type="Script" uid="uid://tgv6xpi88sd0" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_fcomr"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_i060b"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="7_iyghi"] + +[sub_resource type="Resource" id="Resource_wg1pr"] +script = ExtResource("4_4qurp") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_auy8m"] +albedo_texture = ExtResource("7_iyghi") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="Root" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(1, 0, 0, 0, 0.793353, 0.608762, 0, -0.608762, 0.793353, 0, 2.93468, 3.17294) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_6uslv") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.99995, 0, 0, 0, 0.79324, 0.608671, 0, -0.608675, 0.793235, 0, 2.93468, 3.17294) +top_level = true +script = ExtResource("2_5cpe8") +follow_mode = 5 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = ExtResource("3_422w7") +tween_on_load = false +camera_3d_resource = SubResource("Resource_wg1pr") +follow_damping = true +follow_distance = 4.0 +dead_zone_width = 0.139 +dead_zone_height = 0.14 +show_viewfinder_in_play = true +spring_length = 4.0 + +[node name="PlayerCharacterBody3D" parent="Player" instance=ExtResource("5_uw36d")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +script = ExtResource("6_fcomr") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("6_i060b")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.636134, 0.805455, -6.37532) +use_collision = true +radius = 1.71971 +height = 2.61091 +sides = 32 + +[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.54597, -0.540694, -3.39517) +use_collision = true +radius = 1.53269 +height = 2.5036 +sides = 32 + +[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.64877, -1.50101, 1.22863) +use_collision = true +radius = 1.57419 +height = 3.47475 +sides = 32 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.4732, 0.805455, -8.78984) +use_collision = true +radius = 0.956285 +height = 2.61091 +sides = 32 + +[node name="CSGSphere3D" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.40027, -1.69814, 3.36997) +use_collision = true +radius = 3.34732 +rings = 32 + +[node name="CSGSphere3D2" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.13768, -0.599204, -1.04651) +use_collision = true +radius = 2.65844 +rings = 32 + +[node name="CSGSphere3D3" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.7976, -0.599204, -2.42244) +use_collision = true +radius = 2.14606 +rings = 32 + +[node name="CSGTorus3D2" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.84078, -0.497663, 4.44352) +use_collision = true +inner_radius = 0.971543 +outer_radius = 2.15226 +sides = 32 +ring_sides = 18 + +[node name="CSGBox3D" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.52545, 6.53866, -12.6331) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_auy8m") + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.88916, 0.760708, -6.1376) +use_collision = true +size = Vector3(2.64182, 2.52142, 2.30997) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.83837, -0.241718, 7.14677) +use_collision = true +size = Vector3(3.80964, 1.67049, 0.932048) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.34377, 0.138478, -4.36159) +use_collision = true +size = Vector3(1.53893, 1.27695, 1.80814) + +[node name="CSGBox3D6" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.9834, 0.138478, -1.89037) +use_collision = true +size = Vector3(4.03502, 1.27695, 5.2198) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.38147, 0.0440434, 8.36617) +use_collision = true +size = Vector3(4.57784, 1.08809, 3.11285) diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_glued_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_glued_example_scene.tscn new file mode 100644 index 0000000..e7ad802 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_glued_example_scene.tscn @@ -0,0 +1,211 @@ +[gd_scene load_steps=15 format=3 uid="uid://d2lx45noxq685"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_7a3wq"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_158c0"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_ganw1"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_kig2n"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_caky3"] +[ext_resource type="Script" uid="uid://tgv6xpi88sd0" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_b6ic4"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_kkbaa"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="7_i1dbs"] + +[sub_resource type="Resource" id="Resource_ucp3e"] +script = ExtResource("3_ganw1") +duration = 1.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_ab013"] +script = ExtResource("4_kig2n") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_2h36r"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_w3olp"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cw102"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_auy8m"] +albedo_texture = ExtResource("7_i1dbs") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="Node3D" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(1, 0, 0, 0, 0.638767, 0.7694, 0, -0.7694, 0.638768, 0, 6.39, 7) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_7a3wq") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999954, 0, 0, 0, 0.638683, 0.769345, 0, -0.769298, 0.638723, 0, 6.39, 7) +top_level = true +script = ExtResource("2_158c0") +priority = 5 +follow_mode = 1 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = SubResource("Resource_ucp3e") +tween_on_load = false +camera_3d_resource = SubResource("Resource_ab013") +follow_damping = true +follow_damping_value = Vector3(0.3, 0.3, 0.3) + +[node name="PlayerCharacterBody3D" parent="Player" instance=ExtResource("5_caky3")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 6.39, 7) +script = ExtResource("6_b6ic4") +enable_gravity = false + +[node name="PlayerVisual" parent="Player/PlayerCharacterBody3D" index="2"] +visible = false + +[node name="NPCs" type="Node" parent="."] + +[node name="PlayerMeshInstance3D" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.04486, 0.519002, -1.52506) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_w3olp") + +[node name="PlayerMeshInstance3D2" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.51494, 0.519, 4.06618) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_cw102") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("6_kkbaa")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.62737, 0.805455, -6.37532) +use_collision = true +radius = 1.71971 +height = 2.61091 +sides = 32 + +[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 24.9378, 0.31181, -5.46661) +use_collision = true +radius = 2.77591 +height = 1.62362 +sides = 32 + +[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.58617, 0.31181, 6.6322) +use_collision = true +radius = 1.57419 +height = 3.47475 +sides = 32 + +[node name="CSGCylinder3D3" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.774, 0.201103, 2.71259) +use_collision = true +radius = 1.41311 +height = 1.40221 +sides = 32 + +[node name="CSGCylinder3D4" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.40488, 0.201101, 11.6804) +use_collision = true +radius = 2.21673 +height = 7.88261 +sides = 32 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.20971, 0.805455, -8.78984) +use_collision = true +radius = 0.956285 +height = 2.61091 +sides = 32 + +[node name="CSGSphere3D" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.9771, -1.69814, -6.51262) +use_collision = true +radius = 3.34732 +rings = 32 + +[node name="CSGSphere3D2" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.555532, -0.599204, 8.81048) +use_collision = true +radius = 2.65844 +rings = 32 + +[node name="CSGSphere3D3" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.0611, -0.599204, -2.42244) +use_collision = true +radius = 2.14606 +rings = 32 + +[node name="CSGTorus3D" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.21187, -1.90735e-06, 0.346393) +use_collision = true +inner_radius = 1.3 +outer_radius = 2.0 +sides = 32 +ring_sides = 18 + +[node name="CSGTorus3D2" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 21.9283, -1.90735e-06, 7.89765) +use_collision = true +inner_radius = 0.971543 +outer_radius = 2.15226 +sides = 32 +ring_sides = 18 + +[node name="CSGBox3D" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.49828, 6.53866, -12.6331) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_auy8m") + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.15267, 0.760708, -6.1376) +use_collision = true +size = Vector3(2.64182, 2.52142, 2.30997) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.3427, 0.335247, 8.22829) +use_collision = true +size = Vector3(3.80964, 1.67049, 0.932048) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.08027, 0.138478, -4.36159) +use_collision = true +size = Vector3(1.53893, 1.27695, 1.80814) + +[node name="CSGBox3D6" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.7748, 0.138478, 5.20734) +use_collision = true +size = Vector3(4.03502, 1.27695, 5.2198) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 30.1473, 1.78638, -1.60318) +use_collision = true +size = Vector3(4.57784, 4.57276, 3.11285) + +[editable path="Player/PlayerCharacterBody3D"] diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_group_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_group_example_scene.tscn new file mode 100644 index 0000000..c60b01d --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_group_example_scene.tscn @@ -0,0 +1,180 @@ +[gd_scene load_steps=13 format=3 uid="uid://cqy81q5p0tsda"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_3iw7y"] +[ext_resource type="PackedScene" uid="uid://cb83in8f0tbb1" path="res://addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_3d.tscn" id="2_m6p13"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_65wck"] +[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="4_b0eay"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_i3ale"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_5hq8j"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="7_7lab4"] + +[sub_resource type="Resource" id="Resource_1iman"] +script = ExtResource("5_i3ale") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_2h36r"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_w3olp"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cw102"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_auy8m"] +albedo_texture = ExtResource("7_7lab4") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="Node3D" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(1, 0, 0, 0, 0.621367, 0.78352, 0, -0.78352, 0.621367, -7.26116, 10.1812, 8.76176) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_3iw7y") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Player" type="Node" parent="."] + +[node name="PlayerCharacterBody3D" parent="Player" instance=ExtResource("2_m6p13")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.083587, 0.5, 2.05493) + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="Player" node_paths=PackedStringArray("follow_targets")] +unique_name_in_owner = true +transform = Transform3D(0.999954, 0, 0, 0, 0.621285, 0.783464, 0, -0.783416, 0.621322, -7.26116, 10.1812, 8.76176) +top_level = true +script = ExtResource("3_65wck") +priority = 5 +follow_mode = 3 +follow_targets = [NodePath("../PlayerCharacterBody3D"), NodePath("../../NPCs/PlayerMeshInstance3D"), NodePath("../../NPCs/PlayerMeshInstance3D2")] +tween_resource = ExtResource("4_b0eay") +tween_on_load = false +camera_3d_resource = SubResource("Resource_1iman") +follow_damping = true +follow_distance = 5.0 +auto_follow_distance = true +auto_follow_distance_min = 5.0 +auto_follow_distance_max = 15.0 +auto_follow_distance_divisor = 20.0 +spring_length = 5.0 + +[node name="NPCs" type="Node" parent="."] + +[node name="PlayerMeshInstance3D" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.6059, 0.519002, 0.128472) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_w3olp") + +[node name="PlayerMeshInstance3D2" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.0461, 0.519, 0.249913) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_cw102") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("6_5hq8j")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="Wall" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.52545, 6.53866, -12.6331) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_auy8m") + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.6511, 0.805455, -6.37532) +use_collision = true +radius = 1.71971 +height = 2.61091 +sides = 32 + +[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.9141, 0.31181, -5.46661) +use_collision = true +radius = 2.77591 +height = 1.62362 +sides = 32 + +[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.6099, 0.31181, 6.6322) +use_collision = true +radius = 1.57419 +height = 3.47475 +sides = 32 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.81402, 0.805455, -8.78984) +use_collision = true +radius = 0.956285 +height = 2.61091 +sides = 32 + +[node name="CSGSphere3D" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.95333, -1.69814, -6.51262) +use_collision = true +radius = 3.34732 +rings = 32 + +[node name="CSGSphere3D2" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.4682, -0.599204, 8.81048) +use_collision = true +radius = 2.65844 +rings = 32 + +[node name="CSGSphere3D3" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -26.0848, -0.599204, -2.42244) +use_collision = true +radius = 2.14606 +rings = 32 + +[node name="CSGTorus3D2" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.90455, -1.90735e-06, 7.89765) +use_collision = true +inner_radius = 0.971543 +outer_radius = 2.15226 +sides = 32 +ring_sides = 18 + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.1764, 0.760708, -6.1376) +use_collision = true +size = Vector3(2.64182, 2.52142, 2.30997) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.31901, 0.335247, 8.22829) +use_collision = true +size = Vector3(3.80964, 1.67049, 0.932048) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.94346, 0.138478, -4.36159) +use_collision = true +size = Vector3(1.53893, 1.27695, 1.80814) + +[node name="CSGBox3D6" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -26.7985, 0.138478, 5.20734) +use_collision = true +size = Vector3(4.03502, 1.27695, 5.2198) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 18.1236, 1.78638, -1.60318) +use_collision = true +size = Vector3(4.57784, 4.57276, 3.11285) diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_path_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_path_example_scene.tscn new file mode 100644 index 0000000..5b4597f --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_path_example_scene.tscn @@ -0,0 +1,245 @@ +[gd_scene load_steps=25 format=3 uid="uid://oo1y1sjdmr6k"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_p8ccw"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_8itog"] +[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="3_xqpq0"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_akuuo"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_0nadx"] +[ext_resource type="Script" uid="uid://tgv6xpi88sd0" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_7h7mx"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="6_mkxip"] +[ext_resource type="Script" uid="uid://cgknbkjar73w" path="res://addons/phantom_camera/examples/scripts/3D/path_follow.gd" id="7_g1m51"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="8_a1h2k"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="9_rk5lh"] + +[sub_resource type="Resource" id="Resource_ofv2c"] +script = ExtResource("4_akuuo") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_01tho"] +script = ExtResource("6_mkxip") +duration = 1.2 +transition = 3 +ease = 2 + +[sub_resource type="Resource" id="Resource_syh5m"] +script = ExtResource("4_akuuo") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Curve3D" id="Curve3D_b33df"] +_data = { +"points": PackedVector3Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10), +"tilts": PackedFloat32Array(0, 0) +} +point_count = 2 + +[sub_resource type="BoxShape3D" id="BoxShape3D_aovgi"] +size = Vector3(6, 0.1, 10) + +[sub_resource type="BoxMesh" id="BoxMesh_0hdeh"] +size = Vector3(6, 0.1, 10) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fsm1b"] +transparency = 1 +albedo_color = Color(0.988235, 0.478431, 0.905882, 0.0901961) + +[sub_resource type="Resource" id="Resource_xci4c"] +script = ExtResource("4_akuuo") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Curve3D" id="Curve3D_8uw2x"] +_data = { +"points": PackedVector3Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0), +"tilts": PackedFloat32Array(0, 0) +} +point_count = 2 + +[sub_resource type="BoxShape3D" id="BoxShape3D_ctnqu"] +size = Vector3(12, 0.1, 4) + +[sub_resource type="BoxMesh" id="BoxMesh_f6dp8"] +size = Vector3(12, 0.1, 4) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gwnkj"] +transparency = 1 +albedo_color = Color(0.568403, 0.988235, 0.762724, 0.0901961) + +[sub_resource type="BoxMesh" id="BoxMesh_7l3dh"] + +[sub_resource type="BoxMesh" id="BoxMesh_as6ok"] + +[node name="Root" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(0.999996, -0.00216283, 0.00184472, 0, 0.648938, 0.760841, -0.00284268, -0.760838, 0.648936, 0, 2.5, 1.5) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_p8ccw") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999807, -0.00216249, 0.00184445, 0, 0.648836, 0.760728, -0.00284214, -0.760718, 0.648839, 0, 2.5, 1.5) +top_level = true +script = ExtResource("2_8itog") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../PlayerCharacterBody3D2") +tween_resource = ExtResource("3_xqpq0") +tween_on_load = false +camera_3d_resource = SubResource("Resource_ofv2c") +follow_offset = Vector3(0, 2, 1.5) +follow_damping = true + +[node name="PlayerCharacterBody3D2" parent="." instance=ExtResource("5_0nadx")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +script = ExtResource("6_7h7mx") + +[node name="Paths" type="Node" parent="."] + +[node name="PathPhantomCamera3D" type="Node3D" parent="Paths" node_paths=PackedStringArray("follow_target", "follow_path")] +transform = Transform3D(-4.37114e-08, -1, -4.37114e-08, 0, -4.37114e-08, 1, -1, 4.37114e-08, 1.91069e-15, -0.31028, 7.9199, -1.60976) +top_level = true +script = ExtResource("2_8itog") +priority = 2 +follow_mode = 4 +follow_target = NodePath("../../PlayerCharacterBody3D2") +follow_path = NodePath("../FollowPath") +tween_resource = SubResource("Resource_01tho") +camera_3d_resource = SubResource("Resource_syh5m") +follow_damping = true + +[node name="FollowPath" type="Path3D" parent="Paths"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.31028, 7.9199, -1.60976) +curve = SubResource("Curve3D_b33df") + +[node name="StraightPathFollowTrigger" type="Area3D" parent="Paths" node_paths=PackedStringArray("path_pcam")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0420399, -0.45, -6.73666) +priority = 5 +script = ExtResource("7_g1m51") +path_pcam = NodePath("../PathPhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Paths/StraightPathFollowTrigger"] +shape = SubResource("BoxShape3D_aovgi") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Paths/StraightPathFollowTrigger/CollisionShape3D"] +mesh = SubResource("BoxMesh_0hdeh") +skeleton = NodePath("../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_fsm1b") +metadata/_edit_group_ = true + +[node name="PathPhantomCamera3D2" type="Node3D" parent="Paths" node_paths=PackedStringArray("follow_target", "follow_path")] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 7.9199, -13.4572) +top_level = true +visible = false +script = ExtResource("2_8itog") +priority = 2 +follow_mode = 4 +follow_target = NodePath("../../PlayerCharacterBody3D2") +follow_path = NodePath("../FollowPath2") +tween_resource = SubResource("Resource_01tho") +camera_3d_resource = SubResource("Resource_xci4c") +follow_damping = true +follow_damping_value = Vector3(0.6, 0.1, 0.1) + +[node name="FollowPath2" type="Path3D" parent="Paths"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.97141, 7.9199, -13.4572) +curve = SubResource("Curve3D_8uw2x") + +[node name="StraightPathFollowTrigger2" type="Area3D" parent="Paths" node_paths=PackedStringArray("path_pcam")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0420399, 0, -13.7367) +priority = 5 +script = ExtResource("7_g1m51") +path_pcam = NodePath("../PathPhantomCamera3D2") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Paths/StraightPathFollowTrigger2"] +shape = SubResource("BoxShape3D_ctnqu") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Paths/StraightPathFollowTrigger2/CollisionShape3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.45, 0) +mesh = SubResource("BoxMesh_f6dp8") +skeleton = NodePath("../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_gwnkj") +metadata/_edit_group_ = true + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("8_a1h2k")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="Floor3" parent="Environment" instance=ExtResource("8_a1h2k")] +transform = Transform3D(6, 0, 0, 0, 1, 0, 0, 0, 1, -0.44204, 0, 1.76334) + +[node name="Floor2" parent="Environment/Floor3" instance=ExtResource("8_a1h2k")] +transform = Transform3D(0.166667, 0, 0, 0, 3, 0, 0, 0, 14, -0.516667, 1, -6.5) + +[node name="Floor5" parent="Environment/Floor3" instance=ExtResource("8_a1h2k")] +transform = Transform3D(0.166667, 0, 0, 0, 3, 0, 0, 0, 14, 0.65, 1, -6.5) + +[node name="Floor4" parent="Environment/Floor3" instance=ExtResource("8_a1h2k")] +transform = Transform3D(2, 0, 0, 0, 3, 0, 0, 0, 1, 0.0666667, 1, -18) + +[node name="Floor6" parent="Environment/Floor3" instance=ExtResource("8_a1h2k")] +transform = Transform3D(0.333333, 0, 0, 0, 3, 0, 0, 0, 1, -0.766667, 1, -13) +mesh = SubResource("BoxMesh_7l3dh") + +[node name="Floor8" parent="Environment/Floor3" instance=ExtResource("8_a1h2k")] +transform = Transform3D(0.166667, 0, 0, 0, 3, 0, 0, 0, 6, -1.01667, 1, -15.5) +mesh = SubResource("BoxMesh_as6ok") + +[node name="Floor9" parent="Environment/Floor3" instance=ExtResource("8_a1h2k")] +transform = Transform3D(0.166667, 0, 0, 0, 3, 0, 0, 0, 6, 1.15, 1, -15.5) +mesh = SubResource("BoxMesh_as6ok") + +[node name="Floor7" parent="Environment/Floor3" instance=ExtResource("8_a1h2k")] +transform = Transform3D(0.333333, 0, 0, 0, 3, 0, 0, 0, 1, 0.9, 1, -13) +mesh = SubResource("BoxMesh_7l3dh") + +[node name="NPCDescriptionLabel" type="Label3D" parent="Environment"] +transform = Transform3D(5.21541e-08, -1, -7.7486e-07, -1.10675e-15, 2.23517e-07, 0.999999, -0.999999, -7.45058e-08, -5.68829e-14, -3.47306, 2.59595, -5.51755) +text = "Camera follows player while confined to a Path3D" +font = ExtResource("9_rk5lh") +font_size = 64 + +[node name="MovementInstructionsLabel" type="Label3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.02174, -0.455369, 0.570585) +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[WASD] to move" +font = ExtResource("9_rk5lh") +font_size = 48 diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_simple_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_simple_example_scene.tscn new file mode 100644 index 0000000..610e62a --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_simple_example_scene.tscn @@ -0,0 +1,164 @@ +[gd_scene load_steps=12 format=3 uid="uid://c7uyfhhnrmkbx"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_gt67h"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_4ltlo"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_hldrt"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_pqibl"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_o4k7v"] +[ext_resource type="Script" uid="uid://tgv6xpi88sd0" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_8yuc5"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_m6ich"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="7_pagh0"] + +[sub_resource type="Resource" id="Resource_28vpp"] +script = ExtResource("3_hldrt") +duration = 1.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_axopo"] +script = ExtResource("4_pqibl") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_auy8m"] +albedo_texture = ExtResource("7_pagh0") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="Node3D2" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(1, 0, 0, 0, 0.906308, 0.422618, 0, -0.422618, 0.906308, -13.2122, 2.5, 10.4016) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_gt67h") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999954, 0, 0, 0, 0.906188, 0.422588, 0, -0.422562, 0.906243, -13.2122, 2.5, 10.4016) +top_level = true +script = ExtResource("2_4ltlo") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = SubResource("Resource_28vpp") +tween_on_load = false +camera_3d_resource = SubResource("Resource_axopo") +follow_offset = Vector3(0, 2, 2) +follow_damping = true + +[node name="PlayerCharacterBody3D" parent="Player" instance=ExtResource("5_o4k7v")] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.2122, 0.5, 8.40162) +script = ExtResource("6_8yuc5") + +[node name="NPCs" type="Node" parent="."] + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("6_m6ich")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.6511, 0.805455, -6.37532) +use_collision = true +radius = 1.71971 +height = 2.61091 +sides = 32 + +[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.8332, -0.540694, -3.39517) +use_collision = true +radius = 1.53269 +height = 2.5036 +sides = 32 + +[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.936, -1.50101, 1.22863) +use_collision = true +radius = 1.57419 +height = 3.47475 +sides = 32 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.81402, 0.805455, -8.78984) +use_collision = true +radius = 0.956285 +height = 2.61091 +sides = 32 + +[node name="CSGSphere3D" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -23.6875, -1.69814, 3.36997) +use_collision = true +radius = 3.34732 +rings = 32 + +[node name="CSGSphere3D2" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.14955, -0.599204, -1.04651) +use_collision = true +radius = 2.65844 +rings = 32 + +[node name="CSGSphere3D3" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -26.0848, -0.599204, -2.42244) +use_collision = true +radius = 2.14606 +rings = 32 + +[node name="CSGTorus3D2" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.44645, -0.497663, 4.44352) +use_collision = true +inner_radius = 0.971543 +outer_radius = 2.15226 +sides = 32 +ring_sides = 18 + +[node name="CSGBox3D" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.52545, 6.53866, -12.6331) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_auy8m") + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.1764, 0.760708, -6.1376) +use_collision = true +size = Vector3(2.64182, 2.52142, 2.30997) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -18.1256, 0.335247, 7.14677) +use_collision = true +size = Vector3(3.80964, 1.67049, 0.932048) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.94346, 0.138478, -4.36159) +use_collision = true +size = Vector3(1.53893, 1.27695, 1.80814) + +[node name="CSGBox3D6" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.30382, 0.138478, -1.89037) +use_collision = true +size = Vector3(4.03502, 1.27695, 5.2198) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.04727, 0.0440434, 8.36617) +use_collision = true +size = Vector3(4.57784, 1.08809, 3.11285) diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_attribtues_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_attribtues_example_scene.tscn new file mode 100644 index 0000000..a2a93c3 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_attribtues_example_scene.tscn @@ -0,0 +1,220 @@ +[gd_scene load_steps=22 format=3 uid="uid://bklrp02eywxsx"] + +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="1_s26cy"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_m2d6w"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="3_l7kg8"] +[ext_resource type="PackedScene" uid="uid://mskcwn1a1v6d" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn" id="4_qcyfd"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_8von1"] +[ext_resource type="Script" uid="uid://bkr71vxe2t18n" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd" id="5_tarnu"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_o1fj6"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_amcmx"] +[ext_resource type="Texture2D" uid="uid://c3mskbmvnpwux" path="res://addons/phantom_camera/examples/textures/3D/target.png" id="8_rjcgw"] + +[sub_resource type="Resource" id="Resource_8fhct"] +script = ExtResource("2_m2d6w") +duration = 0.3 +transition = 2 +ease = 1 + +[sub_resource type="Resource" id="Resource_7m0fv"] +script = ExtResource("3_l7kg8") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_i42vj"] +dof_blur_far_enabled = true +dof_blur_far_distance = 5.99 +dof_blur_near_enabled = true +dof_blur_near_distance = 0.05 +dof_blur_amount = 0.21 + +[sub_resource type="Resource" id="Resource_e7t18"] +script = ExtResource("2_m2d6w") +duration = 0.4 +transition = 2 +ease = 1 + +[sub_resource type="Resource" id="Resource_jogxh"] +script = ExtResource("3_l7kg8") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 1.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_fvhx5"] +dof_blur_far_enabled = true +dof_blur_far_distance = 31.1 +dof_blur_near_enabled = true +dof_blur_near_distance = 1.79 + +[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_fnb35"] +dof_blur_far_enabled = true +dof_blur_far_distance = 5.99 +dof_blur_near_enabled = true +dof_blur_near_distance = 0.05 +dof_blur_amount = 0.21 + +[sub_resource type="BoxMesh" id="BoxMesh_wsigl"] +size = Vector3(1, 10, 20) + +[sub_resource type="Resource" id="Resource_afrr1"] +script = ExtResource("2_m2d6w") +duration = 0.6 +transition = 3 +ease = 1 + +[sub_resource type="Resource" id="Resource_unpfd"] +script = ExtResource("3_l7kg8") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CylinderMesh" id="CylinderMesh_sm466"] +top_radius = 1.51 +height = 0.2 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_hp48l"] +transparency = 1 +albedo_texture = ExtResource("8_rjcgw") +uv1_scale = Vector3(1.91, 1.91, 1.91) +uv1_offset = Vector3(0.025, -0.927, 0) + +[node name="Root" type="Node3D"] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, -0.0194088, 0.506884, 8.76853) +script = ExtResource("1_s26cy") +priority = 10 +follow_mode = 6 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = SubResource("Resource_8fhct") +tween_on_load = false +camera_3d_resource = SubResource("Resource_7m0fv") +attributes = SubResource("CameraAttributesPractical_i42vj") +follow_damping = true +follow_distance = 3.5 +spring_length = 3.5 + +[node name="PlayerAimPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, -0.0194088, 1.47688, 6.36953) +script = ExtResource("1_s26cy") +follow_mode = 6 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = SubResource("Resource_e7t18") +tween_on_load = false +camera_3d_resource = SubResource("Resource_jogxh") +attributes = SubResource("CameraAttributesPractical_fvhx5") +follow_offset = Vector3(0, 0.97, -0.399) +follow_damping_value = Vector3(0, 0, 0) +follow_distance = 1.5 +spring_length = 1.5 + +[node name="PlayerCharacterBody3D" parent="." instance=ExtResource("4_qcyfd")] +unique_name_in_owner = true +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, -0.0194088, 0.506884, 5.26853) +script = ExtResource("5_tarnu") + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, -0.0194088, 0.506884, 8.76853) +attributes = SubResource("CameraAttributesPractical_fnb35") + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("5_8von1") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("6_o1fj6")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="Wall" parent="Environment" instance=ExtResource("6_o1fj6")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.5, 4.5, 0) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall2" parent="Environment" instance=ExtResource("6_o1fj6")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.5, 4.5, 0) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall3" parent="Environment" instance=ExtResource("6_o1fj6")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 4.5, 10.5) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall4" parent="Environment" instance=ExtResource("6_o1fj6")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 4.5, -9.5) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="CeilingPhantomCamera3D" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(-4.37114e-08, -1, 2.98023e-08, 0, 2.98023e-08, 1, -1, 4.37114e-08, -1.3027e-15, -0.200665, 13.366, -0.162648) +script = ExtResource("1_s26cy") +tween_resource = SubResource("Resource_afrr1") +camera_3d_resource = SubResource("Resource_unpfd") + +[node name="MovementInstructionsLabel" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.0505604, -0.484909, 1.44357) +visible = false +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[WASD] to move" +font = ExtResource("7_amcmx") +font_size = 48 + +[node name="MovementInstructionsLabel3" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.0505604, -0.484909, 0.817134) +visible = false +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[Right Mouse Click] to \"aim\"" +font = ExtResource("7_amcmx") +font_size = 48 + +[node name="MovementInstructionsLabel2" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.0440154, -0.490478, -6.30248) +visible = false +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[Space] to toggle PCam" +font = ExtResource("7_amcmx") +font_size = 48 + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0.260217, 1.60477, -9.07797) +mesh = SubResource("CylinderMesh_sm466") +surface_material_override/0 = SubResource("StandardMaterial3D_hp48l") + +[node name="MeshInstance3D3" type="MeshInstance3D" parent="."] +transform = Transform3D(-1, -8.74228e-08, 3.82137e-15, 0, -4.37114e-08, -1, 8.74228e-08, -1, 4.37114e-08, 0.0525861, 1.60477, 9.98156) +mesh = SubResource("CylinderMesh_sm466") +surface_material_override/0 = SubResource("StandardMaterial3D_hp48l") diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_example_scene.tscn new file mode 100644 index 0000000..eb5809b --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_follow_third_person_example_scene.tscn @@ -0,0 +1,191 @@ +[gd_scene load_steps=17 format=3 uid="uid://ceelq6qrb41uf"] + +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_47xf2"] +[ext_resource type="Script" uid="uid://bkr71vxe2t18n" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd" id="2_uhq7m"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_whx47"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_lii5s"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_jt2lp"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_oc4q1"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_kg7u1"] +[ext_resource type="PackedScene" uid="uid://mskcwn1a1v6d" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn" id="7_kut0u"] + +[sub_resource type="Resource" id="Resource_8fhct"] +script = ExtResource("2_47xf2") +duration = 0.3 +transition = 2 +ease = 1 + +[sub_resource type="Resource" id="Resource_7m0fv"] +script = ExtResource("5_jt2lp") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_e7t18"] +script = ExtResource("2_47xf2") +duration = 0.3 +transition = 2 +ease = 1 + +[sub_resource type="Resource" id="Resource_jogxh"] +script = ExtResource("5_jt2lp") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 1.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxMesh" id="BoxMesh_wsigl"] +size = Vector3(1, 10, 20) + +[sub_resource type="BoxMesh" id="BoxMesh_bj3re"] +size = Vector3(1, 7, 7) + +[sub_resource type="Resource" id="Resource_afrr1"] +script = ExtResource("2_47xf2") +duration = 0.6 +transition = 3 +ease = 1 + +[sub_resource type="Resource" id="Resource_ioijp"] +script = ExtResource("5_jt2lp") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[node name="Root2" type="Node3D"] + +[node name="PlayerCharacterBody3D" parent="." instance=ExtResource("7_kut0u")] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +script = ExtResource("2_uhq7m") + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 0.866025, 0.5, 0, -0.5, 0.866025, 0, 2.25, 3.03109) +script = ExtResource("2_whx47") +priority = 10 +follow_mode = 6 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = SubResource("Resource_8fhct") +tween_on_load = false +camera_3d_resource = SubResource("Resource_7m0fv") +follow_damping = true +follow_distance = 3.5 +vertical_rotation_offset = 0.523599 +spring_length = 3.5 + +[node name="PlayerAimPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.584, 1.3, 1.101) +script = ExtResource("2_whx47") +follow_mode = 6 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = SubResource("Resource_e7t18") +tween_on_load = false +camera_3d_resource = SubResource("Resource_jogxh") +follow_offset = Vector3(0.584, 0.8, -0.399) +follow_distance = 1.5 +spring_length = 1.5 + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(1, 0, 0, 0, 0.866025, 0.5, 0, -0.5, 0.866025, 0, 2.25, 3.03109) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("5_oc4q1") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="Wall" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.5, 4.5, 0) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall5" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.133, 3, -6.5) +mesh = SubResource("BoxMesh_bj3re") +metadata/_edit_lock_ = true + +[node name="Wall6" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.5, 3, 0) +mesh = SubResource("BoxMesh_bj3re") +metadata/_edit_lock_ = true + +[node name="Wall7" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.5, 3, 0) +mesh = SubResource("BoxMesh_bj3re") +metadata/_edit_lock_ = true + +[node name="Wall2" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.5, 4.5, 0) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall3" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 4.5, 10.5) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall4" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 4.5, -9.5) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="CeilingPhantomCamera3D" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(-4.37114e-08, -1, 2.98023e-08, 0, 2.98023e-08, 1, -1, 4.37114e-08, -1.3027e-15, -0.200665, 13.366, -0.162648) +script = ExtResource("2_whx47") +tween_resource = SubResource("Resource_afrr1") +camera_3d_resource = SubResource("Resource_ioijp") + +[node name="MovementInstructionsLabel" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.0505604, -0.484909, 1.44357) +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[WASD] to move" +font = ExtResource("7_kg7u1") +font_size = 48 + +[node name="MovementInstructionsLabel3" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.0505604, -0.484909, 0.817134) +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[Right Mouse Click] to \"aim\"" +font = ExtResource("7_kg7u1") +font_size = 48 + +[node name="MovementInstructionsLabel2" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.0440154, -0.490478, -6.30248) +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[Space] to toggle PCam" +font = ExtResource("7_kg7u1") +font_size = 48 diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_look_at_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_look_at_example_scene.tscn new file mode 100644 index 0000000..6fe3289 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_look_at_example_scene.tscn @@ -0,0 +1,200 @@ +[gd_scene load_steps=15 format=3 uid="uid://dsfixtpa5xwqt"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_jbmnd"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_t3gk2"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_b2lea"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_mqo2b"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_pxkua"] +[ext_resource type="Script" uid="uid://tgv6xpi88sd0" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="6_3rtu0"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_uuxs3"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="7_0dyt0"] + +[sub_resource type="Resource" id="Resource_pwcgo"] +script = ExtResource("3_b2lea") +duration = 1.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_ft2w3"] +script = ExtResource("4_mqo2b") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_2h36r"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_w3olp"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cw102"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_auy8m"] +albedo_texture = ExtResource("7_0dyt0") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="Root" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(0.999765, 0.010421, -0.0189909, 0, 0.876683, 0.481069, 0.0216623, -0.480956, 0.876477, -0.137901, 4.03222, 6.36446) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_jbmnd") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="PhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("look_at_target")] +transform = Transform3D(0.999765, 0.010421, -0.018991, 0, 0.876683, 0.481069, 0.0216623, -0.480956, 0.876478, -0.137901, 4.03222, 6.36446) +script = ExtResource("2_t3gk2") +priority = 10 +look_at_mode = 2 +look_at_target = NodePath("../PlayerCharacterBody3D2") +tween_resource = SubResource("Resource_pwcgo") +tween_on_load = false +camera_3d_resource = SubResource("Resource_ft2w3") +look_at_damping = true + +[node name="PlayerCharacterBody3D2" parent="." instance=ExtResource("5_pxkua")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +script = ExtResource("6_3rtu0") + +[node name="NPCs" type="Node" parent="."] + +[node name="PlayerMeshInstance3D" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.96028, 0.519002, -1.52506) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_w3olp") + +[node name="PlayerMeshInstance3D2" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.59952, 0.519, 4.06618) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_cw102") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("6_uuxs3")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.00548, 0.805455, -6.37532) +use_collision = true +radius = 1.71971 +height = 2.61091 +sides = 32 + +[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 25.5597, 0.31181, -5.46661) +use_collision = true +radius = 2.77591 +height = 1.62362 +sides = 32 + +[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.96428, 0.31181, 6.6322) +use_collision = true +radius = 1.57419 +height = 3.47475 +sides = 32 + +[node name="CSGCylinder3D3" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.3959, 0.201103, 2.71259) +use_collision = true +radius = 1.41311 +height = 1.40221 +sides = 32 + +[node name="CSGCylinder3D4" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.02677, 0.201101, 11.6804) +use_collision = true +radius = 2.21673 +height = 7.88261 +sides = 32 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.8316, 0.805455, -8.78984) +use_collision = true +radius = 0.956285 +height = 2.61091 +sides = 32 + +[node name="CSGSphere3D" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.5989, -1.69814, -6.51262) +use_collision = true +radius = 3.34732 +rings = 32 + +[node name="CSGSphere3D2" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.17742, -0.599204, 8.81048) +use_collision = true +radius = 2.65844 +rings = 32 + +[node name="CSGSphere3D3" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.4392, -0.599204, -2.42244) +use_collision = true +radius = 2.14606 +rings = 32 + +[node name="CSGTorus3D" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.58998, -1.90735e-06, 0.346393) +use_collision = true +inner_radius = 1.3 +outer_radius = 2.0 +sides = 32 +ring_sides = 18 + +[node name="CSGTorus3D2" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 22.5502, -1.90735e-06, 7.89765) +use_collision = true +inner_radius = 0.971543 +outer_radius = 2.15226 +sides = 32 +ring_sides = 18 + +[node name="CSGBox3D" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.1202, 6.53866, -12.6331) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_auy8m") + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.53078, 0.760708, -6.1376) +use_collision = true +size = Vector3(2.64182, 2.52142, 2.30997) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.9646, 0.335247, 8.22829) +use_collision = true +size = Vector3(3.80964, 1.67049, 0.932048) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.70216, 0.138478, -4.36159) +use_collision = true +size = Vector3(1.53893, 1.27695, 1.80814) + +[node name="CSGBox3D6" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.1529, 0.138478, 5.20734) +use_collision = true +size = Vector3(4.03502, 1.27695, 5.2198) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 30.7692, 1.78638, -1.60318) +use_collision = true +size = Vector3(4.57784, 4.57276, 3.11285) diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_noise_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_noise_example_scene.tscn new file mode 100644 index 0000000..34aac82 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_noise_example_scene.tscn @@ -0,0 +1,195 @@ +[gd_scene load_steps=21 format=3 uid="uid://d0fyuvesb472p"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_25rmy"] +[ext_resource type="Script" uid="uid://x5g7kf5k2mac" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd" id="2_7nd2u"] +[ext_resource type="Script" uid="uid://cuffvge5ad4aa" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd" id="3_t4fhv"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="4_tnm2f"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="5_4webr"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="6_dmm4a"] +[ext_resource type="Script" uid="uid://ccmiitq0sdh7j" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd" id="7_2vtho"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="8_bw5oq"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="9_jpkpr"] +[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="10_8pr3k"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="11_vp57v"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_yvgu3"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vc6km"] +albedo_color = Color(0.988235, 0.498039, 0.498039, 1) + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_lsrh7"] +radius = 0.269454 + +[sub_resource type="Resource" id="Resource_lhgur"] +script = ExtResource("5_4webr") +duration = 1.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_ghjuj"] +script = ExtResource("6_dmm4a") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_2l4w0"] +script = ExtResource("3_t4fhv") +amplitude = 40.0 +frequency = 0.2 +randomize_noise_seed = 0 +noise_seed = 0 +rotational_noise = true +positional_noise = false +rotational_multiplier_x = 1.0 +rotational_multiplier_y = 1.0 +rotational_multiplier_z = 0.0 +positional_multiplier_x = 0.1 +positional_multiplier_y = 0.1 +positional_multiplier_z = 0.1 + +[sub_resource type="Resource" id="Resource_6tnhy"] +script = ExtResource("3_t4fhv") +amplitude = 10.0 +frequency = 20.0 +randomize_noise_seed = 0 +noise_seed = 928 +rotational_noise = true +positional_noise = false +rotational_multiplier_x = 1.0 +rotational_multiplier_y = 1.0 +rotational_multiplier_z = 0.1 +positional_multiplier_x = 1.0 +positional_multiplier_y = 1.0 +positional_multiplier_z = 1.0 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_qi01t"] +albedo_texture = ExtResource("9_jpkpr") +uv1_triplanar = true +uv1_world_triplanar = true + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ey47a"] +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_bottom_right = 20 +expand_margin_bottom = 6.0 + +[node name="Root2" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(-0.0372114, 0.0351643, 0.998689, -5.82077e-11, 0.999381, -0.0351886, -0.999307, -0.00130942, -0.0371883, -16.46, 0.503767, 4.249) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_25rmy") + +[node name="PlayerCharacterBody3D" type="CharacterBody3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(0.999897, 0.0143636, 0, -0.0143636, 0.999897, 0, 0, 0, 1, -16.46, 0.503767, 4.249) +script = ExtResource("2_7nd2u") + +[node name="PlayerVisual" type="MeshInstance3D" parent="PlayerCharacterBody3D"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.76837e-05, 0.00331134, 0) +mesh = SubResource("CapsuleMesh_yvgu3") +surface_material_override/0 = SubResource("StandardMaterial3D_vc6km") + +[node name="PlayerArea3D" type="Area3D" parent="PlayerCharacterBody3D"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerCharacterBody3D/PlayerArea3D"] +shape = SubResource("CapsuleShape3D_lsrh7") + +[node name="PlayerCollisionShape3D" type="CollisionShape3D" parent="PlayerCharacterBody3D"] +shape = SubResource("CapsuleShape3D_lsrh7") + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.00441533, 0, 0.999915, 0, 0.999995, 0, -0.999923, 0, 0.00441529, -16.46, 0.503767, 4.249) +top_level = true +script = ExtResource("4_tnm2f") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = SubResource("Resource_lhgur") +tween_on_load = false +camera_3d_resource = SubResource("Resource_ghjuj") +noise = SubResource("Resource_2l4w0") +noise_emitter_layer = 1 + +[node name="PlayerPhantomCameraNoiseEmitter3D" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(-4.37085e-08, 0, 0.999925, 0, 0.999995, 0, -0.999933, 0, -4.37081e-08, -16.46, 0.503767, 4.249) +script = ExtResource("7_2vtho") +noise = SubResource("Resource_6tnhy") +duration = 0.1 +decay_time = 0.1 + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("8_bw5oq")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="CSGBox3D" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.525, 6.539, 2.5) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_qi01t") + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 8.83707, 6.53866, -1.80739) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_qi01t") + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -38.9392, 6.53866, -1.80739) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_qi01t") + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.525, 6.539, 6) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_qi01t") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="EmitterTip" type="Panel" parent="."] +unique_name_in_owner = true +visible = false +anchors_preset = -1 +anchor_right = 0.3 +anchor_bottom = 0.1 +theme_override_styles/panel = SubResource("StyleBoxFlat_ey47a") + +[node name="Guidance" type="RichTextLabel" parent="EmitterTip"] +layout_mode = 1 +anchors_preset = -1 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 8 +theme_override_fonts/normal_font = ExtResource("10_8pr3k") +theme_override_fonts/bold_font = ExtResource("11_vp57v") +theme_override_font_sizes/normal_font_size = 18 +theme_override_font_sizes/bold_font_size = 24 +bbcode_enabled = true +text = "[center]Press [b]Q[/b] to trigger Noise Emitter" +fit_content = true diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_tweening_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_tweening_example_scene.tscn new file mode 100644 index 0000000..d596960 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/3d_tweening_example_scene.tscn @@ -0,0 +1,293 @@ +[gd_scene load_steps=23 format=3 uid="uid://cvnbgtbaxwj5p"] + +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="1_d55xf"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="2_d1opf"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_4whss"] +[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="4_8ap1e"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_1sgnu"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="6_lr46m"] +[ext_resource type="Script" uid="uid://bnhxcejvr6wi3" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="7_istoq"] +[ext_resource type="Script" uid="uid://tgv6xpi88sd0" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="7_x1jex"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="8_qepee"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="9_ptb3h"] + +[sub_resource type="Resource" id="Resource_0dtvs"] +script = ExtResource("5_1sgnu") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxShape3D" id="BoxShape3D_j6fha"] +size = Vector3(5, 0.1, 4) + +[sub_resource type="BoxMesh" id="BoxMesh_xg4en"] +size = Vector3(5, 0.1, 4) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_2dct5"] +transparency = 1 +albedo_color = Color(0.988235, 0.478431, 0.905882, 0.0901961) + +[sub_resource type="Resource" id="Resource_v8ndi"] +script = ExtResource("8_qepee") +duration = 0.6 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_kmep1"] +script = ExtResource("5_1sgnu") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_uxg44"] +script = ExtResource("8_qepee") +duration = 0.3 +transition = 1 +ease = 2 + +[sub_resource type="Resource" id="Resource_eu3bc"] +script = ExtResource("5_1sgnu") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_0nci0"] +script = ExtResource("8_qepee") +duration = 0.3 +transition = 8 +ease = 2 + +[sub_resource type="Resource" id="Resource_u0lff"] +script = ExtResource("5_1sgnu") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_50m5g"] +script = ExtResource("8_qepee") +duration = 1.2 +transition = 10 +ease = 2 + +[sub_resource type="Resource" id="Resource_rexf8"] +script = ExtResource("5_1sgnu") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[node name="Root" type="Node3D"] + +[node name="Environment" type="Node" parent="."] + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Floor" parent="Environment" instance=ExtResource("1_d55xf")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 2.5, 2) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("2_d1opf") + +[node name="------------------" type="Node" parent="."] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999889, 0, 0, 0, 0.707092, 0.707088, 0, -0.707092, 0.707088, 0, 2.5, 2) +top_level = true +script = ExtResource("3_4whss") +priority = 3 +follow_mode = 2 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = ExtResource("4_8ap1e") +tween_on_load = false +camera_3d_resource = SubResource("Resource_0dtvs") +follow_offset = Vector3(0, 2, 2) +follow_damping = true + +[node name="PlayerCharacterBody3D" parent="." instance=ExtResource("6_lr46m")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +script = ExtResource("7_x1jex") + +[node name="-------------------" type="Node" parent="."] + +[node name="Tweening Example" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1.97) + +[node name="Linear" type="Node3D" parent="Tweening Example"] + +[node name="EntryRoomTrigger" type="Area3D" parent="Tweening Example/Linear" node_paths=PackedStringArray("area_pcam")] +priority = 5 +script = ExtResource("7_istoq") +area_pcam = NodePath("../PhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Tweening Example/Linear/EntryRoomTrigger"] +shape = SubResource("BoxShape3D_j6fha") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Tweening Example/Linear/EntryRoomTrigger"] +mesh = SubResource("BoxMesh_xg4en") +skeleton = NodePath("../../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_2dct5") +metadata/_edit_group_ = true + +[node name="PhantomCamera3D" type="Node3D" parent="Tweening Example/Linear"] +transform = Transform3D(1, 0, 0, 0, 0.642788, 0.766044, 0, -0.766044, 0.642788, 0, 4.8, 3.3) +script = ExtResource("3_4whss") +tween_resource = SubResource("Resource_v8ndi") +camera_3d_resource = SubResource("Resource_kmep1") + +[node name="TweenNameLabel" type="Label3D" parent="Tweening Example/Linear"] +transform = Transform3D(1, 0, 0, 0, 0.695913, 0.718126, 0, -0.718126, 0.695913, -1.8, 0.5, 0) +text = "Transition Type: +Linear + +Duration: +0.6s" +font = ExtResource("9_ptb3h") +font_size = 48 + +[node name="Sine" type="Node3D" parent="Tweening Example"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -7.4) + +[node name="EntryRoomTrigger" type="Area3D" parent="Tweening Example/Sine" node_paths=PackedStringArray("area_pcam")] +priority = 5 +script = ExtResource("7_istoq") +area_pcam = NodePath("../PhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Tweening Example/Sine/EntryRoomTrigger"] +shape = SubResource("BoxShape3D_j6fha") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Tweening Example/Sine/EntryRoomTrigger"] +mesh = SubResource("BoxMesh_xg4en") +skeleton = NodePath("../../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_2dct5") +metadata/_edit_group_ = true + +[node name="PhantomCamera3D" type="Node3D" parent="Tweening Example/Sine"] +transform = Transform3D(1, 0, 0, 0, 0.642788, 0.766044, 0, -0.766044, 0.642788, 0, 4.8, 3.3) +script = ExtResource("3_4whss") +tween_resource = SubResource("Resource_uxg44") +camera_3d_resource = SubResource("Resource_eu3bc") + +[node name="TweenNameLabel" type="Label3D" parent="Tweening Example/Sine"] +transform = Transform3D(1, 0, 0, 0, 0.695913, 0.718126, 0, -0.718126, 0.695913, 1.7, 0.5, 0) +text = "Transition Type: +Sine + +Duration: +0.3s" +font = ExtResource("9_ptb3h") +font_size = 72 + +[node name="Circ" type="Node3D" parent="Tweening Example"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -14.1) + +[node name="EntryRoomTrigger" type="Area3D" parent="Tweening Example/Circ" node_paths=PackedStringArray("area_pcam")] +priority = 5 +script = ExtResource("7_istoq") +area_pcam = NodePath("../PhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Tweening Example/Circ/EntryRoomTrigger"] +shape = SubResource("BoxShape3D_j6fha") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Tweening Example/Circ/EntryRoomTrigger"] +mesh = SubResource("BoxMesh_xg4en") +skeleton = NodePath("../../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_2dct5") +metadata/_edit_group_ = true + +[node name="PhantomCamera3D" type="Node3D" parent="Tweening Example/Circ"] +transform = Transform3D(1, 0, 0, 0, 0.642788, 0.766044, 0, -0.766044, 0.642788, 0, 4.8, 3.3) +script = ExtResource("3_4whss") +tween_resource = SubResource("Resource_0nci0") +camera_3d_resource = SubResource("Resource_u0lff") + +[node name="TweenNameLabel" type="Label3D" parent="Tweening Example/Circ"] +transform = Transform3D(1, 0, 0, 0, 0.695913, 0.718126, 0, -0.718126, 0.695913, -1.8, 0.5, 0) +text = "Transition Type: +Circ + +Duration: +0.3s" +font = ExtResource("9_ptb3h") +font_size = 72 + +[node name="Back" type="Node3D" parent="Tweening Example"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -21) + +[node name="EntryRoomTrigger" type="Area3D" parent="Tweening Example/Back" node_paths=PackedStringArray("area_pcam")] +priority = 5 +script = ExtResource("7_istoq") +area_pcam = NodePath("../PhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Tweening Example/Back/EntryRoomTrigger"] +shape = SubResource("BoxShape3D_j6fha") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Tweening Example/Back/EntryRoomTrigger"] +mesh = SubResource("BoxMesh_xg4en") +skeleton = NodePath("../../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_2dct5") +metadata/_edit_group_ = true + +[node name="PhantomCamera3D" type="Node3D" parent="Tweening Example/Back"] +transform = Transform3D(1, 0, 0, 0, 0.642788, 0.766044, 0, -0.766044, 0.642788, -0.8, 4.8, 3.3) +script = ExtResource("3_4whss") +tween_resource = SubResource("Resource_50m5g") +camera_3d_resource = SubResource("Resource_rexf8") + +[node name="TweenNameLabel" type="Label3D" parent="Tweening Example/Back"] +transform = Transform3D(1, 0, 0, 0, 0.695913, 0.718126, 0, -0.718126, 0.695913, 1.7, 0.5, 0) +text = "Transition Type: +Back + +Duration: +1.2s" +font = ExtResource("9_ptb3h") +font_size = 48 diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_3d.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_3d.tscn new file mode 100644 index 0000000..b402af7 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_3d.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=5 format=3 uid="uid://cb83in8f0tbb1"] + +[ext_resource type="Script" uid="uid://tgv6xpi88sd0" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd" id="1_pl87s"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_8efyg"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_2cfaw"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_r3ldp"] +albedo_color = Color(0.988235, 0.498039, 0.498039, 1) + +[node name="PlayerCharacterBody3D2" type="CharacterBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.083587, 0.507, 2.05493) +script = ExtResource("1_pl87s") +metadata/_edit_group_ = true + +[node name="PlayerArea3D" type="Area3D" parent="."] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerArea3D"] +shape = SubResource("CapsuleShape3D_8efyg") + +[node name="PlayerCollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("CapsuleShape3D_8efyg") + +[node name="PlayerVisual" type="Node3D" parent="."] +unique_name_in_owner = true + +[node name="PlayerModel" type="MeshInstance3D" parent="PlayerVisual"] +mesh = SubResource("CapsuleMesh_2cfaw") +skeleton = NodePath("../..") +surface_material_override/0 = SubResource("StandardMaterial3D_r3ldp") diff --git a/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_third_person_3d.tscn b/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_third_person_3d.tscn new file mode 100644 index 0000000..9285cbb --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D-4.4/sub_scenes/playable_character_third_person_3d.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=6 format=3 uid="uid://bhd1kwv2fwj1y"] + +[ext_resource type="Script" uid="uid://bkr71vxe2t18n" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd" id="1_skas8"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_s61dn"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_47f0o"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_mv4do"] +albedo_color = Color(0.988235, 0.498039, 0.498039, 1) + +[sub_resource type="PrismMesh" id="PrismMesh_wg1x3"] +size = Vector3(0.5, 0.5, 0.3) + +[node name="PlayerCharacterBody3D" type="CharacterBody3D"] +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, -0.0194088, 0.506884, -0.0163251) +collision_layer = 2 +script = ExtResource("1_skas8") +metadata/_edit_group_ = true + +[node name="PlayerArea3D" type="Area3D" parent="."] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerArea3D"] +shape = SubResource("CapsuleShape3D_s61dn") + +[node name="PlayerCollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("CapsuleShape3D_s61dn") + +[node name="PlayerVisual" type="Node3D" parent="."] +unique_name_in_owner = true + +[node name="PlayerMeshInstance3D" type="MeshInstance3D" parent="PlayerVisual"] +transform = Transform3D(1, 0, 0, 0, 1, 4.65661e-10, 0, 0, 1, 0, 0, 0) +mesh = SubResource("CapsuleMesh_47f0o") +skeleton = NodePath("../..") +surface_material_override/0 = SubResource("StandardMaterial3D_mv4do") + +[node name="PlayerDirection" type="MeshInstance3D" parent="PlayerVisual"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, -9.31323e-10, 1, 4.65661e-10, 2.98023e-08, 0, 1, -0.0156226, 1.08631, 0) +mesh = SubResource("PrismMesh_wg1x3") +skeleton = NodePath("../..") +surface_material_override/0 = SubResource("StandardMaterial3D_mv4do") diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_example_scene.tscn new file mode 100644 index 0000000..5886011 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_example_scene.tscn @@ -0,0 +1,412 @@ +[gd_scene load_steps=40 format=3 uid="uid://ci12ytew5vwty"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_wn7ww"] +[ext_resource type="Script" uid="uid://uvw6pg1ut0ms" path="res://addons/phantom_camera/examples/scripts/3D/npc.gd" id="2_2n1da"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="2_e7gxt"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="2_tvx5n"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_y3dy8"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="3_f5qrw"] +[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="4_a27nb"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_m2vbn"] +[ext_resource type="Script" uid="uid://bnhxcejvr6wi3" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="4_moad5"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="7_jitt8"] + +[sub_resource type="Resource" id="Resource_jtk1d"] +script = ExtResource("4_m2vbn") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_o161n"] +script = ExtResource("4_m2vbn") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxMesh" id="BoxMesh_7tjw4"] +size = Vector3(2, 0.5, 4) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_hpllm"] +transparency = 1 +albedo_color = Color(0.988235, 0.478431, 0.905882, 0.0901961) + +[sub_resource type="BoxShape3D" id="BoxShape3D_65o6h"] +size = Vector3(2, 0.5, 4) + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_tpc7d"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_g0eml"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_v5iy7"] +albedo_color = Color(0.988235, 0.478431, 0.905882, 1) + +[sub_resource type="Resource" id="Resource_tpvee"] +script = ExtResource("7_jitt8") +duration = 0.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_bxbnv"] +script = ExtResource("4_m2vbn") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxShape3D" id="BoxShape3D_wcrbb"] +size = Vector3(6.8, 0.1, 5.4) + +[sub_resource type="Resource" id="Resource_7ih0k"] +script = ExtResource("7_jitt8") +duration = 0.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_4iyps"] +script = ExtResource("4_m2vbn") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxShape3D" id="BoxShape3D_ctyr8"] +size = Vector3(7.4, 0.1, 3.6) + +[sub_resource type="Resource" id="Resource_x5y0u"] +script = ExtResource("7_jitt8") +duration = 0.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_pgiyx"] +script = ExtResource("4_m2vbn") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxShape3D" id="BoxShape3D_ua072"] +size = Vector3(6.8, 0.1, 3.6) + +[sub_resource type="BoxMesh" id="BoxMesh_ugc3s"] +size = Vector3(1, 1, 2) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_68thd"] +albedo_color = Color(0.34902, 0.862745, 0.854902, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_wphly"] +size = Vector3(1, 0.5, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_gyp5s"] +size = Vector3(20, 40, 30) + +[sub_resource type="BoxShape3D" id="BoxShape3D_lfaqs"] +size = Vector3(20, 40, 30) + +[sub_resource type="BoxMesh" id="BoxMesh_n70lt"] +size = Vector3(14, 40, 6) + +[sub_resource type="BoxShape3D" id="BoxShape3D_jxmqm"] +size = Vector3(14, 40, 6) + +[sub_resource type="BoxMesh" id="BoxMesh_x0tgm"] +size = Vector3(8, 40, 1) + +[sub_resource type="BoxShape3D" id="BoxShape3D_t67ef"] +size = Vector3(50, 40, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_rmslh"] +size = Vector3(0.5, 6, 13.5) + +[sub_resource type="BoxMesh" id="BoxMesh_242ij"] +size = Vector3(2, 3, 3) + +[sub_resource type="BoxMesh" id="BoxMesh_niuda"] +size = Vector3(8, 6, 0.5) + +[node name="Root" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 0.948876, 0.315649, 0, -0.315649, 0.948876, -2.53871, 2, 9.76232) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_wn7ww") + +[node name="PlayerGroup" type="Node" parent="."] + +[node name="PlayerCharacterBody3D" parent="PlayerGroup" instance=ExtResource("2_tvx5n")] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.53871, 0.5, 7.26232) + +[node name="MovementInstructionsLabel" type="Label3D" parent="PlayerGroup"] +transform = Transform3D(1, 0, 0, 0, 0.866025, 0.5, 0, -0.5, 0.866025, -2.47682, -0.0708016, 7.93048) +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[WASD] to move" +font = ExtResource("2_e7gxt") +font_size = 48 + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="PlayerGroup" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999858, 0, 0, 0, 0.94884, 0.315632, 0, -0.315637, 0.948825, -2.53871, 2, 9.76232) +top_level = true +script = ExtResource("2_y3dy8") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../PlayerCharacterBody3D/PlayerVisual") +tween_resource = ExtResource("4_a27nb") +tween_on_load = false +camera_3d_resource = SubResource("Resource_jtk1d") +follow_offset = Vector3(0, 1.5, 2.5) +follow_damping = true + +[node name="NPCGroup" type="Node" parent="."] + +[node name="NPCPhantomCamera3D" type="Node3D" parent="NPCGroup"] +unique_name_in_owner = true +transform = Transform3D(0.616596, -0.109786, 0.779587, -2.23517e-08, 0.990229, 0.13945, -0.78728, -0.0859841, 0.610571, -2.98802, 1.50739, 1.19719) +script = ExtResource("2_y3dy8") +tween_resource = ExtResource("4_a27nb") +camera_3d_resource = SubResource("Resource_o161n") + +[node name="NPCDescriptionLabel" type="Label3D" parent="NPCGroup"] +transform = Transform3D(1, 0, 0, 0, 0.866026, 0.5, 0, -0.5, 0.866025, -3.04693, 0.367287, 0.953757) +text = "Input Example" +font = ExtResource("2_e7gxt") + +[node name="NPCDialogueExampleLabel" type="Label3D" parent="NPCGroup"] +unique_name_in_owner = true +transform = Transform3D(1, 4.54671e-10, 1.65487e-10, 4.25644e-10, 0.939693, 0.34202, 0, -0.34202, 0.939693, -4.46738, 1.58641, -0.253679) +modulate = Color(1, 0.603922, 0.254902, 1) +text = "Press [ F ] to change camera" +font = ExtResource("2_e7gxt") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="NPCGroup"] +transform = Transform3D(0.819152, 4.83851e-10, -0.573576, -3.92481e-09, 1, -6.3473e-09, 0.573576, 7.45058e-09, 0.819152, -3.46138, -0.4, 0.875321) +mesh = SubResource("BoxMesh_7tjw4") +skeleton = NodePath("../..") +surface_material_override/0 = SubResource("StandardMaterial3D_hpllm") +metadata/_edit_group_ = true + +[node name="NPCInteractionArea3D" type="Area3D" parent="NPCGroup/NPCInteractionZoneMesh"] +unique_name_in_owner = true +transform = Transform3D(1, -2.68591e-26, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) +monitorable = false + +[node name="NPCInterationCollisionShape3D" type="CollisionShape3D" parent="NPCGroup/NPCInteractionZoneMesh/NPCInteractionArea3D"] +shape = SubResource("BoxShape3D_65o6h") + +[node name="NPC" type="StaticBody3D" parent="NPCGroup"] +transform = Transform3D(1, 4.83851e-10, 0, 4.25644e-10, 1, -7.45058e-09, 0, 7.45058e-09, 1, -4.56338, 0.5, -0.272679) +script = ExtResource("2_2n1da") + +[node name="PlayerCollisionShape3D2" type="CollisionShape3D" parent="NPCGroup/NPC"] +transform = Transform3D(1, -2.68591e-26, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) +shape = SubResource("CapsuleShape3D_tpc7d") + +[node name="NPCMesh" type="MeshInstance3D" parent="NPCGroup/NPC"] +transform = Transform3D(1, -2.68591e-26, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) +mesh = SubResource("CapsuleMesh_g0eml") +skeleton = NodePath("../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_v5iy7") + +[node name="MoveToLocation" type="Node3D" parent="NPCGroup"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.70084, 0.5, 0.962891) + +[node name="FixedCameraTriggerZone" type="Node" parent="."] + +[node name="FixedCameraLabel" type="Label3D" parent="FixedCameraTriggerZone"] +unique_name_in_owner = true +transform = Transform3D(0.939693, 0.280167, -0.196175, 1.49012e-08, 0.573577, 0.819152, 0.34202, -0.769751, 0.538986, -0.538716, -0.247626, 3.13456) +text = "Fixed Camera +Example" +font = ExtResource("2_e7gxt") + +[node name="NorthRoomPhantomCamera3D" type="Node3D" parent="FixedCameraTriggerZone"] +transform = Transform3D(0.38357, -0.555836, 0.737507, -0.105898, 0.766851, 0.633027, -0.917417, -0.320912, 0.235279, 6.89638, 4.73986, 0.115512) +script = ExtResource("2_y3dy8") +tween_resource = SubResource("Resource_tpvee") +camera_3d_resource = SubResource("Resource_bxbnv") + +[node name="NorthRoomTrigger" type="Area3D" parent="FixedCameraTriggerZone" node_paths=PackedStringArray("area_pcam")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, -0.45, -0.9) +priority = 5 +script = ExtResource("4_moad5") +area_pcam = NodePath("../NorthRoomPhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="FixedCameraTriggerZone/NorthRoomTrigger"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.6, 0, -0.4) +shape = SubResource("BoxShape3D_wcrbb") + +[node name="EntryRoomPhantomCamera3D" type="Node3D" parent="FixedCameraTriggerZone"] +transform = Transform3D(0.258818, -0.482963, 0.836515, 1.3027e-15, 0.866025, 0.499999, -0.965924, -0.129409, 0.224143, 6.69741, 4.73364, 4.02374) +script = ExtResource("2_y3dy8") +tween_resource = SubResource("Resource_7ih0k") +camera_3d_resource = SubResource("Resource_4iyps") + +[node name="EntryRoomTrigger" type="Area3D" parent="FixedCameraTriggerZone" node_paths=PackedStringArray("area_pcam")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.00003, -0.454982, 3.00572) +priority = 5 +script = ExtResource("4_moad5") +area_pcam = NodePath("../EntryRoomPhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="FixedCameraTriggerZone/EntryRoomTrigger"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.3, 0, 0.2) +shape = SubResource("BoxShape3D_ctyr8") + +[node name="SouthRoomPhantomCamera3D" type="Node3D" parent="FixedCameraTriggerZone"] +transform = Transform3D(-0.766043, -0.492403, 0.413175, 0, 0.642787, 0.766043, -0.642786, 0.586825, -0.492403, 6.89741, 4.73364, 5.62374) +script = ExtResource("2_y3dy8") +tween_resource = SubResource("Resource_x5y0u") +camera_3d_resource = SubResource("Resource_pgiyx") + +[node name="SouthRoomTrigger" type="Area3D" parent="FixedCameraTriggerZone" node_paths=PackedStringArray("area_pcam")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, -0.45, 6.7) +priority = 5 +script = ExtResource("4_moad5") +area_pcam = NodePath("../SouthRoomPhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="FixedCameraTriggerZone/SouthRoomTrigger"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.6, 0, 0.1) +shape = SubResource("BoxShape3D_ua072") + +[node name="CSGMesh3D" type="CSGMesh3D" parent="FixedCameraTriggerZone"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.14238, 1.82571, 2.88655) +mesh = SubResource("BoxMesh_ugc3s") +material = SubResource("StandardMaterial3D_68thd") + +[node name="CSGMesh3D2" type="CSGMesh3D" parent="FixedCameraTriggerZone/CSGMesh3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00192642, -0.0120339, 0.00494432) +operation = 2 +mesh = SubResource("BoxMesh_wphly") +material = SubResource("StandardMaterial3D_68thd") + +[node name="Environment" type="Node" parent="."] + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Environment" type="Node3D" parent="Environment"] + +[node name="Floor" parent="Environment/Environment" instance=ExtResource("3_f5qrw")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="West Wall" type="StaticBody3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16, 0.5, 0) +metadata/_edit_group_ = true +metadata/_edit_lock_ = true + +[node name="MeshInstance3D2" type="MeshInstance3D" parent="Environment/Environment/West Wall"] +mesh = SubResource("BoxMesh_gyp5s") +skeleton = NodePath("") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Environment/Environment/West Wall"] +shape = SubResource("BoxShape3D_lfaqs") + +[node name="East Wall" type="StaticBody3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16.999, 0.502, 0) +metadata/_edit_group_ = true +metadata/_edit_lock_ = true + +[node name="MeshInstance3D2" type="MeshInstance3D" parent="Environment/Environment/East Wall"] +mesh = SubResource("BoxMesh_gyp5s") +skeleton = NodePath("") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Environment/Environment/East Wall"] +shape = SubResource("BoxShape3D_lfaqs") + +[node name="North Wall" type="StaticBody3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, -6.90828) +metadata/_edit_group_ = true +metadata/_edit_lock_ = true + +[node name="MeshInstance3D2" type="MeshInstance3D" parent="Environment/Environment/North Wall"] +mesh = SubResource("BoxMesh_n70lt") +skeleton = NodePath("") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Environment/Environment/North Wall"] +shape = SubResource("BoxShape3D_jxmqm") + +[node name="South Wall" type="StaticBody3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, 0.5, 9.087) +metadata/_edit_group_ = true + +[node name="MeshInstance3D3" type="MeshInstance3D" parent="Environment/Environment/South Wall"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0, 0) +mesh = SubResource("BoxMesh_x0tgm") +skeleton = NodePath("") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Environment/Environment/South Wall"] +shape = SubResource("BoxShape3D_t67ef") + +[node name="FixedCamOuterWall" type="CSGMesh3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 2) +use_collision = true +mesh = SubResource("BoxMesh_rmslh") + +[node name="FixedCamOuterDoorway" type="CSGMesh3D" parent="Environment/Environment/FixedCamOuterWall"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.5, 1) +operation = 2 +mesh = SubResource("BoxMesh_242ij") + +[node name="FixedCamNorthWall" type="CSGMesh3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 2.5, 1) +use_collision = true +mesh = SubResource("BoxMesh_niuda") + +[node name="FixedCamNorthDoorway" type="CSGMesh3D" parent="Environment/Environment/FixedCamNorthWall"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.5, 0) +operation = 2 +mesh = SubResource("BoxMesh_242ij") + +[node name="FixedCamSouthWall" type="CSGMesh3D" parent="Environment/Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 2.5, 5.1) +use_collision = true +mesh = SubResource("BoxMesh_niuda") + +[node name="FixedCamSouthDoorway" type="CSGMesh3D" parent="Environment/Environment/FixedCamSouthWall"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.50541, 1.19209e-07) +operation = 2 +mesh = SubResource("BoxMesh_242ij") + +[editable path="PlayerGroup/PlayerCharacterBody3D"] diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_framed_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_framed_example_scene.tscn new file mode 100644 index 0000000..0be8a65 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_framed_example_scene.tscn @@ -0,0 +1,156 @@ +[gd_scene load_steps=10 format=3 uid="uid://c4llb3gsbfv1a"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_7824u"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_g1bv4"] +[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="3_420vh"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_oqbub"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_t4fso"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="5_c0upu"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_f2w3x"] + +[sub_resource type="Resource" id="Resource_wg1pr"] +script = ExtResource("4_oqbub") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_auy8m"] +albedo_texture = ExtResource("5_c0upu") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="Root" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 0.793353, 0.608762, 0, -0.608762, 0.793353, 0.083587, 2.94168, 5.22787) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_7824u") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.99995, 0, 0, 0, 0.79324, 0.608671, 0, -0.608675, 0.793235, 0, 2.43468, 3.17294) +top_level = true +script = ExtResource("2_g1bv4") +follow_mode = 5 +follow_target = NodePath("../PlayerCharacterBody3D2/PlayerVisual") +tween_resource = ExtResource("3_420vh") +tween_on_load = false +camera_3d_resource = SubResource("Resource_wg1pr") +follow_damping = true +follow_distance = 4.0 +dead_zone_width = 0.161 +dead_zone_height = 0.386 +show_viewfinder_in_play = true +spring_length = 4.0 + +[node name="PlayerCharacterBody3D2" parent="Player" instance=ExtResource("5_f2w3x")] + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("4_t4fso")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.636134, 0.805455, -6.37532) +use_collision = true +radius = 1.71971 +height = 2.61091 +sides = 32 + +[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.54597, -0.540694, -3.39517) +use_collision = true +radius = 1.53269 +height = 2.5036 +sides = 32 + +[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.64877, -1.50101, 1.22863) +use_collision = true +radius = 1.57419 +height = 3.47475 +sides = 32 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.4732, 0.805455, -8.78984) +use_collision = true +radius = 0.956285 +height = 2.61091 +sides = 32 + +[node name="CSGSphere3D" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.40027, -1.69814, 3.36997) +use_collision = true +radius = 3.34732 +rings = 32 + +[node name="CSGSphere3D2" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.13768, -0.599204, -1.04651) +use_collision = true +radius = 2.65844 +rings = 32 + +[node name="CSGSphere3D3" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.7976, -0.599204, -2.42244) +use_collision = true +radius = 2.14606 +rings = 32 + +[node name="CSGTorus3D2" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.84078, -0.497663, 4.44352) +use_collision = true +inner_radius = 0.971543 +outer_radius = 2.15226 +sides = 32 +ring_sides = 18 + +[node name="CSGBox3D" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.52545, 6.53866, -12.6331) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_auy8m") + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.88916, 0.760708, -6.1376) +use_collision = true +size = Vector3(2.64182, 2.52142, 2.30997) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.83837, -0.241718, 7.14677) +use_collision = true +size = Vector3(3.80964, 1.67049, 0.932048) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.34377, 0.138478, -4.36159) +use_collision = true +size = Vector3(1.53893, 1.27695, 1.80814) + +[node name="CSGBox3D6" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.9834, 0.138478, -1.89037) +use_collision = true +size = Vector3(4.03502, 1.27695, 5.2198) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.38147, 0.0440434, 8.36617) +use_collision = true +size = Vector3(4.57784, 1.08809, 3.11285) + +[editable path="Player/PlayerCharacterBody3D2"] diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_glued_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_glued_example_scene.tscn new file mode 100644 index 0000000..0fbcc3b --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_glued_example_scene.tscn @@ -0,0 +1,208 @@ +[gd_scene load_steps=14 format=3 uid="uid://dw2yflu7up2rr"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_pmeux"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_q1ygp"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_hpix1"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_8qqha"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_evdoo"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_vqgn5"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="5_wr3bq"] + +[sub_resource type="Resource" id="Resource_ucp3e"] +script = ExtResource("3_hpix1") +duration = 1.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_ab013"] +script = ExtResource("4_evdoo") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_2h36r"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_w3olp"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cw102"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_auy8m"] +albedo_texture = ExtResource("5_wr3bq") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="Node3D" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 0.638767, 0.7694, 0, -0.7694, 0.638768, 0, 6.39, 7) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_pmeux") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999954, 0, 0, 0, 0.638683, 0.769345, 0, -0.769298, 0.638723, 0, 6.39, 7) +top_level = true +script = ExtResource("2_q1ygp") +priority = 5 +follow_mode = 1 +follow_target = NodePath("../PlayerCharacterBody3D/PlayerVisual") +tween_resource = SubResource("Resource_ucp3e") +tween_on_load = false +camera_3d_resource = SubResource("Resource_ab013") +follow_damping = true +follow_damping_value = Vector3(0.3, 0.3, 0.3) + +[node name="PlayerCharacterBody3D" parent="Player" instance=ExtResource("5_vqgn5")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 6.39, 7) +enable_gravity = false + +[node name="PlayerVisual" parent="Player/PlayerCharacterBody3D" index="2"] +visible = false + +[node name="NPCs" type="Node" parent="."] + +[node name="PlayerMeshInstance3D" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.04486, 0.519002, -1.52506) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_w3olp") + +[node name="PlayerMeshInstance3D2" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.51494, 0.519, 4.06618) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_cw102") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("4_8qqha")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.62737, 0.805455, -6.37532) +use_collision = true +radius = 1.71971 +height = 2.61091 +sides = 32 + +[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 24.9378, 0.31181, -5.46661) +use_collision = true +radius = 2.77591 +height = 1.62362 +sides = 32 + +[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.58617, 0.31181, 6.6322) +use_collision = true +radius = 1.57419 +height = 3.47475 +sides = 32 + +[node name="CSGCylinder3D3" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.774, 0.201103, 2.71259) +use_collision = true +radius = 1.41311 +height = 1.40221 +sides = 32 + +[node name="CSGCylinder3D4" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.40488, 0.201101, 11.6804) +use_collision = true +radius = 2.21673 +height = 7.88261 +sides = 32 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.20971, 0.805455, -8.78984) +use_collision = true +radius = 0.956285 +height = 2.61091 +sides = 32 + +[node name="CSGSphere3D" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.9771, -1.69814, -6.51262) +use_collision = true +radius = 3.34732 +rings = 32 + +[node name="CSGSphere3D2" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.555532, -0.599204, 8.81048) +use_collision = true +radius = 2.65844 +rings = 32 + +[node name="CSGSphere3D3" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.0611, -0.599204, -2.42244) +use_collision = true +radius = 2.14606 +rings = 32 + +[node name="CSGTorus3D" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.21187, -1.90735e-06, 0.346393) +use_collision = true +inner_radius = 1.3 +outer_radius = 2.0 +sides = 32 +ring_sides = 18 + +[node name="CSGTorus3D2" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 21.9283, -1.90735e-06, 7.89765) +use_collision = true +inner_radius = 0.971543 +outer_radius = 2.15226 +sides = 32 +ring_sides = 18 + +[node name="CSGBox3D" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.49828, 6.53866, -12.6331) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_auy8m") + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.15267, 0.760708, -6.1376) +use_collision = true +size = Vector3(2.64182, 2.52142, 2.30997) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.3427, 0.335247, 8.22829) +use_collision = true +size = Vector3(3.80964, 1.67049, 0.932048) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.08027, 0.138478, -4.36159) +use_collision = true +size = Vector3(1.53893, 1.27695, 1.80814) + +[node name="CSGBox3D6" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.7748, 0.138478, 5.20734) +use_collision = true +size = Vector3(4.03502, 1.27695, 5.2198) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 30.1473, 1.78638, -1.60318) +use_collision = true +size = Vector3(4.57784, 4.57276, 3.11285) + +[editable path="Player/PlayerCharacterBody3D"] diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_group_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_group_example_scene.tscn new file mode 100644 index 0000000..29eb009 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_group_example_scene.tscn @@ -0,0 +1,180 @@ +[gd_scene load_steps=13 format=3 uid="uid://dbfiy6svpcqap"] + +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="1_r00ve"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_pi7mp"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="2_wnlkq"] +[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="3_1eb12"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="3_a5igg"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="3_wr1tj"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_70gws"] + +[sub_resource type="Resource" id="Resource_1iman"] +script = ExtResource("5_70gws") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_2h36r"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_w3olp"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cw102"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_auy8m"] +albedo_texture = ExtResource("3_a5igg") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="Node3D" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 0.906308, 0.422618, 0, -0.422618, 0.906308, -7.26116, 5.72974, 12.279) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("3_wr1tj") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Player" type="Node" parent="."] + +[node name="PlayerCharacterBody3D2" parent="Player" instance=ExtResource("2_wnlkq")] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="Player" node_paths=PackedStringArray("follow_targets")] +unique_name_in_owner = true +transform = Transform3D(0.999954, 0, 0, 0, 0.906188, 0.422588, 0, -0.422562, 0.906243, -7.30295, 5.45858, 11.2744) +top_level = true +script = ExtResource("2_pi7mp") +priority = 5 +follow_mode = 3 +follow_targets = [NodePath("../PlayerCharacterBody3D2"), NodePath("../../NPCs/PlayerMeshInstance3D"), NodePath("../../NPCs/PlayerMeshInstance3D2")] +tween_resource = ExtResource("3_1eb12") +tween_on_load = false +camera_3d_resource = SubResource("Resource_1iman") +follow_damping = true +follow_distance = 5.0 +auto_follow_distance = true +auto_follow_distance_min = 5.0 +auto_follow_distance_max = 15.0 +auto_follow_distance_divisor = 20.0 +spring_length = 5.0 + +[node name="NPCs" type="Node" parent="."] + +[node name="PlayerMeshInstance3D" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.6059, 0.519002, 0.128472) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_w3olp") + +[node name="PlayerMeshInstance3D2" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.0461, 0.519, 0.249913) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_cw102") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("1_r00ve")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="Wall" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.52545, 6.53866, -12.6331) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_auy8m") + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.6511, 0.805455, -6.37532) +use_collision = true +radius = 1.71971 +height = 2.61091 +sides = 32 + +[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.9141, 0.31181, -5.46661) +use_collision = true +radius = 2.77591 +height = 1.62362 +sides = 32 + +[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.6099, 0.31181, 6.6322) +use_collision = true +radius = 1.57419 +height = 3.47475 +sides = 32 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.81402, 0.805455, -8.78984) +use_collision = true +radius = 0.956285 +height = 2.61091 +sides = 32 + +[node name="CSGSphere3D" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.95333, -1.69814, -6.51262) +use_collision = true +radius = 3.34732 +rings = 32 + +[node name="CSGSphere3D2" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.4682, -0.599204, 8.81048) +use_collision = true +radius = 2.65844 +rings = 32 + +[node name="CSGSphere3D3" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -26.0848, -0.599204, -2.42244) +use_collision = true +radius = 2.14606 +rings = 32 + +[node name="CSGTorus3D2" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.90455, -1.90735e-06, 7.89765) +use_collision = true +inner_radius = 0.971543 +outer_radius = 2.15226 +sides = 32 +ring_sides = 18 + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.1764, 0.760708, -6.1376) +use_collision = true +size = Vector3(2.64182, 2.52142, 2.30997) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.31901, 0.335247, 8.22829) +use_collision = true +size = Vector3(3.80964, 1.67049, 0.932048) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.94346, 0.138478, -4.36159) +use_collision = true +size = Vector3(1.53893, 1.27695, 1.80814) + +[node name="CSGBox3D6" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -26.7985, 0.138478, 5.20734) +use_collision = true +size = Vector3(4.03502, 1.27695, 5.2198) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 18.1236, 1.78638, -1.60318) +use_collision = true +size = Vector3(4.57784, 4.57276, 3.11285) + +[editable path="Player/PlayerCharacterBody3D2"] diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_path_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_path_example_scene.tscn new file mode 100644 index 0000000..e2d196a --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_path_example_scene.tscn @@ -0,0 +1,244 @@ +[gd_scene load_steps=24 format=3 uid="uid://dxx7ngi0emt8h"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_lm5n8"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_bd7x3"] +[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="3_od2r4"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_dfdlo"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_hni7n"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="4_lfwkm"] +[ext_resource type="Script" uid="uid://cgknbkjar73w" path="res://addons/phantom_camera/examples/scripts/3D/path_follow.gd" id="5_vdqkm"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_vms5c"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="6_obo83"] + +[sub_resource type="Resource" id="Resource_ofv2c"] +script = ExtResource("4_hni7n") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_01tho"] +script = ExtResource("4_lfwkm") +duration = 1.2 +transition = 3 +ease = 2 + +[sub_resource type="Resource" id="Resource_syh5m"] +script = ExtResource("4_hni7n") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Curve3D" id="Curve3D_b33df"] +_data = { +"points": PackedVector3Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10), +"tilts": PackedFloat32Array(0, 0) +} +point_count = 2 + +[sub_resource type="BoxShape3D" id="BoxShape3D_aovgi"] +size = Vector3(6, 0.1, 10) + +[sub_resource type="BoxMesh" id="BoxMesh_0hdeh"] +size = Vector3(6, 0.1, 10) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fsm1b"] +transparency = 1 +albedo_color = Color(0.988235, 0.478431, 0.905882, 0.0901961) + +[sub_resource type="Resource" id="Resource_xci4c"] +script = ExtResource("4_hni7n") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Curve3D" id="Curve3D_8uw2x"] +_data = { +"points": PackedVector3Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0), +"tilts": PackedFloat32Array(0, 0) +} +point_count = 2 + +[sub_resource type="BoxShape3D" id="BoxShape3D_ctnqu"] +size = Vector3(12, 0.1, 4) + +[sub_resource type="BoxMesh" id="BoxMesh_f6dp8"] +size = Vector3(12, 0.1, 4) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gwnkj"] +transparency = 1 +albedo_color = Color(0.568403, 0.988235, 0.762724, 0.0901961) + +[sub_resource type="BoxMesh" id="BoxMesh_7l3dh"] + +[sub_resource type="BoxMesh" id="BoxMesh_as6ok"] + +[node name="Root" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(0.999996, -0.00216283, 0.00184472, 0, 0.648938, 0.760841, -0.00284268, -0.760838, 0.648936, 0, 2.507, 1.5) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_lm5n8") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999807, -0.00216249, 0.00184445, 0, 0.648836, 0.760728, -0.00284214, -0.760718, 0.648839, 0, 2.507, 1.5) +top_level = true +script = ExtResource("3_bd7x3") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../PlayerCharacterBody3D2/PlayerVisual") +tween_resource = ExtResource("3_od2r4") +tween_on_load = false +camera_3d_resource = SubResource("Resource_ofv2c") +follow_offset = Vector3(0, 2, 1.5) +follow_damping = true + +[node name="PlayerCharacterBody3D2" parent="." instance=ExtResource("5_vms5c")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.507, 0) + +[node name="Paths" type="Node" parent="."] + +[node name="PathPhantomCamera3D" type="Node3D" parent="Paths" node_paths=PackedStringArray("follow_target", "follow_path")] +transform = Transform3D(-4.37114e-08, -1, -4.37114e-08, 0, -4.37114e-08, 1, -1, 4.37114e-08, 1.91069e-15, -0.31028, 7.9199, -1.60976) +top_level = true +script = ExtResource("3_bd7x3") +priority = 2 +follow_mode = 4 +follow_target = NodePath("../../PlayerCharacterBody3D2/PlayerVisual") +follow_path = NodePath("../FollowPath") +tween_resource = SubResource("Resource_01tho") +camera_3d_resource = SubResource("Resource_syh5m") +follow_damping = true + +[node name="FollowPath" type="Path3D" parent="Paths"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.31028, 7.9199, -1.60976) +curve = SubResource("Curve3D_b33df") + +[node name="StraightPathFollowTrigger" type="Area3D" parent="Paths" node_paths=PackedStringArray("path_pcam")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0420399, -0.45, -6.73666) +priority = 5 +script = ExtResource("5_vdqkm") +path_pcam = NodePath("../PathPhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Paths/StraightPathFollowTrigger"] +shape = SubResource("BoxShape3D_aovgi") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Paths/StraightPathFollowTrigger/CollisionShape3D"] +mesh = SubResource("BoxMesh_0hdeh") +skeleton = NodePath("../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_fsm1b") +metadata/_edit_group_ = true + +[node name="PathPhantomCamera3D2" type="Node3D" parent="Paths" node_paths=PackedStringArray("follow_target", "follow_path")] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 7.9199, -13.4572) +top_level = true +visible = false +script = ExtResource("3_bd7x3") +priority = 2 +follow_mode = 4 +follow_target = NodePath("../../PlayerCharacterBody3D2/PlayerVisual") +follow_path = NodePath("../FollowPath2") +tween_resource = SubResource("Resource_01tho") +camera_3d_resource = SubResource("Resource_xci4c") +follow_damping = true +follow_damping_value = Vector3(0.6, 0.1, 0.1) + +[node name="FollowPath2" type="Path3D" parent="Paths"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.97141, 7.9199, -13.4572) +curve = SubResource("Curve3D_8uw2x") + +[node name="StraightPathFollowTrigger2" type="Area3D" parent="Paths" node_paths=PackedStringArray("path_pcam")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0420399, 0, -13.7367) +priority = 5 +script = ExtResource("5_vdqkm") +path_pcam = NodePath("../PathPhantomCamera3D2") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Paths/StraightPathFollowTrigger2"] +shape = SubResource("BoxShape3D_ctnqu") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Paths/StraightPathFollowTrigger2/CollisionShape3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.45, 0) +mesh = SubResource("BoxMesh_f6dp8") +skeleton = NodePath("../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_gwnkj") +metadata/_edit_group_ = true + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("4_dfdlo")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="Floor3" parent="Environment" instance=ExtResource("4_dfdlo")] +transform = Transform3D(6, 0, 0, 0, 1, 0, 0, 0, 1, -0.44204, 0, 1.76334) + +[node name="Floor2" parent="Environment/Floor3" instance=ExtResource("4_dfdlo")] +transform = Transform3D(0.166667, 0, 0, 0, 3, 0, 0, 0, 14, -0.516667, 1, -6.5) + +[node name="Floor5" parent="Environment/Floor3" instance=ExtResource("4_dfdlo")] +transform = Transform3D(0.166667, 0, 0, 0, 3, 0, 0, 0, 14, 0.65, 1, -6.5) + +[node name="Floor4" parent="Environment/Floor3" instance=ExtResource("4_dfdlo")] +transform = Transform3D(2, 0, 0, 0, 3, 0, 0, 0, 1, 0.0666667, 1, -18) + +[node name="Floor6" parent="Environment/Floor3" instance=ExtResource("4_dfdlo")] +transform = Transform3D(0.333333, 0, 0, 0, 3, 0, 0, 0, 1, -0.766667, 1, -13) +mesh = SubResource("BoxMesh_7l3dh") + +[node name="Floor8" parent="Environment/Floor3" instance=ExtResource("4_dfdlo")] +transform = Transform3D(0.166667, 0, 0, 0, 3, 0, 0, 0, 6, -1.01667, 1, -15.5) +mesh = SubResource("BoxMesh_as6ok") + +[node name="Floor9" parent="Environment/Floor3" instance=ExtResource("4_dfdlo")] +transform = Transform3D(0.166667, 0, 0, 0, 3, 0, 0, 0, 6, 1.15, 1, -15.5) +mesh = SubResource("BoxMesh_as6ok") + +[node name="Floor7" parent="Environment/Floor3" instance=ExtResource("4_dfdlo")] +transform = Transform3D(0.333333, 0, 0, 0, 3, 0, 0, 0, 1, 0.9, 1, -13) +mesh = SubResource("BoxMesh_7l3dh") + +[node name="NPCDescriptionLabel" type="Label3D" parent="Environment"] +transform = Transform3D(5.21541e-08, -1, -7.7486e-07, -1.10675e-15, 2.23517e-07, 0.999999, -0.999999, -7.45058e-08, -5.68829e-14, -3.47306, 2.59595, -5.51755) +text = "Camera follows player while confined to a Path3D" +font = ExtResource("6_obo83") +font_size = 64 + +[node name="MovementInstructionsLabel" type="Label3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.02174, -0.455369, 0.570585) +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[WASD] to move" +font = ExtResource("6_obo83") +font_size = 48 + +[editable path="PlayerCharacterBody3D2"] diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_simple_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_simple_example_scene.tscn new file mode 100644 index 0000000..a3da80d --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_simple_example_scene.tscn @@ -0,0 +1,163 @@ +[gd_scene load_steps=11 format=3 uid="uid://buglvjwpn85ny"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_3tok8"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_grjck"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_j3f4l"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_4u2y6"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_sielv"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="5_1tybo"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="5_7ywxt"] + +[sub_resource type="Resource" id="Resource_28vpp"] +script = ExtResource("3_j3f4l") +duration = 1.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_axopo"] +script = ExtResource("4_sielv") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_auy8m"] +albedo_texture = ExtResource("5_1tybo") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="Node3D2" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 0.906308, 0.422618, 0, -0.422618, 0.906308, -13.2122, 2.5, 10.4016) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_3tok8") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Player" type="Node" parent="."] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="Player" node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999954, 0, 0, 0, 0.906188, 0.422588, 0, -0.422562, 0.906243, -13.2122, 2.5, 10.4016) +top_level = true +script = ExtResource("2_grjck") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../PlayerCharacterBody3D/PlayerVisual") +tween_resource = SubResource("Resource_28vpp") +tween_on_load = false +camera_3d_resource = SubResource("Resource_axopo") +follow_offset = Vector3(0, 2, 2) +follow_damping = true + +[node name="PlayerCharacterBody3D" parent="Player" instance=ExtResource("5_7ywxt")] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.2122, 0.5, 8.40162) + +[node name="NPCs" type="Node" parent="."] + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("4_4u2y6")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.6511, 0.805455, -6.37532) +use_collision = true +radius = 1.71971 +height = 2.61091 +sides = 32 + +[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.8332, -0.540694, -3.39517) +use_collision = true +radius = 1.53269 +height = 2.5036 +sides = 32 + +[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.936, -1.50101, 1.22863) +use_collision = true +radius = 1.57419 +height = 3.47475 +sides = 32 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.81402, 0.805455, -8.78984) +use_collision = true +radius = 0.956285 +height = 2.61091 +sides = 32 + +[node name="CSGSphere3D" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -23.6875, -1.69814, 3.36997) +use_collision = true +radius = 3.34732 +rings = 32 + +[node name="CSGSphere3D2" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.14955, -0.599204, -1.04651) +use_collision = true +radius = 2.65844 +rings = 32 + +[node name="CSGSphere3D3" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -26.0848, -0.599204, -2.42244) +use_collision = true +radius = 2.14606 +rings = 32 + +[node name="CSGTorus3D2" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.44645, -0.497663, 4.44352) +use_collision = true +inner_radius = 0.971543 +outer_radius = 2.15226 +sides = 32 +ring_sides = 18 + +[node name="CSGBox3D" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.52545, 6.53866, -12.6331) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_auy8m") + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.1764, 0.760708, -6.1376) +use_collision = true +size = Vector3(2.64182, 2.52142, 2.30997) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -18.1256, 0.335247, 7.14677) +use_collision = true +size = Vector3(3.80964, 1.67049, 0.932048) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.94346, 0.138478, -4.36159) +use_collision = true +size = Vector3(1.53893, 1.27695, 1.80814) + +[node name="CSGBox3D6" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.30382, 0.138478, -1.89037) +use_collision = true +size = Vector3(4.03502, 1.27695, 5.2198) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.04727, 0.0440434, 8.36617) +use_collision = true +size = Vector3(4.57784, 1.08809, 3.11285) + +[editable path="Player/PlayerCharacterBody3D"] diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_attribtues_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_attribtues_example_scene.tscn new file mode 100644 index 0000000..bdaef4e --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_attribtues_example_scene.tscn @@ -0,0 +1,220 @@ +[gd_scene load_steps=21 format=3 uid="uid://5pjtxclcnx4f"] + +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="1_s26cy"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_m2d6w"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="3_l7kg8"] +[ext_resource type="PackedScene" uid="uid://mskcwn1a1v6d" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn" id="4_qcyfd"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_8von1"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="6_o1fj6"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_amcmx"] +[ext_resource type="Texture2D" uid="uid://c3mskbmvnpwux" path="res://addons/phantom_camera/examples/textures/3D/target.png" id="8_rjcgw"] + +[sub_resource type="Resource" id="Resource_8fhct"] +script = ExtResource("2_m2d6w") +duration = 0.3 +transition = 2 +ease = 1 + +[sub_resource type="Resource" id="Resource_7m0fv"] +script = ExtResource("3_l7kg8") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_i42vj"] +dof_blur_far_enabled = true +dof_blur_far_distance = 5.99 +dof_blur_near_enabled = true +dof_blur_near_distance = 0.05 +dof_blur_amount = 0.21 + +[sub_resource type="Resource" id="Resource_e7t18"] +script = ExtResource("2_m2d6w") +duration = 0.4 +transition = 2 +ease = 1 + +[sub_resource type="Resource" id="Resource_jogxh"] +script = ExtResource("3_l7kg8") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 1.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_fvhx5"] +dof_blur_far_enabled = true +dof_blur_far_distance = 31.1 +dof_blur_near_enabled = true +dof_blur_near_distance = 1.79 + +[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_pst8q"] +dof_blur_far_enabled = true +dof_blur_far_distance = 5.99 +dof_blur_near_enabled = true +dof_blur_near_distance = 0.05 +dof_blur_amount = 0.21 + +[sub_resource type="BoxMesh" id="BoxMesh_wsigl"] +size = Vector3(1, 10, 20) + +[sub_resource type="Resource" id="Resource_afrr1"] +script = ExtResource("2_m2d6w") +duration = 0.6 +transition = 3 +ease = 1 + +[sub_resource type="Resource" id="Resource_unpfd"] +script = ExtResource("3_l7kg8") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CylinderMesh" id="CylinderMesh_sm466"] +top_radius = 1.51 +height = 0.2 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_hp48l"] +transparency = 1 +albedo_texture = ExtResource("8_rjcgw") +uv1_scale = Vector3(1.91, 1.91, 1.91) +uv1_offset = Vector3(0.025, -0.927, 0) + +[node name="Root" type="Node3D"] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, -0.0194088, 0.506884, 9.13821) +script = ExtResource("1_s26cy") +priority = 10 +follow_mode = 6 +follow_target = NodePath("../PlayerCharacterBody3D/PlayerVisual") +tween_resource = SubResource("Resource_8fhct") +tween_on_load = false +camera_3d_resource = SubResource("Resource_7m0fv") +attributes = SubResource("CameraAttributesPractical_i42vj") +follow_damping = true +follow_distance = 3.5 +spring_length = 3.5 + +[node name="PlayerAimPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, -0.0194088, 1.47688, 6.73921) +script = ExtResource("1_s26cy") +follow_mode = 6 +follow_target = NodePath("../PlayerCharacterBody3D/PlayerVisual") +tween_resource = SubResource("Resource_e7t18") +tween_on_load = false +camera_3d_resource = SubResource("Resource_jogxh") +attributes = SubResource("CameraAttributesPractical_fvhx5") +follow_offset = Vector3(0, 0.97, -0.399) +follow_damping_value = Vector3(0, 0, 0) +follow_distance = 1.5 +spring_length = 1.5 + +[node name="PlayerCharacterBody3D" parent="." instance=ExtResource("4_qcyfd")] +unique_name_in_owner = true +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, -0.0194088, 0.506884, 5.63821) + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, -0.0194088, 0.506884, 9.13821) +attributes = SubResource("CameraAttributesPractical_pst8q") + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("5_8von1") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("6_o1fj6")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="Wall" parent="Environment" instance=ExtResource("6_o1fj6")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.5, 4.5, 0) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall2" parent="Environment" instance=ExtResource("6_o1fj6")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.5, 4.5, 0) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall3" parent="Environment" instance=ExtResource("6_o1fj6")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 4.5, 10.5) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall4" parent="Environment" instance=ExtResource("6_o1fj6")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 4.5, -9.5) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="CeilingPhantomCamera3D" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(-4.37114e-08, -1, 2.98023e-08, 0, 2.98023e-08, 1, -1, 4.37114e-08, -1.3027e-15, -0.200665, 13.366, -0.162648) +script = ExtResource("1_s26cy") +tween_resource = SubResource("Resource_afrr1") +camera_3d_resource = SubResource("Resource_unpfd") + +[node name="MovementInstructionsLabel" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.0505604, -0.484909, 1.44357) +visible = false +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[WASD] to move" +font = ExtResource("7_amcmx") +font_size = 48 + +[node name="MovementInstructionsLabel3" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.0505604, -0.484909, 0.817134) +visible = false +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[Right Mouse Click] to \"aim\"" +font = ExtResource("7_amcmx") +font_size = 48 + +[node name="MovementInstructionsLabel2" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.0440154, -0.490478, -6.30248) +visible = false +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[Space] to toggle PCam" +font = ExtResource("7_amcmx") +font_size = 48 + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0.260217, 1.60477, -9.07797) +mesh = SubResource("CylinderMesh_sm466") +surface_material_override/0 = SubResource("StandardMaterial3D_hp48l") + +[node name="MeshInstance3D3" type="MeshInstance3D" parent="."] +transform = Transform3D(-1, -8.74228e-08, 3.82137e-15, 0, -4.37114e-08, -1, 8.74228e-08, -1, 4.37114e-08, 0.0525861, 1.60477, 9.98156) +mesh = SubResource("CylinderMesh_sm466") +surface_material_override/0 = SubResource("StandardMaterial3D_hp48l") + +[editable path="PlayerCharacterBody3D"] diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_example_scene.tscn new file mode 100644 index 0000000..eadbe6e --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_follow_third_person_example_scene.tscn @@ -0,0 +1,191 @@ +[gd_scene load_steps=16 format=3 uid="uid://4i5csj0s34nb"] + +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_47xf2"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_whx47"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_lii5s"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_jt2lp"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="5_oc4q1"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="7_kg7u1"] +[ext_resource type="PackedScene" uid="uid://mskcwn1a1v6d" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn" id="7_kut0u"] + +[sub_resource type="Resource" id="Resource_8fhct"] +script = ExtResource("2_47xf2") +duration = 0.3 +transition = 2 +ease = 1 + +[sub_resource type="Resource" id="Resource_7m0fv"] +script = ExtResource("5_jt2lp") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_e7t18"] +script = ExtResource("2_47xf2") +duration = 0.4 +transition = 2 +ease = 1 + +[sub_resource type="Resource" id="Resource_jogxh"] +script = ExtResource("5_jt2lp") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 1.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxMesh" id="BoxMesh_wsigl"] +size = Vector3(1, 10, 20) + +[sub_resource type="BoxMesh" id="BoxMesh_bj3re"] +size = Vector3(1, 7, 7) + +[sub_resource type="Resource" id="Resource_afrr1"] +script = ExtResource("2_47xf2") +duration = 0.6 +transition = 3 +ease = 1 + +[sub_resource type="Resource" id="Resource_ioijp"] +script = ExtResource("5_jt2lp") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[node name="Root" type="Node3D"] + +[node name="PlayerCharacterBody3D" parent="." instance=ExtResource("7_kut0u")] +unique_name_in_owner = true +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, 0, 0.506884, 0) + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999903, 0.0120916, 0.0069811, -0.0139622, 0.865941, 0.499951, 6.98492e-10, -0.5, 0.866025, 0.0244338, 2.25671, 3.03109) +script = ExtResource("2_whx47") +priority = 10 +follow_mode = 6 +follow_target = NodePath("../PlayerCharacterBody3D/PlayerVisual") +tween_resource = SubResource("Resource_8fhct") +tween_on_load = false +camera_3d_resource = SubResource("Resource_7m0fv") +follow_damping = true +follow_distance = 3.5 +vertical_rotation_offset = 0.523599 +spring_length = 3.5 + +[node name="PlayerAimPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, 0, 1.30688, 1.101) +script = ExtResource("2_whx47") +follow_mode = 6 +follow_target = NodePath("../PlayerCharacterBody3D/PlayerVisual") +tween_resource = SubResource("Resource_e7t18") +tween_on_load = false +camera_3d_resource = SubResource("Resource_jogxh") +follow_offset = Vector3(0, 0.8, -0.399) +follow_distance = 1.5 +spring_length = 1.5 + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +physics_interpolation_mode = 1 +transform = Transform3D(0.999903, 0.0120916, 0.0069811, -0.0139622, 0.865941, 0.499951, 6.98492e-10, -0.5, 0.866025, 0.0244338, 2.25671, 3.03109) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("5_oc4q1") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="Wall" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.5, 4.5, 0) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall5" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.133, 3, -6.5) +mesh = SubResource("BoxMesh_bj3re") +metadata/_edit_lock_ = true + +[node name="Wall6" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.5, 3, 0) +mesh = SubResource("BoxMesh_bj3re") +metadata/_edit_lock_ = true + +[node name="Wall7" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.5, 3, 0) +mesh = SubResource("BoxMesh_bj3re") +metadata/_edit_lock_ = true + +[node name="Wall2" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.5, 4.5, 0) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall3" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 4.5, 10.5) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="Wall4" parent="Environment" instance=ExtResource("4_lii5s")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 4.5, -9.5) +mesh = SubResource("BoxMesh_wsigl") +metadata/_edit_lock_ = true + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="CeilingPhantomCamera3D" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(-4.37114e-08, -1, 2.98023e-08, 0, 2.98023e-08, 1, -1, 4.37114e-08, -1.3027e-15, -0.200665, 13.366, -0.162648) +script = ExtResource("2_whx47") +tween_resource = SubResource("Resource_afrr1") +camera_3d_resource = SubResource("Resource_ioijp") + +[node name="MovementInstructionsLabel" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.0505604, -0.484909, 1.44357) +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[WASD] to move" +font = ExtResource("7_kg7u1") +font_size = 48 + +[node name="MovementInstructionsLabel3" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.0505604, -0.484909, 0.817134) +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[Right Mouse Click] to \"aim\"" +font = ExtResource("7_kg7u1") +font_size = 48 + +[node name="MovementInstructionsLabel2" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.0440154, -0.490478, -6.30248) +modulate = Color(0.294118, 1, 0.631373, 1) +text = "[Space] to toggle PCam" +font = ExtResource("7_kg7u1") +font_size = 48 + +[editable path="PlayerCharacterBody3D"] diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_look_at_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_look_at_example_scene.tscn new file mode 100644 index 0000000..c50d90b --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_look_at_example_scene.tscn @@ -0,0 +1,198 @@ +[gd_scene load_steps=14 format=3 uid="uid://bdhrdhbux7sjg"] + +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="1_i2pjc"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_lldvu"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_8md3q"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_dqss1"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="4_2i811"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_m3qpq"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="5_u5qhp"] + +[sub_resource type="Resource" id="Resource_pwcgo"] +script = ExtResource("3_dqss1") +duration = 1.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_ft2w3"] +script = ExtResource("4_m3qpq") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_2h36r"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_w3olp"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cw102"] +albedo_color = Color(0.227451, 0.337255, 0.576471, 1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_auy8m"] +albedo_texture = ExtResource("5_u5qhp") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="Root" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(0.998682, 0.0324725, -0.0397495, 0, 0.774433, 0.632656, 0.0513272, -0.631822, 0.773412, -0.137901, 4.03222, 6.36446) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_lldvu") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="PhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("look_at_target")] +transform = Transform3D(0.999694, 0.0136487, -0.0206552, -0.000166996, 0.838005, 0.545663, 0.0247567, -0.545492, 0.837751, -0.137901, 4.03222, 6.36446) +script = ExtResource("2_8md3q") +priority = 10 +look_at_mode = 2 +look_at_target = NodePath("../PlayerCharacterBody3D2/PlayerVisual") +tween_resource = SubResource("Resource_pwcgo") +tween_on_load = false +camera_3d_resource = SubResource("Resource_ft2w3") +look_at_damping = true + +[node name="PlayerCharacterBody3D2" parent="." instance=ExtResource("1_i2pjc")] + +[node name="NPCs" type="Node" parent="."] + +[node name="PlayerMeshInstance3D" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.96028, 0.519002, -1.52506) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_w3olp") + +[node name="PlayerMeshInstance3D2" type="MeshInstance3D" parent="NPCs"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.59952, 0.519, 4.06618) +mesh = SubResource("CapsuleMesh_2h36r") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_cw102") + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("4_2i811")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.00548, 0.805455, -6.37532) +use_collision = true +radius = 1.71971 +height = 2.61091 +sides = 32 + +[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 25.5597, 0.31181, -5.46661) +use_collision = true +radius = 2.77591 +height = 1.62362 +sides = 32 + +[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.96428, 0.31181, 6.6322) +use_collision = true +radius = 1.57419 +height = 3.47475 +sides = 32 + +[node name="CSGCylinder3D3" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.3959, 0.201103, 2.71259) +use_collision = true +radius = 1.41311 +height = 1.40221 +sides = 32 + +[node name="CSGCylinder3D4" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.02677, 0.201101, 11.6804) +use_collision = true +radius = 2.21673 +height = 7.88261 +sides = 32 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.8316, 0.805455, -8.78984) +use_collision = true +radius = 0.956285 +height = 2.61091 +sides = 32 + +[node name="CSGSphere3D" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15.5989, -1.69814, -6.51262) +use_collision = true +radius = 3.34732 +rings = 32 + +[node name="CSGSphere3D2" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.17742, -0.599204, 8.81048) +use_collision = true +radius = 2.65844 +rings = 32 + +[node name="CSGSphere3D3" type="CSGSphere3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.4392, -0.599204, -2.42244) +use_collision = true +radius = 2.14606 +rings = 32 + +[node name="CSGTorus3D" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.58998, -1.90735e-06, 0.346393) +use_collision = true +inner_radius = 1.3 +outer_radius = 2.0 +sides = 32 +ring_sides = 18 + +[node name="CSGTorus3D2" type="CSGTorus3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 22.5502, -1.90735e-06, 7.89765) +use_collision = true +inner_radius = 0.971543 +outer_radius = 2.15226 +sides = 32 +ring_sides = 18 + +[node name="CSGBox3D" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.1202, 6.53866, -12.6331) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_auy8m") + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.53078, 0.760708, -6.1376) +use_collision = true +size = Vector3(2.64182, 2.52142, 2.30997) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.9646, 0.335247, 8.22829) +use_collision = true +size = Vector3(3.80964, 1.67049, 0.932048) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.70216, 0.138478, -4.36159) +use_collision = true +size = Vector3(1.53893, 1.27695, 1.80814) + +[node name="CSGBox3D6" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.1529, 0.138478, 5.20734) +use_collision = true +size = Vector3(4.03502, 1.27695, 5.2198) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 30.7692, 1.78638, -1.60318) +use_collision = true +size = Vector3(4.57784, 4.57276, 3.11285) + +[editable path="PlayerCharacterBody3D2"] diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_noise_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_noise_example_scene.tscn new file mode 100644 index 0000000..0e63ea5 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_noise_example_scene.tscn @@ -0,0 +1,210 @@ +[gd_scene load_steps=22 format=3 uid="uid://p7s5t3tthmo"] + +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="1_ggfbg"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="2_dreow"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="3_f8fcw"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="4_mjtut"] +[ext_resource type="Script" uid="uid://cuffvge5ad4aa" path="res://addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd" id="4_poyyk"] +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="5_d6uqs"] +[ext_resource type="Script" uid="uid://b3n22atuw76sm" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd" id="6_fbad7"] +[ext_resource type="Script" uid="uid://ccmiitq0sdh7j" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd" id="6_n8u0x"] +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="6_vpla5"] +[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="10_0thai"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="11_i8r8q"] + +[sub_resource type="Resource" id="Resource_t3bgw"] +script = ExtResource("4_poyyk") +amplitude = 30.0 +frequency = 2.0 +randomize_noise_seed = 1 +noise_seed = 0 +rotational_noise = true +positional_noise = false +rotational_multiplier_x = 0.1 +rotational_multiplier_y = 0.1 +rotational_multiplier_z = 0.0 +positional_multiplier_x = 0.0 +positional_multiplier_y = 0.0 +positional_multiplier_z = 0.0 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_yvgu3"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vc6km"] +albedo_color = Color(0.988235, 0.498039, 0.498039, 1) + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_lsrh7"] +radius = 0.269454 + +[sub_resource type="Resource" id="Resource_lhgur"] +script = ExtResource("3_f8fcw") +duration = 1.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_ghjuj"] +script = ExtResource("4_mjtut") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_2l4w0"] +script = ExtResource("4_poyyk") +amplitude = 40.0 +frequency = 0.2 +randomize_noise_seed = 0 +noise_seed = 0 +rotational_noise = true +positional_noise = false +rotational_multiplier_x = 1.0 +rotational_multiplier_y = 1.0 +rotational_multiplier_z = 0.0 +positional_multiplier_x = 0.1 +positional_multiplier_y = 0.1 +positional_multiplier_z = 0.1 + +[sub_resource type="Resource" id="Resource_6tnhy"] +script = ExtResource("4_poyyk") +amplitude = 10.0 +frequency = 4.2 +randomize_noise_seed = 0 +noise_seed = 928 +rotational_noise = true +positional_noise = false +rotational_multiplier_x = 1.0 +rotational_multiplier_y = 1.0 +rotational_multiplier_z = 0.1 +positional_multiplier_x = 1.0 +positional_multiplier_y = 1.0 +positional_multiplier_z = 1.0 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_qi01t"] +albedo_texture = ExtResource("6_vpla5") +uv1_triplanar = true +uv1_world_triplanar = true + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ey47a"] +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_bottom_right = 20 +expand_margin_bottom = 6.0 + +[node name="Root" type="Node3D"] + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(0.0129783, 0.0962422, 0.995273, 0, 0.995357, -0.0962503, -0.999916, 0.00124916, 0.012918, -16.46, 0.503767, 4.249) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("1_ggfbg") + +[node name="PlayerCharacterBody3D" type="CharacterBody3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(0.999897, 0.0143636, 0, -0.0143636, 0.999897, 0, 0, 0, 1, -16.46, 0.503767, 4.249) +script = ExtResource("6_fbad7") +run_noise = SubResource("Resource_t3bgw") + +[node name="PlayerVisual" type="MeshInstance3D" parent="PlayerCharacterBody3D"] +unique_name_in_owner = true +visible = false +mesh = SubResource("CapsuleMesh_yvgu3") +surface_material_override/0 = SubResource("StandardMaterial3D_vc6km") + +[node name="PlayerArea3D" type="Area3D" parent="PlayerCharacterBody3D"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerCharacterBody3D/PlayerArea3D"] +shape = SubResource("CapsuleShape3D_lsrh7") + +[node name="PlayerCollisionShape3D" type="CollisionShape3D" parent="PlayerCharacterBody3D"] +shape = SubResource("CapsuleShape3D_lsrh7") + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.00441533, 0, 0.999915, 0, 0.999995, 0, -0.999923, 0, 0.00441529, -16.46, 0.503767, 4.249) +top_level = true +script = ExtResource("2_dreow") +priority = 10 +follow_mode = 2 +follow_target = NodePath("../PlayerCharacterBody3D") +tween_resource = SubResource("Resource_lhgur") +tween_on_load = false +camera_3d_resource = SubResource("Resource_ghjuj") +noise = SubResource("Resource_2l4w0") +noise_emitter_layer = 1 + +[node name="PlayerPhantomCameraNoiseEmitter3D" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(-4.37085e-08, 0, 0.999925, 0, 0.999995, 0, -0.999933, 0, -4.37081e-08, -16.46, 0.503767, 4.249) +script = ExtResource("6_n8u0x") +noise = SubResource("Resource_6tnhy") +duration = 0.1 +decay_time = 0.1 + +[node name="Environment" type="Node" parent="."] + +[node name="Floor" parent="Environment" instance=ExtResource("5_d6uqs")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="CSGBox3D" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.525, 6.539, 2.5) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_qi01t") + +[node name="CSGBox3D3" type="CSGBox3D" parent="Environment"] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 8.83707, 6.53866, -1.80739) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_qi01t") + +[node name="CSGBox3D4" type="CSGBox3D" parent="Environment"] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -38.9392, 6.53866, -1.80739) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_qi01t") + +[node name="CSGBox3D2" type="CSGBox3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.525, 6.539, 6) +use_collision = true +size = Vector3(178.429, 14.0773, 1) +material = SubResource("StandardMaterial3D_qi01t") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="EmitterTip" type="Panel" parent="."] +unique_name_in_owner = true +visible = false +anchors_preset = -1 +anchor_right = 0.3 +anchor_bottom = 0.1 +theme_override_styles/panel = SubResource("StyleBoxFlat_ey47a") + +[node name="Guidance" type="RichTextLabel" parent="EmitterTip"] +layout_mode = 1 +anchors_preset = -1 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 8 +theme_override_fonts/normal_font = ExtResource("10_0thai") +theme_override_fonts/bold_font = ExtResource("11_i8r8q") +theme_override_font_sizes/normal_font_size = 18 +theme_override_font_sizes/bold_font_size = 24 +bbcode_enabled = true +text = "[center]Press [b]Q[/b] to trigger Noise Emitter" +fit_content = true diff --git a/addons/phantom_camera/examples/example_scenes/3D/3d_tweening_example_scene.tscn b/addons/phantom_camera/examples/example_scenes/3D/3d_tweening_example_scene.tscn new file mode 100644 index 0000000..2524686 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/3d_tweening_example_scene.tscn @@ -0,0 +1,291 @@ +[gd_scene load_steps=22 format=3 uid="uid://5xtssqdfilal"] + +[ext_resource type="PackedScene" uid="uid://cixlwqycoox8h" path="res://addons/phantom_camera/examples/models/3d_cube_dark.tscn" id="1_ydeog"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="2_b2yrt"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_m2w30"] +[ext_resource type="Resource" uid="uid://cptfoggk2ok67" path="res://addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres" id="4_425ma"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_cn3g7"] +[ext_resource type="Script" uid="uid://bnhxcejvr6wi3" path="res://addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd" id="5_h0ouh"] +[ext_resource type="PackedScene" uid="uid://bulsh7s0ibmao" path="res://addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn" id="6_gcjyn"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="6_wup4d"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="8_60rny"] + +[sub_resource type="Resource" id="Resource_0dtvs"] +script = ExtResource("5_cn3g7") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="BoxShape3D" id="BoxShape3D_j6fha"] +size = Vector3(5, 0.1, 4) + +[sub_resource type="BoxMesh" id="BoxMesh_xg4en"] +size = Vector3(5, 0.1, 4) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_2dct5"] +transparency = 1 +albedo_color = Color(0.988235, 0.478431, 0.905882, 0.0901961) + +[sub_resource type="Resource" id="Resource_v8ndi"] +script = ExtResource("6_wup4d") +duration = 0.6 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_kmep1"] +script = ExtResource("5_cn3g7") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_uxg44"] +script = ExtResource("6_wup4d") +duration = 0.3 +transition = 1 +ease = 2 + +[sub_resource type="Resource" id="Resource_eu3bc"] +script = ExtResource("5_cn3g7") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_0nci0"] +script = ExtResource("6_wup4d") +duration = 0.3 +transition = 8 +ease = 2 + +[sub_resource type="Resource" id="Resource_u0lff"] +script = ExtResource("5_cn3g7") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[sub_resource type="Resource" id="Resource_50m5g"] +script = ExtResource("6_wup4d") +duration = 1.2 +transition = 10 +ease = 2 + +[sub_resource type="Resource" id="Resource_rexf8"] +script = ExtResource("5_cn3g7") +keep_aspect = 1 +cull_mask = 1048575 +h_offset = 0.0 +v_offset = 0.0 +projection = 0 +fov = 75.0 +size = 1.0 +frustum_offset = Vector2(0, 0) +near = 0.05 +far = 4000.0 + +[node name="Root" type="Node3D"] + +[node name="Environment" type="Node" parent="."] + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment"] +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 0) +metadata/_edit_lock_ = true + +[node name="Floor" parent="Environment" instance=ExtResource("1_ydeog")] +transform = Transform3D(1000, 0, 0, 0, 1, 0, 0, 0, 1000, 0, -1, 0) +metadata/_edit_lock_ = true + +[node name="MainCamera3D" type="Camera3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 5.08867e-06, 2.00003, 2.00013) + +[node name="PhantomCameraHost" type="Node" parent="MainCamera3D"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("2_b2yrt") + +[node name="------------------" type="Node" parent="."] + +[node name="PlayerPhantomCamera3D" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")] +unique_name_in_owner = true +transform = Transform3D(0.999889, 0, 0, 0, 0.707092, 0.707088, 0, -0.707092, 0.707088, 0, 2, 2) +top_level = true +script = ExtResource("3_m2w30") +priority = 3 +follow_mode = 2 +follow_target = NodePath("../PlayerCharacterBody3D2/PlayerVisual") +tween_resource = ExtResource("4_425ma") +tween_on_load = false +camera_3d_resource = SubResource("Resource_0dtvs") +follow_offset = Vector3(0, 2, 2) +follow_damping = true + +[node name="PlayerCharacterBody3D2" parent="." instance=ExtResource("6_gcjyn")] + +[node name="-------------------" type="Node" parent="."] + +[node name="Tweening Example" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1.97) + +[node name="Linear" type="Node3D" parent="Tweening Example"] + +[node name="EntryRoomTrigger" type="Area3D" parent="Tweening Example/Linear" node_paths=PackedStringArray("area_pcam")] +priority = 5 +script = ExtResource("5_h0ouh") +area_pcam = NodePath("../PhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Tweening Example/Linear/EntryRoomTrigger"] +shape = SubResource("BoxShape3D_j6fha") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Tweening Example/Linear/EntryRoomTrigger"] +mesh = SubResource("BoxMesh_xg4en") +skeleton = NodePath("../../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_2dct5") +metadata/_edit_group_ = true + +[node name="PhantomCamera3D" type="Node3D" parent="Tweening Example/Linear"] +transform = Transform3D(1, 0, 0, 0, 0.642788, 0.766044, 0, -0.766044, 0.642788, 0, 4.8, 3.3) +script = ExtResource("3_m2w30") +tween_resource = SubResource("Resource_v8ndi") +camera_3d_resource = SubResource("Resource_kmep1") + +[node name="TweenNameLabel" type="Label3D" parent="Tweening Example/Linear"] +transform = Transform3D(1, 0, 0, 0, 0.695913, 0.718126, 0, -0.718126, 0.695913, -1.8, 0.5, 0) +text = "Transition Type: +Linear + +Duration: +0.6s" +font = ExtResource("8_60rny") +font_size = 48 + +[node name="Sine" type="Node3D" parent="Tweening Example"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -7.4) + +[node name="EntryRoomTrigger" type="Area3D" parent="Tweening Example/Sine" node_paths=PackedStringArray("area_pcam")] +priority = 5 +script = ExtResource("5_h0ouh") +area_pcam = NodePath("../PhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Tweening Example/Sine/EntryRoomTrigger"] +shape = SubResource("BoxShape3D_j6fha") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Tweening Example/Sine/EntryRoomTrigger"] +mesh = SubResource("BoxMesh_xg4en") +skeleton = NodePath("../../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_2dct5") +metadata/_edit_group_ = true + +[node name="PhantomCamera3D" type="Node3D" parent="Tweening Example/Sine"] +transform = Transform3D(1, 0, 0, 0, 0.642788, 0.766044, 0, -0.766044, 0.642788, 0, 4.8, 3.3) +script = ExtResource("3_m2w30") +tween_resource = SubResource("Resource_uxg44") +camera_3d_resource = SubResource("Resource_eu3bc") + +[node name="TweenNameLabel" type="Label3D" parent="Tweening Example/Sine"] +transform = Transform3D(1, 0, 0, 0, 0.695913, 0.718126, 0, -0.718126, 0.695913, 1.7, 0.5, 0) +text = "Transition Type: +Sine + +Duration: +0.3s" +font = ExtResource("8_60rny") +font_size = 72 + +[node name="Circ" type="Node3D" parent="Tweening Example"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -14.1) + +[node name="EntryRoomTrigger" type="Area3D" parent="Tweening Example/Circ" node_paths=PackedStringArray("area_pcam")] +priority = 5 +script = ExtResource("5_h0ouh") +area_pcam = NodePath("../PhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Tweening Example/Circ/EntryRoomTrigger"] +shape = SubResource("BoxShape3D_j6fha") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Tweening Example/Circ/EntryRoomTrigger"] +mesh = SubResource("BoxMesh_xg4en") +skeleton = NodePath("../../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_2dct5") +metadata/_edit_group_ = true + +[node name="PhantomCamera3D" type="Node3D" parent="Tweening Example/Circ"] +transform = Transform3D(1, 0, 0, 0, 0.642788, 0.766044, 0, -0.766044, 0.642788, 0, 4.8, 3.3) +script = ExtResource("3_m2w30") +tween_resource = SubResource("Resource_0nci0") +camera_3d_resource = SubResource("Resource_u0lff") + +[node name="TweenNameLabel" type="Label3D" parent="Tweening Example/Circ"] +transform = Transform3D(1, 0, 0, 0, 0.695913, 0.718126, 0, -0.718126, 0.695913, -1.8, 0.5, 0) +text = "Transition Type: +Circ + +Duration: +0.3s" +font = ExtResource("8_60rny") +font_size = 72 + +[node name="Back" type="Node3D" parent="Tweening Example"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -21) + +[node name="EntryRoomTrigger" type="Area3D" parent="Tweening Example/Back" node_paths=PackedStringArray("area_pcam")] +priority = 5 +script = ExtResource("5_h0ouh") +area_pcam = NodePath("../PhantomCamera3D") +metadata/_edit_group_ = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Tweening Example/Back/EntryRoomTrigger"] +shape = SubResource("BoxShape3D_j6fha") + +[node name="NPCInteractionZoneMesh" type="MeshInstance3D" parent="Tweening Example/Back/EntryRoomTrigger"] +mesh = SubResource("BoxMesh_xg4en") +skeleton = NodePath("../../../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_2dct5") +metadata/_edit_group_ = true + +[node name="PhantomCamera3D" type="Node3D" parent="Tweening Example/Back"] +transform = Transform3D(1, 0, 0, 0, 0.642788, 0.766044, 0, -0.766044, 0.642788, -0.8, 4.8, 3.3) +script = ExtResource("3_m2w30") +tween_resource = SubResource("Resource_50m5g") +camera_3d_resource = SubResource("Resource_rexf8") + +[node name="TweenNameLabel" type="Label3D" parent="Tweening Example/Back"] +transform = Transform3D(1, 0, 0, 0, 0.695913, 0.718126, 0, -0.718126, 0.695913, 1.7, 0.5, 0) +text = "Transition Type: +Back + +Duration: +1.2s" +font = ExtResource("8_60rny") +font_size = 48 + +[editable path="PlayerCharacterBody3D2"] diff --git a/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn b/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn new file mode 100644 index 0000000..26460f4 --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_3d.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=5 format=3 uid="uid://bulsh7s0ibmao"] + +[ext_resource type="Script" uid="uid://dut3e76k2c71n" path="res://addons/phantom_camera/examples/scripts/3D/player_controller.gd" id="1_6hh6c"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_8efyg"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_2cfaw"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_r3ldp"] +albedo_color = Color(0.988235, 0.498039, 0.498039, 1) + +[node name="PlayerCharacterBody3D2" type="CharacterBody3D"] +script = ExtResource("1_6hh6c") +metadata/_edit_group_ = true + +[node name="PlayerArea3D" type="Area3D" parent="."] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerArea3D"] +shape = SubResource("CapsuleShape3D_8efyg") + +[node name="PlayerCollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("CapsuleShape3D_8efyg") + +[node name="PlayerVisual" type="Node3D" parent="."] +unique_name_in_owner = true + +[node name="PlayerModel" type="MeshInstance3D" parent="PlayerVisual"] +mesh = SubResource("CapsuleMesh_2cfaw") +skeleton = NodePath("../..") +surface_material_override/0 = SubResource("StandardMaterial3D_r3ldp") diff --git a/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn b/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn new file mode 100644 index 0000000..ca4b97c --- /dev/null +++ b/addons/phantom_camera/examples/example_scenes/3D/sub_scenes/playable_character_third_person_3d.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=6 format=3 uid="uid://mskcwn1a1v6d"] + +[ext_resource type="Script" uid="uid://34uhyq3cpi67" path="res://addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd" id="1_0dnfe"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_s61dn"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_47f0o"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_mv4do"] +albedo_color = Color(0.988235, 0.498039, 0.498039, 1) + +[sub_resource type="PrismMesh" id="PrismMesh_wg1x3"] +size = Vector3(0.5, 0.5, 0.3) + +[node name="PlayerCharacterBody3D" type="CharacterBody3D"] +transform = Transform3D(0.999903, 0.0139622, 0, -0.0139622, 0.999903, 0, 0, 0, 1, 0, 0, 0) +collision_layer = 2 +script = ExtResource("1_0dnfe") +metadata/_edit_group_ = true + +[node name="PlayerArea3D" type="Area3D" parent="."] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerArea3D"] +shape = SubResource("CapsuleShape3D_s61dn") + +[node name="PlayerCollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("CapsuleShape3D_s61dn") + +[node name="PlayerVisual" type="Node3D" parent="."] +unique_name_in_owner = true + +[node name="PlayerMeshInstance3D" type="MeshInstance3D" parent="PlayerVisual"] +transform = Transform3D(1, 0, 0, 0, 1, 4.65661e-10, 0, 0, 1, 0, 0, 0) +mesh = SubResource("CapsuleMesh_47f0o") +skeleton = NodePath("../..") +surface_material_override/0 = SubResource("StandardMaterial3D_mv4do") + +[node name="PlayerDirection" type="MeshInstance3D" parent="PlayerVisual"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, -9.31323e-10, 1, 4.65661e-10, 2.98023e-08, 0, 1, -0.0156226, 1.08631, 0) +mesh = SubResource("PrismMesh_wg1x3") +skeleton = NodePath("../..") +surface_material_override/0 = SubResource("StandardMaterial3D_mv4do") diff --git a/addons/phantom_camera/examples/models/3d_cube_dark.tscn b/addons/phantom_camera/examples/models/3d_cube_dark.tscn new file mode 100644 index 0000000..feab949 --- /dev/null +++ b/addons/phantom_camera/examples/models/3d_cube_dark.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=4 format=3 uid="uid://cixlwqycoox8h"] + +[ext_resource type="Texture2D" uid="uid://bj7h2fc5jx4ax" path="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" id="1_836jx"] + +[sub_resource type="BoxMesh" id="BoxMesh_d24c3"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_aox6v"] +albedo_texture = ExtResource("1_836jx") +uv1_triplanar = true +uv1_world_triplanar = true + +[node name="3DPrototypeCube" type="CSGMesh3D"] +use_collision = true +mesh = SubResource("BoxMesh_d24c3") +material = SubResource("StandardMaterial3D_aox6v") diff --git a/addons/phantom_camera/examples/resources/tween/fixed_camera_tween.tres b/addons/phantom_camera/examples/resources/tween/fixed_camera_tween.tres new file mode 100644 index 0000000..8888f93 --- /dev/null +++ b/addons/phantom_camera/examples/resources/tween/fixed_camera_tween.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="PhantomCameraTween" load_steps=2 format=3 uid="uid://c1v786g5agaw5"] + +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_ptlie"] + +[resource] +script = ExtResource("1_ptlie") +duration = 0.0 +transition = 0 +ease = 2 diff --git a/addons/phantom_camera/examples/resources/tween/inventory_phantom_camera_2d_tween.tres b/addons/phantom_camera/examples/resources/tween/inventory_phantom_camera_2d_tween.tres new file mode 100644 index 0000000..5a0708e --- /dev/null +++ b/addons/phantom_camera/examples/resources/tween/inventory_phantom_camera_2d_tween.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="PhantomCameraTween" load_steps=2 format=3 uid="uid://cllveybboaqk5"] + +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_7yoy0"] + +[resource] +script = ExtResource("1_7yoy0") +duration = 0.6 +transition = 5 +ease = 1 diff --git a/addons/phantom_camera/examples/resources/tween/item_focus_phantom_camera_2d_tween.tres b/addons/phantom_camera/examples/resources/tween/item_focus_phantom_camera_2d_tween.tres new file mode 100644 index 0000000..8464eff --- /dev/null +++ b/addons/phantom_camera/examples/resources/tween/item_focus_phantom_camera_2d_tween.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="PhantomCameraTween" load_steps=2 format=3 uid="uid://cecrnq0wnkexh"] + +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_sq5ls"] + +[resource] +script = ExtResource("1_sq5ls") +duration = 0.6 +transition = 8 +ease = 1 diff --git a/addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres b/addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres new file mode 100644 index 0000000..5258ea7 --- /dev/null +++ b/addons/phantom_camera/examples/resources/tween/player_phantom_camera_2d_tween.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="PhantomCameraTween" load_steps=2 format=3 uid="uid://euybd2w0bax"] + +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_by4ei"] + +[resource] +script = ExtResource("1_by4ei") +duration = 0.6 +transition = 3 +ease = 1 diff --git a/addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres b/addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres new file mode 100644 index 0000000..e586199 --- /dev/null +++ b/addons/phantom_camera/examples/resources/tween/player_phantom_camera_3d_tween.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="PhantomCameraTween" load_steps=2 format=3 uid="uid://cptfoggk2ok67"] + +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="1_q5tix"] + +[resource] +script = ExtResource("1_q5tix") +duration = 0.6 +transition = 3 +ease = 2 diff --git a/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd new file mode 100644 index 0000000..06e9180 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd @@ -0,0 +1,36 @@ +extends Node2D + +@onready var pcam_room_left: PhantomCamera2D = %RoomLeftPhantomCamera2D +@onready var pcam_room_centre: PhantomCamera2D = %RoomCentrePhantomCamera2D +@onready var pcam_room_right: PhantomCamera2D = %RoomRightPhantomCamera2D + +@onready var player: Node2D = %CharacterBody2D/%PlayerVisuals + +@onready var area_2d_room_left: Area2D = %RoomLeftArea2D +@onready var area_2d_room_centre: Area2D = %RoomCentreArea2D +@onready var area_2d_room_right: Area2D = %RoomRightArea2D + + +func _ready(): + pcam_room_left.set_follow_offset(Vector2(0, -80)) + pcam_room_right.set_follow_offset(Vector2(0, -80)) + + area_2d_room_left.body_entered.connect(_on_body_entered.bind(pcam_room_left)) + area_2d_room_centre.body_entered.connect(_on_body_entered.bind(pcam_room_centre)) + area_2d_room_right.body_entered.connect(_on_body_entered.bind(pcam_room_right)) + + area_2d_room_left.body_exited.connect(_on_body_exited.bind(pcam_room_left)) + area_2d_room_centre.body_exited.connect(_on_body_exited.bind(pcam_room_centre)) + area_2d_room_right.body_exited.connect(_on_body_exited.bind(pcam_room_right)) + + +func _on_body_entered(body: Node2D, pcam: PhantomCamera2D) -> void: + if body == player.get_parent(): + pcam.set_follow_target(player) + pcam.set_priority(20) + + +func _on_body_exited(body: Node2D, pcam: PhantomCamera2D) -> void: + if body == player.get_parent(): + pcam.set_priority(0) + pcam.set_follow_target(null) diff --git a/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd.uid b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd.uid new file mode 100644 index 0000000..1a32325 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween.gd.uid @@ -0,0 +1 @@ +uid://c5yewe1hewu7j diff --git a/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd new file mode 100644 index 0000000..970c52e --- /dev/null +++ b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd @@ -0,0 +1,36 @@ +extends Node2D + +@onready var pcam_room_left: PhantomCamera2D = %RoomLeftPhantomCamera2D +@onready var pcam_room_centre: PhantomCamera2D = %RoomCentrePhantomCamera2D +@onready var pcam_room_right: PhantomCamera2D = %RoomRightPhantomCamera2D + +@onready var player: Node2D = %CharacterBody2D + +@onready var area_2d_room_left: Area2D = %RoomLeftArea2D +@onready var area_2d_room_centre: Area2D = %RoomCentreArea2D +@onready var area_2d_room_right: Area2D = %RoomRightArea2D + + +func _ready(): + pcam_room_left.set_follow_offset(Vector2(0, -80)) + pcam_room_right.set_follow_offset(Vector2(0, -80)) + + area_2d_room_left.body_entered.connect(_on_body_entered.bind(pcam_room_left)) + area_2d_room_centre.body_entered.connect(_on_body_entered.bind(pcam_room_centre)) + area_2d_room_right.body_entered.connect(_on_body_entered.bind(pcam_room_right)) + + area_2d_room_left.body_exited.connect(_on_body_exited.bind(pcam_room_left)) + area_2d_room_centre.body_exited.connect(_on_body_exited.bind(pcam_room_centre)) + area_2d_room_right.body_exited.connect(_on_body_exited.bind(pcam_room_right)) + + +func _on_body_entered(body: Node2D, pcam: PhantomCamera2D) -> void: + if body == player: + pcam.set_follow_target(player) + pcam.set_priority(20) + + +func _on_body_exited(body: Node2D, pcam: PhantomCamera2D) -> void: + if body == player: + pcam.set_priority(0) + pcam.set_follow_target(null) diff --git a/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd.uid b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd.uid new file mode 100644 index 0000000..fc56f1c --- /dev/null +++ b/addons/phantom_camera/examples/scripts/2D/2d_room_limit_tween_4.3.gd.uid @@ -0,0 +1 @@ +uid://dtcuvut1eklnd diff --git a/addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd b/addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd new file mode 100644 index 0000000..db0209c --- /dev/null +++ b/addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd @@ -0,0 +1,16 @@ +extends Area2D + +@export var area_pcam: PhantomCamera2D + +func _ready() -> void: + connect("area_entered", _entered_area) + connect("area_exited", _exited_area) + +func _entered_area(area_2d: Area2D) -> void: + if area_2d.get_parent() is CharacterBody2D: + area_pcam.set_priority(20) + +func _exited_area(area_2d: Area2D) -> void: + if area_2d.get_parent() is CharacterBody2D: + area_pcam.set_priority(0) + diff --git a/addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd.uid b/addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd.uid new file mode 100644 index 0000000..c5ac45f --- /dev/null +++ b/addons/phantom_camera/examples/scripts/2D/2d_trigger_area.gd.uid @@ -0,0 +1 @@ +uid://t8wa4e5y5hcf diff --git a/addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd new file mode 100644 index 0000000..8003bb3 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd @@ -0,0 +1,189 @@ +extends CharacterBody2D + +@onready var _player_area2d = %PlayerArea2D +@onready var _player_visuals: Node2D = %PlayerVisuals +@onready var _player_sprite: Sprite2D = %PlayerSprite +@onready var _interaction_prompt: Panel = %InteractionPrompt +@onready var _ui_sign: Control +@onready var _dark_overlay: ColorRect = %DarkOverlay + +const KEY_STRINGNAME: StringName = "Key" +const ACTION_STRINGNAME: StringName = "Action" +const INPUT_MOVE_LEFT_STRINGNAME: StringName = "move_left" +const INPUT_MOVE_RIGHT_STRINGNAME: StringName = "move_right" + +const SPEED = 350.0 +const JUMP_VELOCITY = -750.0 + +# Get the gravity from the project settings to be synced with RigidBody nodes. +var gravity: int = 2400 +var _is_interactive: bool +var _can_open_inventory: bool +var _movement_disabled: bool +var tween: Tween +var _interactive_UI: Control +var _active_pcam: PhantomCamera2D + +var _physics_body_trans_last: Transform2D +var _physics_body_trans_current: Transform2D + +enum InteractiveType { + NONE = 0, + ITEM = 1, + INVENTORY = 2, +} +var _interactive_object: InteractiveType = InteractiveType.NONE + +var InputMovementDic: Dictionary = { + INPUT_MOVE_LEFT_STRINGNAME: { + KEY_STRINGNAME: KEY_A, + ACTION_STRINGNAME: INPUT_MOVE_LEFT_STRINGNAME + }, + INPUT_MOVE_RIGHT_STRINGNAME: { + KEY_STRINGNAME: KEY_D, + ACTION_STRINGNAME: INPUT_MOVE_RIGHT_STRINGNAME + }, +} + + +func _ready() -> void: + _player_area2d.body_shape_entered.connect(_show_prompt) + _player_area2d.body_shape_exited.connect(_hide_prompt) + + _ui_sign = owner.get_node("%UISign") + + for input in InputMovementDic: + var key_val = InputMovementDic[input].get(KEY_STRINGNAME) + var action_val = InputMovementDic[input].get(ACTION_STRINGNAME) + + var movement_input = InputEventKey.new() + movement_input.physical_keycode = key_val + InputMap.add_action(action_val) + InputMap.action_add_event(action_val, movement_input) + + _player_visuals.top_level = true + + if Engine.get_version_info().major == 4 and \ + Engine.get_version_info().minor >= 3: + printerr("Please run the other 2D example scenes, in the 2D-4.3 directory, for more up-to-date example setups.") + + +func _unhandled_input(event: InputEvent) -> void: + if _is_interactive: + if Input.is_physical_key_pressed(KEY_F): + if tween: + tween.kill() + + if not _movement_disabled: + tween = get_tree().create_tween() + + _movement_disabled = true + _active_pcam.set_priority(10) + + _show_interactive_node(_interactive_UI) + _interactive_node_logic() + + else: + _hide_interactive_node(_interactive_UI) + _interactive_node_logic() + + + if Input.is_physical_key_pressed(KEY_ESCAPE) and _movement_disabled: + _hide_interactive_node(_interactive_UI) + _interactive_node_logic() + + +func _show_interactive_node(UI: Control) -> void: + UI.modulate.a = 0 + UI.visible = true + tween.tween_property(UI, "modulate", Color.WHITE, 1).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_CIRC) + + +func _hide_interactive_node(UI: Control) -> void: + _movement_disabled = false + _active_pcam.set_priority(0) + UI.visible = false + + +func _interactive_node_logic() -> void: + match _interactive_object: + 2: + if _movement_disabled: + _dark_overlay.set_visible(true) + else: + _dark_overlay.set_visible(false) + + +func _physics_process(delta: float) -> void: + _physics_body_trans_last = _physics_body_trans_current + _physics_body_trans_current = global_transform + + if not is_on_floor(): + velocity.y += gravity * delta + + if Input.is_action_just_pressed("ui_accept") and is_on_floor(): + velocity.y = JUMP_VELOCITY + + if _movement_disabled: return + + var input_dir: = Input.get_axis( + INPUT_MOVE_LEFT_STRINGNAME, + INPUT_MOVE_RIGHT_STRINGNAME + ) + + if input_dir: + velocity.x = input_dir * SPEED + if input_dir > 0: + _player_sprite.set_flip_h(false) + elif input_dir < 0: + _player_sprite.set_flip_h(true) + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + + move_and_slide() + + +func _process(delta) -> void: + _player_visuals.global_position = _physics_body_trans_last.interpolate_with( + _physics_body_trans_current, + Engine.get_physics_interpolation_fraction() + ).origin + + +func _show_prompt(body_rid: RID, body: Node2D, body_shape_index: int, local_shape: int) -> void: + if body is TileMap: + var tile_map: TileMap = body + + var tile_coords: Vector2i = tile_map.get_coords_for_body_rid(body_rid) + var cell_data: TileData = tile_map.get_cell_tile_data(1, tile_coords) + + if cell_data: + var cell_data_type: StringName = cell_data.get_custom_data("Type") +# var cell_global_pos: Vector2 = tile_map.to_global(tile_map.map_to_local(tile_coords)) + _is_interactive = true + _interaction_prompt.set_visible(true) + + match cell_data_type: + "Sign": + _interactive_UI = owner.get_node("%UISign") + _active_pcam = %ItemFocusPhantomCamera2D + _interactive_object = InteractiveType.ITEM + "Inventory": + _interactive_UI = owner.get_node("%UIInventory") + _interactive_object = InteractiveType.INVENTORY + _active_pcam = %InventoryPhantomCamera2D + + +func _hide_prompt(body_rid: RID, body: Node2D, body_shape_index: int, local_shape: int) -> void: + if body is TileMap: + var tile_map: TileMap = body + + var tile_coords: Vector2i = tile_map.get_coords_for_body_rid(body_rid) + var cell_data: TileData = tile_map.get_cell_tile_data(1, tile_coords) + + if cell_data: + _interaction_prompt.set_visible(false) + _is_interactive = false + _interactive_UI = null + _interactive_object = InteractiveType.NONE + _active_pcam = null diff --git a/addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd.uid b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd.uid new file mode 100644 index 0000000..2f250b4 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d.gd.uid @@ -0,0 +1 @@ +uid://cb46ypjv5p72s diff --git a/addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd new file mode 100644 index 0000000..41ab5e2 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd @@ -0,0 +1,179 @@ +extends CharacterBody2D + +@onready var _player_area2d = %PlayerArea2D +@onready var _player_visuals: Node2D = %PlayerVisuals +@onready var _player_sprite: Sprite2D = %PlayerSprite +@onready var _interaction_prompt: Panel = %InteractionPrompt +@onready var _ui_sign: Control +@onready var _dark_overlay: ColorRect = %DarkOverlay +@onready var _noise_emitter: PhantomCameraNoiseEmitter2D + +const KEY_STRINGNAME: StringName = "Key" +const ACTION_STRINGNAME: StringName = "Action" +const INPUT_MOVE_LEFT_STRINGNAME: StringName = "move_left" +const INPUT_MOVE_RIGHT_STRINGNAME: StringName = "move_right" + +const SPEED = 350.0 +const JUMP_VELOCITY = -750.0 + +# Get the gravity from the project settings to be synced with RigidBody nodes. +var gravity: int = 2400 +var _is_interactive: bool +var _can_open_inventory: bool +var _movement_disabled: bool +var tween: Tween +var _interactive_UI: Control +var _active_pcam: PhantomCamera2D + +enum InteractiveType { + NONE = 0, + ITEM = 1, + INVENTORY = 2, +} +var _interactive_object: InteractiveType = InteractiveType.NONE + +var InputMovementDic: Dictionary = { + INPUT_MOVE_LEFT_STRINGNAME: { + KEY_STRINGNAME: KEY_A, + ACTION_STRINGNAME: INPUT_MOVE_LEFT_STRINGNAME + }, + INPUT_MOVE_RIGHT_STRINGNAME: { + KEY_STRINGNAME: KEY_D, + ACTION_STRINGNAME: INPUT_MOVE_RIGHT_STRINGNAME + }, +} + + +func _ready() -> void: + _player_area2d.body_shape_entered.connect(_show_prompt) + _player_area2d.body_shape_exited.connect(_hide_prompt) + + _ui_sign = owner.get_node("%UISign") + + for input in InputMovementDic: + var key_val = InputMovementDic[input].get(KEY_STRINGNAME) + var action_val = InputMovementDic[input].get(ACTION_STRINGNAME) + + var movement_input = InputEventKey.new() + movement_input.physical_keycode = key_val + InputMap.add_action(action_val) + InputMap.action_add_event(action_val, movement_input) + + if Engine.get_version_info().major == 4 and \ + Engine.get_version_info().minor < 3: + printerr("This scene is designed to only work properly in Godot 4.3 or later that supports 2D Physics Interpolation.") + printerr("Please run the other 2D example scenes in the other directory.") + + +func _unhandled_input(event: InputEvent) -> void: + if _is_interactive: + if Input.is_physical_key_pressed(KEY_F): + if tween: + tween.kill() + + if not _movement_disabled: + tween = get_tree().create_tween() + + _movement_disabled = true + _active_pcam.set_priority(10) + + _show_interactive_node(_interactive_UI) + _interactive_node_logic() + + else: + _hide_interactive_node(_interactive_UI) + _interactive_node_logic() + + + if Input.is_physical_key_pressed(KEY_ESCAPE) and _movement_disabled: + _hide_interactive_node(_interactive_UI) + _interactive_node_logic() + + if Input.is_physical_key_pressed(KEY_Q): + if get_node_or_null("%PlayerPhantomCameraNoiseEmitter2D"): + %PlayerPhantomCameraNoiseEmitter2D.emit() + + +func _show_interactive_node(UI: Control) -> void: + UI.modulate.a = 0 + UI.visible = true + tween.tween_property(UI, "modulate", Color.WHITE, 1).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_CIRC) + + +func _hide_interactive_node(UI: Control) -> void: + _movement_disabled = false + _active_pcam.set_priority(0) + UI.visible = false + + +func _interactive_node_logic() -> void: + match _interactive_object: + 2: + if _movement_disabled: + _dark_overlay.set_visible(true) + else: + _dark_overlay.set_visible(false) + + +func _physics_process(delta: float) -> void: + if not is_on_floor(): + velocity.y += gravity * delta + + if Input.is_action_just_pressed("ui_accept") and is_on_floor(): + velocity.y = JUMP_VELOCITY + + if _movement_disabled: return + + var input_dir: = Input.get_axis( + INPUT_MOVE_LEFT_STRINGNAME, + INPUT_MOVE_RIGHT_STRINGNAME + ) + + if input_dir: + velocity.x = input_dir * SPEED + if input_dir > 0: + _player_sprite.set_flip_h(false) + elif input_dir < 0: + _player_sprite.set_flip_h(true) + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + + move_and_slide() + + +func _show_prompt(body_rid: RID, body: Node2D, body_shape_index: int, local_shape: int) -> void: + if body.is_class("TileMapLayer"): # TODO - Using string reference to support Godot 4.2 + var tile_map := body + var tile_coords: Vector2i = tile_map.get_coords_for_body_rid(body_rid) + var cell_data: TileData = tile_map.get_cell_tile_data(tile_coords) + + if cell_data: + var cell_data_type: StringName = cell_data.get_custom_data("Type") +# var cell_global_pos: Vector2 = tile_map.to_global(tile_map.map_to_local(tile_coords)) + _is_interactive = true + _interaction_prompt.set_visible(true) + + match cell_data_type: + "Sign": + _interactive_UI = owner.get_node("%UISign") + _active_pcam = %ItemFocusPhantomCamera2D + _interactive_object = InteractiveType.ITEM + "Inventory": + _interactive_UI = owner.get_node("%UIInventory") + _interactive_object = InteractiveType.INVENTORY + _active_pcam = %InventoryPhantomCamera2D + + +func _hide_prompt(body_rid: RID, body: Node2D, body_shape_index: int, local_shape: int) -> void: + if body.is_class("TileMapLayer"): # TODO - Using string reference to support Godot 4.2 + var tile_map := body + + var tile_coords: Vector2i = tile_map.get_coords_for_body_rid(body_rid) + var cell_data: TileData = tile_map.get_cell_tile_data(tile_coords) + + if cell_data: + _interaction_prompt.set_visible(false) + _is_interactive = false + _interactive_UI = null + _interactive_object = InteractiveType.NONE + _active_pcam = null diff --git a/addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd.uid b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd.uid new file mode 100644 index 0000000..411f7c4 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/2D/player_character_body_2d_4.3.gd.uid @@ -0,0 +1 @@ +uid://cnnaky2ns2pn4 diff --git a/addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd b/addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd new file mode 100644 index 0000000..4fc9764 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd @@ -0,0 +1,26 @@ +extends Area3D + +@export var area_pcam: PhantomCamera3D + +var initial_camera_position: Vector3 +var initial_camera_rotation: Vector3 + +var tween: Tween +var tween_duration: float = 0.9 + + +func _ready() -> void: + connect("area_entered", _entered_area) + connect("area_exited", _exited_area) + + +func _entered_area(area_3D: Area3D) -> void: + if area_3D.get_parent() is CharacterBody3D: + area_pcam.set_priority(20) + + +func _exited_area(area_3D: Area3D) -> void: + if area_3D.get_parent() is CharacterBody3D: + area_pcam.set_priority(0) + + diff --git a/addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd.uid b/addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd.uid new file mode 100644 index 0000000..5499427 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/3d_trigger_area.gd.uid @@ -0,0 +1 @@ +uid://bnhxcejvr6wi3 diff --git a/addons/phantom_camera/examples/scripts/3D/npc.gd b/addons/phantom_camera/examples/scripts/3D/npc.gd new file mode 100644 index 0000000..3d9a523 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/npc.gd @@ -0,0 +1,71 @@ +extends Node3D + +@onready var npc_pcam: PhantomCamera3D = %NPCPhantomCamera3D +@onready var dialogueArea: Area3D = %NPCInteractionArea3D +@onready var dialogueLabel3D: Label3D = %NPCDialogueExampleLabel + +@onready var player: CharacterBody3D = %PlayerCharacterBody3D + +@onready var move_to_location: Vector3 = %MoveToLocation.get_global_position() + +var dialogue_label_initial_position: Vector3 +var dialogue_label_initial_rotation: Vector3 + +var tween: Tween +var tween_duration: float = 0.9 +var tween_transition: Tween.TransitionType = Tween.TRANS_QUAD + +var interactable: bool +var is_interacting: bool + +func _ready() -> void: + dialogueArea.connect("area_entered", _interactable) + dialogueArea.connect("area_exited", _not_interactable) + + dialogueLabel3D.set_visible(false) + + dialogue_label_initial_position = dialogueLabel3D.get_global_position() + dialogue_label_initial_rotation = dialogueLabel3D.get_global_rotation() + + npc_pcam.tween_completed.connect(_on_tween_started) + + + +func _on_tween_started() -> void: + player.movement_enabled = false + + +func _interactable(area_3D: Area3D) -> void: + if area_3D.get_parent() is CharacterBody3D: + dialogueLabel3D.set_visible(true) + interactable = true + + var tween: Tween = get_tree().create_tween().set_trans(tween_transition).set_ease(Tween.EASE_IN_OUT).set_loops() + tween.tween_property(dialogueLabel3D, "global_position", dialogue_label_initial_position - Vector3(0, -0.2, 0), tween_duration) + tween.tween_property(dialogueLabel3D, "position", dialogue_label_initial_position, tween_duration) + + +func _not_interactable(area_3D: Area3D) -> void: + if area_3D.get_parent() is CharacterBody3D: + dialogueLabel3D.set_visible(false) + interactable = false + + +func _input(event) -> void: + if not interactable: return + + if event is InputEventKey and event.pressed: + if event.keycode == KEY_F: + var tween: Tween = get_tree().create_tween() \ + .set_parallel(true) \ + .set_trans(Tween.TRANS_QUART) \ + .set_ease(Tween.EASE_IN_OUT) + if not is_interacting: + npc_pcam.priority = 20 + tween.tween_property(player, "global_position", move_to_location, 0.6).set_trans(tween_transition) + tween.tween_property(dialogueLabel3D, "rotation", Vector3(deg_to_rad(-20), deg_to_rad(53), 0), 0.6).set_trans(tween_transition) + else: + npc_pcam.priority = 0 + tween.tween_property(dialogueLabel3D, "rotation", dialogue_label_initial_rotation, 0.9) + player.movement_enabled = true + is_interacting = !is_interacting diff --git a/addons/phantom_camera/examples/scripts/3D/npc.gd.uid b/addons/phantom_camera/examples/scripts/3D/npc.gd.uid new file mode 100644 index 0000000..7464c88 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/npc.gd.uid @@ -0,0 +1 @@ +uid://uvw6pg1ut0ms diff --git a/addons/phantom_camera/examples/scripts/3D/path_follow.gd b/addons/phantom_camera/examples/scripts/3D/path_follow.gd new file mode 100644 index 0000000..8535e4c --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/path_follow.gd @@ -0,0 +1,17 @@ +extends Node + +@export var path_pcam: PhantomCamera3D + +func _ready() -> void: + connect("area_entered", _entered_area) + connect("area_exited", _exited_area) + + +func _entered_area(area_3D: Area3D) -> void: + if area_3D.get_parent() is CharacterBody3D: + path_pcam.set_priority(20) + + +func _exited_area(area_3D: Area3D) -> void: + if area_3D.get_parent() is CharacterBody3D: + path_pcam.set_priority(0) diff --git a/addons/phantom_camera/examples/scripts/3D/path_follow.gd.uid b/addons/phantom_camera/examples/scripts/3D/path_follow.gd.uid new file mode 100644 index 0000000..c2f56ca --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/path_follow.gd.uid @@ -0,0 +1 @@ +uid://cgknbkjar73w diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller.gd b/addons/phantom_camera/examples/scripts/3D/player_controller.gd new file mode 100644 index 0000000..b136103 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller.gd @@ -0,0 +1,103 @@ +extends CharacterBody3D + +@export var SPEED: float = 5.0 +@export var JUMP_VELOCITY: float = 4.5 +@export var enable_gravity = true + +@onready var _camera: Camera3D + +@onready var _player_visual: Node3D = %PlayerVisual + +# Get the gravity from the project settings to be synced with RigidBody nodes. +var gravity: float = 9.8 + +var movement_enabled: bool = true + +var _physics_body_trans_last: Transform3D +var _physics_body_trans_current: Transform3D + +const KEY_STRINGNAME: StringName = "Key" +const ACTION_STRINGNAME: StringName = "Action" + +const INPUT_MOVE_UP_STRINGNAME: StringName = "move_up" +const INPUT_MOVE_DOWM_STRINGNAME: StringName = "move_down" +const INPUT_MOVE_LEFT_STRINGNAME: StringName = "move_left" +const INPUT_MOVE_RIGHT_STRINGNAME: StringName = "move_right" + +var InputMovementDic: Dictionary = { + INPUT_MOVE_UP_STRINGNAME: { + KEY_STRINGNAME: KEY_W, + ACTION_STRINGNAME: INPUT_MOVE_UP_STRINGNAME + }, + INPUT_MOVE_DOWM_STRINGNAME: { + KEY_STRINGNAME: KEY_S, + ACTION_STRINGNAME: INPUT_MOVE_DOWM_STRINGNAME + }, + INPUT_MOVE_LEFT_STRINGNAME: { + KEY_STRINGNAME: KEY_A, + ACTION_STRINGNAME: INPUT_MOVE_LEFT_STRINGNAME + }, + INPUT_MOVE_RIGHT_STRINGNAME: { + KEY_STRINGNAME: KEY_D, + ACTION_STRINGNAME: INPUT_MOVE_RIGHT_STRINGNAME + }, +} + + +func _ready() -> void: + for input in InputMovementDic: + var key_val = InputMovementDic[input].get(KEY_STRINGNAME) + var action_val = InputMovementDic[input].get(ACTION_STRINGNAME) + + _camera = owner.get_node("%MainCamera3D") + + var movement_input = InputEventKey.new() + movement_input.physical_keycode = key_val + InputMap.add_action(action_val) + InputMap.action_add_event(action_val, movement_input) + + _player_visual.top_level = true + + +func _physics_process(delta: float) -> void: + _physics_body_trans_last = _physics_body_trans_current + _physics_body_trans_current = global_transform + + # Add the gravity. + if enable_gravity and not is_on_floor(): + velocity.y -= gravity * delta + + if not movement_enabled: return + + # Get the input direction and handle the movement/deceleration. + # As good practice, you should replace UI actions with custom gameplay actions. + var input_dir: Vector2 = Input.get_vector( + INPUT_MOVE_LEFT_STRINGNAME, + INPUT_MOVE_RIGHT_STRINGNAME, + INPUT_MOVE_UP_STRINGNAME, + INPUT_MOVE_DOWM_STRINGNAME + ) + + var cam_dir: Vector3 = -_camera.global_transform.basis.z + + var direction: Vector3 = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() + if direction: + var move_dir: Vector3 = Vector3.ZERO + move_dir.x = direction.x + move_dir.z = direction.z + + move_dir = move_dir.rotated(Vector3.UP, _camera.rotation.y).normalized() + velocity.x = move_dir.x * SPEED + velocity.z = move_dir.z * SPEED + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + velocity.z = move_toward(velocity.z, 0, SPEED) + + move_and_slide() + + +func _process(_delta: float) -> void: + _player_visual.global_transform = _physics_body_trans_last.interpolate_with( + _physics_body_trans_current, + Engine.get_physics_interpolation_fraction() + ) diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller.gd.uid new file mode 100644 index 0000000..c23173c --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller.gd.uid @@ -0,0 +1 @@ +uid://dut3e76k2c71n diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd b/addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd new file mode 100644 index 0000000..e907eca --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd @@ -0,0 +1,84 @@ +extends CharacterBody3D + +@export var SPEED: float = 5.0 +@export var JUMP_VELOCITY: float = 4.5 +@export var enable_gravity = true + +@onready var _camera: Camera3D + +# Get the gravity from the project settings to be synced with RigidBody nodes. +var gravity: float = 9.8 + +var movement_enabled: bool = true + +const KEY_STRINGNAME: StringName = "Key" +const ACTION_STRINGNAME: StringName = "Action" + +const INPUT_MOVE_UP_STRINGNAME: StringName = "move_up" +const INPUT_MOVE_DOWM_STRINGNAME: StringName = "move_down" +const INPUT_MOVE_LEFT_STRINGNAME: StringName = "move_left" +const INPUT_MOVE_RIGHT_STRINGNAME: StringName = "move_right" + +var InputMovementDic: Dictionary = { + INPUT_MOVE_UP_STRINGNAME: { + KEY_STRINGNAME: KEY_W, + ACTION_STRINGNAME: INPUT_MOVE_UP_STRINGNAME + }, + INPUT_MOVE_DOWM_STRINGNAME: { + KEY_STRINGNAME: KEY_S, + ACTION_STRINGNAME: INPUT_MOVE_DOWM_STRINGNAME + }, + INPUT_MOVE_LEFT_STRINGNAME: { + KEY_STRINGNAME: KEY_A, + ACTION_STRINGNAME: INPUT_MOVE_LEFT_STRINGNAME + }, + INPUT_MOVE_RIGHT_STRINGNAME: { + KEY_STRINGNAME: KEY_D, + ACTION_STRINGNAME: INPUT_MOVE_RIGHT_STRINGNAME + }, +} + + +func _ready() -> void: + for input in InputMovementDic: + var key_val = InputMovementDic[input].get(KEY_STRINGNAME) + var action_val = InputMovementDic[input].get(ACTION_STRINGNAME) + + _camera = owner.get_node("%MainCamera3D") + + var movement_input = InputEventKey.new() + movement_input.physical_keycode = key_val + InputMap.add_action(action_val) + InputMap.action_add_event(action_val, movement_input) + + +func _physics_process(delta: float) -> void: + # Add the gravity. + if enable_gravity and not is_on_floor(): + velocity.y -= gravity * delta + + if not movement_enabled: return + + # Get the input direction and handle the movement/deceleration. + # As good practice, you should replace UI actions with custom gameplay actions. + var input_dir: Vector2 = Input.get_vector( + INPUT_MOVE_LEFT_STRINGNAME, + INPUT_MOVE_RIGHT_STRINGNAME, + INPUT_MOVE_UP_STRINGNAME, + INPUT_MOVE_DOWM_STRINGNAME + ) + + var direction: Vector3 = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() + if direction: + var move_dir: Vector3 = Vector3.ZERO + move_dir.x = direction.x + move_dir.z = direction.z + + move_dir = move_dir.rotated(Vector3.UP, _camera.rotation.y).normalized() + velocity.x = move_dir.x * SPEED + velocity.z = move_dir.z * SPEED + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + velocity.z = move_toward(velocity.z, 0, SPEED) + + move_and_slide() diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd.uid new file mode 100644 index 0000000..182faff --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller_4.4.gd.uid @@ -0,0 +1 @@ +uid://tgv6xpi88sd0 diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd new file mode 100644 index 0000000..7e2da3f --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd @@ -0,0 +1,54 @@ +extends "player_controller.gd" + +@onready var _player_pcam: PhantomCamera3D = %PlayerPhantomCamera3D + +@onready var _player_character: CharacterBody3D = %PlayerCharacterBody3D + +@export var mouse_sensitivity: float = 0.05 + +@export var min_pitch: float = -89.9 +@export var max_pitch: float = 50 + +@export var min_yaw: float = 0 +@export var max_yaw: float = 360 + +@export var run_noise: PhantomCameraNoise3D + +func _ready() -> void: + super() + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + + if get_node_or_null("%PlayerPhantomCameraNoiseEmitter3D"): + %EmitterTip.visible = true + + +func _physics_process(delta: float) -> void: + super(delta) + + +func _unhandled_input(event: InputEvent) -> void: + if event is InputEventKey: + if get_node_or_null("%PlayerPhantomCameraNoiseEmitter3D"): + if event.keycode == KEY_Q and event.is_pressed(): + %PlayerPhantomCameraNoiseEmitter3D.emit() + + if event is InputEventMouseMotion: + var pcam_rotation_degrees: Vector3 + + # Assigns the current 3D rotation of the SpringArm3D node - so it starts off where it is in the editor + pcam_rotation_degrees = _player_pcam.rotation_degrees + + # Change the X rotation + pcam_rotation_degrees.x -= event.relative.y * mouse_sensitivity + + # Clamp the rotation in the X axis so it go over or under the target + pcam_rotation_degrees.x = clampf(pcam_rotation_degrees.x, min_pitch, max_pitch) + + # Change the Y rotation value + pcam_rotation_degrees.y -= event.relative.x * mouse_sensitivity + + # Sets the rotation to fully loop around its target, but witout going below or exceeding 0 and 360 degrees respectively + pcam_rotation_degrees.y = wrapf(pcam_rotation_degrees.y, min_yaw, max_yaw) + + # Change the SpringArm3D node's rotation and rotate around its target + _player_pcam.rotation_degrees = pcam_rotation_degrees diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd.uid new file mode 100644 index 0000000..c31115d --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person.gd.uid @@ -0,0 +1 @@ +uid://b3n22atuw76sm diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd new file mode 100644 index 0000000..33e4601 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd @@ -0,0 +1,54 @@ +extends "player_controller_4.4.gd" + +@onready var _player_pcam: PhantomCamera3D = %PlayerPhantomCamera3D + +@onready var _player_character: CharacterBody3D = %PlayerCharacterBody3D + +@export var mouse_sensitivity: float = 0.05 + +@export var min_pitch: float = -89.9 +@export var max_pitch: float = 50 + +@export var min_yaw: float = 0 +@export var max_yaw: float = 360 + +@export var run_noise: PhantomCameraNoise3D + +func _ready() -> void: + super() + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + + if get_node_or_null("%PlayerPhantomCameraNoiseEmitter3D"): + %EmitterTip.visible = true + + +func _physics_process(delta: float) -> void: + super(delta) + + +func _unhandled_input(event: InputEvent) -> void: + if event is InputEventKey: + if get_node_or_null("%PlayerPhantomCameraNoiseEmitter3D"): + if event.keycode == KEY_Q and event.is_pressed(): + %PlayerPhantomCameraNoiseEmitter3D.emit() + + if event is InputEventMouseMotion: + var pcam_rotation_degrees: Vector3 + + # Assigns the current 3D rotation of the SpringArm3D node - so it starts off where it is in the editor + pcam_rotation_degrees = _player_pcam.rotation_degrees + + # Change the X rotation + pcam_rotation_degrees.x -= event.relative.y * mouse_sensitivity + + # Clamp the rotation in the X axis so it go over or under the target + pcam_rotation_degrees.x = clampf(pcam_rotation_degrees.x, min_pitch, max_pitch) + + # Change the Y rotation value + pcam_rotation_degrees.y -= event.relative.x * mouse_sensitivity + + # Sets the rotation to fully loop around its target, but witout going below or exceeding 0 and 360 degrees respectively + pcam_rotation_degrees.y = wrapf(pcam_rotation_degrees.y, min_yaw, max_yaw) + + # Change the SpringArm3D node's rotation and rotate around its target + _player_pcam.rotation_degrees = pcam_rotation_degrees diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd.uid new file mode 100644 index 0000000..ee16763 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller_first_person_4.4.gd.uid @@ -0,0 +1 @@ +uid://x5g7kf5k2mac diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd new file mode 100644 index 0000000..f5d5579 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd @@ -0,0 +1,87 @@ +extends "player_controller.gd" + +@onready var _player_pcam: PhantomCamera3D +@onready var _aim_pcam: PhantomCamera3D +@onready var _player_direction: Node3D = %PlayerDirection +@onready var _ceiling_pcam: PhantomCamera3D + +@export var mouse_sensitivity: float = 0.05 + +@export var min_pitch: float = -89.9 +@export var max_pitch: float = 50 + +@export var min_yaw: float = 0 +@export var max_yaw: float = 360 + + + +func _ready() -> void: + super() + + _player_pcam = owner.get_node("%PlayerPhantomCamera3D") + _aim_pcam = owner.get_node("%PlayerAimPhantomCamera3D") + _ceiling_pcam = owner.get_node("%CeilingPhantomCamera3D") + + if _player_pcam.get_follow_mode() == _player_pcam.FollowMode.THIRD_PERSON: + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + + +func _physics_process(delta: float) -> void: + super(delta) + + if velocity.length() > 0.2: + var look_direction: Vector2 = Vector2(velocity.z, velocity.x) + _player_direction.rotation.y = look_direction.angle() + + +func _unhandled_input(event: InputEvent) -> void: + if _player_pcam.get_follow_mode() == _player_pcam.FollowMode.THIRD_PERSON: + var active_pcam: PhantomCamera3D + + _set_pcam_rotation(_player_pcam, event) + _set_pcam_rotation(_aim_pcam, event) + if _player_pcam.get_priority() > _aim_pcam.get_priority(): + _toggle_aim_pcam(event) + else: + _toggle_aim_pcam(event) + + if event is InputEventKey and event.pressed: + if event.keycode == KEY_SPACE: + if _ceiling_pcam.get_priority() < 30 and _player_pcam.is_active(): + _ceiling_pcam.set_priority(30) + else: + _ceiling_pcam.set_priority(1) + + +func _set_pcam_rotation(pcam: PhantomCamera3D, event: InputEvent) -> void: + if event is InputEventMouseMotion: + var pcam_rotation_degrees: Vector3 + + # Assigns the current 3D rotation of the SpringArm3D node - so it starts off where it is in the editor + pcam_rotation_degrees = pcam.get_third_person_rotation_degrees() + + # Change the X rotation + pcam_rotation_degrees.x -= event.relative.y * mouse_sensitivity + + # Clamp the rotation in the X axis so it go over or under the target + pcam_rotation_degrees.x = clampf(pcam_rotation_degrees.x, min_pitch, max_pitch) + + # Change the Y rotation value + pcam_rotation_degrees.y -= event.relative.x * mouse_sensitivity + + # Sets the rotation to fully loop around its target, but witout going below or exceeding 0 and 360 degrees respectively + pcam_rotation_degrees.y = wrapf(pcam_rotation_degrees.y, min_yaw, max_yaw) + + # Change the SpringArm3D node's rotation and rotate around its target + pcam.set_third_person_rotation_degrees(pcam_rotation_degrees) + + +func _toggle_aim_pcam(event: InputEvent) -> void: + if event is InputEventMouseButton \ + and event.is_pressed() \ + and event.button_index == 2 \ + and (_player_pcam.is_active() or _aim_pcam.is_active()): + if _player_pcam.get_priority() > _aim_pcam.get_priority(): + _aim_pcam.set_priority(30) + else: + _aim_pcam.set_priority(0) diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd.uid new file mode 100644 index 0000000..2218a6a --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person.gd.uid @@ -0,0 +1 @@ +uid://34uhyq3cpi67 diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd new file mode 100644 index 0000000..d0d56d4 --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd @@ -0,0 +1,86 @@ +extends "player_controller_4.4.gd" + +@onready var _player_pcam: PhantomCamera3D +@onready var _aim_pcam: PhantomCamera3D +@onready var _player_direction: Node3D = %PlayerDirection +@onready var _ceiling_pcam: PhantomCamera3D + +@export var mouse_sensitivity: float = 0.05 + +@export var min_pitch: float = -89.9 +@export var max_pitch: float = 50 + +@export var min_yaw: float = 0 +@export var max_yaw: float = 360 + + +func _ready() -> void: + super() + + _player_pcam = owner.get_node("%PlayerPhantomCamera3D") + _aim_pcam = owner.get_node("%PlayerAimPhantomCamera3D") + _ceiling_pcam = owner.get_node("%CeilingPhantomCamera3D") + + if _player_pcam.get_follow_mode() == _player_pcam.FollowMode.THIRD_PERSON: + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + + +func _physics_process(delta: float) -> void: + super(delta) + + if velocity.length() > 0.2: + var look_direction: Vector2 = Vector2(velocity.z, velocity.x) + _player_direction.rotation.y = look_direction.angle() + + +func _unhandled_input(event: InputEvent) -> void: + if _player_pcam.get_follow_mode() == _player_pcam.FollowMode.THIRD_PERSON: + var active_pcam: PhantomCamera3D + + _set_pcam_rotation(_player_pcam, event) + _set_pcam_rotation(_aim_pcam, event) + if _player_pcam.get_priority() > _aim_pcam.get_priority(): + _toggle_aim_pcam(event) + else: + _toggle_aim_pcam(event) + + if event is InputEventKey and event.pressed: + if event.keycode == KEY_SPACE: + if _ceiling_pcam.get_priority() < 30 and _player_pcam.is_active(): + _ceiling_pcam.set_priority(30) + else: + _ceiling_pcam.set_priority(1) + + +func _set_pcam_rotation(pcam: PhantomCamera3D, event: InputEvent) -> void: + if event is InputEventMouseMotion: + var pcam_rotation_degrees: Vector3 + + # Assigns the current 3D rotation of the SpringArm3D node - so it starts off where it is in the editor + pcam_rotation_degrees = pcam.get_third_person_rotation_degrees() + + # Change the X rotation + pcam_rotation_degrees.x -= event.relative.y * mouse_sensitivity + + # Clamp the rotation in the X axis so it go over or under the target + pcam_rotation_degrees.x = clampf(pcam_rotation_degrees.x, min_pitch, max_pitch) + + # Change the Y rotation value + pcam_rotation_degrees.y -= event.relative.x * mouse_sensitivity + + # Sets the rotation to fully loop around its target, but witout going below or exceeding 0 and 360 degrees respectively + pcam_rotation_degrees.y = wrapf(pcam_rotation_degrees.y, min_yaw, max_yaw) + + # Change the SpringArm3D node's rotation and rotate around its target + pcam.set_third_person_rotation_degrees(pcam_rotation_degrees) + + +func _toggle_aim_pcam(event: InputEvent) -> void: + if event is InputEventMouseButton \ + and event.is_pressed() \ + and event.button_index == 2 \ + and (_player_pcam.is_active() or _aim_pcam.is_active()): + if _player_pcam.get_priority() > _aim_pcam.get_priority(): + _aim_pcam.set_priority(30) + else: + _aim_pcam.set_priority(0) diff --git a/addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd.uid b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd.uid new file mode 100644 index 0000000..6346cec --- /dev/null +++ b/addons/phantom_camera/examples/scripts/3D/player_controller_third_person_4.4.gd.uid @@ -0,0 +1 @@ +uid://bkr71vxe2t18n diff --git a/addons/phantom_camera/examples/textures/2D/inventory_container.png b/addons/phantom_camera/examples/textures/2D/inventory_container.png new file mode 100644 index 0000000..7dd5178 Binary files /dev/null and b/addons/phantom_camera/examples/textures/2D/inventory_container.png differ diff --git a/addons/phantom_camera/examples/textures/2D/inventory_container.png.import b/addons/phantom_camera/examples/textures/2D/inventory_container.png.import new file mode 100644 index 0000000..82a4687 --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/inventory_container.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b7cs6me43ufh3" +path="res://.godot/imported/inventory_container.png-12241277f279bfc4bf7d5dad6b3e8ff2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/examples/textures/2D/inventory_container.png" +dest_files=["res://.godot/imported/inventory_container.png-12241277f279bfc4bf7d5dad6b3e8ff2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/phantom_camera/examples/textures/2D/level_spritesheet.png b/addons/phantom_camera/examples/textures/2D/level_spritesheet.png new file mode 100644 index 0000000..939cb28 Binary files /dev/null and b/addons/phantom_camera/examples/textures/2D/level_spritesheet.png differ diff --git a/addons/phantom_camera/examples/textures/2D/level_spritesheet.png.import b/addons/phantom_camera/examples/textures/2D/level_spritesheet.png.import new file mode 100644 index 0000000..6c9b22c --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/level_spritesheet.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c77npili4pel4" +path="res://.godot/imported/level_spritesheet.png-26a44dd21a040a5480d5ccba54377d99.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/examples/textures/2D/level_spritesheet.png" +dest_files=["res://.godot/imported/level_spritesheet.png-26a44dd21a040a5480d5ccba54377d99.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png b/addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png new file mode 100644 index 0000000..2012b3a Binary files /dev/null and b/addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png differ diff --git a/addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png.import b/addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png.import new file mode 100644 index 0000000..fb6efd8 --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cwep0on2tthn7" +path="res://.godot/imported/phantom_camera_2d_sprite.png-deab230b83ae03aeb308a08ff66b8dbc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png" +dest_files=["res://.godot/imported/phantom_camera_2d_sprite.png-deab230b83ae03aeb308a08ff66b8dbc.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/phantom_camera/examples/textures/2D/player_sprite.svg b/addons/phantom_camera/examples/textures/2D/player_sprite.svg new file mode 100644 index 0000000..ce261b1 --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/player_sprite.svg @@ -0,0 +1,4 @@ + + + + diff --git a/addons/phantom_camera/examples/textures/2D/player_sprite.svg.import b/addons/phantom_camera/examples/textures/2D/player_sprite.svg.import new file mode 100644 index 0000000..55eb0bc --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/player_sprite.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cscjjt55iw2cu" +path="res://.godot/imported/player_sprite.svg-8862ecb19e12152eb892607676f3831f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/examples/textures/2D/player_sprite.svg" +dest_files=["res://.godot/imported/player_sprite.svg-8862ecb19e12152eb892607676f3831f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=8.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/examples/textures/2D/sign_prompt.png b/addons/phantom_camera/examples/textures/2D/sign_prompt.png new file mode 100644 index 0000000..a730837 Binary files /dev/null and b/addons/phantom_camera/examples/textures/2D/sign_prompt.png differ diff --git a/addons/phantom_camera/examples/textures/2D/sign_prompt.png.import b/addons/phantom_camera/examples/textures/2D/sign_prompt.png.import new file mode 100644 index 0000000..0db7219 --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/sign_prompt.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bloouh2jtndx1" +path="res://.godot/imported/sign_prompt.png-18d451127e1cd1a16367acd23cec47e5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/examples/textures/2D/sign_prompt.png" +dest_files=["res://.godot/imported/sign_prompt.png-18d451127e1cd1a16367acd23cec47e5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png b/addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png new file mode 100644 index 0000000..4aeae6c Binary files /dev/null and b/addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png differ diff --git a/addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png.import b/addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png.import new file mode 100644 index 0000000..9bfe7d0 --- /dev/null +++ b/addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png.import @@ -0,0 +1,41 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bj7h2fc5jx4ax" +path.s3tc="res://.godot/imported/checker_pattern_dark.png-70cedad2d3abf4ad6166d6614eefa7fb.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png" +dest_files=["res://.godot/imported/checker_pattern_dark.png-70cedad2d3abf4ad6166d6614eefa7fb.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/addons/phantom_camera/examples/textures/3D/target.png b/addons/phantom_camera/examples/textures/3D/target.png new file mode 100644 index 0000000..96fed65 Binary files /dev/null and b/addons/phantom_camera/examples/textures/3D/target.png differ diff --git a/addons/phantom_camera/examples/textures/3D/target.png.import b/addons/phantom_camera/examples/textures/3D/target.png.import new file mode 100644 index 0000000..8df98fc --- /dev/null +++ b/addons/phantom_camera/examples/textures/3D/target.png.import @@ -0,0 +1,41 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c3mskbmvnpwux" +path.s3tc="res://.godot/imported/target.png-878c5e8d057c8a9a4c2322d4ab88e9ef.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/phantom_camera/examples/textures/3D/target.png" +dest_files=["res://.godot/imported/target.png-878c5e8d057c8a9a4c2322d4ab88e9ef.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/addons/phantom_camera/examples/ui/ui_inventory.tscn b/addons/phantom_camera/examples/ui/ui_inventory.tscn new file mode 100644 index 0000000..cddd377 --- /dev/null +++ b/addons/phantom_camera/examples/ui/ui_inventory.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=3 format=3 uid="uid://dg7rhrymsrrrm"] + +[ext_resource type="Texture2D" uid="uid://b7cs6me43ufh3" path="res://addons/phantom_camera/examples/textures/2D/inventory_container.png" id="1_pi2dp"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="2_0rdcn"] + +[node name="Control" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="TextureRect" type="TextureRect" parent="."] +layout_mode = 1 +anchors_preset = 4 +anchor_top = 0.5 +anchor_bottom = 0.5 +offset_left = 28.0 +offset_top = -255.0 +offset_right = 908.0 +offset_bottom = 183.0 +grow_vertical = 2 +texture = ExtResource("1_pi2dp") + +[node name="Label" type="Label" parent="TextureRect"] +layout_mode = 0 +offset_left = 345.0 +offset_top = 12.0 +offset_right = 535.0 +offset_bottom = 60.0 +theme_override_colors/font_color = Color(0.356863, 0.105882, 0.133333, 1) +theme_override_fonts/font = ExtResource("2_0rdcn") +theme_override_font_sizes/font_size = 32 +text = "Inventory" +horizontal_alignment = 1 +uppercase = true diff --git a/addons/phantom_camera/examples/ui/ui_sign.tscn b/addons/phantom_camera/examples/ui/ui_sign.tscn new file mode 100644 index 0000000..1b891ef --- /dev/null +++ b/addons/phantom_camera/examples/ui/ui_sign.tscn @@ -0,0 +1,83 @@ +[gd_scene load_steps=4 format=3 uid="uid://iq5xd1ob1res"] + +[ext_resource type="Texture2D" uid="uid://bloouh2jtndx1" path="res://addons/phantom_camera/examples/textures/2D/sign_prompt.png" id="1_tftrk"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="2_y5454"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_r4h3u"] +bg_color = Color(0.470588, 0.6, 0.45098, 1) +corner_radius_top_right = 47 +corner_radius_bottom_left = 40 + +[node name="Control" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="TextureRect" type="TextureRect" parent="."] +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -273.568 +offset_top = 47.0 +offset_right = 273.568 +offset_bottom = 413.0 +grow_horizontal = 2 +texture = ExtResource("1_tftrk") +metadata/_edit_group_ = true + +[node name="Label" type="Label" parent="TextureRect"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 25.0 +offset_top = 64.0 +offset_right = -25.0 +offset_bottom = -88.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_colors/font_color = Color(0.207843, 0.0470588, 0.0666667, 1) +theme_override_fonts/font = ExtResource("2_y5454") +theme_override_font_sizes/font_size = 62 +text = "Stay Awhile +and read" +horizontal_alignment = 1 +vertical_alignment = 1 +uppercase = true + +[node name="Panel" type="Panel" parent="."] +visible = false +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -240.0 +offset_right = 240.0 +offset_bottom = 200.0 +grow_horizontal = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_styles/panel = SubResource("StyleBoxFlat_r4h3u") +metadata/_edit_use_anchors_ = true + +[node name="VBoxContainer" type="VBoxContainer" parent="Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +alignment = 1 + +[node name="Label2" type="Label" parent="Panel/VBoxContainer"] +layout_mode = 2 +text = "Example Textsdadassa +" +horizontal_alignment = 1 +vertical_alignment = 1 diff --git a/addons/phantom_camera/fonts/Nunito-Black.ttf b/addons/phantom_camera/fonts/Nunito-Black.ttf new file mode 100644 index 0000000..1081731 Binary files /dev/null and b/addons/phantom_camera/fonts/Nunito-Black.ttf differ diff --git a/addons/phantom_camera/fonts/Nunito-Black.ttf.import b/addons/phantom_camera/fonts/Nunito-Black.ttf.import new file mode 100644 index 0000000..ac0fdb7 --- /dev/null +++ b/addons/phantom_camera/fonts/Nunito-Black.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://c4mm3of2mc8o5" +path="res://.godot/imported/Nunito-Black.ttf-2a374efbc207a97a99b8c70bdc4b7cbb.fontdata" + +[deps] + +source_file="res://addons/phantom_camera/fonts/Nunito-Black.ttf" +dest_files=["res://.godot/imported/Nunito-Black.ttf-2a374efbc207a97a99b8c70bdc4b7cbb.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/addons/phantom_camera/fonts/Nunito-Regular.ttf b/addons/phantom_camera/fonts/Nunito-Regular.ttf new file mode 100644 index 0000000..dfd0fcb Binary files /dev/null and b/addons/phantom_camera/fonts/Nunito-Regular.ttf differ diff --git a/addons/phantom_camera/fonts/Nunito-Regular.ttf.import b/addons/phantom_camera/fonts/Nunito-Regular.ttf.import new file mode 100644 index 0000000..a2ee2e8 --- /dev/null +++ b/addons/phantom_camera/fonts/Nunito-Regular.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://dve7mgsjik4dg" +path="res://.godot/imported/Nunito-Regular.ttf-b6054d499efa1a10921004862b1e217a.fontdata" + +[deps] + +source_file="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" +dest_files=["res://.godot/imported/Nunito-Regular.ttf-b6054d499efa1a10921004862b1e217a.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/addons/phantom_camera/icons/misc/PriorityOverride.svg b/addons/phantom_camera/icons/misc/PriorityOverride.svg new file mode 100644 index 0000000..de7fd01 --- /dev/null +++ b/addons/phantom_camera/icons/misc/PriorityOverride.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/addons/phantom_camera/icons/misc/PriorityOverride.svg.import b/addons/phantom_camera/icons/misc/PriorityOverride.svg.import new file mode 100644 index 0000000..79ad2a1 --- /dev/null +++ b/addons/phantom_camera/icons/misc/PriorityOverride.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dy8eifa6aw2en" +path="res://.godot/imported/PriorityOverride.svg-e76e07f4bbd98169f119e17fe5f2f03f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/misc/PriorityOverride.svg" +dest_files=["res://.godot/imported/PriorityOverride.svg-e76e07f4bbd98169f119e17fe5f2f03f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/phantom_camera_2d.svg b/addons/phantom_camera/icons/phantom_camera_2d.svg new file mode 100644 index 0000000..0c67805 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_2d.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/phantom_camera/icons/phantom_camera_2d.svg.import b/addons/phantom_camera/icons/phantom_camera_2d.svg.import new file mode 100644 index 0000000..9fe97c8 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_2d.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dchkkx4v3ikpw" +path="res://.godot/imported/phantom_camera_2d.svg-e5483cbc858fc5f95f7210b1649dff0d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_2d.svg" +dest_files=["res://.godot/imported/phantom_camera_2d.svg-e5483cbc858fc5f95f7210b1649dff0d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/phantom_camera_3d.svg b/addons/phantom_camera/icons/phantom_camera_3d.svg new file mode 100644 index 0000000..db18730 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_3d.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/phantom_camera/icons/phantom_camera_3d.svg.import b/addons/phantom_camera/icons/phantom_camera_3d.svg.import new file mode 100644 index 0000000..8d1154b --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_3d.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c71drpb8o4prn" +path="res://.godot/imported/phantom_camera_3d.svg-41ed612e834470377fb56eebffa083fe.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_3d.svg" +dest_files=["res://.godot/imported/phantom_camera_3d.svg-41ed612e834470377fb56eebffa083fe.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/phantom_camera_camera_3d_resource.svg b/addons/phantom_camera/icons/phantom_camera_camera_3d_resource.svg new file mode 100644 index 0000000..282adf2 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_camera_3d_resource.svg @@ -0,0 +1,3 @@ + + + diff --git a/addons/phantom_camera/icons/phantom_camera_camera_3d_resource.svg.import b/addons/phantom_camera/icons/phantom_camera_camera_3d_resource.svg.import new file mode 100644 index 0000000..a2a2fa6 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_camera_3d_resource.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dnaykbu6ue5lo" +path="res://.godot/imported/phantom_camera_camera_3d_resource.svg-f8bf8d1a5b7442fd6933bfbed999d57d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_camera_3d_resource.svg" +dest_files=["res://.godot/imported/phantom_camera_camera_3d_resource.svg-f8bf8d1a5b7442fd6933bfbed999d57d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/phantom_camera_gizmo.svg b/addons/phantom_camera/icons/phantom_camera_gizmo.svg new file mode 100644 index 0000000..d791ce0 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_gizmo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/phantom_camera/icons/phantom_camera_gizmo.svg.import b/addons/phantom_camera/icons/phantom_camera_gizmo.svg.import new file mode 100644 index 0000000..e46b332 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_gizmo.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://e36npe2rbxyg" +path.s3tc="res://.godot/imported/phantom_camera_gizmo.svg-ba1aacb9b1c5f4ef401d3bd3697a542b.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_gizmo.svg" +dest_files=["res://.godot/imported/phantom_camera_gizmo.svg-ba1aacb9b1c5f4ef401d3bd3697a542b.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/phantom_camera_glow_logo.png b/addons/phantom_camera/icons/phantom_camera_glow_logo.png new file mode 100644 index 0000000..41ad8de Binary files /dev/null and b/addons/phantom_camera/icons/phantom_camera_glow_logo.png differ diff --git a/addons/phantom_camera/icons/phantom_camera_glow_logo.png.import b/addons/phantom_camera/icons/phantom_camera_glow_logo.png.import new file mode 100644 index 0000000..8cc3625 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_glow_logo.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cjli3p2b8mfyh" +path="res://.godot/imported/phantom_camera_glow_logo.png-078f944973b55b32029ba02980211fe0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_glow_logo.png" +dest_files=["res://.godot/imported/phantom_camera_glow_logo.png-078f944973b55b32029ba02980211fe0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/phantom_camera/icons/phantom_camera_host.svg b/addons/phantom_camera/icons/phantom_camera_host.svg new file mode 100644 index 0000000..4ff3ada --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_host.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/phantom_camera/icons/phantom_camera_host.svg.import b/addons/phantom_camera/icons/phantom_camera_host.svg.import new file mode 100644 index 0000000..bd05ffc --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_host.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://5fatldiu7dd5" +path="res://.godot/imported/phantom_camera_host.svg-3150f8f2d82ca9ecab9a3a415da21c5b.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_host.svg" +dest_files=["res://.godot/imported/phantom_camera_host.svg-3150f8f2d82ca9ecab9a3a415da21c5b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=true diff --git a/addons/phantom_camera/icons/phantom_camera_logo.png b/addons/phantom_camera/icons/phantom_camera_logo.png new file mode 100644 index 0000000..bc43e56 Binary files /dev/null and b/addons/phantom_camera/icons/phantom_camera_logo.png differ diff --git a/addons/phantom_camera/icons/phantom_camera_logo.png.import b/addons/phantom_camera/icons/phantom_camera_logo.png.import new file mode 100644 index 0000000..12e3ccd --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_logo.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cc0wmici0eic8" +path="res://.godot/imported/phantom_camera_logo.png-8b8d347b5e4800c86cd8095d030a3e5a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_logo.png" +dest_files=["res://.godot/imported/phantom_camera_logo.png-8b8d347b5e4800c86cd8095d030a3e5a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/phantom_camera/icons/phantom_camera_noise_emitter_2d.svg b/addons/phantom_camera/icons/phantom_camera_noise_emitter_2d.svg new file mode 100644 index 0000000..f6fbad3 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_emitter_2d.svg @@ -0,0 +1,4 @@ + + + + diff --git a/addons/phantom_camera/icons/phantom_camera_noise_emitter_2d.svg.import b/addons/phantom_camera/icons/phantom_camera_noise_emitter_2d.svg.import new file mode 100644 index 0000000..f25e7c0 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_emitter_2d.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b2r7mhd780y8d" +path="res://.godot/imported/phantom_camera_noise_emitter_2d.svg-1b3d37fe36964dc86a6ea6681d0772bb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_noise_emitter_2d.svg" +dest_files=["res://.godot/imported/phantom_camera_noise_emitter_2d.svg-1b3d37fe36964dc86a6ea6681d0772bb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/phantom_camera_noise_emitter_3d.svg b/addons/phantom_camera/icons/phantom_camera_noise_emitter_3d.svg new file mode 100644 index 0000000..c567f6a --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_emitter_3d.svg @@ -0,0 +1,4 @@ + + + + diff --git a/addons/phantom_camera/icons/phantom_camera_noise_emitter_3d.svg.import b/addons/phantom_camera/icons/phantom_camera_noise_emitter_3d.svg.import new file mode 100644 index 0000000..fd4775c --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_emitter_3d.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cby76y7m6xn4f" +path.s3tc="res://.godot/imported/phantom_camera_noise_emitter_3d.svg-9b90fe54aa618f65d52ac94515d41ea4.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_noise_emitter_3d.svg" +dest_files=["res://.godot/imported/phantom_camera_noise_emitter_3d.svg-9b90fe54aa618f65d52ac94515d41ea4.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/phantom_camera_noise_emitter_gizmo.svg b/addons/phantom_camera/icons/phantom_camera_noise_emitter_gizmo.svg new file mode 100644 index 0000000..9b9bcb2 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_emitter_gizmo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/addons/phantom_camera/icons/phantom_camera_noise_emitter_gizmo.svg.import b/addons/phantom_camera/icons/phantom_camera_noise_emitter_gizmo.svg.import new file mode 100644 index 0000000..f94b1f9 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_emitter_gizmo.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dw4iy855s0atm" +path.s3tc="res://.godot/imported/phantom_camera_noise_emitter_gizmo.svg-9a593802655a8d5038c7f55deab3882d.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_noise_emitter_gizmo.svg" +dest_files=["res://.godot/imported/phantom_camera_noise_emitter_gizmo.svg-9a593802655a8d5038c7f55deab3882d.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/phantom_camera_noise_resource.svg b/addons/phantom_camera/icons/phantom_camera_noise_resource.svg new file mode 100644 index 0000000..d3c6deb --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_resource.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/addons/phantom_camera/icons/phantom_camera_noise_resource.svg.import b/addons/phantom_camera/icons/phantom_camera_noise_resource.svg.import new file mode 100644 index 0000000..92c7e3d --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_resource.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://fudwitkewe70" +path="res://.godot/imported/phantom_camera_noise_resource.svg-a81ed223714edd2c0d9cfa00be0c3f58.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_noise_resource.svg" +dest_files=["res://.godot/imported/phantom_camera_noise_resource.svg-a81ed223714edd2c0d9cfa00be0c3f58.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/phantom_camera_tween.svg b/addons/phantom_camera/icons/phantom_camera_tween.svg new file mode 100644 index 0000000..6956fb5 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_tween.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/phantom_camera/icons/phantom_camera_tween.svg.import b/addons/phantom_camera/icons/phantom_camera_tween.svg.import new file mode 100644 index 0000000..b9e024b --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_tween.svg.import @@ -0,0 +1,44 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dphl04mdf3220" +path="res://.godot/imported/phantom_camera_tween.svg-16faced08ef4a5f3458264d894230dbd.ctex" +metadata={ +"has_editor_variant": true, +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_tween.svg" +dest_files=["res://.godot/imported/phantom_camera_tween.svg-16faced08ef4a5f3458264d894230dbd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=true diff --git a/addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg b/addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg new file mode 100644 index 0000000..6d3bcd4 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg.import b/addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg.import new file mode 100644 index 0000000..d1ace76 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d4j4hrb7yusyq" +path="res://.godot/imported/phantom_camera_updater_panel_icon.svg-19823e6cbee8115f8b2554d0ee6e79db.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg" +dest_files=["res://.godot/imported/phantom_camera_updater_panel_icon.svg-19823e6cbee8115f8b2554d0ee6e79db.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/viewfinder/Camera2DIcon.svg b/addons/phantom_camera/icons/viewfinder/Camera2DIcon.svg new file mode 100644 index 0000000..59efad4 --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Camera2DIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/addons/phantom_camera/icons/viewfinder/Camera2DIcon.svg.import b/addons/phantom_camera/icons/viewfinder/Camera2DIcon.svg.import new file mode 100644 index 0000000..714d685 --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Camera2DIcon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ccnsrg8hq74p2" +path="res://.godot/imported/Camera2DIcon.svg-300e6f57281180711c5ecf391104d4ba.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/viewfinder/Camera2DIcon.svg" +dest_files=["res://.godot/imported/Camera2DIcon.svg-300e6f57281180711c5ecf391104d4ba.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/viewfinder/Camera3DIcon.svg b/addons/phantom_camera/icons/viewfinder/Camera3DIcon.svg new file mode 100644 index 0000000..2366c3f --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Camera3DIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/addons/phantom_camera/icons/viewfinder/Camera3DIcon.svg.import b/addons/phantom_camera/icons/viewfinder/Camera3DIcon.svg.import new file mode 100644 index 0000000..be171ac --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Camera3DIcon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dkiefpjsrj37n" +path="res://.godot/imported/Camera3DIcon.svg-4805c46004db1c89cc9443dd740693f5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/viewfinder/Camera3DIcon.svg" +dest_files=["res://.godot/imported/Camera3DIcon.svg-4805c46004db1c89cc9443dd740693f5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/viewfinder/SceneTypesIcon.svg b/addons/phantom_camera/icons/viewfinder/SceneTypesIcon.svg new file mode 100644 index 0000000..87e3f79 --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/SceneTypesIcon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/addons/phantom_camera/icons/viewfinder/SceneTypesIcon.svg.import b/addons/phantom_camera/icons/viewfinder/SceneTypesIcon.svg.import new file mode 100644 index 0000000..e97d921 --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/SceneTypesIcon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dk7omm0x44suj" +path="res://.godot/imported/SceneTypesIcon.svg-66e2255bd3398007bec03a5cbfa4d0aa.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/viewfinder/SceneTypesIcon.svg" +dest_files=["res://.godot/imported/SceneTypesIcon.svg-66e2255bd3398007bec03a5cbfa4d0aa.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/viewfinder/Select.svg b/addons/phantom_camera/icons/viewfinder/Select.svg new file mode 100644 index 0000000..34b109b --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Select.svg @@ -0,0 +1,3 @@ + + + diff --git a/addons/phantom_camera/icons/viewfinder/Select.svg.import b/addons/phantom_camera/icons/viewfinder/Select.svg.import new file mode 100644 index 0000000..b1cb20c --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Select.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://rghrkoqrm2ig" +path="res://.godot/imported/Select.svg-cdf90b8b400d3b91a023b70c6a823894.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/viewfinder/Select.svg" +dest_files=["res://.godot/imported/Select.svg-cdf90b8b400d3b91a023b70c6a823894.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/icons/warning.svg b/addons/phantom_camera/icons/warning.svg new file mode 100644 index 0000000..63dbedf --- /dev/null +++ b/addons/phantom_camera/icons/warning.svg @@ -0,0 +1,4 @@ + + + + diff --git a/addons/phantom_camera/icons/warning.svg.import b/addons/phantom_camera/icons/warning.svg.import new file mode 100644 index 0000000..07b7909 --- /dev/null +++ b/addons/phantom_camera/icons/warning.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cjlv0bg7byjx0" +path="res://.godot/imported/warning.svg-c1b21c265e0842bbdc9ed10735995366.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/phantom_camera/icons/warning.svg" +dest_files=["res://.godot/imported/warning.svg-c1b21c265e0842bbdc9ed10735995366.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=2.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/phantom_camera/inspector/phantom_camera_inspector_plugin.gd b/addons/phantom_camera/inspector/phantom_camera_inspector_plugin.gd new file mode 100644 index 0000000..d5a0d22 --- /dev/null +++ b/addons/phantom_camera/inspector/phantom_camera_inspector_plugin.gd @@ -0,0 +1,46 @@ +@tool +extends EditorInspectorPlugin + +#var _phantom_camera_script: Script = preload("res://addons/phantom_camera/scripts/phantom_camera.gd") + + +# TODO - Enable again once work is resumed for inspector based tasks + +#func _can_handle(object) -> bool: +# return object is _phantom_camera_script + + +func _parse_category(object: Object, category: String) -> void: + + var _margin_container: MarginContainer = MarginContainer.new() + var _margin_v: float = 20 + _margin_container.add_theme_constant_override("margin_left", 10) + _margin_container.add_theme_constant_override("margin_top", _margin_v) + _margin_container.add_theme_constant_override("margin_right", 10) + _margin_container.add_theme_constant_override("margin_bottom", _margin_v) + add_custom_control(_margin_container) + + var _vbox_container: VBoxContainer = VBoxContainer.new() + _margin_container.add_child(_vbox_container) + + var align_with_view_button = Button.new() + align_with_view_button.connect("pressed", _align_camera_with_view.bind(object)) + align_with_view_button.set_custom_minimum_size(Vector2(0, 60)) + align_with_view_button.set_text("Align with view") + _vbox_container.add_child(align_with_view_button) + + var preview_camera_button = Button.new() + preview_camera_button.connect("pressed", _preview_camera.bind(object)) + preview_camera_button.set_custom_minimum_size(Vector2(0, 60)) + preview_camera_button.set_text("Preview Camera") + _vbox_container.add_child(preview_camera_button) + + + +func _align_camera_with_view(object: Object) -> void: + print("Aligning camera with view") + print(object) + +func _preview_camera(object: Object) -> void: + print("Previewing camera") + print(object) diff --git a/addons/phantom_camera/inspector/phantom_camera_inspector_plugin.gd.uid b/addons/phantom_camera/inspector/phantom_camera_inspector_plugin.gd.uid new file mode 100644 index 0000000..325b3c0 --- /dev/null +++ b/addons/phantom_camera/inspector/phantom_camera_inspector_plugin.gd.uid @@ -0,0 +1 @@ +uid://dhwxgngr7sn6d diff --git a/addons/phantom_camera/panel/editor.gd.uid b/addons/phantom_camera/panel/editor.gd.uid new file mode 100644 index 0000000..52a27c4 --- /dev/null +++ b/addons/phantom_camera/panel/editor.gd.uid @@ -0,0 +1 @@ +uid://ppret7j0jle7 diff --git a/addons/phantom_camera/panel/editor.tscn b/addons/phantom_camera/panel/editor.tscn new file mode 100644 index 0000000..0c75c6a --- /dev/null +++ b/addons/phantom_camera/panel/editor.tscn @@ -0,0 +1,23 @@ +[gd_scene load_steps=4 format=3 uid="uid://cfdoaceoosi1w"] + +[ext_resource type="Script" uid="uid://cgfwg3paxkj2x" path="res://addons/phantom_camera/scripts/panel/editor.gd" id="1_86hp7"] +[ext_resource type="PackedScene" uid="uid://cuqkqsp3ikv5u" path="res://addons/phantom_camera/panel/updater/update_button.tscn" id="1_oowcd"] +[ext_resource type="PackedScene" uid="uid://dbkr3d716wtx0" path="res://addons/phantom_camera/panel/viewfinder/viewfinder_panel.tscn" id="2_xecnk"] + +[node name="EditorPanel" type="VBoxContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_86hp7") + +[node name="UpdateButton" parent="." instance=ExtResource("1_oowcd")] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 8 +size_flags_vertical = 1 + +[node name="ViewfinderPanel" parent="." instance=ExtResource("2_xecnk")] +unique_name_in_owner = true +layout_mode = 2 diff --git a/addons/phantom_camera/panel/updater/download_update_panel.tscn b/addons/phantom_camera/panel/updater/download_update_panel.tscn new file mode 100644 index 0000000..5fa49e3 --- /dev/null +++ b/addons/phantom_camera/panel/updater/download_update_panel.tscn @@ -0,0 +1,253 @@ +[gd_scene load_steps=15 format=3 uid="uid://b25fl4usw0nlp"] + +[ext_resource type="Script" uid="uid://cjblcocen12r3" path="res://addons/phantom_camera/scripts/panel/updater/download_update_panel.gd" id="1_sx5xq"] +[ext_resource type="Texture2D" uid="uid://cc0wmici0eic8" path="res://addons/phantom_camera/icons/phantom_camera_logo.png" id="2_f3yo7"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="3_h8uk3"] +[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="4_gwh4i"] +[ext_resource type="Texture2D" uid="uid://censw3w53gldn" path="res://addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png" id="5_bonti"] + +[sub_resource type="ImageTexture" id="ImageTexture_sjwi2"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_insma"] +bg_color = Color(0.0190018, 0.21903, 0.16997, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.0980392, 0.572549, 0.458824, 1) +border_blend = true +corner_radius_bottom_right = 12 +corner_radius_bottom_left = 12 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8m63d"] +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.105882, 0.619608, 0.498039, 1) +corner_radius_bottom_right = 12 +corner_radius_bottom_left = 12 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_yn22d"] +bg_color = Color(0.0117647, 0.164706, 0.12549, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.0980392, 0.572549, 0.458824, 1) +border_blend = true +corner_radius_bottom_right = 12 +corner_radius_bottom_left = 12 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_djsbc"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_xtrn6"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_o12j0"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_buptb"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_g3tf0"] + +[node name="DownloadUpdatePanel" type="Control"] +custom_minimum_size = Vector2(300, 350) +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_bottom = -61.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_sx5xq") + +[node name="DownloadHTTPRequest" type="HTTPRequest" parent="."] +unique_name_in_owner = true + +[node name="Timer" type="Timer" parent="DownloadHTTPRequest"] +one_shot = true + +[node name="VBox" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/separation = 2 + +[node name="VBoxContainer2" type="VBoxContainer" parent="VBox"] +layout_mode = 2 +theme_override_constants/separation = -20 + +[node name="MarginContainer" type="MarginContainer" parent="VBox/VBoxContainer2"] +layout_mode = 2 +theme_override_constants/margin_top = 12 + +[node name="Logo" type="TextureRect" parent="VBox/VBoxContainer2/MarginContainer"] +unique_name_in_owner = true +clip_contents = true +custom_minimum_size = Vector2(300, 160) +layout_mode = 2 +texture = ExtResource("2_f3yo7") +expand_mode = 3 +stretch_mode = 5 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBox/VBoxContainer2"] +layout_mode = 2 +theme_override_constants/separation = -5 + +[node name="NameLabel" type="Label" parent="VBox/VBoxContainer2/VBoxContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.960784, 0.960784, 0.960784, 1) +theme_override_fonts/font = ExtResource("3_h8uk3") +theme_override_font_sizes/font_size = 32 +text = "Phantom Camera" +horizontal_alignment = 1 + +[node name="DownloadVersionLabel" type="Label" parent="VBox/VBoxContainer2/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_colors/font_color = Color(0.960784, 0.960784, 0.960784, 1) +theme_override_fonts/font = ExtResource("4_gwh4i") +theme_override_font_sizes/font_size = 18 +text = "v1.2.3 is available for download." +horizontal_alignment = 1 + +[node name="CurrentVersionLabel" type="Label" parent="VBox"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +theme_override_fonts/font = ExtResource("4_gwh4i") +text = "Current version: 0.0.0" +horizontal_alignment = 1 + +[node name="Center2" type="CenterContainer" parent="VBox"] +layout_mode = 2 + +[node name="NotesButton" type="LinkButton" parent="VBox/Center2"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.917647, 0.631373, 0.368627, 1) +theme_override_colors/font_hover_color = Color(0.721569, 0.454902, 0.192157, 1) +theme_override_fonts/font = ExtResource("3_h8uk3") +theme_override_font_sizes/font_size = 18 +text = "Release Notes" + +[node name="Center" type="CenterContainer" parent="VBox"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBox/Center"] +layout_mode = 2 + +[node name="BreakingLabel" type="Label" parent="VBox/Center/VBoxContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +theme_override_colors/font_color = Color(0.72549, 0.227451, 0.34902, 1) +theme_override_fonts/font = ExtResource("3_h8uk3") +theme_override_font_sizes/font_size = 18 +text = "Potential Breaking Changes +in new release" +horizontal_alignment = 1 +uppercase = true + +[node name="BreakingMarginContainer" type="MarginContainer" parent="VBox/Center/VBoxContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBox/Center/VBoxContainer/BreakingMarginContainer"] +layout_mode = 2 + +[node name="RichTextLabel2" type="RichTextLabel" parent="VBox/Center/VBoxContainer/BreakingMarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_fonts/normal_font = ExtResource("4_gwh4i") +theme_override_fonts/bold_font = ExtResource("3_h8uk3") +theme_override_fonts/mono_font = ExtResource("3_h8uk3") +theme_override_font_sizes/normal_font_size = 18 +theme_override_font_sizes/bold_font_size = 14 +theme_override_font_sizes/mono_font_size = 12 +bbcode_enabled = true +text = "[center][b]I am prepared for any breaking +changes that may occur from this update[/b][/center]" +fit_content = true + +[node name="BreakingOptionButton" type="OptionButton" parent="VBox/Center/VBoxContainer/BreakingMarginContainer/VBoxContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +mouse_default_cursor_shape = 2 +theme_override_fonts/font = ExtResource("3_h8uk3") +theme_override_font_sizes/font_size = 18 +theme_override_icons/arrow = SubResource("ImageTexture_sjwi2") +theme_override_styles/normal = SubResource("StyleBoxFlat_insma") +theme_override_styles/hover = SubResource("StyleBoxFlat_8m63d") +theme_override_styles/pressed = SubResource("StyleBoxFlat_yn22d") +alignment = 1 +item_count = 2 +selected = 0 +popup/item_0/text = "Confirm choice" +popup/item_0/id = 0 +popup/item_1/text = "Yes, I am prepared" +popup/item_1/id = 1 + +[node name="DownloadButton" type="Button" parent="VBox/Center/VBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(240, 90) +layout_mode = 2 +mouse_default_cursor_shape = 2 +theme_override_styles/normal = SubResource("StyleBoxEmpty_djsbc") +theme_override_styles/hover = SubResource("StyleBoxEmpty_xtrn6") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_o12j0") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_buptb") +theme_override_styles/focus = SubResource("StyleBoxEmpty_g3tf0") + +[node name="DownloadButtonBG" type="NinePatchRect" parent="VBox/Center/VBoxContainer/DownloadButton"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("5_bonti") +patch_margin_left = 38 +patch_margin_top = 37 +patch_margin_right = 38 +patch_margin_bottom = 39 + +[node name="UpdateLabel" type="Label" parent="VBox/Center/VBoxContainer/DownloadButton"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 14 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +offset_top = -14.5 +offset_bottom = 14.5 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_colors/font_color = Color(0.960784, 0.960784, 0.960784, 1) +theme_override_colors/font_shadow_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("3_h8uk3") +theme_override_font_sizes/font_size = 20 +text = "Update" +horizontal_alignment = 1 +uppercase = true + +[node name="MarginContainer" type="MarginContainer" parent="VBox"] +layout_mode = 2 +theme_override_constants/margin_top = 10 + +[node name="RichTextLabel" type="RichTextLabel" parent="VBox/MarginContainer"] +layout_mode = 2 +theme_override_fonts/normal_font = ExtResource("4_gwh4i") +theme_override_fonts/mono_font = ExtResource("3_h8uk3") +theme_override_font_sizes/normal_font_size = 12 +theme_override_font_sizes/mono_font_size = 12 +bbcode_enabled = true +text = "[center]The updater can be disabled within: +[code]Project Settings / Phantom Camera / Updater / Enable Updater[/code][/center]" +fit_content = true + +[connection signal="pressed" from="VBox/Center2/NotesButton" to="." method="_on_notes_button_pressed"] diff --git a/addons/phantom_camera/panel/updater/update_button.tscn b/addons/phantom_camera/panel/updater/update_button.tscn new file mode 100644 index 0000000..a6efba1 --- /dev/null +++ b/addons/phantom_camera/panel/updater/update_button.tscn @@ -0,0 +1,101 @@ +[gd_scene load_steps=10 format=3 uid="uid://cuqkqsp3ikv5u"] + +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="1_5e5k4"] +[ext_resource type="Script" uid="uid://bwc42i46603qn" path="res://addons/phantom_camera/scripts/panel/updater/update_button.gd" id="1_xtaw5"] +[ext_resource type="Texture2D" uid="uid://d4j4hrb7yusyq" path="res://addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg" id="2_c4d83"] +[ext_resource type="PackedScene" uid="uid://b25fl4usw0nlp" path="res://addons/phantom_camera/panel/updater/download_update_panel.tscn" id="2_vtgcx"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_c7fd1"] +content_margin_left = 10.0 +content_margin_top = 4.0 +content_margin_right = 10.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0980392, 0.415686, 0.341176, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 20 +corner_radius_top_right = 20 +corner_radius_bottom_right = 20 +corner_radius_bottom_left = 20 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_y83dj"] +content_margin_left = 10.0 +content_margin_top = 4.0 +content_margin_right = 10.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.960784, 0.960784, 0.960784, 1) +corner_radius_top_left = 20 +corner_radius_top_right = 20 +corner_radius_bottom_right = 20 +corner_radius_bottom_left = 20 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_slf6e"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_lekqh"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dr4n4"] +content_margin_bottom = 20.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) + +[node name="UpdateButton" type="Button"] +visible = false +offset_left = 1.0 +offset_right = 149.0 +offset_bottom = 28.0 +size_flags_vertical = 3 +theme_override_colors/font_color = Color(0.960784, 0.960784, 0.960784, 1) +theme_override_colors/font_hover_color = Color(0.939288, 0.917743, 0.892615, 1) +theme_override_colors/icon_normal_color = Color(0.960784, 0.960784, 0.960784, 1) +theme_override_fonts/font = ExtResource("1_5e5k4") +theme_override_font_sizes/font_size = 14 +theme_override_styles/normal = SubResource("StyleBoxFlat_c7fd1") +theme_override_styles/hover = SubResource("StyleBoxFlat_y83dj") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_slf6e") +theme_override_styles/focus = SubResource("StyleBoxEmpty_lekqh") +text = "Update available" +icon = ExtResource("2_c4d83") +script = ExtResource("1_xtaw5") + +[node name="HTTPRequest" type="HTTPRequest" parent="."] +unique_name_in_owner = true + +[node name="DownloadDialog" type="AcceptDialog" parent="."] +unique_name_in_owner = true +transparent_bg = true +title = "New Update" +initial_position = 2 +size = Vector2i(450, 480) +transient = false +unresizable = true +borderless = true +keep_title_visible = false +content_scale_mode = 1 +theme_override_constants/buttons_separation = 30 +theme_override_styles/panel = SubResource("StyleBoxFlat_dr4n4") +ok_button_text = "Close" + +[node name="DownloadUpdatePanel" parent="DownloadDialog" instance=ExtResource("2_vtgcx")] +unique_name_in_owner = true +offset_left = 2.0 +offset_top = 2.0 +offset_right = -2.0 +offset_bottom = -80.0 + +[node name="NeedsReloadDialog" type="ConfirmationDialog" parent="."] +unique_name_in_owner = true + +[node name="UpdateFailedDialog" type="AcceptDialog" parent="."] +unique_name_in_owner = true diff --git a/addons/phantom_camera/panel/viewfinder/deadzone_style_box.tres b/addons/phantom_camera/panel/viewfinder/deadzone_style_box.tres new file mode 100644 index 0000000..7353299 --- /dev/null +++ b/addons/phantom_camera/panel/viewfinder/deadzone_style_box.tres @@ -0,0 +1,14 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://dpa7yvxlq043a"] + +[resource] +bg_color = Color(0.227451, 0.72549, 0.603922, 0.2) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_detail = 1 +expand_margin_left = 1.0 +expand_margin_top = 1.0 +expand_margin_right = 1.0 +expand_margin_bottom = 1.0 diff --git a/addons/phantom_camera/panel/viewfinder/host_list/host_list.tscn b/addons/phantom_camera/panel/viewfinder/host_list/host_list.tscn new file mode 100644 index 0000000..332415d --- /dev/null +++ b/addons/phantom_camera/panel/viewfinder/host_list/host_list.tscn @@ -0,0 +1,87 @@ +[gd_scene load_steps=8 format=3 uid="uid://mbjdav5oqves"] + +[ext_resource type="Script" uid="uid://c84cxry3t35ny" path="res://addons/phantom_camera/scripts/panel/viewfinder/host_list.gd" id="1_h6ayt"] +[ext_resource type="Texture2D" uid="uid://5fatldiu7dd5" path="res://addons/phantom_camera/icons/phantom_camera_host.svg" id="1_xlgqb"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_w002y"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kq7gm"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_top = 2 +border_width_right = 2 +border_color = Color(0.960784, 0.960784, 0.960784, 1) +corner_radius_top_right = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ynag5"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.960784, 0.960784, 0.960784, 1) +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +corner_radius_top_right = 6 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q2svd"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_right = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_e0jvt"] +content_margin_left = 0.0 +content_margin_top = 8.0 +content_margin_right = 0.0 +content_margin_bottom = 8.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_top = 2 +border_width_right = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_right = 10 + +[node name="PCamHostList" type="VBoxContainer"] +anchors_preset = 9 +anchor_bottom = 1.0 +size_flags_horizontal = 0 +size_flags_vertical = 0 +theme_override_constants/separation = -2 +alignment = 2 +script = ExtResource("1_h6ayt") + +[node name="HostListButton" type="Button" parent="."] +unique_name_in_owner = true +custom_minimum_size = Vector2(40, 40) +layout_mode = 2 +size_flags_horizontal = 0 +theme_override_colors/icon_hover_color = Color(0.0784314, 0.109804, 0.129412, 1) +theme_override_colors/icon_hover_pressed_color = Color(0.0784314, 0.109804, 0.129412, 1) +theme_override_styles/focus = SubResource("StyleBoxEmpty_w002y") +theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_kq7gm") +theme_override_styles/hover = SubResource("StyleBoxFlat_ynag5") +theme_override_styles/pressed = SubResource("StyleBoxFlat_kq7gm") +theme_override_styles/normal = SubResource("StyleBoxFlat_q2svd") +icon = ExtResource("1_xlgqb") +expand_icon = true + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +theme_override_styles/panel = SubResource("StyleBoxFlat_e0jvt") +horizontal_scroll_mode = 0 + +[node name="HostListContainer" type="VBoxContainer" parent="ScrollContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_constants/separation = 8 diff --git a/addons/phantom_camera/panel/viewfinder/host_list/host_list_item.tscn b/addons/phantom_camera/panel/viewfinder/host_list/host_list_item.tscn new file mode 100644 index 0000000..9ce67e5 --- /dev/null +++ b/addons/phantom_camera/panel/viewfinder/host_list/host_list_item.tscn @@ -0,0 +1,68 @@ +[gd_scene load_steps=10 format=3 uid="uid://btn6jgv0vix7"] + +[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="1_anjxo"] +[ext_resource type="Theme" uid="uid://bhppejri5dbsf" path="res://addons/phantom_camera/themes/theme.tres" id="1_wql5t"] +[ext_resource type="Texture2D" uid="uid://rghrkoqrm2ig" path="res://addons/phantom_camera/icons/viewfinder/Select.svg" id="2_71b6g"] +[ext_resource type="ButtonGroup" uid="uid://dfu0b8jbtyr1n" path="res://addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres" id="3_06a0y"] +[ext_resource type="Script" uid="uid://bv24ubx8mutw7" path="res://addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd" id="3_a5o8b"] +[ext_resource type="Texture2D" uid="uid://cjlv0bg7byjx0" path="res://addons/phantom_camera/icons/warning.svg" id="3_qgpy7"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_0rxfi"] +content_margin_right = 6.0 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_llqnh"] + +[sub_resource type="Theme" id="Theme_7h15c"] +Button/colors/icon_hover_color = Color(0.960784, 0.960784, 0.960784, 1) +Button/colors/icon_hover_pressed_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/colors/icon_normal_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/colors/icon_pressed_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/constants/icon_max_width = 20 +Button/styles/focus = SubResource("StyleBoxEmpty_llqnh") + +[node name="HostListItem" type="PanelContainer"] +offset_right = 229.0 +offset_bottom = 34.0 +theme_override_styles/panel = SubResource("StyleBoxEmpty_0rxfi") +script = ExtResource("3_a5o8b") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +theme_override_constants/separation = 2 + +[node name="SelectPCamHost" type="Button" parent="HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 4 +tooltip_text = "Select the Phantom Camera Host node from the scene hierarchy" +focus_mode = 0 +theme = SubResource("Theme_7h15c") +icon = ExtResource("2_71b6g") +flat = true + +[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 8 + +[node name="ErrorPCamHost" type="TextureRect" parent="HBoxContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(18, 18) +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 4 +tooltip_text = "This Phantom Camera Host node will not affect a Camera node. +See the warning in the Scene Tree for more information." +texture = ExtResource("3_qgpy7") +expand_mode = 1 + +[node name="SwitchPCamHost" type="Button" parent="HBoxContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(40, 0) +layout_mode = 2 +tooltip_text = "Change the viewfinder's camera to the camera of this Phantom Camera Host" +theme = ExtResource("1_wql5t") +theme_override_fonts/font = ExtResource("1_anjxo") +theme_override_font_sizes/font_size = 18 +toggle_mode = true +button_group = ExtResource("3_06a0y") +text = "{ PCamHostName }" diff --git a/addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres b/addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres new file mode 100644 index 0000000..c6439b5 --- /dev/null +++ b/addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres @@ -0,0 +1,3 @@ +[gd_resource type="ButtonGroup" load_steps=0 format=3 uid="uid://dfu0b8jbtyr1n"] + +[resource] diff --git a/addons/phantom_camera/panel/viewfinder/viewfinder_panel.tscn b/addons/phantom_camera/panel/viewfinder/viewfinder_panel.tscn new file mode 100644 index 0000000..b6caa0d --- /dev/null +++ b/addons/phantom_camera/panel/viewfinder/viewfinder_panel.tscn @@ -0,0 +1,563 @@ +[gd_scene load_steps=28 format=3 uid="uid://dbkr3d716wtx0"] + +[ext_resource type="Script" uid="uid://drmv3363t8amc" path="res://addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd" id="1_utvi8"] +[ext_resource type="StyleBox" uid="uid://dpa7yvxlq043a" path="res://addons/phantom_camera/panel/viewfinder/deadzone_style_box.tres" id="2_uabt4"] +[ext_resource type="FontFile" uid="uid://c4mm3of2mc8o5" path="res://addons/phantom_camera/fonts/Nunito-Black.ttf" id="3_li3i3"] +[ext_resource type="Texture2D" uid="uid://5fatldiu7dd5" path="res://addons/phantom_camera/icons/phantom_camera_host.svg" id="4_lcg1p"] +[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="5_4jhax"] +[ext_resource type="Texture2D" uid="uid://dy8eifa6aw2en" path="res://addons/phantom_camera/icons/misc/PriorityOverride.svg" id="6_ptuth"] +[ext_resource type="Script" uid="uid://c84cxry3t35ny" path="res://addons/phantom_camera/scripts/panel/viewfinder/host_list.gd" id="7_kpij0"] +[ext_resource type="Theme" uid="uid://bhppejri5dbsf" path="res://addons/phantom_camera/themes/theme.tres" id="8_b4akn"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fle8t"] +bg_color = Color(0.227451, 0.72549, 0.603922, 0.2) +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_detail = 1 +expand_margin_left = 1.0 +expand_margin_top = 1.0 +expand_margin_right = 1.0 +expand_margin_bottom = 1.0 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xmo1t"] +draw_center = false +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.745098, 0.858824, 0.380392, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q7vs4"] +bg_color = Color(0.929412, 0.87451, 0.619608, 1) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0, 0, 0, 1) +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_iho1a"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_obaj6"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_4b76l"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_yh38y"] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(0.129412, 0.407843, 0.337255, 1) +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(0.988235, 0.498039, 0.498039, 1) +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_gci88"] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(0.180392, 0.576471, 0.482353, 1) +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fsxik"] +content_margin_left = 10.0 +content_margin_top = 10.0 +content_margin_right = 10.0 +content_margin_bottom = 10.0 +bg_color = Color(0.129412, 0.407843, 0.337255, 1) +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_g5wua"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_x4bx8"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_840sd"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ja3vm"] +bg_color = Color(0.53, 0.1643, 0.255725, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_blend = true +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_mk273"] +bg_color = Color(0.43, 0.1333, 0.207475, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_blend = true +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_agqdu"] +bg_color = Color(0.72549, 0.227451, 0.34902, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_blend = true +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_w002y"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kq7gm"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_top = 2 +border_width_right = 2 +border_color = Color(0.960784, 0.960784, 0.960784, 1) +corner_radius_top_right = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ynag5"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.960784, 0.960784, 0.960784, 1) +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +corner_radius_top_right = 6 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q2svd"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_right = 8 + +[node name="ViewfinderPanel" type="Control"] +clip_contents = true +custom_minimum_size = Vector2(0, 300) +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +mouse_filter = 2 +script = ExtResource("1_utvi8") + +[node name="Viewfinder" type="Control" parent="."] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +metadata/_edit_lock_ = true + +[node name="SubViewportContainer" type="SubViewportContainer" parent="Viewfinder"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +stretch = true + +[node name="SubViewport" type="SubViewport" parent="Viewfinder/SubViewportContainer"] +unique_name_in_owner = true +handle_input_locally = false +canvas_item_default_texture_filter = 0 +gui_disable_input = true +size = Vector2i(1152, 648) +size_2d_override_stretch = true +render_target_update_mode = 4 + +[node name="Camera2D" type="Camera2D" parent="Viewfinder/SubViewportContainer/SubViewport"] +unique_name_in_owner = true +editor_draw_screen = false + +[node name="DeadZoneHBoxContainer" type="HBoxContainer" parent="Viewfinder"] +unique_name_in_owner = true +clip_contents = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_constants/separation = 0 + +[node name="DeadZoneLeftHBoxContainer" type="VBoxContainer" parent="Viewfinder/DeadZoneHBoxContainer"] +clip_contents = true +layout_mode = 2 +size_flags_horizontal = 3 +mouse_filter = 2 +theme_override_constants/separation = 0 + +[node name="DeadZoneLeftTopPanel" type="Panel" parent="Viewfinder/DeadZoneHBoxContainer/DeadZoneLeftHBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 +theme_override_styles/panel = ExtResource("2_uabt4") + +[node name="DeadZoneLeftCenterPanel" type="Panel" parent="Viewfinder/DeadZoneHBoxContainer/DeadZoneLeftHBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +mouse_filter = 2 +theme_override_styles/panel = ExtResource("2_uabt4") + +[node name="DeadZoneLeftBottomPanel" type="Panel" parent="Viewfinder/DeadZoneHBoxContainer/DeadZoneLeftHBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 +theme_override_styles/panel = ExtResource("2_uabt4") + +[node name="DeadZoneCenterHBoxContainer" type="VBoxContainer" parent="Viewfinder/DeadZoneHBoxContainer"] +unique_name_in_owner = true +clip_contents = true +layout_mode = 2 +size_flags_horizontal = 4 +mouse_filter = 2 +theme_override_constants/separation = 0 + +[node name="DeadZoneCenterTopPanel" type="Panel" parent="Viewfinder/DeadZoneHBoxContainer/DeadZoneCenterHBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 +theme_override_styles/panel = ExtResource("2_uabt4") + +[node name="DeadZoneCenterCenterPanel" type="Panel" parent="Viewfinder/DeadZoneHBoxContainer/DeadZoneCenterHBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 4 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_fle8t") + +[node name="DeadZoneCenterBottomPanel" type="Panel" parent="Viewfinder/DeadZoneHBoxContainer/DeadZoneCenterHBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 +theme_override_styles/panel = ExtResource("2_uabt4") + +[node name="DeadZoneRightHBoxContainer" type="VBoxContainer" parent="Viewfinder/DeadZoneHBoxContainer"] +clip_contents = true +layout_mode = 2 +size_flags_horizontal = 3 +mouse_filter = 2 +theme_override_constants/separation = 0 + +[node name="DeadZoneRightTopPanel" type="Panel" parent="Viewfinder/DeadZoneHBoxContainer/DeadZoneRightHBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 +theme_override_styles/panel = ExtResource("2_uabt4") + +[node name="DeadZoneRightCenterPanel" type="Panel" parent="Viewfinder/DeadZoneHBoxContainer/DeadZoneRightHBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +mouse_filter = 2 +theme_override_styles/panel = ExtResource("2_uabt4") + +[node name="DeadZoneRightBottomPanel" type="Panel" parent="Viewfinder/DeadZoneHBoxContainer/DeadZoneRightHBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +mouse_filter = 2 +theme_override_styles/panel = ExtResource("2_uabt4") + +[node name="AspectRatioContainer" type="AspectRatioContainer" parent="Viewfinder"] +unique_name_in_owner = true +clip_contents = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +ratio = 1.77778 + +[node name="CameraViewportPanel" type="Panel" parent="Viewfinder/AspectRatioContainer"] +layout_mode = 2 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_xmo1t") + +[node name="TargetPoint" type="Panel" parent="Viewfinder/AspectRatioContainer/CameraViewportPanel"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -3.0 +offset_top = -3.0 +offset_right = 3.0 +offset_bottom = 3.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_q7vs4") + +[node name="NoSupportMsg" type="Label" parent="."] +unique_name_in_owner = true +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -8.0 +offset_bottom = -8.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("3_li3i3") +theme_override_font_sizes/font_size = 24 +theme_override_styles/normal = SubResource("StyleBoxEmpty_iho1a") +text = "Control scenes are not supported" +horizontal_alignment = 1 +vertical_alignment = 1 +metadata/_edit_lock_ = true + +[node name="EmptyStateControl" type="Control" parent="."] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +metadata/_edit_use_anchors_ = true +metadata/_edit_lock_ = true + +[node name="BGColorRect" type="ColorRect" parent="EmptyStateControl"] +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0, 0, 0, 1) +metadata/_edit_lock_ = true + +[node name="VBoxContainer" type="VBoxContainer" parent="EmptyStateControl"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -200.0 +offset_top = -112.0 +offset_right = 200.0 +offset_bottom = 112.0 +grow_horizontal = 2 +grow_vertical = 2 +alignment = 1 + +[node name="EmptyStateIcon" type="TextureRect" parent="EmptyStateControl/VBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(0, 64) +layout_mode = 2 +texture = ExtResource("4_lcg1p") +expand_mode = 1 +stretch_mode = 5 + +[node name="EmptyStateText" type="RichTextLabel" parent="EmptyStateControl/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_colors/default_color = Color(1, 1, 1, 1) +theme_override_fonts/normal_font = ExtResource("5_4jhax") +theme_override_fonts/bold_font = ExtResource("3_li3i3") +theme_override_font_sizes/normal_font_size = 24 +theme_override_font_sizes/bold_font_size = 24 +theme_override_styles/focus = SubResource("StyleBoxEmpty_obaj6") +theme_override_styles/normal = SubResource("StyleBoxEmpty_iho1a") +bbcode_enabled = true +text = "[center][b]NodeType[/b] Description [/center]" +fit_content = true + +[node name="AddNodeButton" type="Button" parent="EmptyStateControl/VBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(400, 54) +layout_mode = 2 +size_flags_horizontal = 4 +focus_mode = 0 +theme_override_colors/font_color = Color(1, 1, 1, 1) +theme_override_fonts/font = ExtResource("3_li3i3") +theme_override_font_sizes/font_size = 24 +theme_override_styles/focus = SubResource("StyleBoxEmpty_4b76l") +theme_override_styles/hover = SubResource("StyleBoxFlat_yh38y") +theme_override_styles/pressed = SubResource("StyleBoxFlat_gci88") +theme_override_styles/normal = SubResource("StyleBoxFlat_fsxik") + +[node name="AddNodeTypeText" type="RichTextLabel" parent="EmptyStateControl/VBoxContainer/AddNodeButton"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = 9.0 +offset_bottom = -11.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_colors/default_color = Color(1, 1, 1, 1) +theme_override_fonts/normal_font = ExtResource("5_4jhax") +theme_override_fonts/bold_font = ExtResource("3_li3i3") +theme_override_font_sizes/normal_font_size = 24 +theme_override_font_sizes/bold_font_size = 24 +theme_override_styles/focus = SubResource("StyleBoxEmpty_g5wua") +theme_override_styles/normal = SubResource("StyleBoxEmpty_x4bx8") +bbcode_enabled = true +text = "[center]Add [img=32]res://addons/phantom_camera/icons/viewfinder/Camera3DIcon.svg[/img] [b]{NodeType}[/b][/center]" +scroll_active = false + +[node name="PriorityOverrideButton" type="Button" parent="."] +unique_name_in_owner = true +visible = false +layout_mode = 1 +offset_left = 5.0 +offset_top = 5.0 +offset_right = 165.0 +offset_bottom = 57.0 +mouse_default_cursor_shape = 2 +theme_override_styles/focus = SubResource("StyleBoxEmpty_840sd") +theme_override_styles/hover = SubResource("StyleBoxFlat_ja3vm") +theme_override_styles/pressed = SubResource("StyleBoxFlat_mk273") +theme_override_styles/normal = SubResource("StyleBoxFlat_agqdu") +metadata/_edit_lock_ = true + +[node name="PriorityOverrideIcon" type="TextureRect" parent="PriorityOverrideButton"] +layout_mode = 1 +offset_left = 8.0 +offset_top = 4.0 +offset_right = 32.0 +offset_bottom = 28.0 +texture = ExtResource("6_ptuth") +expand_mode = 1 + +[node name="PriorityOverrideByLabel" type="Label" parent="PriorityOverrideButton"] +layout_mode = 0 +offset_left = 30.0 +offset_top = 1.0 +offset_right = 140.0 +offset_bottom = 24.0 +theme_override_fonts/font = ExtResource("3_li3i3") +theme_override_font_sizes/font_size = 14 +text = "OVERRIDDEN BY" +vertical_alignment = 1 + +[node name="PriorityOverrideNameLabel" type="Label" parent="PriorityOverrideButton"] +unique_name_in_owner = true +layout_mode = 0 +offset_left = 6.0 +offset_top = 21.0 +offset_right = 153.0 +offset_bottom = 44.0 +theme_override_fonts/font = ExtResource("5_4jhax") +theme_override_font_sizes/font_size = 14 +text = "PCam_Name +" +vertical_alignment = 1 +text_overrun_behavior = 3 + +[node name="SizeLabel" type="Label" parent="."] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 4 +anchor_top = 0.5 +anchor_bottom = 0.5 +offset_top = -11.5 +offset_right = 40.0 +offset_bottom = 11.5 +grow_vertical = 2 + +[node name="PCamHostList" type="VBoxContainer" parent="."] +unique_name_in_owner = true +visible = false +layout_mode = 1 +anchors_preset = -1 +anchor_bottom = 1.0 +offset_top = 588.0 +grow_vertical = 2 +size_flags_horizontal = 0 +size_flags_vertical = 0 +theme_override_constants/separation = -2 +alignment = 2 +script = ExtResource("7_kpij0") + +[node name="HostListButton" type="Button" parent="PCamHostList"] +unique_name_in_owner = true +custom_minimum_size = Vector2(40, 40) +layout_mode = 2 +size_flags_horizontal = 0 +theme_override_colors/icon_hover_pressed_color = Color(0.0784314, 0.109804, 0.129412, 1) +theme_override_colors/icon_hover_color = Color(0.0784314, 0.109804, 0.129412, 1) +theme_override_styles/focus = SubResource("StyleBoxEmpty_w002y") +theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_kq7gm") +theme_override_styles/hover = SubResource("StyleBoxFlat_ynag5") +theme_override_styles/pressed = SubResource("StyleBoxFlat_kq7gm") +theme_override_styles/normal = SubResource("StyleBoxFlat_q2svd") +icon = ExtResource("4_lcg1p") +expand_icon = true + +[node name="PanelContainer" type="PanelContainer" parent="PCamHostList"] +layout_mode = 2 +size_flags_vertical = 3 +theme = ExtResource("8_b4akn") + +[node name="ScrollContainer" type="ScrollContainer" parent="PCamHostList/PanelContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +theme = ExtResource("8_b4akn") +horizontal_scroll_mode = 0 + +[node name="HostListContainer" type="VBoxContainer" parent="PCamHostList/PanelContainer/ScrollContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme = ExtResource("8_b4akn") diff --git a/addons/phantom_camera/plugin.cfg b/addons/phantom_camera/plugin.cfg new file mode 100644 index 0000000..6325827 --- /dev/null +++ b/addons/phantom_camera/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Phantom Camera" +description="Control the movement and dynamically tween 2D & 3D cameras positions. Built for Godot 4. Inspired by Cinemachine." +author="Marcus Skov" +version="0.9.3.1" +script="plugin.gd" diff --git a/addons/phantom_camera/plugin.gd b/addons/phantom_camera/plugin.gd new file mode 100644 index 0000000..0421330 --- /dev/null +++ b/addons/phantom_camera/plugin.gd @@ -0,0 +1,181 @@ +@tool +extends EditorPlugin + +#region Constants + +const PCAM_HOST: String = "PhantomCameraHost" +const PCAM_2D: String = "PhantomCamera2D" +const PCAM_3D: String = "PhantomCamera3D" +const PCAM_NOISE_EMITTER_2D: String = "PhantomCameraNoiseEmitter2D" +const PCAM_NOISE_EMITTER_3D: String = "PhantomCameraNoiseEmitter3D" + +const PCam3DPlugin: Script = preload("res://addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd") +const PCam3DNoiseEmitterPlugin: Script = preload("res://addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd") +const EditorPanel: PackedScene = preload("res://addons/phantom_camera/panel/editor.tscn") +const updater_constants: Script = preload("res://addons/phantom_camera/scripts/panel/updater/updater_constants.gd") +const PHANTOM_CAMERA_MANAGER: StringName = "PhantomCameraManager" + +#endregion + +#region Private Variables + +var _settings_show_jitter_tips: String = "phantom_camera/tips/show_jitter_tips" +var _settings_enable_editor_shortcut: String = "phantom_camera/general/enable_editor_shortcut" +var _settings_editor_shortcut: String = "phantom_camera/general/editor_shortcut" + +# TODO - Pending merge of https://github.com/godotengine/godot/pull/102889 - Should only support Godot version after the release that is featured in +#var _editor_shortcut: Shortcut = Shortcut.new() +#var _editor_shortcut_input: InputEventKey +#endregion + +#region Public Variables + +var pcam_3d_gizmo_plugin = PCam3DPlugin.new() +var pcam_3d_noise_emitter_gizmo_plugin = PCam3DNoiseEmitterPlugin.new() + +var editor_panel_instance: Control +var panel_button: Button +#var viewfinder_panel_instance + + +#endregion + +#region Private Functions + +func _enable_plugin() -> void: + print_rich("Phantom Camera documentation can be found at: [url=https://phantom-camera.dev]https://phantom-camera.dev[/url]") + if not Engine.has_singleton(PHANTOM_CAMERA_MANAGER): + add_autoload_singleton(PHANTOM_CAMERA_MANAGER, "res://addons/phantom_camera/scripts/managers/phantom_camera_manager.gd") + + +func _disable_plugin() -> void: + remove_autoload_singleton(PHANTOM_CAMERA_MANAGER) + + +func _enter_tree() -> void: + add_autoload_singleton(PHANTOM_CAMERA_MANAGER, "res://addons/phantom_camera/scripts/managers/phantom_camera_manager.gd") + + # Phantom Camera Nodes + add_custom_type(PCAM_2D, "Node2D", preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd"), preload("res://addons/phantom_camera/icons/phantom_camera_2d.svg")) + add_custom_type(PCAM_3D, "Node3D", preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd"), preload("res://addons/phantom_camera/icons/phantom_camera_2d.svg")) + add_custom_type(PCAM_HOST, "Node", preload("res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd"), preload("res://addons/phantom_camera/icons/phantom_camera_2d.svg")) + add_custom_type(PCAM_NOISE_EMITTER_2D, "Node2D", preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd"), preload("res://addons/phantom_camera/icons/phantom_camera_noise_emitter_2d.svg")) + add_custom_type(PCAM_NOISE_EMITTER_3D, "Node3D", preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd"), preload("res://addons/phantom_camera/icons/phantom_camera_noise_emitter_3d.svg")) + + # Phantom Camera 3D Gizmo + add_node_3d_gizmo_plugin(pcam_3d_gizmo_plugin) + add_node_3d_gizmo_plugin(pcam_3d_noise_emitter_gizmo_plugin) + + var setting_updater_mode: String + var setting_updater_mode_default: int + if FileAccess.file_exists("res://dev_scenes/3d/dev_scene_3d.tscn"): # For forks + setting_updater_mode = "Off, Console Output" + setting_updater_mode_default = 1 + else: # For end-users + setting_updater_mode = "Off, Console Output, Updater Window" + setting_updater_mode_default = 2 + + if not ProjectSettings.has_setting(updater_constants.setting_updater_mode): + ProjectSettings.set_setting(updater_constants.setting_updater_mode, setting_updater_mode_default) + ProjectSettings.add_property_info({ + "name": updater_constants.setting_updater_mode, + "type": TYPE_INT, + "hint": PROPERTY_HINT_ENUM, + "hint_string": setting_updater_mode, + }) + ProjectSettings.set_initial_value(updater_constants.setting_updater_mode, setting_updater_mode_default) + ProjectSettings.set_as_basic(updater_constants.setting_updater_mode, true) + + + ## Setting for enabling / disabling Jitter tips in the Output + if not ProjectSettings.has_setting(_settings_show_jitter_tips): + ProjectSettings.set_setting(_settings_show_jitter_tips, true) + ProjectSettings.add_property_info({ + "name": _settings_show_jitter_tips, + "type": TYPE_BOOL, + }) + ProjectSettings.set_initial_value(_settings_show_jitter_tips, true) + ProjectSettings.set_as_basic(_settings_show_jitter_tips, true) + + +# TODO - Pending merge of https://github.com/godotengine/godot/pull/102889 - Should only support Godot version after this release +# if not ProjectSettings.has_setting(_settings_enable_editor_shortcut): +# ProjectSettings.set_setting(_settings_enable_editor_shortcut, false) +# ProjectSettings.set_initial_value(_settings_enable_editor_shortcut, false) + +# TODO - Pending merge of https://github.com/godotengine/godot/pull/102889 - Should only support Godot version after this release +# _viewfinder_shortcut_default.events = [editor_shortcut] +# if ProjectSettings.get_setting(_settings_enable_editor_shortcut): +# if not ProjectSettings.has_setting(_settings_editor_shortcut): +# ProjectSettings.set_setting(_settings_editor_shortcut, _editor_shortcut) +# ProjectSettings.set_initial_value(_settings_editor_shortcut, _editor_shortcut) + + + # TODO - Should be disabled unless in editor + # Viewfinder + editor_panel_instance = EditorPanel.instantiate() + editor_panel_instance.editor_plugin = self + panel_button = add_control_to_bottom_panel(editor_panel_instance, "Phantom Camera") + panel_button.toggled.connect(_btn_toggled) + if panel_button.toggle_mode: _btn_toggled(true) + + scene_changed.connect(editor_panel_instance.viewfinder.scene_changed) + scene_changed.connect(_scene_changed) + + +func _exit_tree() -> void: + panel_button.toggled.disconnect(_btn_toggled) + scene_changed.disconnect(editor_panel_instance.viewfinder.scene_changed) + scene_changed.disconnect(_scene_changed) + + remove_control_from_bottom_panel(editor_panel_instance) + editor_panel_instance.queue_free() + + remove_node_3d_gizmo_plugin(pcam_3d_gizmo_plugin) + remove_node_3d_gizmo_plugin(pcam_3d_noise_emitter_gizmo_plugin) + + remove_custom_type(PCAM_2D) + remove_custom_type(PCAM_3D) + remove_custom_type(PCAM_HOST) + remove_custom_type(PCAM_NOISE_EMITTER_2D) + remove_custom_type(PCAM_NOISE_EMITTER_3D) + + remove_autoload_singleton(PHANTOM_CAMERA_MANAGER) +# if get_tree().root.get_node_or_null(String(PHANTOM_CAMERA_MANAGER)): +# remove_autoload_singleton(PHANTOM_CAMERA_MANAGER) + + +func _btn_toggled(toggled_on: bool): + editor_panel_instance.viewfinder.set_visibility(toggled_on) +# if toggled_on: +# editor_panel_instance.viewfinder.viewfinder_visible = true +# editor_panel_instance.viewfinder.visibility_check() +# else: +# editor_panel_instance.viewfinder.viewfinder_visible = false + +func _make_visible(visible): + if editor_panel_instance: + editor_panel_instance.set_visible(visible) + +## TODO - Signal can be added directly to the editor_panel with the changes in Godot 4.5 (https://github.com/godotengine/godot/pull/102986) +func _scene_changed(scene_root: Node) -> void: + editor_panel_instance.viewfinder.scene_changed(scene_root) + +# TODO - Pending merge of https://github.com/godotengine/godot/pull/102889 - Should only support Godot version after this release +#func _set_editor_shortcut() -> InputEventKey: +# var shortcut: InputEventKey = InputEventKey.new() +# shortcut.keycode = 67 # Key = C +# shortcut.alt_pressed = true +# return shortcut + +#endregion + + +#region Public Functions + +func get_version() -> String: + var config: ConfigFile = ConfigFile.new() + config.load(get_script().resource_path.get_base_dir() + "/plugin.cfg") + return config.get_value("plugin", "version") + +#endregion diff --git a/addons/phantom_camera/plugin.gd.uid b/addons/phantom_camera/plugin.gd.uid new file mode 100644 index 0000000..1c23477 --- /dev/null +++ b/addons/phantom_camera/plugin.gd.uid @@ -0,0 +1 @@ +uid://c7g41in1osxi6 diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd new file mode 100644 index 0000000..27e7eed --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd @@ -0,0 +1,84 @@ +@tool +extends EditorNode3DGizmo + +#var pcam_3d: PhantomCamera3D + +func _redraw() -> void: + clear() + + var icon: Material = get_plugin().get_material(get_plugin().get_name(), self) + add_unscaled_billboard(icon, 0.035) + + var pcam_3d: PhantomCamera3D = get_node_3d() + +# if pcam_3d.is_following(): +# _draw_target(pcam_3d, pcam_3d.get_follow_target_position(), "follow_target") +# if pcam_3d.is_looking_at(): +# _draw_target(pcam_3d, pcam_3d.get_look_at_target_position(), "look_at_target") + + if pcam_3d.is_active(): return + + var frustum_lines: PackedVector3Array = PackedVector3Array() + var height: float = 0.25 + var width: float = height * 1.25 + var forward: float = height * -1.5 + + # Trapezoid + frustum_lines.push_back(Vector3.ZERO) + frustum_lines.push_back(Vector3(-width, height, forward)) + + frustum_lines.push_back(Vector3.ZERO) + frustum_lines.push_back(Vector3(width, height, forward)) + + frustum_lines.push_back(Vector3.ZERO) + frustum_lines.push_back(Vector3(-width, -height, forward)) + + frustum_lines.push_back(Vector3.ZERO) + frustum_lines.push_back(Vector3(width, -height, forward)) + + ####### + # Frame + ####### + ## Left + frustum_lines.push_back(Vector3(-width, height, forward)) + frustum_lines.push_back(Vector3(-width, -height, forward)) + + ## Bottom + frustum_lines.push_back(Vector3(-width, -height, forward)) + frustum_lines.push_back(Vector3(width, -height, forward)) + + ## Right + frustum_lines.push_back(Vector3(width, -height, forward)) + frustum_lines.push_back(Vector3(width, height, forward)) + + ## Top + frustum_lines.push_back(Vector3(width, height, forward)) + frustum_lines.push_back(Vector3(-width, height, forward)) + + ############## + # Up Direction + ############## + var up_height: float = height + 0.15 + var up_width: float = width / 3 + + ## Left + frustum_lines.push_back(Vector3(0, up_height, forward)) + frustum_lines.push_back(Vector3(-up_width, height, forward)) + + ## Right + frustum_lines.push_back(Vector3(0, up_height, forward)) + frustum_lines.push_back(Vector3(up_width, height, forward)) + + var frustum_material: StandardMaterial3D = get_plugin().get_material("frustum", self) + add_lines(frustum_lines, frustum_material, false) + + +func _draw_target(pcam_3d: Node3D, target_position: Vector3, type: String) -> void: + var target_lines: PackedVector3Array = PackedVector3Array() + var direction: Vector3 = target_position - pcam_3d.global_position + var end_position: Vector3 = pcam_3d.global_basis.z * direction + + target_lines.push_back(Vector3.ZERO) + target_lines.push_back(end_position) + var target_material: StandardMaterial3D = get_plugin().get_material(type, self) + add_lines(target_lines, target_material, false) diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd.uid b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd.uid new file mode 100644 index 0000000..564e0cf --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd.uid @@ -0,0 +1 @@ +uid://cyr6fgximfw6q diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd new file mode 100644 index 0000000..2caf713 --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd @@ -0,0 +1,37 @@ +@tool +extends EditorNode3DGizmoPlugin + +const PhantomCamera3DNode: Script = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd") +const PhantomCamera3DGizmo: Script = preload("res://addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo.gd") +const _icon_texture: Texture2D = preload("res://addons/phantom_camera/icons/phantom_camera_gizmo.svg") +var _gizmo_name: String = "PhantomCamera3D" + +var gizmo_name: String: set = set_gizmo_name +var _gizmo_icon: Texture2D +var _gizmo_spatial_script: Script = PhantomCamera3DNode + + +func set_gizmo_name(name: String) -> void: + _gizmo_name = name + + +func _get_gizmo_name() -> String: + return _gizmo_name + + +func _has_gizmo(spatial: Node3D) -> bool: + return spatial is PhantomCamera3D + + +func _init() -> void: + create_icon_material(gizmo_name, _icon_texture, false, Color.WHITE) + create_material("frustum", Color8(252, 127, 127, 255)) + create_material("follow_target", Color8(185, 58, 89)) + create_material("look_at_target", Color8(61, 207, 225)) + + +func _create_gizmo(for_node_3d: Node3D) -> EditorNode3DGizmo: + if for_node_3d is PhantomCamera3DNode: + return PhantomCamera3DGizmo.new() + else: + return null diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd.uid b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd.uid new file mode 100644 index 0000000..ce528d7 --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_3d_gizmo_plugin.gd.uid @@ -0,0 +1 @@ +uid://bkevga3bx4rfj diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd b/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd new file mode 100644 index 0000000..3dd4d3e --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd @@ -0,0 +1,29 @@ +extends EditorNode3DGizmoPlugin + +var _spatial_script: Script = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd") +var _gizmo_icon: Texture2D = preload("res://addons/phantom_camera/icons/phantom_camera_noise_emitter_gizmo.svg") + +var _gizmo_name: StringName = "PhantomCameraNoiseEmitter" + +func _init() -> void: + create_material("main", Color8(252, 127, 127, 255)) + create_handle_material("handles") + create_icon_material(_gizmo_name, _gizmo_icon, false, Color.WHITE) + + +func _has_gizmo(node: Node3D): + return node.get_script() == _spatial_script + + +func _get_gizmo_name() -> String: + return _gizmo_name + + +func _redraw(gizmo: EditorNode3DGizmo): + gizmo.clear() + + var icon: Material = get_material(_gizmo_name, gizmo) + gizmo.add_unscaled_billboard(icon, 0.035) + + #var material = get_material("main", gizmo) + #gizmo.add_lines(_draw_frustum(), material) diff --git a/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd.uid b/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd.uid new file mode 100644 index 0000000..2b93b6c --- /dev/null +++ b/addons/phantom_camera/scripts/gizmos/phantom_camera_noise_emitter_gizmo_plugin_3d.gd.uid @@ -0,0 +1 @@ +uid://dddokcd2ug05i diff --git a/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs b/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs new file mode 100644 index 0000000..5005230 --- /dev/null +++ b/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs @@ -0,0 +1,36 @@ +using System.Linq; +using Godot; + +#nullable enable + +namespace PhantomCamera.Manager; + +public static class PhantomCameraManager +{ + private static GodotObject? _instance; + + public static GodotObject Instance => _instance ??= Engine.GetSingleton("PhantomCameraManager"); + + public static PhantomCamera2D[] PhantomCamera2Ds => + Instance.Call(MethodName.GetPhantomCamera2Ds).AsGodotArray() + .Select(node => new PhantomCamera2D(node)).ToArray(); + + public static PhantomCamera3D[] PhantomCamera3Ds => + Instance.Call(MethodName.GetPhantomCamera3Ds).AsGodotArray() + .Select(node => new PhantomCamera3D(node)).ToArray(); + + public static PhantomCameraHost[] PhantomCameraHosts => + Instance.Call(MethodName.GetPhantomCameraHosts).AsGodotArray() + .Select(node => new PhantomCameraHost(node)).ToArray(); + + public static PhantomCamera2D[] GetPhantomCamera2Ds() => PhantomCamera2Ds; + public static PhantomCamera3D[] GetPhantomCamera3Ds() => PhantomCamera3Ds; + public static PhantomCameraHost[] GetPhantomCameraHosts() => PhantomCameraHosts; + + public static class MethodName + { + public const string GetPhantomCamera2Ds = "get_phantom_camera_2ds"; + public const string GetPhantomCamera3Ds = "get_phantom_camera_3ds"; + public const string GetPhantomCameraHosts = "get_phantom_camera_hosts"; + } +} diff --git a/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs.uid b/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs.uid new file mode 100644 index 0000000..cdf7f4e --- /dev/null +++ b/addons/phantom_camera/scripts/managers/PhantomCameraManager.cs.uid @@ -0,0 +1 @@ +uid://vtj8iqx4bp43 diff --git a/addons/phantom_camera/scripts/managers/phantom_camera_manager.gd b/addons/phantom_camera/scripts/managers/phantom_camera_manager.gd new file mode 100644 index 0000000..6e13d9a --- /dev/null +++ b/addons/phantom_camera/scripts/managers/phantom_camera_manager.gd @@ -0,0 +1,149 @@ +@tool +extends Node + +const _CONSTANTS = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") + +#region Signals + +# Noise +signal noise_2d_emitted(noise_output: Transform2D, emitter_layer: int) +signal noise_3d_emitted(noise_output: Transform3D, emitter_layer: int) + +# PCam Host +signal pcam_host_added_to_scene(pcam_host: PhantomCameraHost) +signal pcam_host_removed_from_scene(pcam_host: PhantomCameraHost) + +# PCam +signal pcam_added_to_scene(pcam: Node) +signal pcam_removed_from_scene(pcam: Node) + +# Priority +signal pcam_priority_changed(pcam: Node) +signal pcam_visibility_changed(pcam: Node) + +signal pcam_teleport(pcam: Node) + +# Limit (2D) +signal limit_2d_changed(side: int, limit: int) +signal draw_limit_2d(enabled: bool) + +# Camera3DResource (3D) +signal camera_3d_resource_changed(property: String, value: Variant) + +# Viewfinder Signals +signal viewfinder_pcam_host_switch(pcam_host: PhantomCameraHost) +signal pcam_priority_override(pcam: Node, shouldOverride: bool) +signal pcam_dead_zone_changed(pcam: Node) +signal pcam_host_layer_changed(pcam: Node) + +#endregion + +#region Private Variables + +var _phantom_camera_host_list: Array[PhantomCameraHost] +var _phantom_camera_2d_list: Array[PhantomCamera2D] +var _phantom_camera_3d_list: Array[Node] ## Note: To support disable_3d export templates for 2D projects, this is purposely not strongly typed. + +#endregion + +#region Public Variables + +var phantom_camera_hosts: Array[PhantomCameraHost]: + get: + return _phantom_camera_host_list + +var phantom_camera_2ds: Array[PhantomCamera2D]: + get: + return _phantom_camera_2d_list + +var phantom_camera_3ds: Array[Node]: ## Note: To support disable_3d export templates for 2D projects, this is purposely not strongly typed. + get: + return _phantom_camera_3d_list + +var screen_size: Vector2i + +#endregion + +#region Private Functions + +func _enter_tree() -> void: + if not Engine.has_singleton(_CONSTANTS.PCAM_MANAGER_NODE_NAME): + Engine.register_singleton(_CONSTANTS.PCAM_MANAGER_NODE_NAME, self) + Engine.physics_jitter_fix = 0 + + +func _ready() -> void: + # Setting default screensize + screen_size = Vector2i( + ProjectSettings.get_setting("display/window/size/viewport_width"), + ProjectSettings.get_setting("display/window/size/viewport_height") + ) + + # For editor + if Engine.is_editor_hint(): + ProjectSettings.settings_changed.connect(func(): + screen_size = Vector2i( + ProjectSettings.get_setting("display/window/size/viewport_width"), + ProjectSettings.get_setting("display/window/size/viewport_height") + ) + ) + # For runtime + else: + get_tree().get_root().size_changed.connect(func(): + screen_size = get_viewport().get_visible_rect().size + ) + +#endregion + +#region Public Functions + +func pcam_host_added(caller: Node) -> void: + if is_instance_of(caller, PhantomCameraHost): + _phantom_camera_host_list.append(caller) + pcam_host_added_to_scene.emit(caller) + else: + printerr("This method can only be called from a PhantomCameraHost node") + +func pcam_host_removed(caller: Node) -> void: + if is_instance_of(caller, PhantomCameraHost): + _phantom_camera_host_list.erase(caller) + pcam_host_removed_from_scene.emit(caller) + else: + printerr("This method can only be called from a PhantomCameraHost node") + + +func pcam_added(caller) -> void: + if is_instance_of(caller, PhantomCamera2D): + _phantom_camera_2d_list.append(caller) + pcam_added_to_scene.emit(caller) + elif caller.is_class("PhantomCamera3D"): ## Note: To support disable_3d export templates for 2D projects, this is purposely not strongly typed. + _phantom_camera_3d_list.append(caller) + pcam_added_to_scene.emit(caller) + +func pcam_removed(caller) -> void: + if is_instance_of(caller, PhantomCamera2D): + _phantom_camera_2d_list.erase(caller) + pcam_removed_from_scene.emit(caller) + elif caller.is_class("PhantomCamera3D"): ## Note: To support disable_3d export templates for 2D projects, this is purposely not strongly typed. + _phantom_camera_3d_list.erase(caller) + pcam_removed_from_scene.emit(caller) + else: + printerr("This method can only be called from a PhantomCamera node") + + +func get_phantom_camera_hosts() -> Array[PhantomCameraHost]: + return _phantom_camera_host_list + +func get_phantom_camera_2ds() -> Array[PhantomCamera2D]: + return _phantom_camera_2d_list + +func get_phantom_camera_3ds() -> Array: ## Note: To support disable_3d export templates for 2D projects, this is purposely not strongly typed. + return _phantom_camera_3d_list + + +func scene_changed() -> void: + _phantom_camera_2d_list.clear() + _phantom_camera_3d_list.clear() + _phantom_camera_host_list.clear() + +#endregion diff --git a/addons/phantom_camera/scripts/managers/phantom_camera_manager.gd.uid b/addons/phantom_camera/scripts/managers/phantom_camera_manager.gd.uid new file mode 100644 index 0000000..ea18023 --- /dev/null +++ b/addons/phantom_camera/scripts/managers/phantom_camera_manager.gd.uid @@ -0,0 +1 @@ +uid://duq6jhf6unyis diff --git a/addons/phantom_camera/scripts/panel/editor.gd b/addons/phantom_camera/scripts/panel/editor.gd new file mode 100644 index 0000000..a10018c --- /dev/null +++ b/addons/phantom_camera/scripts/panel/editor.gd @@ -0,0 +1,23 @@ +@tool +extends VBoxContainer + +#region Onready + +@onready var updater: Control = %UpdateButton +@onready var viewfinder: Control = %ViewfinderPanel + +#endregion + +#region Public Variables + +var editor_plugin: EditorPlugin + +#endregion + + +#region Private Functions + +func _ready(): + updater.editor_plugin = editor_plugin + +#endregion diff --git a/addons/phantom_camera/scripts/panel/editor.gd.uid b/addons/phantom_camera/scripts/panel/editor.gd.uid new file mode 100644 index 0000000..6be368c --- /dev/null +++ b/addons/phantom_camera/scripts/panel/editor.gd.uid @@ -0,0 +1 @@ +uid://cgfwg3paxkj2x diff --git a/addons/phantom_camera/scripts/panel/updater/download_update_panel.gd b/addons/phantom_camera/scripts/panel/updater/download_update_panel.gd new file mode 100644 index 0000000..b19beb9 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/updater/download_update_panel.gd @@ -0,0 +1,162 @@ +####################################################################### +# Credit goes to the Dialogue Manager plugin for this script +# Check it out at: https://github.com/nathanhoad/godot_dialogue_manager +####################################################################### + +@tool +extends Control + +#region Constants + +const TEMP_FILE_NAME = "user://temp.zip" + +#endregion + + +#region Signals + +signal failed() +signal updated(updated_to_version: String) + +#endregion + + +#region @onready + +#@onready var logo: TextureRect = %Logo +@onready var _download_verion: Label = %DownloadVersionLabel +@onready var _download_http_request: HTTPRequest = %DownloadHTTPRequest +@onready var _download_button: Button = %DownloadButton +@onready var _download_button_bg: NinePatchRect = %DownloadButtonBG +@onready var _download_label: Label = %UpdateLabel + +@onready var _breaking_label: Label = %BreakingLabel +@onready var _breaking_margin_container: MarginContainer = %BreakingMarginContainer +@onready var _breaking_options_button: OptionButton = %BreakingOptionButton +#@onready var current_version_label: Label = %CurrentVersionLabel + +#endregion + + +#region Variables + +# Todo - For 4.2 upgrade - Shows current version +var _download_dialogue: AcceptDialog +var _button_texture_default: Texture2D = load("res://addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png") +var _button_texture_hover: Texture2D = load("res://addons/phantom_camera/assets/PhantomCameraBtnPrimaryHover.png") + +var next_version_release: Dictionary: + set(value): + next_version_release = value + _download_verion.text = "%s update is available for download" % value.tag_name.substr(1) + # Todo - For 4.2 upgrade + #current_version_label.text = "Current version is " + editor_plugin.get_version() + get: + return next_version_release + +var _breaking_window_height: float = 520 +var _breaking_window_height_update: float = 600 + +#endregion + + +#region Private Functions + +func _ready() -> void: + _download_http_request.request_completed.connect(_on_http_request_request_completed) + _download_button.pressed.connect(_on_download_button_pressed) + _download_button.mouse_entered.connect(_on_mouse_entered) + _download_button.mouse_exited.connect(_on_mouse_exited) + + _breaking_label.hide() + _breaking_margin_container.hide() + _breaking_options_button.hide() + + _breaking_options_button.item_selected.connect(_on_item_selected) + + +func _on_item_selected(index: int) -> void: + if index == 1: + _download_button.show() + _download_dialogue.size = Vector2(_download_dialogue.size.x, _breaking_window_height_update) + else: + _download_button.hide() + _download_dialogue.size = Vector2(_download_dialogue.size.x, _breaking_window_height) + + +func _on_download_button_pressed() -> void: + _download_http_request.request(next_version_release.zipball_url) + _download_button.disabled = true + _download_label.text = "Downloading..." + _download_button_bg.hide() + + +func _on_mouse_entered() -> void: + _download_button_bg.set_texture(_button_texture_hover) + + +func _on_mouse_exited() -> void: + _download_button_bg.set_texture(_button_texture_default) + + +func _on_http_request_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void: + if result != HTTPRequest.RESULT_SUCCESS: + failed.emit() + return + + # Save the downloaded zip + var zip_file: FileAccess = FileAccess.open(TEMP_FILE_NAME, FileAccess.WRITE) + zip_file.store_buffer(body) + zip_file.close() + + OS.move_to_trash(ProjectSettings.globalize_path("res://addons/phantom_camera")) + + var zip_reader: ZIPReader = ZIPReader.new() + zip_reader.open(TEMP_FILE_NAME) + var files: PackedStringArray = zip_reader.get_files() + + var base_path = files[1] + # Remove archive folder + files.remove_at(0) + # Remove assets folder + files.remove_at(0) + + for path in files: + var new_file_path: String = path.replace(base_path, "") + if path.ends_with("/"): + DirAccess.make_dir_recursive_absolute("res://addons/%s" % new_file_path) + else: + var file: FileAccess = FileAccess.open("res://addons/%s" % new_file_path, FileAccess.WRITE) + file.store_buffer(zip_reader.read_file(path)) + + zip_reader.close() + DirAccess.remove_absolute(TEMP_FILE_NAME) + + updated.emit(next_version_release.tag_name.substr(1)) + + +func _on_notes_button_pressed() -> void: + OS.shell_open(next_version_release.html_url) + +#endregion + +#region Public Functions + +func show_updater_warning(next_version_number: Array, current_version_number: Array) -> void: + var current_version_number_0: int = current_version_number[0] as int + var current_version_number_1: int = current_version_number[1] as int + + var next_version_number_0: int = next_version_number[0] as int # Major release number in the new release + var next_version_number_1: int = next_version_number[1] as int # Minor release number in the new release + + if next_version_number_0 > current_version_number_0 or \ + next_version_number_1 > current_version_number_1: + _breaking_label.show() + _breaking_margin_container.show() + _breaking_options_button.show() + _download_button.hide() + + _download_dialogue = get_parent() + _download_dialogue.size = Vector2(_download_dialogue.size.x, _breaking_window_height) + +#endregion diff --git a/addons/phantom_camera/scripts/panel/updater/download_update_panel.gd.uid b/addons/phantom_camera/scripts/panel/updater/download_update_panel.gd.uid new file mode 100644 index 0000000..ff50946 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/updater/download_update_panel.gd.uid @@ -0,0 +1 @@ +uid://cjblcocen12r3 diff --git a/addons/phantom_camera/scripts/panel/updater/update_button.gd b/addons/phantom_camera/scripts/panel/updater/update_button.gd new file mode 100644 index 0000000..686535c --- /dev/null +++ b/addons/phantom_camera/scripts/panel/updater/update_button.gd @@ -0,0 +1,177 @@ +####################################################################### +# Credit goes to the Dialogue Manager plugin for this script +# Check it out at: https://github.com/nathanhoad/godot_dialogue_manager +####################################################################### + +@tool +extends Button + +#region Constants + +const REMOTE_RELEASE_URL: StringName = "https://api.github.com/repos/ramokz/phantom-camera/releases" +const UPDATER_CONSTANTS := preload("res://addons/phantom_camera/scripts/panel/updater/updater_constants.gd") + +#endregion + + +#region @onready + +@onready var http_request: HTTPRequest = %HTTPRequest +@onready var download_dialog: AcceptDialog = %DownloadDialog +@onready var download_update_panel: Control = %DownloadUpdatePanel +@onready var needs_reload_dialog: AcceptDialog = %NeedsReloadDialog +@onready var update_failed_dialog: AcceptDialog = %UpdateFailedDialog + +#endregion + + +#region Variables + +# The main editor plugin +var editor_plugin: EditorPlugin + +var needs_reload: bool = false + +# A lambda that gets called just before refreshing the plugin. Return false to stop the reload. +var on_before_refresh: Callable = func(): return true + +#endregion + + +#region Private Functions + +func _ready() -> void: + hide() + + # Check for updates on GitHub Releases + check_for_update() + + pressed.connect(_on_update_button_pressed) + http_request.request_completed.connect(_request_request_completed) + download_update_panel.updated.connect(_on_download_update_panel_updated) + needs_reload_dialog.confirmed.connect(_on_needs_reload_dialog_confirmed) + + +func _request_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void: + if result != HTTPRequest.RESULT_SUCCESS: return + + if not editor_plugin: return + var current_version: String = editor_plugin.get_version() + + # Work out the next version from the releases information on GitHub + var response: Array = JSON.parse_string(body.get_string_from_utf8()) + if typeof(response) != TYPE_ARRAY: return + + # GitHub releases are in order of creation, not order of version + var versions: Array = response.filter(func(release): + var version: String = release.tag_name.substr(1) + return version_to_number(version) > version_to_number(current_version) + ) + + if versions.size() > 0: + if ProjectSettings.get_setting(UPDATER_CONSTANTS.setting_updater_mode) == 1: ## For console output mode + + print_rich(" +[color=#3AB99A] ********[/color] +[color=#3AB99A] ************[/color] +[color=#3AB99A]**************[/color] +[color=#3AB99A]****** *** *[/color] +[color=#3AB99A]****** ***[/color] +[color=#3AB99A]********** *****[/color] +[color=#3AB99A]******** ***********[/color] +[color=#3AB99A]******** *********** **[/color] +[color=#3AB99A]********* **************[/color] +[color=#3AB99A]********** *************[/color] +[color=#3AB99A]** ** ** ******* **[/color] +[font_size=18][b]New Phantom Camera version is available[/b][/font_size]") + + if FileAccess.file_exists("res://dev_scenes/3d/dev_scene_3d.tscn"): + print_rich("[font_size=14][color=#EAA15E][b]As you're using a fork of the project, you will need to update it manually[/b][/color][/font_size]") + + print_rich("[font_size=12]If you don't want to see this message, then it can be disabled inside:\n[code]Project Settings/Phantom Camera/Updater/Show New Release Info on Editor Launch in Output[/code]") + + return + + download_update_panel.next_version_release = versions[0] + download_update_panel.show_updater_warning( + versions[0].tag_name.substr(1).split("."), + current_version.split(".") + ) + _set_scale() + editor_plugin.panel_button.add_theme_color_override("font_color", Color("#3AB99A")) + editor_plugin.panel_button.icon = load("res://addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg") + editor_plugin.panel_button.add_theme_color_override("icon_normal_color", Color("#3AB99A")) + show() + + +func _on_update_button_pressed() -> void: + if needs_reload: + var will_refresh = on_before_refresh.call() + if will_refresh: + EditorInterface.restart_editor(true) + else: + _set_scale() + download_dialog.popup_centered() + + +func _set_scale() -> void: + var scale: float = EditorInterface.get_editor_scale() + download_dialog.min_size = Vector2(300, 250) * scale + + +func _on_download_dialog_close_requested() -> void: + download_dialog.hide() + + +func _on_download_update_panel_updated(updated_to_version: String) -> void: + download_dialog.hide() + + needs_reload_dialog.dialog_text = "Reload to finish update" + needs_reload_dialog.ok_button_text = "Reload" + needs_reload_dialog.cancel_button_text = "Cancel" + needs_reload_dialog.popup_centered() + + needs_reload = true + text = "Reload Project" + + +func _on_download_update_panel_failed() -> void: + download_dialog.hide() + update_failed_dialog.dialog_text = "Updated Failed" + update_failed_dialog.popup_centered() + + +func _on_needs_reload_dialog_confirmed() -> void: + EditorInterface.restart_editor(true) + + +func _on_timer_timeout() -> void: + if not needs_reload: + check_for_update() + +#endregion + + +#region Public Functions + +# Convert a version number to an actually comparable number +func version_to_number(version: String) -> int: + var regex = RegEx.new() + regex.compile("[a-zA-Z]+") + if regex.search(str(version)): return 0 + + var bits = version.split(".") + var version_bit: int + var multiplier: int = 10000 + for i in bits.size(): + version_bit += bits[i].to_int() * multiplier / (10 ** (i)) + + return version_bit + + +func check_for_update() -> void: + if ProjectSettings.get_setting(UPDATER_CONSTANTS.setting_updater_mode) == 0: return + + http_request.request(REMOTE_RELEASE_URL) + +#endregion diff --git a/addons/phantom_camera/scripts/panel/updater/update_button.gd.uid b/addons/phantom_camera/scripts/panel/updater/update_button.gd.uid new file mode 100644 index 0000000..cb88ddc --- /dev/null +++ b/addons/phantom_camera/scripts/panel/updater/update_button.gd.uid @@ -0,0 +1 @@ +uid://bwc42i46603qn diff --git a/addons/phantom_camera/scripts/panel/updater/updater_constants.gd b/addons/phantom_camera/scripts/panel/updater/updater_constants.gd new file mode 100644 index 0000000..94ac2ad --- /dev/null +++ b/addons/phantom_camera/scripts/panel/updater/updater_constants.gd @@ -0,0 +1,8 @@ +extends RefCounted + +# Plugin Project Settings Sections +const setting_phantom_camera: StringName = "phantom_camera/" +const setting_updater_name: StringName = setting_phantom_camera + "updater/" + +# Updater Settings +const setting_updater_mode: StringName = setting_updater_name + "updater_mode" diff --git a/addons/phantom_camera/scripts/panel/updater/updater_constants.gd.uid b/addons/phantom_camera/scripts/panel/updater/updater_constants.gd.uid new file mode 100644 index 0000000..1f86170 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/updater/updater_constants.gd.uid @@ -0,0 +1 @@ +uid://c8qkbc38waor2 diff --git a/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd b/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd new file mode 100644 index 0000000..662e598 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd @@ -0,0 +1,112 @@ +@tool +extends VBoxContainer + +#region Constants + +const _constants := preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") +const _host_list_item: PackedScene = preload("res://addons/phantom_camera/panel/viewfinder/host_list/host_list_item.tscn") + +#endregion + +signal pcam_host_removed(pcam_host: PhantomCameraHost) + +@onready var _host_list_button: Button = %HostListButton +@onready var _host_list_scroll_container: ScrollContainer = %ScrollContainer +@onready var _host_list_item_container: VBoxContainer = %HostListContainer + +var _host_list_open: bool = false + +var _bottom_offset_value: float + +var _pcam_host_list: Array[PhantomCameraHost] +var _pcam_manager: Node + +var _viewfinder_panel: Control + +#region Private Functions + +func _ready() -> void: + _host_list_button.pressed.connect(_host_list_button_pressed) + if Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): + _pcam_manager = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME) + _pcam_manager.pcam_host_removed_from_scene.connect(_remove_pcam_host) + + if not get_parent() is Control: return # To prevent errors when opening the scene on its own + _viewfinder_panel = get_parent() + _viewfinder_panel.resized.connect(_set_offset_top) + + _host_list_item_container.resized.connect(_set_offset_top) + + +func _set_offset_top() -> void: + offset_top = _set_host_list_size() + + +func _host_list_button_pressed() -> void: + _host_list_open = !_host_list_open + + var tween: Tween = create_tween() + var max_duration: float = 0.6 + + # 300 being the minimum size of the viewfinder's height + var duration: float = clampf( + max_duration / (300 / _host_list_item_container.size.y), + 0.3, + max_duration) + + tween.tween_property(self, "offset_top", _set_host_list_size(), duration)\ + .set_ease(Tween.EASE_OUT)\ + .set_trans(Tween.TRANS_QUINT) + + +func _set_host_list_size() -> float: + if not _host_list_open: + return clampf( + _viewfinder_panel.size.y - \ + _host_list_item_container.size.y - \ + _host_list_button.size.y - 20, + 0, + INF + ) + else: + return (_viewfinder_panel.size.y - _host_list_button.size.y / 2) + + +func _remove_pcam_host(pcam_host: PhantomCameraHost) -> void: + if _pcam_host_list.has(pcam_host): + _pcam_host_list.erase(pcam_host) + + var freed_pcam_host: Control + for host_list_item_instance in _host_list_item_container.get_children(): + if not host_list_item_instance.pcam_host == pcam_host: continue + freed_pcam_host = host_list_item_instance + host_list_item_instance.queue_free() + +#endregion + +#region Public Functions + +func add_pcam_host(pcam_host: PhantomCameraHost, is_default: bool) -> void: + if _pcam_host_list.has(pcam_host): return + + _pcam_host_list.append(pcam_host) + + var host_list_item_instance: PanelContainer = _host_list_item.instantiate() + var switch_pcam_host_button: Button = host_list_item_instance.get_node("%SwitchPCamHost") + if is_default: switch_pcam_host_button.button_pressed = true + + if not pcam_host.tree_exiting.is_connected(_remove_pcam_host): + pcam_host.tree_exiting.connect(_remove_pcam_host.bind(pcam_host)) + + host_list_item_instance.pcam_host = pcam_host + + _host_list_item_container.add_child(host_list_item_instance) + + +func clear_pcam_host_list() -> void: + _pcam_host_list.clear() + + for host_list_item_instance in _host_list_item_container.get_children(): + host_list_item_instance.queue_free() + +#endregion diff --git a/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd.uid b/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd.uid new file mode 100644 index 0000000..6923d3e --- /dev/null +++ b/addons/phantom_camera/scripts/panel/viewfinder/host_list.gd.uid @@ -0,0 +1 @@ +uid://c84cxry3t35ny diff --git a/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd b/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd new file mode 100644 index 0000000..5707974 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd @@ -0,0 +1,58 @@ +@tool +extends Control + +const button_group_resource: ButtonGroup = preload("res://addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres") +const _constants = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") + +@onready var select_pcam_host: Button = %SelectPCamHost +@onready var switch_pcam_host: Button = %SwitchPCamHost + +var pcam_host: PhantomCameraHost: + set(value): + pcam_host = value + if not is_instance_valid(value): return + if not pcam_host.renamed.is_connected(_rename_pcam_host): + pcam_host.renamed.connect(_rename_pcam_host) + pcam_host.has_error.connect(_pcam_host_has_error) + get: + return pcam_host + +var _pcam_manager: Node + +#region Private fucntions + +func _ready() -> void: + switch_pcam_host.button_group = button_group_resource + select_pcam_host.pressed.connect(_select_pcam) + switch_pcam_host.pressed.connect(_switch_pcam_host) + + if not is_instance_valid(pcam_host): return + switch_pcam_host.text = pcam_host.name + + _pcam_host_has_error() + + +func _pcam_host_has_error() -> void: + if pcam_host.show_warning: + %ErrorPCamHost.visible = true + else: + %ErrorPCamHost.visible = false + + +func _rename_pcam_host() -> void: + switch_pcam_host.text = pcam_host.name + + +func _select_pcam() -> void: + EditorInterface.get_selection().clear() + EditorInterface.get_selection().add_node(pcam_host) + + +func _switch_pcam_host() -> void: + if not Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): return + if not is_instance_valid(_pcam_manager): + _pcam_manager = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME) + + _pcam_manager.viewfinder_pcam_host_switch.emit(pcam_host) + +#endregion diff --git a/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd.uid b/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd.uid new file mode 100644 index 0000000..9df2919 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/viewfinder/host_list_item.gd.uid @@ -0,0 +1 @@ +uid://bv24ubx8mutw7 diff --git a/addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd b/addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd new file mode 100644 index 0000000..fe163a7 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd @@ -0,0 +1,605 @@ +@tool +extends Control + +#region Constants + +const _constants = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") + +# TODO - Should be in a central location +const _camera_2d_icon: CompressedTexture2D = preload("res://addons/phantom_camera/icons/viewfinder/Camera2DIcon.svg") +const _camera_3d_icon: CompressedTexture2D = preload("res://addons/phantom_camera/icons/viewfinder/Camera3DIcon.svg") +const _pcam_host_icon: CompressedTexture2D = preload("res://addons/phantom_camera/icons/phantom_camera_host.svg") +const _pcam_2D_icon: CompressedTexture2D = preload("res://addons/phantom_camera/icons/phantom_camera_2d.svg") +const _pcam_3D_icon: CompressedTexture2D = preload("res://addons/phantom_camera/icons/phantom_camera_3d.svg") + +const _overlay_color_alpha: float = 0.3 + +#endregion + +#region @onready + +@onready var dead_zone_center_hbox: VBoxContainer = %DeadZoneCenterHBoxContainer +@onready var dead_zone_center_center_panel: Panel = %DeadZoneCenterCenterPanel +@onready var dead_zone_left_center_panel: Panel = %DeadZoneLeftCenterPanel +@onready var dead_zone_right_center_panel: Panel = %DeadZoneRightCenterPanel +@onready var target_point: Panel = %TargetPoint + +@onready var aspect_ratio_container: AspectRatioContainer = %AspectRatioContainer +@onready var camera_viewport_panel: Panel = aspect_ratio_container.get_child(0) +@onready var _viewfinder: Control = %Viewfinder +@onready var _dead_zone_h_box_container: Control = %DeadZoneHBoxContainer +@onready var sub_viewport: SubViewport = %SubViewport + +@onready var _empty_state_control: Control = %EmptyStateControl +@onready var _empty_state_icon: TextureRect = %EmptyStateIcon +@onready var _empty_state_text: RichTextLabel = %EmptyStateText +@onready var _add_node_button: Button = %AddNodeButton +@onready var _add_node_button_text: RichTextLabel = %AddNodeTypeText + +@onready var _priority_override_button: Button = %PriorityOverrideButton +@onready var _priority_override_name_label: Label = %PriorityOverrideNameLabel + +@onready var _camera_2d: Camera2D = %Camera2D + +@onready var _pcam_host_list: VBoxContainer = %PCamHostList + +#endregion + +#region Private Variables + +var _no_open_scene_icon: CompressedTexture2D = preload("res://addons/phantom_camera/icons/viewfinder/SceneTypesIcon.svg") +var _no_open_scene_string: String = "[b]2D[/b] or [b]3D[/b] scene open" + +var _selected_camera: Node +var _active_pcam: Node + +var _is_2d: bool + +var _pcam_manager: Node + +var _root_node: Node + +#endregion + +#region Public Variables + +var pcam_host_group: Array[PhantomCameraHost] + +var is_scene: bool + +var viewfinder_visible: bool + +var min_horizontal: float +var max_horizontal: float +var min_vertical: float +var max_vertical: float + +var pcam_host: PhantomCameraHost + +#endregion + + +#region Private Functions + +func _ready() -> void: + if not Engine.is_editor_hint(): + set_process(true) + camera_viewport_panel.self_modulate.a = 0 + + _root_node = get_tree().current_scene + + if _root_node is Node2D || _root_node is Node3D: + %SubViewportContainer.visible = false + if _root_node is Node2D: + _is_2d = true + else: + _is_2d = false + + _set_viewfinder(_root_node, false) + + if not Engine.is_editor_hint(): + _empty_state_control.visible = false + + _priority_override_button.visible = false + + # Triggered when viewport size is changed in Project Settings + ProjectSettings.settings_changed.connect(_settings_changed) + + # PCam Host List + _pcam_host_list.visible = false + _assign_manager() + _visibility_check() + + +func _pcam_host_switch(new_pcam_host: PhantomCameraHost) -> void: + _set_viewfinder_camera(new_pcam_host, true) + + +func _exit_tree() -> void: + if aspect_ratio_container.resized.is_connected(_resized): + aspect_ratio_container.resized.disconnect(_resized) + + if _add_node_button.pressed.is_connected(_visibility_check): + _add_node_button.pressed.disconnect(_visibility_check) + + if is_instance_valid(_active_pcam): + if _active_pcam.dead_zone_changed.is_connected(_on_dead_zone_changed): + _active_pcam.dead_zone_changed.disconnect(_on_dead_zone_changed) + + if _priority_override_button.pressed.is_connected(_select_override_pcam): + _priority_override_button.pressed.disconnect(_select_override_pcam) + + +func _process(_delta: float) -> void: + if Engine.is_editor_hint() and not viewfinder_visible: return + if not is_instance_valid(_active_pcam): return + + var unprojected_position_clamped: Vector2 = Vector2( + clamp(_active_pcam.viewport_position.x, min_horizontal, max_horizontal), + clamp(_active_pcam.viewport_position.y, min_vertical, max_vertical) + ) + + if not Engine.is_editor_hint(): + target_point.position = camera_viewport_panel.size * unprojected_position_clamped - target_point.size / 2 + + if not _is_2d: return + if not is_instance_valid(pcam_host): return + if not is_instance_valid(pcam_host.camera_2d): return + + var window_size_height: float = ProjectSettings.get_setting("display/window/size/viewport_height") + sub_viewport.size_2d_override = sub_viewport.size * (window_size_height / sub_viewport.size.y) + + _camera_2d.global_transform = pcam_host.camera_2d.global_transform + _camera_2d.offset = pcam_host.camera_2d.offset + _camera_2d.zoom = pcam_host.camera_2d.zoom + _camera_2d.ignore_rotation = pcam_host.camera_2d.ignore_rotation + _camera_2d.anchor_mode = pcam_host.camera_2d.anchor_mode + _camera_2d.limit_left = pcam_host.camera_2d.limit_left + _camera_2d.limit_top = pcam_host.camera_2d.limit_top + _camera_2d.limit_right = pcam_host.camera_2d.limit_right + _camera_2d.limit_bottom = pcam_host.camera_2d.limit_bottom + + +func _settings_changed() -> void: + var viewport_width: float = ProjectSettings.get_setting("display/window/size/viewport_width") + var viewport_height: float = ProjectSettings.get_setting("display/window/size/viewport_height") + var ratio: float = viewport_width / viewport_height + aspect_ratio_container.set_ratio(ratio) + camera_viewport_panel.size.x = viewport_width / (viewport_height / sub_viewport.size.y) + + # Applies Project Settings to Viewport + sub_viewport.canvas_item_default_texture_filter = ProjectSettings.get_setting("rendering/textures/canvas_textures/default_texture_filter") + + # TODO - Add resizer for Framed Viewfinder + + +func _visibility_check() -> void: + if not viewfinder_visible: return + + var pcam_host: PhantomCameraHost + var has_camera: bool = false + if not Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): return + + if not Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME).get_phantom_camera_hosts().is_empty(): + has_camera = true + pcam_host = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME).get_phantom_camera_hosts()[0] + + var root: Node = EditorInterface.get_edited_scene_root() + if root is Node2D: + var camera_2d: Camera2D + + if has_camera: + camera_2d = pcam_host.camera_2d + else: + camera_2d = _get_camera_2d() + + _is_2d = true + is_scene = true + _add_node_button.visible = true + _check_camera(root, camera_2d) + elif root is Node3D: + var camera_3d: Camera3D + if has_camera: + camera_3d = pcam_host.camera_3d + elif root.get_viewport() != null: + if root.get_viewport().get_camera_3d() != null: + camera_3d = root.get_viewport().get_camera_3d() + + _is_2d = false + is_scene = true + _add_node_button.visible = true + _check_camera(root, camera_3d) + else: + # Is not a 2D or 3D scene + is_scene = false + _set_empty_viewfinder_state(_no_open_scene_string, _no_open_scene_icon) + _add_node_button.visible = false + + # Checks if a new scene is created and changes viewfinder accordingly + if not get_tree().node_added.is_connected(_node_added_to_scene): + get_tree().node_added.connect(_node_added_to_scene) + + if not _priority_override_button.pressed.is_connected(_select_override_pcam): + _priority_override_button.pressed.connect(_select_override_pcam) + + +func _node_added_to_scene(node: Node) -> void: + if node is Node2D or node is Node3D: + get_tree().node_added.disconnect(_node_added_to_scene) + _visibility_check() + + +func _get_camera_2d() -> Camera2D: + var edited_scene_root: Node = EditorInterface.get_edited_scene_root() + + if edited_scene_root == null: return null + + var viewport: Viewport = edited_scene_root.get_viewport() + if viewport == null: return null + + var viewport_rid: RID = viewport.get_viewport_rid() + if viewport_rid == null: return null + + var camerasGroupName: String = "__cameras_%d" % viewport_rid.get_id() + var cameras: Array[Node] = get_tree().get_nodes_in_group(camerasGroupName) + + for camera in cameras: + if camera is Camera2D and camera.is_current: + return camera + + return null + + +func _check_camera(root: Node, camera: Node) -> void: + var camera_string: String + var pcam_string: String + var color: Color + var camera_icon: CompressedTexture2D + var pcam_icon: CompressedTexture2D + + if _is_2d: + camera_string = _constants.CAMERA_2D_NODE_NAME + pcam_string = _constants.PCAM_2D_NODE_NAME + color = _constants.COLOR_2D + camera_icon = _camera_2d_icon + pcam_icon = _pcam_2D_icon + else: + camera_string = _constants.CAMERA_3D_NODE_NAME + pcam_string = _constants.PCAM_3D_NODE_NAME + color = _constants.COLOR_3D + camera_icon = _camera_3d_icon + pcam_icon = _pcam_3D_icon + + if camera: +# Has Camera + if camera.get_children().size() > 0: + for cam_child in camera.get_children(): + if cam_child is PhantomCameraHost: + pcam_host = cam_child + + if pcam_host: + if get_tree().root.get_node(_constants.PCAM_MANAGER_NODE_NAME).get_phantom_camera_2ds() or \ + get_tree().root.get_node(_constants.PCAM_MANAGER_NODE_NAME).get_phantom_camera_3ds(): + # Pcam exists in tree + _set_viewfinder(root, true) + _set_viewfinder_state() + %NoSupportMsg.visible = false + else: +# No PCam in scene + _update_button(pcam_string, pcam_icon, color) + _set_empty_viewfinder_state(pcam_string, pcam_icon) + else: +# No PCamHost in scene + _update_button(_constants.PCAM_HOST_NODE_NAME, _pcam_host_icon, _constants.PCAM_HOST_COLOR) + _set_empty_viewfinder_state(_constants.PCAM_HOST_NODE_NAME, _pcam_host_icon) + else: +# No PCamHost in scene + _update_button(_constants.PCAM_HOST_NODE_NAME, _pcam_host_icon, _constants.PCAM_HOST_COLOR) + _set_empty_viewfinder_state(_constants.PCAM_HOST_NODE_NAME, _pcam_host_icon) + else: +# No Camera + _update_button(camera_string, camera_icon, color) + _set_empty_viewfinder_state(camera_string, camera_icon) + + +func _update_button(text: String, icon: CompressedTexture2D, color: Color) -> void: + _add_node_button_text.set_text("[center]Add [img=32]" + icon.resource_path + "[/img] [b]"+ text + "[/b][/center]"); + var button_theme_hover: StyleBoxFlat = _add_node_button.get_theme_stylebox("hover") + button_theme_hover.border_color = color + _add_node_button.add_theme_stylebox_override("hover", button_theme_hover) + + +func _set_viewfinder_state() -> void: + _empty_state_control.visible = false + _viewfinder.visible = true + + if is_instance_valid(_active_pcam): + if _active_pcam.get_follow_mode() == _active_pcam.FollowMode.FRAMED: + _dead_zone_h_box_container.visible = true + target_point.visible = true + else: + _dead_zone_h_box_container.visible = false + target_point.visible = false + + +func _set_empty_viewfinder_state(text: String, icon: CompressedTexture2D) -> void: + _viewfinder.visible = false + _framed_view_visible(false) + + _empty_state_control.visible = true + _empty_state_icon.texture = icon + if icon == _no_open_scene_icon: + _empty_state_text.set_text("[center]No " + text + "[/center]") + else: + _empty_state_text.set_text("[center]No [b]" + text + "[/b] in scene[/center]") + + if _add_node_button.pressed.is_connected(_add_node): + _add_node_button.pressed.disconnect(_add_node) + + _add_node_button.pressed.connect(_add_node.bind(text)) + + +func _add_node(node_type: String) -> void: + var scene_root: Node = EditorInterface.get_edited_scene_root() + + match node_type: + _no_open_scene_string: + pass + _constants.CAMERA_2D_NODE_NAME: + var camera: Camera2D = Camera2D.new() + _instantiate_node(scene_root, camera, _constants.CAMERA_2D_NODE_NAME) + _constants.CAMERA_3D_NODE_NAME: + var camera: Camera3D = Camera3D.new() + _instantiate_node(scene_root, camera, _constants.CAMERA_3D_NODE_NAME) + _constants.PCAM_HOST_NODE_NAME: + var pcam_host: PhantomCameraHost = PhantomCameraHost.new() + var camera_owner: Node + if _is_2d: + camera_owner = _get_camera_2d() + else: + camera_owner = get_tree().get_edited_scene_root().get_viewport().get_camera_3d() + _instantiate_node( + scene_root, + pcam_host, + _constants.PCAM_HOST_NODE_NAME, + camera_owner + ) + _constants.PCAM_2D_NODE_NAME: + var pcam_2D: PhantomCamera2D = PhantomCamera2D.new() + _instantiate_node(scene_root, pcam_2D, _constants.PCAM_2D_NODE_NAME) + _constants.PCAM_3D_NODE_NAME: + var pcam_3D: PhantomCamera3D = PhantomCamera3D.new() + _instantiate_node(scene_root, pcam_3D, _constants.PCAM_3D_NODE_NAME) + + _visibility_check() + + +func _instantiate_node(scene_root: Node, node: Node, name: String, parent: Node = scene_root) -> void: + node.set_name(name) + parent.add_child(node) + node.owner = scene_root + + +func _set_viewfinder(root: Node, editor: bool) -> void: + pcam_host_group = get_tree().root.get_node(_constants.PCAM_MANAGER_NODE_NAME).get_phantom_camera_hosts() + if pcam_host_group.size() != 0: + if pcam_host_group.size() == 1: + _pcam_host_list.visible = false + _set_viewfinder_camera(pcam_host_group[0], editor) + else: + _pcam_host_list.visible = true + _set_viewfinder_camera(pcam_host_group[0], editor) + for i in pcam_host_group.size(): + var is_default: bool = false + if i == 0: + is_default = true + _pcam_host_list.add_pcam_host(pcam_host_group[i], is_default) + + +func _set_viewfinder_camera(new_pcam_host: PhantomCameraHost, editor: bool) -> void: + pcam_host = new_pcam_host + + if _is_2d: + _selected_camera = pcam_host.camera_2d + + if editor: + sub_viewport.disable_3d = true + pcam_host = pcam_host + _camera_2d.zoom = pcam_host.camera_2d.zoom + _camera_2d.offset = pcam_host.camera_2d.offset + _camera_2d.ignore_rotation = pcam_host.camera_2d.ignore_rotation + + sub_viewport.world_2d = pcam_host.camera_2d.get_world_2d() + sub_viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS + sub_viewport.render_target_clear_mode = SubViewport.CLEAR_MODE_ALWAYS + sub_viewport.size_2d_override_stretch = true + else: + _selected_camera = pcam_host.camera_3d + if editor: + var camera_3d_rid: RID = _selected_camera.get_camera_rid() + sub_viewport.disable_3d = false + sub_viewport.world_3d = pcam_host.camera_3d.get_world_3d() + RenderingServer.viewport_attach_camera(sub_viewport.get_viewport_rid(), camera_3d_rid) + + if _selected_camera.keep_aspect == Camera3D.KeepAspect.KEEP_HEIGHT: + aspect_ratio_container.set_stretch_mode(AspectRatioContainer.STRETCH_HEIGHT_CONTROLS_WIDTH) + else: + aspect_ratio_container.set_stretch_mode(AspectRatioContainer.STRETCH_WIDTH_CONTROLS_HEIGHT) + + set_process(true) + + if not pcam_host.viewfinder_update.is_connected(_on_update_editor_viewfinder): + pcam_host.viewfinder_update.connect(_on_update_editor_viewfinder) + + if not pcam_host.viewfinder_disable_dead_zone.is_connected(_disconnect_dead_zone): + pcam_host.viewfinder_disable_dead_zone.connect(_disconnect_dead_zone) + + if not aspect_ratio_container.resized.is_connected(_resized): + aspect_ratio_container.resized.connect(_resized) + + if is_instance_valid(pcam_host.get_active_pcam()): + _active_pcam = pcam_host.get_active_pcam() + else: + _framed_view_visible(false) + _active_pcam = null + return + + if not _active_pcam.follow_mode == PhantomCamera2D.FollowMode.FRAMED: return + + _framed_view_visible(true) + _on_dead_zone_changed() + _connect_dead_zone() + + +func _connect_dead_zone() -> void: + if not _active_pcam and is_instance_valid(pcam_host.get_active_pcam()): + _active_pcam = pcam_host.get_active_pcam() + + if not _active_pcam.dead_zone_changed.is_connected(_on_dead_zone_changed): + _active_pcam.dead_zone_changed.connect(_on_dead_zone_changed) + + _framed_view_visible(true) + _viewfinder.visible = true + _on_dead_zone_changed() + +func _disconnect_dead_zone() -> void: + if not is_instance_valid(_active_pcam): return + _framed_view_visible(_is_framed_pcam()) + + if _active_pcam.follow_mode_changed.is_connected(_check_follow_mode): + _active_pcam.follow_mode_changed.disconnect(_check_follow_mode) + + if _active_pcam.dead_zone_changed.is_connected(_on_dead_zone_changed): + _active_pcam.dead_zone_changed.disconnect(_on_dead_zone_changed) + + +func _resized() -> void: + _on_dead_zone_changed() + + +func _is_framed_pcam() -> bool: + if not is_instance_valid(pcam_host): return false + _active_pcam = pcam_host.get_active_pcam() + if not is_instance_valid(_active_pcam): return false + if not _active_pcam.follow_mode == PhantomCamera2D.FollowMode.FRAMED: return false + + return true + + +func _framed_view_visible(should_show: bool) -> void: + if should_show: + target_point.visible = true + _dead_zone_h_box_container.visible = true + else: + target_point.visible = false + _dead_zone_h_box_container.visible = false + + +func _on_dead_zone_changed() -> void: + if not is_instance_valid(_active_pcam): return + if not _active_pcam.follow_mode == _active_pcam.FollowMode.FRAMED: return + + # Waits until the camera_viewport_panel has been resized when launching the game + if camera_viewport_panel.size.x == 0: + await camera_viewport_panel.resized + + if not _active_pcam == pcam_host.get_active_pcam(): + _active_pcam == pcam_host.get_active_pcam() + + var dead_zone_width: float = _active_pcam.dead_zone_width * camera_viewport_panel.size.x + var dead_zone_height: float = _active_pcam.dead_zone_height * camera_viewport_panel.size.y + dead_zone_center_hbox.set_custom_minimum_size(Vector2(dead_zone_width, 0)) + dead_zone_center_center_panel.set_custom_minimum_size(Vector2(0, dead_zone_height)) + dead_zone_left_center_panel.set_custom_minimum_size(Vector2(0, dead_zone_height)) + dead_zone_right_center_panel.set_custom_minimum_size(Vector2(0, dead_zone_height)) + + min_horizontal = 0.5 - _active_pcam.dead_zone_width / 2 + max_horizontal = 0.5 + _active_pcam.dead_zone_width / 2 + min_vertical = 0.5 - _active_pcam.dead_zone_height / 2 + max_vertical = 0.5 + _active_pcam.dead_zone_height / 2 + + +func _check_follow_mode() -> void: + _framed_view_visible(_is_framed_pcam()) + + +func _on_update_editor_viewfinder(check_framed_view: bool = false) -> void: + _active_pcam = pcam_host.get_active_pcam() + + if not is_instance_valid(_active_pcam): return + + if not _active_pcam.follow_mode_changed.is_connected(_check_follow_mode): + _active_pcam.follow_mode_changed.connect(_check_follow_mode) + + if _active_pcam.priority_override: + _priority_override_button.visible = true + _priority_override_name_label.set_text(_active_pcam.name) + _priority_override_button.set_tooltip_text(_active_pcam.name) + else: + _priority_override_button.visible = false + + _framed_view_visible(false) + if not check_framed_view: return + if _is_framed_pcam(): _connect_dead_zone() + + +func _select_override_pcam() -> void: + EditorInterface.get_selection().clear() + EditorInterface.get_selection().add_node(_active_pcam) + + +func _assign_manager() -> void: + if not is_instance_valid(_pcam_manager): + if Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): + _pcam_manager = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME) + _pcam_manager.pcam_host_added_to_scene.connect(_pcam_changed) + _pcam_manager.pcam_host_removed_from_scene.connect(_pcam_host_removed_from_scene) + + _pcam_manager.pcam_added_to_scene.connect(_pcam_changed) + _pcam_manager.pcam_removed_from_scene.connect(_pcam_changed) + + _pcam_manager.viewfinder_pcam_host_switch.connect(_pcam_host_switch) + + +func _pcam_host_removed_from_scene(pcam_host: PhantomCameraHost) -> void: + if _pcam_manager.phantom_camera_hosts.size() < 2: + _pcam_host_list.visible = false + + _visibility_check() + + +func _pcam_changed(pcam: Node) -> void: + _visibility_check() + +#endregion + + +#region Public Functions + +func set_visibility(visible: bool) -> void: + if visible: + viewfinder_visible = true + _visibility_check() + else: + viewfinder_visible = false + + +func update_dead_zone() -> void: + _set_viewfinder(_root_node, true) + + +## TODO - Signal can be added directly to this file with the changes in Godot 4.5 (https://github.com/godotengine/godot/pull/102986) +func scene_changed(scene_root: Node) -> void: + _assign_manager() + _priority_override_button.visible = false + _pcam_host_list.clear_pcam_host_list() + + if not scene_root is Node2D and not scene_root is Node3D: + is_scene = false + _pcam_host_list.visible = false + _set_empty_viewfinder_state(_no_open_scene_string, _no_open_scene_icon) + _add_node_button.visible = false + else: + _visibility_check() + +#endregion diff --git a/addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd.uid b/addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd.uid new file mode 100644 index 0000000..f115630 --- /dev/null +++ b/addons/phantom_camera/scripts/panel/viewfinder/viewfinder.gd.uid @@ -0,0 +1 @@ +uid://drmv3363t8amc diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs new file mode 100644 index 0000000..267adf0 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs @@ -0,0 +1,253 @@ +using Godot; +using PhantomCamera.Noise; + +#nullable enable + +namespace PhantomCamera; + +public enum InactiveUpdateMode +{ + Always, + Never +} + +public abstract class PhantomCamera +{ + protected readonly GodotObject Node; + + public delegate void BecameActiveEventHandler(); + public delegate void BecameInactiveEventHandler(); + public delegate void FollowTargetChangedEventHandler(); + public delegate void DeadZoneChangedEventHandler(); + public delegate void TweenStartedEventHandler(); + public delegate void IsTweeningEventHandler(); + public delegate void TweenCompletedEventHandler(); + + public event BecameActiveEventHandler? BecameActive; + public event BecameInactiveEventHandler? BecameInactive; + public event FollowTargetChangedEventHandler? FollowTargetChanged; + public event DeadZoneChangedEventHandler? DeadZoneChanged; + public event TweenStartedEventHandler? TweenStarted; + public event IsTweeningEventHandler? IsTweening; + public event TweenCompletedEventHandler? TweenCompleted; + + private readonly Callable _callableBecameActive; + private readonly Callable _callableBecameInactive; + private readonly Callable _callableFollowTargetChanged; + private readonly Callable _callableDeadZoneChanged; + private readonly Callable _callableTweenStarted; + private readonly Callable _callableIsTweening; + private readonly Callable _callableTweenCompleted; + + public int Priority + { + get => (int)Node.Call(MethodName.GetPriority); + set => Node.Call(MethodName.SetPriority, value); + } + + public bool IsActive => (bool)Node.Call(MethodName.IsActive); + + public bool FollowDamping + { + get => (bool)Node.Call(MethodName.GetFollowDamping); + set => Node.Call(MethodName.SetFollowDamping, value); + } + + public bool IsFollowing => (bool)Node.Call(PhantomCamera.MethodName.IsFollowing); + + public float DeadZoneWidth + { + get => (float)Node.Get(PropertyName.DeadZoneWidth); + set => Node.Set(PropertyName.DeadZoneWidth, value); + } + + public float DeadZoneHeight + { + get => (float)Node.Get(PropertyName.DeadZoneHeight); + set => Node.Set(PropertyName.DeadZoneHeight, value); + } + + public PhantomCameraTween TweenResource + { + get => new((Resource)Node.Call(MethodName.GetTweenResource)); + set => Node.Call(MethodName.SetTweenResource, (GodotObject)value.Resource); + } + + public bool TweenSkip + { + get => (bool)Node.Call(MethodName.GetTweenSkip); + set => Node.Call(MethodName.SetTweenSkip, value); + } + + public float TweenDuration + { + get => (float)Node.Call(MethodName.GetTweenDuration); + set => Node.Call(MethodName.SetTweenDuration, value); + } + + public TransitionType TweenTransition + { + get => (TransitionType)(int)Node.Call(MethodName.GetTweenTransition); + set => Node.Call(MethodName.SetTweenTransition, (int)value); + } + + public EaseType TweenEase + { + get => (EaseType)(int)Node.Call(MethodName.GetTweenEase); + set => Node.Call(MethodName.SetTweenEase, (int)value); + } + + public bool TweenOnLoad + { + get => (bool)Node.Call(MethodName.GetTweenOnLoad); + set => Node.Call(MethodName.SetTweenOnLoad, value); + } + + public InactiveUpdateMode InactiveUpdateMode + { + get => (InactiveUpdateMode)(int)Node.Call(MethodName.GetInactiveUpdateMode); + set => Node.Call(MethodName.SetInactiveUpdateMode, (int)value); + } + + public int HostLayers + { + get => (int)Node.Call(MethodName.GetHostLayers); + set => Node.Call(MethodName.SetHostLayers, value); + } + + public int NoiseEmitterLayer + { + get => (int)Node.Call(MethodName.GetNoiseEmitterLayer); + set => Node.Call(MethodName.SetNoiseEmitterLayer, value); + } + + public void TeleportPosition() + { + Node.Call(MethodName.TeleportPosition); + } + + public void SetHostLayersValue(int layer, bool enabled) + { + Node.Call(MethodName.SetHostLayersValue, layer, enabled); + } + + protected PhantomCamera(GodotObject phantomCameraNode) + { + Node = phantomCameraNode; + + _callableBecameActive = Callable.From(() => BecameActive?.Invoke()); + _callableBecameInactive = Callable.From(() => BecameInactive?.Invoke()); + _callableFollowTargetChanged = Callable.From(() => FollowTargetChanged?.Invoke()); + _callableDeadZoneChanged = Callable.From(() => DeadZoneChanged?.Invoke()); + _callableTweenStarted = Callable.From(() => TweenStarted?.Invoke()); + _callableIsTweening = Callable.From(() => IsTweening?.Invoke()); + _callableTweenCompleted = Callable.From(() => TweenCompleted?.Invoke()); + + Node.Connect(SignalName.BecameActive, _callableBecameActive); + Node.Connect(SignalName.BecameInactive, _callableBecameInactive); + Node.Connect(SignalName.FollowTargetChanged, _callableFollowTargetChanged); + Node.Connect(SignalName.DeadZoneChanged, _callableDeadZoneChanged); + Node.Connect(SignalName.TweenStarted, _callableTweenStarted); + Node.Connect(SignalName.IsTweening, _callableIsTweening); + Node.Connect(SignalName.TweenCompleted, _callableTweenCompleted); + } + + ~PhantomCamera() + { + Node.Disconnect(SignalName.BecameActive, _callableBecameActive); + Node.Disconnect(SignalName.BecameInactive, _callableBecameInactive); + Node.Disconnect(SignalName.FollowTargetChanged, _callableFollowTargetChanged); + Node.Disconnect(SignalName.DeadZoneChanged, _callableDeadZoneChanged); + Node.Disconnect(SignalName.TweenStarted, _callableTweenStarted); + Node.Disconnect(SignalName.IsTweening, _callableIsTweening); + Node.Disconnect(SignalName.TweenCompleted, _callableTweenCompleted); + } + + public static class MethodName + { + public const string GetFollowMode = "get_follow_mode"; + public const string IsActive = "is_active"; + + public const string GetPriority = "get_priority"; + public const string SetPriority = "set_priority"; + + public const string IsFollowing = "is_following"; + + public const string GetFollowTarget = "get_follow_target"; + public const string SetFollowTarget = "set_follow_target"; + + public const string GetFollowTargets = "get_follow_targets"; + public const string SetFollowTargets = "set_follow_targets"; + + public const string TeleportPosition = "teleport_position"; + + public const string AppendFollowTargets = "append_follow_targets"; + public const string AppendFollowTargetsArray = "append_follow_targets_array"; + public const string EraseFollowTargets = "erase_follow_targets"; + + public const string GetFollowPath = "get_follow_path"; + public const string SetFollowPath = "set_follow_path"; + + public const string GetFollowOffset = "get_follow_offset"; + public const string SetFollowOffset = "set_follow_offset"; + + public const string GetFollowDamping = "get_follow_damping"; + public const string SetFollowDamping = "set_follow_damping"; + + public const string GetFollowDampingValue = "get_follow_damping_value"; + public const string SetFollowDampingValue = "set_follow_damping_value"; + + public const string GetFollowAxisLock = "get_follow_axis_lock"; + public const string SetFollowAxisLock = "set_follow_axis_lock"; + + public const string GetTweenResource = "get_tween_resource"; + public const string SetTweenResource = "set_tween_resource"; + + public const string GetTweenSkip = "get_tween_skip"; + public const string SetTweenSkip = "set_tween_skip"; + + public const string GetTweenDuration = "get_tween_duration"; + public const string SetTweenDuration = "set_tween_duration"; + + public const string GetTweenTransition = "get_tween_transition"; + public const string SetTweenTransition = "set_tween_transition"; + + public const string GetTweenEase = "get_tween_ease"; + public const string SetTweenEase = "set_tween_ease"; + + public const string GetTweenOnLoad = "get_tween_on_load"; + public const string SetTweenOnLoad = "set_tween_on_load"; + + public const string GetInactiveUpdateMode = "get_inactive_update_mode"; + public const string SetInactiveUpdateMode = "set_inactive_update_mode"; + + public const string GetHostLayers = "get_host_layers"; + public const string SetHostLayers = "set_host_layers"; + public const string SetHostLayersValue = "set_host_layers_value"; + + public const string GetNoiseEmitterLayer = "get_noise_emitter_layer"; + public const string SetNoiseEmitterLayer = "set_noise_emitter_layer"; + + public const string EmitNoise = "emit_noise"; + } + + public static class PropertyName + { + public const string DeadZoneWidth = "dead_zone_width"; + public const string DeadZoneHeight = "dead_zone_height"; + } + + public static class SignalName + { + public const string BecameActive = "became_active"; + public const string BecameInactive = "became_inactive"; + public const string FollowTargetChanged = "follow_target_changed"; + public const string DeadZoneChanged = "dead_zone_changed"; + public const string DeadZoneReached = "dead_zone_reached"; + public const string TweenStarted = "tween_started"; + public const string IsTweening = "is_tweening"; + public const string TweenCompleted = "tween_completed"; + public const string TweenInterrupted = "tween_interrupted"; + public const string NoiseEmitted = "noise_emitted"; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs.uid b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs.uid new file mode 100644 index 0000000..856fbdb --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera.cs.uid @@ -0,0 +1 @@ +uid://d3wh0457i0i3 diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs new file mode 100644 index 0000000..20b3ba5 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs @@ -0,0 +1,351 @@ +using System.Linq; +using Godot; +using Godot.Collections; +using PhantomCamera.Noise; + +#nullable enable + +namespace PhantomCamera; + +public enum FollowMode2D +{ + None, + Glued, + Simple, + Group, + Path, + Framed +} + +public enum FollowLockAxis2D +{ + None, + X, + Y, + XY +} + +public static class PhantomCamera2DExtensions +{ + public static PhantomCamera2D AsPhantomCamera2D(this Node2D node2D) + { + return new PhantomCamera2D(node2D); + } + + public static PhantomCameraNoiseEmitter2D AsPhantomCameraNoiseEmitter2D(this Node2D node2D) + { + return new PhantomCameraNoiseEmitter2D(node2D); + } + + public static PhantomCameraNoise2D AsPhantomCameraNoise2D(this Resource resource) + { + return new PhantomCameraNoise2D(resource); + } +} + +public class PhantomCamera2D : PhantomCamera +{ + public Node2D Node2D => (Node2D)Node; + + public delegate void TweenInterruptedEventHandler(Node2D pCam); + public delegate void DeadZoneReachedEventHandler(Vector2 side); + public delegate void NoiseEmittedEventHandler(Transform2D output); + + public event TweenInterruptedEventHandler? TweenInterrupted; + public event DeadZoneReachedEventHandler? DeadZoneReached; + public event NoiseEmittedEventHandler? NoiseEmitted; + + private readonly Callable _callableTweenInterrupted; + private readonly Callable _callableDeadZoneReached; + private readonly Callable _callableNoiseEmitted; + + public Node2D FollowTarget + { + get => (Node2D)Node2D.Call(PhantomCamera.MethodName.GetFollowTarget); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowTarget, value); + } + + public Node2D[] FollowTargets + { + get => Node2D.Call(PhantomCamera.MethodName.GetFollowTargets).AsGodotArray().ToArray(); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowTargets, new Array(value)); + } + + public void AppendFollowTargets(Node2D target) => Node2D.Call(PhantomCamera.MethodName.AppendFollowTargets, target); + public void AppendFollowTargetsArray(Node2D[] targets) => Node2D.Call(PhantomCamera.MethodName.AppendFollowTargetsArray, targets); + public void EraseFollowTargets(Node2D target) => Node2D.Call(PhantomCamera.MethodName.EraseFollowTargets, target); + + public FollowMode2D FollowMode => (FollowMode2D)(int)Node.Call(PhantomCamera.MethodName.GetFollowMode); + + public Path2D FollowPath + { + get => (Path2D)Node2D.Call(PhantomCamera.MethodName.GetFollowPath); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowPath, value); + } + + public Vector2 FollowOffset + { + get => (Vector2)Node2D.Call(PhantomCamera.MethodName.GetFollowOffset); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowOffset, value); + } + + public Vector2 FollowDampingValue + { + get => (Vector2)Node2D.Call(PhantomCamera.MethodName.GetFollowDampingValue); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowDampingValue, value); + } + + public FollowLockAxis2D FollowAxisLock + { + get => (FollowLockAxis2D)(int)Node2D.Call(PhantomCamera.MethodName.GetFollowAxisLock); + set => Node2D.Call(PhantomCamera.MethodName.SetFollowAxisLock, (int)value); + } + + public Vector2 Zoom + { + get => (Vector2)Node2D.Call(MethodName.GetZoom); + set => Node2D.Call(MethodName.SetZoom, value); + } + + public bool SnapToPixel + { + get => (bool)Node2D.Call(MethodName.GetSnapToPixel); + set => Node2D.Call(MethodName.SetSnapToPixel, value); + } + + public bool RotateWithTarget + { + get => (bool)Node2D.Call(MethodName.GetRotateWithTarget); + set => Node2D.Call(MethodName.SetRotateWithTarget, value); + } + + public float RotationOffset + { + get => (float)Node2D.Call(MethodName.GetRotationOffset); + set => Node2D.Call(MethodName.SetRotationOffset, value); + } + + public bool RotationDamping + { + get => (bool)Node2D.Call(MethodName.GetRotationDamping); + set => Node2D.Call(MethodName.SetRotationDamping, value); + } + + public float RotationDampingValue + { + get => (float)Node2D.Call(MethodName.GetRotationDampingValue); + set => Node2D.Call(MethodName.SetRotationDampingValue, value); + } + + public int LimitLeft + { + get => (int)Node2D.Call(MethodName.GetLimitLeft); + set => Node2D.Call(MethodName.SetLimitLeft, value); + } + + public int LimitTop + { + get => (int)Node2D.Call(MethodName.GetLimitTop); + set => Node2D.Call(MethodName.SetLimitTop, value); + } + + public int LimitRight + { + get => (int)Node2D.Call(MethodName.GetLimitRight); + set => Node2D.Call(MethodName.SetLimitRight, value); + } + + public int LimitBottom + { + get => (int)Node2D.Call(MethodName.GetLimitBottom); + set => Node2D.Call(MethodName.SetLimitBottom, value); + } + + public Vector4I LimitMargin + { + get => (Vector4I)Node2D.Call(MethodName.GetLimitMargin); + set => Node2D.Call(MethodName.SetLimitMargin, value); + } + + public bool AutoZoom + { + get => (bool)Node2D.Call(MethodName.GetAutoZoom); + set => Node2D.Call(MethodName.SetAutoZoom, value); + } + + public float AutoZoomMin + { + get => (float)Node2D.Call(MethodName.GetAutoZoomMin); + set => Node2D.Call(MethodName.SetAutoZoomMin, value); + } + + public float AutoZoomMax + { + get => (float)Node2D.Call(MethodName.GetAutoZoomMax); + set => Node2D.Call(MethodName.SetAutoZoomMax, value); + } + + public Vector4 AutoZoomMargin + { + get => (Vector4)Node2D.Call(MethodName.GetAutoZoomMargin); + set => Node2D.Call(MethodName.SetAutoZoomMargin, value); + } + + public bool DrawLimits + { + get => (bool)Node2D.Get(PropertyName.DrawLimits); + set => Node2D.Set(PropertyName.DrawLimits, value); + } + + public PhantomCameraNoise2D Noise + { + get => new((Resource)Node2D.Call(MethodName.GetNoise)); + set => Node2D.Call(MethodName.SetNoise, (GodotObject)value.Resource); + } + + public void EmitNoise(Transform2D transform) => Node2D.Call(PhantomCamera.MethodName.EmitNoise, transform); + + public NodePath LimitTarget + { + get => (NodePath)Node2D.Call(MethodName.GetLimitTarget); + set => Node2D.Call(MethodName.SetLimitTarget, value); + } + + public static PhantomCamera2D FromScript(string path) => new(GD.Load(path).New().AsGodotObject()); + public static PhantomCamera2D FromScript(GDScript script) => new(script.New().AsGodotObject()); + + public PhantomCamera2D(GodotObject phantomCameraNode) : base(phantomCameraNode) + { + _callableTweenInterrupted = Callable.From(pCam => TweenInterrupted?.Invoke(pCam)); + _callableDeadZoneReached = Callable.From((Vector2 side) => DeadZoneReached?.Invoke(side)); + _callableNoiseEmitted = Callable.From((Transform2D output) => NoiseEmitted?.Invoke(output)); + + Node2D.Connect(SignalName.TweenInterrupted, _callableTweenInterrupted); + Node2D.Connect(SignalName.DeadZoneReached, _callableDeadZoneReached); + Node2D.Connect(SignalName.NoiseEmitted, _callableNoiseEmitted); + } + + ~PhantomCamera2D() + { + Node2D.Disconnect(SignalName.TweenInterrupted, _callableTweenInterrupted); + Node2D.Disconnect(SignalName.DeadZoneReached, _callableDeadZoneReached); + Node2D.Disconnect(SignalName.NoiseEmitted, _callableNoiseEmitted); + } + + public void SetLimitTarget(TileMap tileMap) + { + Node2D.Call(MethodName.SetLimitTarget, tileMap.GetPath()); + } + + public void SetLimitTarget(TileMapLayer tileMapLayer) + { + Node2D.Call(MethodName.SetLimitTarget, tileMapLayer.GetPath()); + } + + public void SetLimitTarget(CollisionShape2D shape2D) + { + Node2D.Call(MethodName.SetLimitTarget, shape2D.GetPath()); + } + + public LimitTargetQueryResult? GetLimitTarget() + { + var result = (NodePath)Node2D.Call(MethodName.GetLimitTarget); + return result.IsEmpty ? null : new LimitTargetQueryResult(Node2D.GetNode(result)); + } + + public void SetLimit(Side side, int value) + { + Node2D.Call(MethodName.SetLimit, (int)side, value); + } + + public int GetLimit(Side side) + { + return (int)Node2D.Call(MethodName.GetLimit, (int)side); + } + + public new static class MethodName + { + public const string GetZoom = "get_zoom"; + public const string SetZoom = "set_zoom"; + + public const string GetSnapToPixel = "get_snap_to_pixel"; + public const string SetSnapToPixel = "set_snap_to_pixel"; + + public const string GetRotateWithTarget = "get_rotate_with_target"; + public const string SetRotateWithTarget = "set_rotate_with_target"; + + public const string GetRotationOffset = "get_rotation_offset"; + public const string SetRotationOffset = "set_rotation_offset"; + + public const string GetRotationDamping = "get_rotation_damping"; + public const string SetRotationDamping = "set_rotation_damping"; + + public const string GetRotationDampingValue = "get_rotation_damping_value"; + public const string SetRotationDampingValue = "set_rotation_damping_value"; + + public const string GetLimit = "get_limit"; + public const string SetLimit = "set_limit"; + + public const string GetLimitLeft = "get_limit_left"; + public const string SetLimitLeft = "set_limit_left"; + + public const string GetLimitTop = "get_limit_top"; + public const string SetLimitTop = "set_limit_top"; + + public const string GetLimitRight = "get_limit_right"; + public const string SetLimitRight = "set_limit_right"; + + public const string GetLimitBottom = "get_limit_bottom"; + public const string SetLimitBottom = "set_limit_bottom"; + + public const string GetLimitTarget = "get_limit_target"; + public const string SetLimitTarget = "set_limit_target"; + + public const string GetLimitMargin = "get_limit_margin"; + public const string SetLimitMargin = "set_limit_margin"; + + public const string GetAutoZoom = "get_auto_zoom"; + public const string SetAutoZoom = "set_auto_zoom"; + + public const string GetAutoZoomMin = "get_auto_zoom_min"; + public const string SetAutoZoomMin = "set_auto_zoom_min"; + + public const string GetAutoZoomMax = "get_auto_zoom_max"; + public const string SetAutoZoomMax = "set_auto_zoom_max"; + + public const string GetAutoZoomMargin = "get_auto_zoom_margin"; + public const string SetAutoZoomMargin = "set_auto_zoom_margin"; + + public const string GetNoise = "get_noise"; + public const string SetNoise = "set_noise"; + } + + public new static class PropertyName + { + public const string DrawLimits = "draw_limits"; + } +} + +public class LimitTargetQueryResult(GodotObject godotObject) +{ + public bool IsTileMap => godotObject.IsClass("TileMap"); + + public bool IsTileMapLayer => godotObject.IsClass("TileMapLayer"); + + public bool IsCollisionShape2D => godotObject.IsClass("CollisionShape2D"); + + public TileMap? AsTileMap() + { + return IsTileMap ? (TileMap)godotObject : null; + } + + public TileMapLayer? AsTileMapLayer() + { + return IsTileMapLayer ? (TileMapLayer)godotObject : null; + } + + public CollisionShape2D? AsCollisionShape2D() + { + return IsCollisionShape2D ? (CollisionShape2D)godotObject : null; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs.uid b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs.uid new file mode 100644 index 0000000..8cc93f0 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera2D.cs.uid @@ -0,0 +1 @@ +uid://c38e5qhsf3fk3 diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs new file mode 100644 index 0000000..a3081d9 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs @@ -0,0 +1,493 @@ +using System.Linq; +using Godot; +using Godot.Collections; +using PhantomCamera.Noise; + +#nullable enable + +namespace PhantomCamera; + +public enum LookAtMode +{ + None, + Mimic, + Simple, + Group +} + +public enum FollowMode3D +{ + None, + Glued, + Simple, + Group, + Path, + Framed, + ThirdPerson +} + +public enum FollowLockAxis3D +{ + None, + X, + Y, + Z, + XY, + XZ, + YZ, + XYZ +} + +public static class PhantomCamera3DExtensions +{ + public static PhantomCamera3D AsPhantomCamera3D(this Node3D node3D) + { + return new PhantomCamera3D(node3D); + } + + public static PhantomCameraNoiseEmitter3D AsPhantomCameraNoiseEmitter3D(this Node3D node3D) + { + return new PhantomCameraNoiseEmitter3D(node3D); + } + + public static PhantomCameraNoise3D AsPhantomCameraNoise3D(this Resource resource) + { + return new PhantomCameraNoise3D(resource); + } + + public static Camera3DResource AsCamera3DResource(this Resource resource) + { + return new Camera3DResource(resource); + } + + public static Vector3 GetThirdPersonRotation(this PhantomCamera3D pCam3D) => + (Vector3)pCam3D.Node3D.Call(PhantomCamera3D.MethodName.GetThirdPersonRotation); + + public static void SetThirdPersonRotation(this PhantomCamera3D pCam3D, Vector3 rotation) => + pCam3D.Node3D.Call(PhantomCamera3D.MethodName.SetThirdPersonRotation, rotation); + + public static Vector3 GetThirdPersonRotationDegrees(this PhantomCamera3D pCam3D) => + (Vector3)pCam3D.Node3D.Call(PhantomCamera3D.MethodName.GetThirdPersonRotationDegrees); + + public static void SetThirdPersonDegrees(this PhantomCamera3D pCam3D, Vector3 rotation) => + pCam3D.Node3D.Call(PhantomCamera3D.MethodName.SetThirdPersonRotationDegrees, rotation); + + public static Quaternion GetThirdPersonQuaternion(this PhantomCamera3D pCam3D) => + (Quaternion)pCam3D.Node3D.Call(PhantomCamera3D.MethodName.GetThirdPersonQuaternion); + + public static void SetThirdPersonQuaternion(this PhantomCamera3D pCam3D, Quaternion quaternion) => + pCam3D.Node3D.Call(PhantomCamera3D.MethodName.SetThirdPersonQuaternion, quaternion); + +} + +public class PhantomCamera3D : PhantomCamera +{ + public Node3D Node3D => (Node3D)Node; + + public delegate void LookAtTargetChangedEventHandler(); + public delegate void DeadZoneReachedEventHandler(); + public delegate void Camera3DResourceChangedEventHandler(); + public delegate void Camera3DResourcePropertyChangedEventHandler(StringName property, Variant value); + public delegate void TweenInterruptedEventHandler(Node3D pCam); + public delegate void NoiseEmittedEventHandler(Transform3D output); + + public event LookAtTargetChangedEventHandler? LookAtTargetChanged; + public event DeadZoneReachedEventHandler? DeadZoneReached; + public event Camera3DResourceChangedEventHandler? Camera3DResourceChanged; + public event Camera3DResourcePropertyChangedEventHandler? Camera3DResourcePropertyChanged; + public event TweenInterruptedEventHandler? TweenInterrupted; + public event NoiseEmittedEventHandler? NoiseEmitted; + + private readonly Callable _callableLookAtTargetChanged; + private readonly Callable _callableDeadZoneReached; + private readonly Callable _callableCamera3DResourceChanged; + private readonly Callable _callableCamera3DResourcePropertyChanged; + private readonly Callable _callableTweenInterrupted; + private readonly Callable _callableNoiseEmitted; + + public Node3D FollowTarget + { + get => (Node3D)Node3D.Call(PhantomCamera.MethodName.GetFollowTarget); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowTarget, value); + } + + public Node3D[] FollowTargets + { + get => Node3D.Call(PhantomCamera.MethodName.GetFollowTargets).AsGodotArray().ToArray(); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowTargets, new Array(value)); + } + + public void AppendFollowTarget(Node3D target) => Node3D.Call(PhantomCamera.MethodName.AppendFollowTargets, target); + public void AppendFollowTargetArray(Node3D[] targets) => Node3D.Call(PhantomCamera.MethodName.AppendFollowTargetsArray, targets); + public void EraseFollowTarget(Node3D target) => Node3D.Call(PhantomCamera.MethodName.EraseFollowTargets, target); + + public FollowMode3D FollowMode => (FollowMode3D)(int)Node.Call(PhantomCamera.MethodName.GetFollowMode); + + public Path3D FollowPath + { + get => (Path3D)Node3D.Call(PhantomCamera.MethodName.GetFollowPath); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowPath, value); + } + + public Vector3 FollowOffset + { + get => (Vector3)Node3D.Call(PhantomCamera.MethodName.GetFollowOffset); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowOffset, value); + } + + public Vector3 FollowDampingValue + { + get => (Vector3)Node3D.Call(PhantomCamera.MethodName.GetFollowDampingValue); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowDampingValue, value); + } + + public FollowLockAxis3D FollowAxisLock + { + get => (FollowLockAxis3D)(int)Node3D.Call(PhantomCamera.MethodName.GetFollowAxisLock); + set => Node3D.Call(PhantomCamera.MethodName.SetFollowAxisLock, (int)value); + } + + public LookAtMode LookAtMode => (LookAtMode)(int)Node3D.Call(MethodName.GetLookAtMode); + + public Camera3DResource Camera3DResource + { + get => new((Resource)Node3D.Call(MethodName.GetCamera3DResource)); + set => Node3D.Call(MethodName.SetCamera3DResource, value.Resource); + } + + public float SpringLength + { + get => (float)Node3D.Call(MethodName.GetSpringLength); + set => Node3D.Call(MethodName.SetSpringLength, value); + } + + public float VerticalRotationOffset + { + get => (float)Node3D.Call(MethodName.GetVerticalRotationOffset); + set => Node3D.Call(MethodName.SetVerticalRotationOffset, value); + } + + public float HorizontalRotationOffset + { + get => (float)Node3D.Call(MethodName.GetHorizontalRotationOffset); + set => Node3D.Call(MethodName.SetHorizontalRotationOffset, value); + } + + public float FollowDistance + { + get => (float)Node3D.Call(MethodName.GetFollowDistance); + set => Node3D.Call(MethodName.SetFollowDistance, value); + } + + public bool AutoFollowDistance + { + get => (bool)Node3D.Call(MethodName.GetAutoFollowDistance); + set => Node3D.Call(MethodName.SetAutoFollowDistance, value); + } + + public float AutoFollowDistanceMin + { + get => (float)Node3D.Call(MethodName.GetAutoFollowDistanceMin); + set => Node3D.Call(MethodName.SetAutoFollowDistanceMin, value); + } + + public float AutoFollowDistanceMax + { + get => (float)Node3D.Call(MethodName.GetAutoFollowDistanceMax); + set => Node3D.Call(MethodName.SetAutoFollowDistanceMax, value); + } + + public float AutoFollowDistanceDivisor + { + get => (float)Node3D.Call(MethodName.GetAutoFollowDistanceDivisor); + set => Node3D.Call(MethodName.SetAutoFollowDistanceDivisor, value); + } + + public Node3D LookAtTarget + { + get => (Node3D)Node3D.Call(MethodName.GetLookAtTarget); + set => Node3D.Call(MethodName.SetLookAtTarget, value); + } + + public Node3D[] LookAtTargets + { + get => Node3D.Call(MethodName.GetLookAtTargets).AsGodotArray().ToArray(); + set => Node3D.Call(MethodName.SetLookAtTargets, new Array(value)); + } + + public bool IsLooking => (bool)Node3D.Call(MethodName.IsLooking); + + public int CollisionMask + { + get => (int)Node3D.Call(MethodName.GetCollisionMask); + set => Node3D.Call(MethodName.SetCollisionMask, value); + } + + public void SetCollisionMaskValue(int maskLayer, bool enable) => + Node3D.Call(MethodName.SetCollisionMaskValue, maskLayer, enable); + + public Shape3D Shape + { + get => (Shape3D)Node3D.Call(MethodName.GetShape); + set => Node3D.Call(MethodName.SetShape, value); + } + + public float Margin + { + get => (float)Node3D.Call(MethodName.GetMargin); + set => Node3D.Call(MethodName.SetMargin, value); + } + + public Vector3 LookAtOffset + { + get => (Vector3)Node3D.Call(MethodName.GetLookAtOffset); + set => Node3D.Call(MethodName.SetLookAtOffset, value); + } + + public bool LookAtDamping + { + get => (bool)Node3D.Call(MethodName.GetLookAtDamping); + set => Node3D.Call(MethodName.SetLookAtDamping, value); + } + + public float LookAtDampingValue + { + get => (float)Node3D.Call(MethodName.GetLookAtDampingValue); + set => Node3D.Call(MethodName.SetLookAtDampingValue, value); + } + + public Node3D Up + { + get => (Node3D)Node3D.Call(MethodName.GetUp); + set => Node3D.Call(MethodName.SetUp, value); + } + + public Vector3 UpTarget + { + get => (Vector3)Node3D.Call(MethodName.GetUpTarget); + set => Node3D.Call(MethodName.SetUpTarget, value); + } + + public int CullMask + { + get => (int)Node3D.Call(MethodName.GetCullMask); + set => Node3D.Call(MethodName.SetCullMask, value); + } + + public float HOffset + { + get => (float)Node3D.Call(MethodName.GetHOffset); + set => Node3D.Call(MethodName.SetHOffset, value); + } + + public float VOffset + { + get => (float)Node3D.Call(MethodName.GetVOffset); + set => Node3D.Call(MethodName.SetVOffset, value); + } + + public ProjectionType Projection + { + get => (ProjectionType)(int)Node3D.Call(MethodName.GetProjection); + set => Node3D.Call(MethodName.SetProjection, (int)value); + } + + public float Fov + { + get => (float)Node3D.Call(MethodName.GetFov); + set => Node3D.Call(MethodName.SetFov, value); + } + + public float Size + { + get => (float)Node3D.Call(MethodName.GetSize); + set => Node3D.Call(MethodName.SetSize, value); + } + + public Vector2 FrustumOffset + { + get => (Vector2)Node3D.Call(MethodName.GetFrustumOffset); + set => Node3D.Call(MethodName.SetFrustumOffset, value); + } + + public float Far + { + get => (float)Node3D.Call(MethodName.GetFar); + set => Node3D.Call(MethodName.SetFar, value); + } + + public float Near + { + get => (float)Node3D.Call(MethodName.GetNear); + set => Node3D.Call(MethodName.SetNear, value); + } + + public Environment Environment + { + get => (Environment)Node3D.Call(MethodName.GetEnvironment); + set => Node3D.Call(MethodName.SetEnvironment, value); + } + + public CameraAttributes Attributes + { + get => (CameraAttributes)Node3D.Call(MethodName.GetAttributes); + set => Node3D.Call(MethodName.SetAttributes, value); + } + + public PhantomCameraNoise3D Noise + { + get => new((Resource)Node3D.Call(MethodName.GetNoise)); + set => Node3D.Call(MethodName.SetNoise, (GodotObject)value.Resource); + } + + public void EmitNoise(Transform3D transform) => Node3D.Call(PhantomCamera.MethodName.EmitNoise, transform); + + public static PhantomCamera3D FromScript(string path) => new(GD.Load(path).New().AsGodotObject()); + public static PhantomCamera3D FromScript(GDScript script) => new(script.New().AsGodotObject()); + + public PhantomCamera3D(GodotObject phantomCamera3DNode) : base(phantomCamera3DNode) + { + _callableLookAtTargetChanged = Callable.From(() => LookAtTargetChanged?.Invoke()); + _callableDeadZoneReached = Callable.From(() => DeadZoneReached?.Invoke()); + _callableCamera3DResourceChanged = Callable.From(() => Camera3DResourceChanged?.Invoke()); + _callableCamera3DResourcePropertyChanged = Callable.From((StringName property, Variant value) => + Camera3DResourcePropertyChanged?.Invoke(property, value)); + _callableTweenInterrupted = Callable.From(pCam => TweenInterrupted?.Invoke(pCam)); + _callableNoiseEmitted = Callable.From((Transform3D output) => NoiseEmitted?.Invoke(output)); + + Node3D.Connect(SignalName.LookAtTargetChanged, _callableLookAtTargetChanged); + Node3D.Connect(PhantomCamera.SignalName.DeadZoneReached, _callableDeadZoneReached); + Node3D.Connect(SignalName.Camera3DResourceChanged, _callableCamera3DResourceChanged); + Node3D.Connect(SignalName.Camera3DResourcePropertyChanged, _callableCamera3DResourcePropertyChanged); + Node3D.Connect(PhantomCamera.SignalName.TweenInterrupted, _callableTweenInterrupted); + Node3D.Connect(PhantomCamera.SignalName.NoiseEmitted, _callableNoiseEmitted); + } + + ~PhantomCamera3D() + { + Node3D.Disconnect(SignalName.LookAtTargetChanged, _callableLookAtTargetChanged); + Node3D.Disconnect(PhantomCamera.SignalName.DeadZoneReached, _callableDeadZoneReached); + Node3D.Disconnect(SignalName.Camera3DResourceChanged, _callableCamera3DResourceChanged); + Node3D.Disconnect(SignalName.Camera3DResourcePropertyChanged, _callableCamera3DResourcePropertyChanged); + Node3D.Disconnect(PhantomCamera.SignalName.TweenInterrupted, _callableTweenInterrupted); + Node3D.Disconnect(PhantomCamera.SignalName.NoiseEmitted, _callableNoiseEmitted); + } + + public new static class MethodName + { + public const string GetLookAtMode = "get_look_at_mode"; + + public const string GetCamera3DResource = "get_camera_3d_resource"; + public const string SetCamera3DResource = "set_camera_3d_resource"; + + public const string GetThirdPersonRotation = "get_third_person_rotation"; + public const string SetThirdPersonRotation = "set_third_person_rotation"; + + public const string GetThirdPersonRotationDegrees = "get_third_person_rotation_degrees"; + public const string SetThirdPersonRotationDegrees = "set_third_person_rotation_degrees"; + + public const string GetThirdPersonQuaternion = "get_third_person_quaternion"; + public const string SetThirdPersonQuaternion = "set_third_person_quaternion"; + + public const string GetVerticalRotationOffset = "get_vertical_rotation_offset"; + public const string SetVerticalRotationOffset = "set_vertical_rotation_offset"; + + public const string GetHorizontalRotationOffset = "get_horizontal_rotation_offset"; + public const string SetHorizontalRotationOffset = "set_horizontal_rotation_offset"; + + public const string GetSpringLength = "get_spring_length"; + public const string SetSpringLength = "set_spring_length"; + + public const string GetFollowDistance = "get_follow_distance"; + public const string SetFollowDistance = "set_follow_distance"; + + public const string GetAutoFollowDistance = "get_auto_follow_distance"; + public const string SetAutoFollowDistance = "set_auto_follow_distance"; + + public const string GetAutoFollowDistanceMin = "get_auto_follow_distance_min"; + public const string SetAutoFollowDistanceMin = "set_auto_follow_distance_min"; + + public const string GetAutoFollowDistanceMax = "get_auto_follow_distance_max"; + public const string SetAutoFollowDistanceMax = "set_auto_follow_distance_max"; + + public const string GetAutoFollowDistanceDivisor = "get_auto_follow_distance_divisor"; + public const string SetAutoFollowDistanceDivisor = "set_auto_follow_distance_divisor"; + + public const string GetLookAtTarget = "get_look_at_target"; + public const string SetLookAtTarget = "set_look_at_target"; + + public const string GetLookAtTargets = "get_look_at_targets"; + public const string SetLookAtTargets = "set_look_at_targets"; + + public const string IsLooking = "is_looking"; + + public const string GetUp = "get_up"; + public const string SetUp = "set_up"; + + public const string GetUpTarget = "get_up_target"; + public const string SetUpTarget = "set_up_target"; + + public const string GetCollisionMask = "get_collision_mask"; + public const string SetCollisionMask = "set_collision_mask"; + + public const string SetCollisionMaskValue = "set_collision_mask_value"; + + public const string GetShape = "get_shape"; + public const string SetShape = "set_shape"; + + public const string GetMargin = "get_margin"; + public const string SetMargin = "set_margin"; + + public const string GetLookAtOffset = "get_look_at_offset"; + public const string SetLookAtOffset = "set_look_at_offset"; + + public const string GetLookAtDamping = "get_look_at_damping"; + public const string SetLookAtDamping = "set_look_at_damping"; + + public const string GetLookAtDampingValue = "get_look_at_damping_value"; + public const string SetLookAtDampingValue = "set_look_at_damping_value"; + + public const string GetCullMask = "get_cull_mask"; + public const string SetCullMask = "set_cull_mask"; + + public const string GetHOffset = "get_h_offset"; + public const string SetHOffset = "set_h_offset"; + + public const string GetVOffset = "get_v_offset"; + public const string SetVOffset = "set_v_offset"; + + public const string GetProjection = "get_projection"; + public const string SetProjection = "set_projection"; + + public const string GetFov = "get_fov"; + public const string SetFov = "set_fov"; + + public const string GetSize = "get_size"; + public const string SetSize = "set_size"; + + public const string GetFrustumOffset = "get_frustum_offset"; + public const string SetFrustumOffset = "set_frustum_offset"; + + public const string GetFar = "get_far"; + public const string SetFar = "set_far"; + + public const string GetNear = "get_near"; + public const string SetNear = "set_near"; + + public const string GetEnvironment = "get_environment"; + public const string SetEnvironment = "set_environment"; + + public const string GetAttributes = "get_attributes"; + public const string SetAttributes = "set_attributes"; + + public const string GetNoise = "get_noise"; + public const string SetNoise = "set_noise"; + } + + public new static class SignalName + { + public const string LookAtTargetChanged = "look_at_target_changed"; + public const string Camera3DResourceChanged = "camera_3d_resource_changed"; + public const string Camera3DResourcePropertyChanged = "camera_3d_resource_property_changed"; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs.uid b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs.uid new file mode 100644 index 0000000..c1f0801 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCamera3D.cs.uid @@ -0,0 +1 @@ +uid://bx3g7jxtwhi04 diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs new file mode 100644 index 0000000..1e73b57 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs @@ -0,0 +1,83 @@ +using Godot; + +namespace PhantomCamera.Noise; + +public class PhantomCameraNoiseEmitter2D(GodotObject node) +{ + public Node2D Node2D = (Node2D)node; + + public PhantomCameraNoise2D Noise + { + get => new((Resource)Node2D.Call(MethodName.GetNoise)); + set => Node2D.Call(MethodName.SetNoise, (GodotObject)value.Resource); + } + + public bool Continuous + { + get => (bool)Node2D.Call(MethodName.GetContinuous); + set => Node2D.Call(MethodName.SetContinuous, value); + } + + public float GrowthTime + { + get => (float)Node2D.Call(MethodName.GetGrowthTime); + set => Node2D.Call(MethodName.SetGrowthTime, value); + } + + public float Duration + { + get => (float)Node2D.Call(MethodName.GetDuration); + set => Node2D.Call(MethodName.SetDuration, value); + } + + public float DecayTime + { + get => (float)Node2D.Call(MethodName.GetDecayTime); + set => Node2D.Call(MethodName.SetDecayTime, value); + } + + public int NoiseEmitterLayer + { + get => (int)Node2D.Call(MethodName.GetNoiseEmitterLayer); + set => Node2D.Call(MethodName.SetNoiseEmitterLayer, value); + } + + public void SetNoiseEmitterLayerValue(int layer, bool value) => + Node2D.Call(MethodName.SetNoiseEmitterLayerValue, layer, value); + + public void Emit() => Node2D.Call(MethodName.Emit); + + public bool IsEmitting() => (bool)Node2D.Call(MethodName.IsEmitting); + + public void Stop() => Node2D.Call(MethodName.Stop); + + public void Toggle() => Node2D.Call(MethodName.Toggle); + + public static class MethodName + { + public const string GetNoise = "get_noise"; + public const string SetNoise = "set_noise"; + + public const string GetContinuous = "get_continuous"; + public const string SetContinuous = "set_continuous"; + + public const string GetGrowthTime = "get_growth_time"; + public const string SetGrowthTime = "set_growth_time"; + + public const string GetDuration = "get_duration"; + public const string SetDuration = "set_duration"; + + public const string GetDecayTime = "get_decay_time"; + public const string SetDecayTime = "set_decay_time"; + + public const string GetNoiseEmitterLayer = "get_noise_emitter_layer"; + public const string SetNoiseEmitterLayer = "set_noise_emitter_layer"; + + public const string SetNoiseEmitterLayerValue = "set_noise_emitter_layer_value"; + + public const string Emit = "emit"; + public const string IsEmitting = "is_emitting"; + public const string Stop = "stop"; + public const string Toggle = "toggle"; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs.uid b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs.uid new file mode 100644 index 0000000..4f35145 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter2D.cs.uid @@ -0,0 +1 @@ +uid://btom8l3wlkn2j diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs new file mode 100644 index 0000000..18620b2 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs @@ -0,0 +1,83 @@ +using Godot; + +namespace PhantomCamera.Noise; + +public class PhantomCameraNoiseEmitter3D(GodotObject node) +{ + public Node3D Node3D = (Node3D)node; + + public PhantomCameraNoise3D Noise + { + get => new((Resource)Node3D.Call(MethodName.GetNoise)); + set => Node3D.Call(MethodName.SetNoise, (GodotObject)value.Resource); + } + + public bool Continuous + { + get => (bool)Node3D.Call(MethodName.GetContinuous); + set => Node3D.Call(MethodName.SetContinuous, value); + } + + public float GrowthTime + { + get => (float)Node3D.Call(MethodName.GetGrowthTime); + set => Node3D.Call(MethodName.SetGrowthTime, value); + } + + public float Duration + { + get => (float)Node3D.Call(MethodName.GetDuration); + set => Node3D.Call(MethodName.SetDuration, value); + } + + public float DecayTime + { + get => (float)Node3D.Call(MethodName.GetDecayTime); + set => Node3D.Call(MethodName.SetDecayTime, value); + } + + public int NoiseEmitterLayer + { + get => (int)Node3D.Call(MethodName.GetNoiseEmitterLayer); + set => Node3D.Call(MethodName.SetNoiseEmitterLayer, value); + } + + public void SetNoiseEmitterLayerValue(int layer, bool value) => + Node3D.Call(MethodName.SetNoiseEmitterLayerValue, layer, value); + + public void Emit() => Node3D.Call(MethodName.Emit); + + public bool IsEmitting() => (bool)Node3D.Call(MethodName.IsEmitting); + + public void Stop() => Node3D.Call(MethodName.Stop); + + public void Toggle() => Node3D.Call(MethodName.Toggle); + + public static class MethodName + { + public const string GetNoise = "get_noise"; + public const string SetNoise = "set_noise"; + + public const string GetContinuous = "get_continuous"; + public const string SetContinuous = "set_continuous"; + + public const string GetGrowthTime = "get_growth_time"; + public const string SetGrowthTime = "set_growth_time"; + + public const string GetDuration = "get_duration"; + public const string SetDuration = "set_duration"; + + public const string GetDecayTime = "get_decay_time"; + public const string SetDecayTime = "set_decay_time"; + + public const string GetNoiseEmitterLayer = "get_noise_emitter_layer"; + public const string SetNoiseEmitterLayer = "set_noise_emitter_layer"; + + public const string SetNoiseEmitterLayerValue = "set_noise_emitter_layer_value"; + + public const string Emit = "emit"; + public const string IsEmitting = "is_emitting"; + public const string Stop = "stop"; + public const string Toggle = "toggle"; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs.uid b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs.uid new file mode 100644 index 0000000..bf32a5b --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/PhantomCameraNoiseEmitter3D.cs.uid @@ -0,0 +1 @@ +uid://buvda14filkjx diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd new file mode 100644 index 0000000..966c580 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd @@ -0,0 +1,1726 @@ +@tool +@icon("res://addons/phantom_camera/icons/phantom_camera_2d.svg") +class_name PhantomCamera2D +extends Node2D + +## Controls a scene's [Camera2D] and applies logic to it. +## +## The scene's [param Camera2D] will follow the position of the +## [param PhantomCamera2D] with the highest priority. +## Each instance can have different positional and rotational logic applied +## to them. + +#region Constants + +const _constants := preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") + +#endregion + +#region Signals + +## Emitted when the [param PhantomCamera2D] becomes active. +signal became_active + +## Emitted when the [param PhantomCamera2D] becomes inactive. +signal became_inactive + +## Emitted when the follow_mode changes. +## Note: This is for internal use only +signal follow_mode_changed + +## Emitted when [member follow_target] changes. +signal follow_target_changed + +## Emitted when dead zones changes.[br] +## [b]Note:[/b] Only applicable in [param Framed] [enum FollowMode]. +signal dead_zone_changed + +## Emitted when a target touches the edge of the dead zone in [param Framed] [enum FollowMode]. +signal dead_zone_reached(side: Vector2) + +## Emitted when the [param Camera2D] starts to tween to another [param PhantomCamera2D]. +signal tween_started + +## Emitted when the [param Camera2D] is to tweening towards another [param PhantomCamera2D]. +signal is_tweening + +## Emitted when the tween is interrupted due to another [param PhantomCamera2D] +## becoming active. The argument is the [param PhantomCamera2D] that interrupted +## the tween. +signal tween_interrupted(pcam_2d: PhantomCamera2D) + +## Emitted when the [param Camera2D] completes its tween to the +## [param PhantomCamera2D]. +signal tween_completed + +## Emitted when Noise should be applied to the Camera2D. +signal noise_emitted(noise_output: Transform2D) + +signal physics_target_changed + +#endregion + +#region Enums + +## Determines the positional logic for a given [param PhantomCamera2D] +## [br][br] +## The different modes have different functionalities and purposes, so choosing +## the correct one depends on what each [param PhantomCamera2D] is meant to do. +enum FollowMode { + NONE = 0, ## Default - No follow logic is applied. + GLUED = 1, ## Sticks to its target. + SIMPLE = 2, ## Follows its target with an optional offset. + GROUP = 3, ## Follows multiple targets with option to dynamically reframe itself. + PATH = 4, ## Follows a target while being positionally confined to a [Path2D] node. + FRAMED = 5, ## Applies a dead zone on the frame and only follows its target when it tries to leave it. +} + +## Determines how often an inactive [param PhantomCamera2D] should update +## its positional and rotational values. This is meant to reduce the amount +## of calculations inactive [param PhantomCamera2D] are doing when idling to +## improve performance. +enum InactiveUpdateMode { + ALWAYS, ## Always updates the [param PhantomCamera2D], even when it's inactive. + NEVER, ## Never updates the [param PhantomCamera2D] when it's inactive. Reduces the amount of computational resources when inactive. +# EXPONENTIALLY, +} + +enum FollowLockAxis { + NONE = 0, + X = 1, + Y = 2, + XY = 3, +} + +#endregion + +#region Exported Properties + +## To quickly preview a [param PhantomCamera2D] without adjusting its +## [member priority], this property allows the selected PCam to ignore the +## Priority system altogether and forcefully become the active one. It's +## partly designed to work within the Viewfinder, and will be disabled when +## running a build export of the game. +@export var priority_override: bool = false: + set(value): + priority_override = value + if Engine.is_editor_hint(): + if value: + if not Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): return + Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME).pcam_priority_override.emit(self, true) + else: + if not Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): return + Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME).pcam_priority_override.emit(self, false) + get: + return priority_override + + +## It defines which [param PhantomCamera2D] a scene's [param Camera2D] should +## be corresponding with and be attached to. This is decided by the PCam with +## the highest [param Priority]. +## [br][br] +## Changing [param Priority] will send an event to the scene's +## [PhantomCameraHost], which will then determine whether if the +## [param Priority] value is greater than or equal to the currently +## highest [param PhantomCamera2D]'s in the scene. The [param PhantomCamera2D] +## with the highest value will then reattach the [param Camera2D] accordingly. +@export var priority: int = 0: + set = set_priority, + get = get_priority + + +## Determines the positional logic for a given [param PhantomCamera2D]. +## The different modes have different functionalities and purposes, so +## choosing the correct one depends on what each [param PhantomCamera2D] +## is meant to do. +@export var follow_mode: FollowMode = FollowMode.NONE: + set(value): + follow_mode = value + + if follow_mode == FollowMode.NONE: + _should_follow = false + top_level = false + _is_parents_physics() + notify_property_list_changed() + return + + match follow_mode: + FollowMode.PATH: + if is_instance_valid(follow_path): + _should_follow_checker() + else: + _should_follow = false + FollowMode.GROUP: + _follow_targets_size_check() + _: + _should_follow_checker() + + if follow_mode == FollowMode.FRAMED: + if _follow_framed_initial_set and follow_target: + _follow_framed_initial_set = false + dead_zone_changed.connect(_on_dead_zone_changed) + else: + if dead_zone_changed.is_connected(_on_dead_zone_changed): + dead_zone_changed.disconnect(_on_dead_zone_changed) + + top_level = true + follow_mode_changed.emit() + notify_property_list_changed() + get: + return follow_mode + +## Determines which target should be followed. +## The [param Camera2D] will follow the position of the Follow Target +## based on the [member follow_mode] type and its parameters. +@export var follow_target: Node2D = null: + set = set_follow_target, + get = get_follow_target + +### Defines the targets that the [param PhantomCamera2D] should be following. +@export var follow_targets: Array[Node2D] = []: + set = set_follow_targets, + get = get_follow_targets + +## Determines the [Path2D] the [param PhantomCamera2D] +## should be bound to. +## The [param PhantomCamera2D] will follow the position of the +## [member follow_target] while sticking to the closest point on this path. +@export var follow_path: Path2D = null: + set = set_follow_path, + get = get_follow_path + + +## Applies a zoom level to the [param PhantomCamera2D], which effectively +## overrides the [param zoom] property of the [param Camera2D] node. +@export_custom(PROPERTY_HINT_LINK, "") var zoom: Vector2 = Vector2.ONE: + set = set_zoom, + get = get_zoom + + +## If enabled, will snap the [param Camera2D] to whole pixels as it moves. +## [br][br] +## This should be particularly useful in pixel art projects, +## where assets should always be aligned to the monitor's pixels to avoid +## unintended stretching. +@export var snap_to_pixel: bool = false: + set = set_snap_to_pixel, + get = get_snap_to_pixel + + +## Enables a preview of what the [PhantomCamera2D] will see in the +## scene. It works identically to how a [param Camera2D] shows which area +## will be visible during runtime. Likewise, this too will be affected by the +## [member zoom] property and the [param viewport_width] and +## [param Viewport Height] defined in the [param Project Settings]. +@export var frame_preview: bool = true: + set(value): + frame_preview = value + queue_redraw() + get: + return frame_preview + + +## Defines how the [param PhantomCamera2D] transition between one another. +## Changing the tween values for a given [param PhantomCamera2D] +## determines how transitioning to that instance will look like. +## This is a resource type that can be either used for one +## [param PhantomCamera] or reused across multiple - both 2D and 3D. +## By default, all [param PhantomCameras] will use a [param linear] +## transition, [param easeInOut] ease with a [param 1s] duration. +@export var tween_resource: PhantomCameraTween = PhantomCameraTween.new(): + set = set_tween_resource, + get = get_tween_resource + +## If enabled, the moment a [param PhantomCamera2D] is instantiated into +## a scene, and has the highest priority, it will perform its tween transition. +## This is most obvious if a [param PhantomCamera2D] has a long duration and +## is attached to a playable character that can be moved the moment a scene +## is loaded. Disabling the [param tween_on_load] property will +## disable this behaviour and skip the tweening entirely when instantiated. +@export var tween_on_load: bool = true: + set = set_tween_on_load, + get = get_tween_on_load + + +## Determines how often an inactive [param PhantomCamera2D] should update +## its positional and rotational values. This is meant to reduce the amount +## of calculations inactive [param PhantomCamera2Ds] are doing when idling +## to improve performance. +@export var inactive_update_mode: InactiveUpdateMode = InactiveUpdateMode.ALWAYS + + +## Determines which layers this [param PhantomCamera2D] should be able to communicate with [PhantomCameraHost] nodes.[br] +## A corresponding layer needs to be set on the [PhantomCameraHost] node. +@export_flags_2d_render var host_layers: int = 1: + set = set_host_layers, + get = get_host_layers + + +@export_group("Follow Parameters") +## Offsets the [member follow_target] position. +@export var follow_offset: Vector2 = Vector2.ZERO: + set = set_follow_offset, + get = get_follow_offset + +## Applies a damping effect on the [param Camera2D]'s movement. +## Leading to heavier / slower camera movement as the targeted node moves around. +## This is useful to avoid sharp and rapid camera movement. +@export var follow_damping: bool = false: + set = set_follow_damping, + get = get_follow_damping + +## Defines the damping amount. The ideal range should be somewhere between 0-1.[br][br] +## The damping amount can be specified in the individual axis.[br][br] +## [b]Lower value[/b] = faster / sharper camera movement.[br] +## [b]Higher value[/b] = slower / heavier camera movement. +@export_custom(PROPERTY_HINT_LINK, "") +var follow_damping_value: Vector2 = Vector2(0.1, 0.1): + set = set_follow_damping_value, + get = get_follow_damping_value + +## Prevents the [param PhantomCamera2D] from moving in a designated axis. +## This can be enabled or disabled at runtime or from the editor directly. +@export var follow_axis_lock: FollowLockAxis = FollowLockAxis.NONE: + set = set_lock_axis, + get = get_lock_axis +var _follow_axis_is_locked: bool = false +var _follow_axis_lock_value: Vector2 = Vector2.ZERO + +## Makes the [param PhantomCamera2D] copy the rotation of its [member follow_target][br] +## This behavior is only available when [member follow_mode] is set and only has one [member follow_target].[br][br] +## [b]Important:[/b] Be sure to disable [member Camera2D.ignore_rotation] on the [Camera2D] node to enable this feature. +@export var rotate_with_target: bool = false: + set = set_rotate_with_target, + get = get_rotate_with_target +var _should_rotate_with_target: bool = false + +## Offsets the rotation when [member rotate_with_target] is enabled. +@export_range(-360, 360, 0.001, "radians_as_degrees") var rotation_offset: float = 0: + set = set_rotation_offset, + get = get_rotation_offset + +## Enables rotational damping when [member rotate_with_target] is enabled. +@export var rotation_damping: bool = false: + set = set_rotation_damping, + get = get_rotation_damping + +## Defines the damping amount for the [member rotate_with_target]. +@export_range(0, 1) var rotation_damping_value: float = 0.1: + set = set_rotation_damping_value, + get = get_rotation_damping_value + + +@export_subgroup("Follow Group") +## Enables the [param PhantomCamera2D] to dynamically zoom in and out based on +## the targets' distances between each other. +## Once enabled, the [param Camera2D] will stay as zoomed in as possible, +## limited by the [member auto_zoom_max] and start zooming out as the targets +## move further apart, limited by the [member auto_zoom_min]. +## Note: Enabling this property hides and disables the [member zoom] property +## as this effectively overrides that value. +@export var auto_zoom: bool = false: + set = set_auto_zoom, + get = get_auto_zoom + +## Sets the param minimum zoom amount, in other words how far away the +## [param Camera2D] can be from scene.[br][br] +## This only works when [member auto_zoom] is enabled. +@export var auto_zoom_min: float = 1: + set = set_auto_zoom_min, + get = get_auto_zoom_min + +## Sets the maximum zoom amount, in other words how close the [param Camera2D] +## can move towards the scene.[br][br] +## This only works when [member auto_zoom] is enabled. +@export var auto_zoom_max: float = 5: + set = set_auto_zoom_max, + get = get_auto_zoom_max + +## Determines how close to the edges the targets are allowed to be. +## This is useful to avoid targets being cut off at the edges of the screen. +## [br][br] +## The Vector4 parameter order goes: [param Left] - [param Top] - [param Right] +## - [param Bottom]. +@export var auto_zoom_margin: Vector4 = Vector4.ZERO: + set = set_auto_zoom_margin, + get = get_auto_zoom_margin + + +@export_subgroup("Dead Zones") +## Defines the horizontal dead zone area. While the target is within it, the +## [param PhantomCamera2D] will not move in the horizontal axis. +## If the targeted node leaves the horizontal bounds, the +## [param PhantomCamera2D] will follow the target horizontally to keep +## it within bounds. +@export_range(0, 1) var dead_zone_width: float = 0: + set(value): + dead_zone_width = value + dead_zone_changed.emit() + get: + return dead_zone_width + +## Defines the vertical dead zone area. While the target is within it, the +## [param PhantomCamera2D] will not move in the vertical axis. +## If the targeted node leaves the vertical bounds, the +## [param PhantomCamera2D] will follow the target horizontally to keep +## it within bounds. +@export_range(0, 1) var dead_zone_height: float = 0: + set(value): + dead_zone_height = value + dead_zone_changed.emit() + get: + return dead_zone_height + +## Enables the [param dead zones] to be visible when running the game from the editor. +## [br] +## [param dead zones] will never be visible in build exports. +@export var show_viewfinder_in_play: bool = false + + +@export_group("Limit") + +## Shows the [param Camera2D]'s built-in limit border.[br] +## The [param PhantomCamera2D] and [param Camera2D] can move around anywhere within it. +@export var draw_limits: bool = false: + set(value): + _draw_limits = value + if Engine.is_editor_hint(): + _draw_camera_2d_limit() + get: + return _draw_limits + +## Defines the left side of the [param Camera2D] limit. +## The camera will not be able to move past this point. +@export var limit_left: int = -10000000: + set = set_limit_left, + get = get_limit_left +## Defines the top side of the [param Camera2D] limit. +## The camera will not be able to move past this point. +@export var limit_top: int = -10000000: + set = set_limit_top, + get = get_limit_top +## Defines the right side of the [param Camera2D] limit. +## The camera will not be able to move past this point. +@export var limit_right: int = 10000000: + set = set_limit_right, + get = get_limit_right +## Defines the bottom side of the [param Camera2D] limit. +## The camera will not be able to move past this point. +@export var limit_bottom: int = 10000000: + set = set_limit_bottom, + get = get_limit_bottom + +## Allows for setting either a [TileMap], [TileMapLayer] or [CollisionShape2D] node to +## automatically apply a limit size instead of manually adjusting the Left, +## Top, Right and Left properties.[br][br] +## [b]TileMap / TileMapLayer[/b][br] +## The Limit will update after the [TileSet] of the [TileMap] / [TileMapLayer] has changed.[br] +## [b]Note:[/b] The limit size will only update after closing the TileMap editor +## bottom panel. +## [br][br] +## [b]CollisionShape2D[/b][br] +## The limit will update in realtime as the Shape2D changes its size. +## Note: For performance reasons, resizing the [Shape2D] during runtime will not change the Limits sides. +@export_node_path("TileMap", "Node2D", "CollisionShape2D") var limit_target: NodePath = NodePath(""): + set = set_limit_target, + get = get_limit_target + +## Applies an offset to the [TileMap]/[TileMapLayer] Limit or [Shape2D] Limit. +## The values goes from [param Left], [param Top], [param Right] +## and [param Bottom]. +@export var limit_margin: Vector4i = Vector4.ZERO: + set = set_limit_margin, + get = get_limit_margin +#@export var limit_smoothed: bool = false: # TODO - Needs proper support + #set = set_limit_smoothing, + #get = get_limit_smoothing + +@export_group("Noise") +## Applies a noise, or shake, to a [Camera2D].[br] +## Once set, the noise will run continuously after the tween to the [PhantomCamera2D] is complete. +@export var noise: PhantomCameraNoise2D = null: + set = set_noise, + get = get_noise + +## If true, will trigger the noise while in the editor.[br] +## Useful in cases where you want to temporarily disable the noise in the editor without removing +## the resource.[br][br] +## [b]Note:[/b] This property has no effect on runtime behaviour. +@export var _preview_noise: bool = true: + set(value): + _preview_noise = value + if not value: + _transform_noise = Transform2D() + +## Enable a corresponding layer for a [member PhantomCameraNoiseEmitter2D.noise_emitter_layer] +## to make this [PhantomCamera2D] be affect by it. +@export_flags_2d_render var noise_emitter_layer: int = 0: + set = set_noise_emitter_layer, + get = get_noise_emitter_layer + +#region Private Variables + +var _is_active: bool = false + +var _should_follow: bool = false +var _follow_framed_offset: Vector2 = Vector2.ZERO +var _follow_target_physics_based: bool = false +var _physics_interpolation_enabled: bool = false # NOTE - Enable for Godot 4.3 and when PhysicsInterpolationMode bug is resolved + +var _has_multiple_follow_targets: bool = false +var _follow_targets_single_target_index: int = 0 +var _follow_targets: Array[Node2D] = [] + +var _follow_velocity_ref: Vector2 = Vector2.ZERO # Stores and applies the velocity of the follow movement +var _rotation_velocity_ref: float = 0 # Stores and applies the velocity of the rotation movement + +var _has_follow_path: bool = false + +var _tween_skip: bool = false + +## Defines the position of the [member follow_target] within the viewport.[br] +## This is only used for when [member follow_mode] is set to [param Framed]. +var _follow_framed_initial_set: bool = false + +static var _draw_limits: bool = false + +var _limit_sides: Vector4i = _limit_sides_default +var _limit_sides_default: Vector4i = Vector4i(-10000000, -10000000, 10000000, 10000000) + +var _limit_node: Node2D = null +var _tile_size_perspective_scaler: Vector2 = Vector2.ONE + +var _limit_inactive_pcam: bool = false + +var _follow_target_position: Vector2 = Vector2.ZERO + +var _transform_output: Transform2D = Transform2D() +var _transform_noise: Transform2D = Transform2D() + +var _has_noise_resource: bool = false + +# NOTE - Temp solution until Godot has better plugin autoload recognition out-of-the-box. +var _phantom_camera_manager: Node = null + +#endregion + +#region Public Variables + +var tween_duration: float: + set = set_tween_duration, + get = get_tween_duration +var tween_transition: PhantomCameraTween.TransitionType: + set = set_tween_transition, + get = get_tween_transition +var tween_ease: PhantomCameraTween.EaseType: + set = set_tween_ease, + get = get_tween_ease + +var viewport_position: Vector2 + +#endregion + +#region Private Functions + +func _validate_property(property: Dictionary) -> void: + ################ + ## Follow Target + ################ + if property.name == "follow_target": + if follow_mode == FollowMode.NONE or \ + follow_mode == FollowMode.GROUP: + property.usage = PROPERTY_USAGE_NO_EDITOR + + elif property.name == "follow_path" and \ + follow_mode != FollowMode.PATH: + property.usage = PROPERTY_USAGE_NO_EDITOR + + + #################### + ## Follow Parameters + #################### + if follow_mode == FollowMode.NONE: + match property.name: + "follow_offset", \ + "follow_damping", \ + "follow_damping_value", \ + "follow_axis_lock", \ + "rotate_with_target": + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "follow_offset": + if follow_mode == FollowMode.PATH or \ + follow_mode == FollowMode.GLUED: + property.usage = PROPERTY_USAGE_NO_EDITOR + + + ############### + ## Follow Group + ############### + if follow_mode != FollowMode.GROUP: + match property.name: + "follow_targets", \ + "auto_zoom": + property.usage = PROPERTY_USAGE_NO_EDITOR + + if not auto_zoom or follow_mode != FollowMode.GROUP: + match property.name: + "auto_zoom_min", \ + "auto_zoom_max", \ + "auto_zoom_margin": + property.usage = PROPERTY_USAGE_NO_EDITOR + + ################ + ## Follow Framed + ################ + if not follow_mode == FollowMode.FRAMED: + match property.name: + "dead_zone_width", \ + "dead_zone_height", \ + "show_viewfinder_in_play": + property.usage = PROPERTY_USAGE_NO_EDITOR + + + ##################### + ## Rotate With Target + ##################### + if property.name == "rotate_with_target" and follow_mode == FollowMode.GROUP: + property.usage = PROPERTY_USAGE_NO_EDITOR + + + if not rotate_with_target or follow_mode == FollowMode.GROUP: + match property.name: + "rotation_damping", \ + "rotation_offset", \ + "rotation_damping_value": + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "rotation_damping_value": + if not rotation_damping: + property.usage = PROPERTY_USAGE_NO_EDITOR + + + ####### + ## Zoom + ####### + if property.name == "zoom" and follow_mode == FollowMode.GROUP and auto_zoom: + property.usage = PROPERTY_USAGE_NO_EDITOR + + ######## + ## Limit + ######## + if is_instance_valid(_limit_node): + match property.name: + "limit_left", \ + "limit_top", \ + "limit_right", \ + "limit_bottom": + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "limit_margin" and not _limit_node: + property.usage = PROPERTY_USAGE_NO_EDITOR + + +func _enter_tree() -> void: + _phantom_camera_manager = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME) + _tween_skip = !tween_on_load + + _phantom_camera_manager.pcam_added(self) + + priority_override = false + + match follow_mode: + FollowMode.NONE: + _is_parents_physics() + FollowMode.PATH: + if is_instance_valid(follow_path): + _should_follow_checker() + else: + _should_follow = false + FollowMode.GROUP: + _follow_targets_size_check() + _should_follow_checker() + _: + _should_follow_checker() + + if not visibility_changed.is_connected(_check_visibility): + visibility_changed.connect(_check_visibility) + + update_limit_all_sides() + + + +func _exit_tree() -> void: + if not follow_mode == FollowMode.GROUP: + follow_targets = [] + + if not is_instance_valid(_phantom_camera_manager): return + _phantom_camera_manager.pcam_removed(self) + + +func _ready() -> void: + if is_instance_valid(follow_target): + _transform_output.origin = _get_target_position_offset() + else: + _transform_output = global_transform + + _phantom_camera_manager.noise_2d_emitted.connect(_noise_emitted) + + if not Engine.is_editor_hint(): + _preview_noise = true + + if follow_mode == FollowMode.GROUP: + _follow_targets_size_check() + + +func _process(delta: float) -> void: + if _follow_target_physics_based or _is_active: return + process_logic(delta) + + +func _physics_process(delta: float) -> void: + if not _follow_target_physics_based or _is_active: return + process_logic(delta) + + +func process_logic(delta: float) -> void: + if _is_active: + if _has_noise_resource and _preview_noise: + _transform_noise = noise.get_noise_transform(delta) + else: + match inactive_update_mode: + InactiveUpdateMode.NEVER: return + InactiveUpdateMode.ALWAYS: + # Only triggers if limit isn't default + if _limit_inactive_pcam: + global_position = _set_limit_clamp_position(global_position) + # InactiveUpdateMode.EXPONENTIALLY: + # TODO - Trigger positional updates less frequently as more PCams gets added + + _limit_checker() + + if _should_follow: + _follow(delta) + else: + _transform_output = global_transform + + if _follow_axis_is_locked: + match follow_axis_lock: + FollowLockAxis.X: + _transform_output.origin.x = _follow_axis_lock_value.x + FollowLockAxis.Y: + _transform_output.origin.y = _follow_axis_lock_value.y + FollowLockAxis.XY: + _transform_output.origin.x = _follow_axis_lock_value.x + _transform_output.origin.y = _follow_axis_lock_value.y + + +func _limit_checker() -> void: + ## TODO - Needs to see if this can be triggerd only from CollisionShape2D Transform changes + if not Engine.is_editor_hint(): return + if draw_limits: + update_limit_all_sides() + + +func _follow(delta: float) -> void: + _set_follow_position() + _interpolate_position(_follow_target_position, delta) + + +func _set_follow_position() -> void: + match follow_mode: + FollowMode.GLUED: + _follow_target_position = follow_target.global_position + + FollowMode.SIMPLE: + _follow_target_position = _get_target_position_offset() + + FollowMode.GROUP: + if _has_multiple_follow_targets: + var rect: Rect2 = Rect2(_follow_targets[0].global_position, Vector2.ZERO) + for target in _follow_targets: + rect = rect.expand(target.global_position) + if auto_zoom: + rect = rect.grow_individual( + auto_zoom_margin.x, + auto_zoom_margin.y, + auto_zoom_margin.z, + auto_zoom_margin.w + ) + + if rect.size.x > rect.size.y * _phantom_camera_manager.screen_size.aspect(): + zoom = clamp(_phantom_camera_manager.screen_size.x / rect.size.x, auto_zoom_min, auto_zoom_max) * Vector2.ONE + else: + zoom = clamp(_phantom_camera_manager.screen_size.y / rect.size.y, auto_zoom_min, auto_zoom_max) * Vector2.ONE + _follow_target_position = rect.get_center() + follow_offset + else: + _follow_target_position = follow_targets[_follow_targets_single_target_index].global_position + follow_offset + + FollowMode.PATH: + var path_position: Vector2 = follow_path.global_position + + _follow_target_position = \ + follow_path.curve.get_closest_point( + _get_target_position_offset() - path_position + ) + path_position + + FollowMode.FRAMED: + if not Engine.is_editor_hint(): + if not _is_active: + _follow_target_position = _get_target_position_offset() + else: + viewport_position = (get_follow_target().get_global_transform_with_canvas().get_origin() + follow_offset) / get_viewport_rect().size + var framed_side_offset: Vector2 = _get_framed_side_offset() + + if framed_side_offset != Vector2.ZERO: + var glo_pos: Vector2 + var target_position: Vector2 = _get_target_position_offset() + _follow_framed_offset + + if dead_zone_width == 0 || dead_zone_height == 0: + if dead_zone_width == 0 && dead_zone_height != 0: + _follow_target_position = _get_target_position_offset() + elif dead_zone_width != 0 && dead_zone_height == 0: + glo_pos = _get_target_position_offset() + glo_pos.x += target_position.x - global_position.x + _follow_target_position = glo_pos + else: + _follow_target_position = _get_target_position_offset() + + # If a horizontal dead zone is reached + if framed_side_offset.x != 0 and framed_side_offset.y == 0: + _follow_target_position.y = _transform_output.origin.y + _follow_target_position.x = target_position.x + _follow_framed_offset.y = global_position.y - _get_target_position_offset().y + dead_zone_reached.emit(Vector2(framed_side_offset.x, 0)) + # If a vertical dead zone is reached + elif framed_side_offset.x == 0 and framed_side_offset.y != 0: + _follow_target_position.x = _transform_output.origin.x + _follow_target_position.y = target_position.y + _follow_framed_offset.x = global_position.x - _get_target_position_offset().x + dead_zone_reached.emit(Vector2(0, framed_side_offset.y)) + # If a deadzone corner is reached + else: + _follow_target_position = target_position + dead_zone_reached.emit(Vector2(framed_side_offset.x, framed_side_offset.y)) + else: + _follow_framed_offset = _transform_output.origin - _get_target_position_offset() + return + else: + _follow_target_position = _get_target_position_offset() + + +func _set_follow_velocity(index: int, value: float): + _follow_velocity_ref[index] = value + +func _set_rotation_velocity(index: int, value: float): + _rotation_velocity_ref = value + +func _interpolate_position(target_position: Vector2, delta: float) -> void: + var output_rotation: float = global_transform.get_rotation() + if rotate_with_target: + if rotation_damping and not Engine.is_editor_hint(): + output_rotation = _smooth_damp( + follow_target.get_rotation() + rotation_offset, + _transform_output.get_rotation(), + 0, + _rotation_velocity_ref, + _set_rotation_velocity, + rotation_damping_value, + delta + ) + else: + output_rotation = follow_target.get_rotation() + rotation_offset + + if _limit_inactive_pcam and not _tween_skip: + target_position = _set_limit_clamp_position(target_position) + + global_position = target_position + + if follow_damping and not Engine.is_editor_hint(): + var output_position: Vector2 + for i in 2: + output_position[i] = _smooth_damp( + global_position[i], + _transform_output.origin[i], + i, + _follow_velocity_ref[i], + _set_follow_velocity, + follow_damping_value[i], + delta + ) + _transform_output = Transform2D(output_rotation, output_position) + else: + _transform_output = Transform2D(output_rotation, target_position) + + +func _smooth_damp(target_axis: float, self_axis: float, index: int, current_velocity: float, set_velocity: Callable, damping_time: float, delta: float) -> float: + damping_time = maxf(0.0001, damping_time) + var omega: float = 2 / damping_time + var x: float = omega * delta + var exponential: float = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x) + var diff: float = self_axis - target_axis + var _target_axis: float = target_axis + + var max_change: float = INF * damping_time + diff = clampf(diff, -max_change, max_change) + target_axis = self_axis - diff + + var temp: float = (current_velocity + omega * diff) * delta + set_velocity.call(index, (current_velocity - omega * temp) * exponential) + var output: float = target_axis + (diff + temp) * exponential + + ## To prevent overshooting + if (_target_axis - self_axis > 0.0) == (output > _target_axis): + output = _target_axis + set_velocity.call(index, (output - _target_axis) / delta) + + return output + + +func _set_limit_clamp_position(value: Vector2) -> Vector2: + var camera_frame_rect_size: Vector2 = _camera_frame_rect().size + value.x = clampf(value.x, _limit_sides.x + camera_frame_rect_size.x / 2, _limit_sides.z - camera_frame_rect_size.x / 2) + value.y = clampf(value.y, _limit_sides.y + camera_frame_rect_size.y / 2, _limit_sides.w - camera_frame_rect_size.y / 2) + return value + + +func _draw() -> void: + if not Engine.is_editor_hint(): return + + if frame_preview and not _is_active: + draw_rect(_camera_frame_rect(), Color("3ab99a"), false, 2) + + +func _camera_frame_rect() -> Rect2: + var screen_size_zoom: Vector2 = Vector2(_phantom_camera_manager.screen_size.x / get_zoom().x, _phantom_camera_manager.screen_size.y / get_zoom().y) + + return Rect2(-screen_size_zoom / 2, screen_size_zoom) + + +func _on_tile_map_changed() -> void: + update_limit_all_sides() + + +func _get_target_position_offset() -> Vector2: + return follow_target.global_position + follow_offset + + +func _on_dead_zone_changed() -> void: + global_position = _get_target_position_offset() + + +func _get_framed_side_offset() -> Vector2: + var frame_out_bounds: Vector2 + + if viewport_position.x < 0.5 - dead_zone_width / 2: + # Is outside left edge + frame_out_bounds.x = -1 + + if viewport_position.y < 0.5 - dead_zone_height / 2: + # Is outside top edge + frame_out_bounds.y = 1 + + if viewport_position.x > 0.5 + dead_zone_width / 2: + # Is outside right edge + frame_out_bounds.x = 1 + + if viewport_position.y > 0.5001 + dead_zone_height / 2: # 0.501 to resolve an issue where the bottom vertical Dead Zone never becoming 0 when the Dead Zone Vertical parameter is set to 0 + # Is outside bottom edge + frame_out_bounds.y = -1 + + return frame_out_bounds + + +func _draw_camera_2d_limit() -> void: + if not is_instance_valid(_phantom_camera_manager): return + _phantom_camera_manager.draw_limit_2d.emit(draw_limits) + + +func _check_limit_is_not_default() -> void: + if _limit_sides == _limit_sides_default: + _limit_inactive_pcam = false + else: + _limit_inactive_pcam = true + + +func _check_visibility() -> void: + _phantom_camera_manager.pcam_visibility_changed.emit(self) + + +func _follow_target_tree_exiting(target: Node) -> void: + if target == follow_target: + _should_follow = false + if _follow_targets.has(target): + _follow_targets.erase(target) + + +func _should_follow_checker() -> void: + if follow_mode == FollowMode.NONE: + _should_follow = false + return + + if not follow_mode == FollowMode.GROUP: + if is_instance_valid(follow_target): + _should_follow = true + else: + _should_follow = false + + +func _follow_targets_size_check() -> void: + var targets_size: int = 0 + _follow_target_physics_based = false + _follow_targets = [] + for i in follow_targets.size(): + if follow_targets[i] == null: continue + if follow_targets[i].is_inside_tree(): + _follow_targets.append(follow_targets[i]) + targets_size += 1 + _follow_targets_single_target_index = i + _check_physics_body(follow_targets[i]) + if not follow_targets[i].tree_exiting.is_connected(_follow_target_tree_exiting): + follow_targets[i].tree_exiting.connect(_follow_target_tree_exiting.bind(follow_targets[i])) + + match targets_size: + 0: + _should_follow = false + _has_multiple_follow_targets = false + 1: + _should_follow = true + _has_multiple_follow_targets = false + _: + _should_follow = true + _has_multiple_follow_targets = true + + +func _noise_emitted(emitter_noise_output: Transform2D, emitter_layer: int) -> void: + if noise_emitter_layer & emitter_layer != 0: + noise_emitted.emit(emitter_noise_output) + + +func _set_layer(current_layers: int, layer_number: int, value: bool) -> int: + var mask: int = current_layers + + # From https://github.com/godotengine/godot/blob/51991e20143a39e9ef0107163eaf283ca0a761ea/scene/3d/camera_3d.cpp#L638 + if layer_number < 1 or layer_number > 20: + printerr("Render layer must be between 1 and 20.") + else: + if value: + mask |= 1 << (layer_number - 1) + else: + mask &= ~(1 << (layer_number - 1)) + + return mask + + +func _check_physics_body(target: Node2D) -> void: + if target is PhysicsBody2D: + var show_jitter_tips := ProjectSettings.get_setting("phantom_camera/tips/show_jitter_tips") + var physics_interpolation_enabled := ProjectSettings.get_setting("physics/common/physics_interpolation") + + ## NOTE - Feature Toggle + if Engine.get_version_info().major == 4 and \ + Engine.get_version_info().minor < 3: + if show_jitter_tips == null: # Default value is null when referencing custom Project Setting + print_rich("Following a [b]PhysicsBody2D[/b] node will likely result in jitter - on lower physics ticks in particular.") + print_rich("If possible, will recommend upgrading to Godot 4.3, as it has built-in support for 2D Physics Interpolation, which will mitigate this issue.") + print_rich("Otherwise, try following the guide on the [url=https://phantom-camera.dev/support/faq#i-m-seeing-jitter-what-can-i-do]documentation site[/url] for better results.") + print_rich("This tip can be disabled from within [code]Project Settings / Phantom Camera / Tips / Show Jitter Tips[/code]") + return + ## NOTE - Only supported in Godot 4.3 or above + elif not physics_interpolation_enabled and show_jitter_tips == null: # Default value is null when referencing custom Project Setting + printerr("Physics Interpolation is disabled in the Project Settings, recommend enabling it to smooth out physics-based camera movement") + print_rich("This tip can be disabled from within [code]Project Settings / Phantom Camera / Tips / Show Jitter Tips[/code]") + _follow_target_physics_based = true + else: + _is_parents_physics(target) + physics_target_changed.emit() + + +func _is_parents_physics(target: Node = self) -> void: + var current_node: Node = target + while current_node: + current_node = current_node.get_parent() + if not current_node is PhysicsBody2D: continue + _follow_target_physics_based = true + +#endregion + + +#region Public Functions + +## Updates the limit sides based what has been set to define it +## This should be automatic, but can be called manully if need be. +func update_limit_all_sides() -> void: + var limit_rect: Rect2 + + if not is_instance_valid(_limit_node): + _limit_sides.x = limit_left + _limit_sides.y = limit_top + _limit_sides.z = limit_right + _limit_sides.w = limit_bottom + elif _limit_node is TileMap or _limit_node.is_class("TileMapLayer"): + var tile_map := _limit_node + + if not tile_map.tile_set: return # TODO: This should be removed once https://github.com/godotengine/godot/issues/96898 is resolved + + var tile_map_size: Vector2 = Vector2(tile_map.get_used_rect().size) * Vector2(tile_map.tile_set.tile_size) * tile_map.get_scale() + var tile_map_position: Vector2 = tile_map.global_position + Vector2(tile_map.get_used_rect().position) * Vector2(tile_map.tile_set.tile_size) * tile_map.get_scale() + + ## Calculates the Rect2 based on the Tile Map position and size + margin + limit_rect = Rect2( + tile_map_position + Vector2(limit_margin.x, limit_margin.y), + tile_map_size - Vector2(limit_margin.x, limit_margin.y) - Vector2(limit_margin.z, limit_margin.w) + ) + + # Left + _limit_sides.x = roundi(limit_rect.position.x) + # Top + _limit_sides.y = roundi(limit_rect.position.y) + # Right + _limit_sides.z = roundi(limit_rect.position.x + limit_rect.size.x) + # Bottom + _limit_sides.w = roundi(limit_rect.position.y + limit_rect.size.y) + elif _limit_node is CollisionShape2D: + var collision_shape_2d: CollisionShape2D = _limit_node as CollisionShape2D + + if not collision_shape_2d.get_shape(): return + + var shape_2d: Shape2D = collision_shape_2d.get_shape() + var shape_2d_size: Vector2 = shape_2d.get_rect().size + var shape_2d_position: Vector2 = collision_shape_2d.global_position + Vector2(shape_2d.get_rect().position) + + ## Calculates the Rect2 based on the Tile Map position and size + limit_rect = Rect2(shape_2d_position, shape_2d_size) + + ## Calculates the Rect2 based on the Tile Map position and size + margin + limit_rect = Rect2( + limit_rect.position + Vector2(limit_margin.x, limit_margin.y), + limit_rect.size - Vector2(limit_margin.x, limit_margin.y) - Vector2(limit_margin.z, limit_margin.w) + ) + + # Left + _limit_sides.x = roundi(limit_rect.position.x) + # Top + _limit_sides.y = roundi(limit_rect.position.y) + # Right + _limit_sides.z = roundi(limit_rect.position.x + limit_rect.size.x) + # Bottom + _limit_sides.w = roundi(limit_rect.position.y + limit_rect.size.y) + + _check_limit_is_not_default() + if not _is_active: return + if not is_instance_valid(_phantom_camera_manager): return + _phantom_camera_manager.limit_2d_changed.emit(SIDE_LEFT, _limit_sides.x) + _phantom_camera_manager.limit_2d_changed.emit(SIDE_TOP, _limit_sides.y) + _phantom_camera_manager.limit_2d_changed.emit(SIDE_RIGHT, _limit_sides.z) + _phantom_camera_manager.limit_2d_changed.emit(SIDE_BOTTOM, _limit_sides.w) + _phantom_camera_manager.draw_limit_2d.emit(draw_limits) + + +func reset_limit() -> void: + if not is_instance_valid(_phantom_camera_manager): return + _phantom_camera_manager.limit_2d_changed.emit(SIDE_LEFT, _limit_sides_default.x) + _phantom_camera_manager.limit_2d_changed.emit(SIDE_TOP, _limit_sides_default.y) + _phantom_camera_manager.limit_2d_changed.emit(SIDE_RIGHT, _limit_sides_default.z) + _phantom_camera_manager.limit_2d_changed.emit(SIDE_BOTTOM, _limit_sides_default.w) + _phantom_camera_manager.draw_limit_2d.emit(draw_limits) + + +## Assigns the value of the [param has_tweened] property. +## [b][color=yellow]Important:[/color][/b] This value can only be changed +## from the [PhantomCameraHost] script. +func set_tween_skip(caller: Node, value: bool) -> void: + if is_instance_of(caller, PhantomCameraHost): + _tween_skip = value + else: + printerr("Can only be called PhantomCameraHost class") +## Returns the current [param has_tweened] value. +func get_tween_skip() -> bool: + return _tween_skip + +## Returns the [Transform3D] value based on the [member follow_mode] / [member look_at_mode] target value. +func get_transform_output() -> Transform2D: + return _transform_output + + +## Returns the noise [Transform3D] value. +func get_noise_transform() -> Transform2D: + return _transform_noise + + +## Emits a noise based on a custom [Transform2D] value.[br] +## Use this function if you wish to make use of external noise patterns from, for example, other addons. +func emit_noise(value: Transform2D) -> void: + noise_emitted.emit(value) + + +## Teleports the [param PhantomCamera2D] and [Camera2D] to their designated position, +## bypassing the damping process. +func teleport_position() -> void: + _follow_velocity_ref = Vector2.ZERO + _set_follow_position() + _transform_output.origin = _follow_target_position + _phantom_camera_manager.pcam_teleport.emit(self) + + +# TODO: Enum link does link to anywhere is being tracked in: https://github.com/godotengine/godot/issues/106828 +## Returns true if this [param PhantomCamera2D]'s [member follow_mode] is not set to [enum FollowMode] +## and has a valid [member follow_target]. +func is_following() -> bool: + return _should_follow + +#endregion + + +#region Setter & Getter Functions + +## Assigns new [member zoom] value. +func set_zoom(value: Vector2) -> void: + zoom = value + queue_redraw() + +## Gets current [member zoom] value. +func get_zoom() -> Vector2: + return zoom + + +## Assigns new [member priority] value. +func set_priority(value: int) -> void: + priority = maxi(0, value) + if not is_node_ready(): return + if not Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): return + Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME).pcam_priority_changed.emit(self) + +## Gets current [member priority] value. +func get_priority() -> int: + return priority + + +## Assigns a new PhantomCameraTween resource to the PhantomCamera2D +func set_tween_resource(value: PhantomCameraTween) -> void: + tween_resource = value + +## Gets the PhantomCameraTween resource assigned to the PhantomCamera2D +## Returns null if there's nothing assigned to it. +func get_tween_resource() -> PhantomCameraTween: + return tween_resource + + +## Assigns a new [param Tween Duration] to the [member tween_resource] value.[br] +## The duration value is in seconds. +func set_tween_duration(value: float) -> void: + tween_resource.duration = value + +## Gets the current [param Tween Duration] value inside the +## [member tween_resource].[br] +## The duration value is in seconds. +func get_tween_duration() -> float: + return tween_resource.duration + + +## Assigns a new [param Tween Transition] value inside the +## [member tween_resource]. +func set_tween_transition(value: int) -> void: + tween_resource.transition = value + +## Gets the current [param Tween Transition] value inside the +## [member tween_resource]. +func get_tween_transition() -> int: + return tween_resource.transition + + +## Assigns a new [param Tween Ease] value inside the [member tween_resource]. +func set_tween_ease(value: int) -> void: + tween_resource.ease = value + +## Gets the current [param Tween Ease] value inside the [member tween_resource]. +func get_tween_ease() -> int: + return tween_resource.ease + + +## Sets the [param PhantomCamera2D] active state.[br] +## [b][color=yellow]Important:[/color][/b] This value can only be changed +## from the [PhantomCameraHost] script. +func set_is_active(node, value) -> void: + if node is PhantomCameraHost: + _is_active = value + if value: + _should_follow_checker() + queue_redraw() + else: + printerr("PCams can only be set from the PhantomCameraHost") + +## Gets current active state of the [param PhantomCamera2D]. +## If it returns true, it means the [param PhantomCamera2D] is what the +## [param Camera2D] is currently following. +func is_active() -> bool: + return _is_active + + +## Enables or disables the [member tween_on_load]. +func set_tween_on_load(value: bool) -> void: + tween_on_load = value + +## Gets the current [member tween_on_load] value. +func get_tween_on_load() -> bool: + return tween_on_load + +## Sets the [member host_layers] value. +func set_host_layers(value: int) -> void: + host_layers = value + if is_instance_valid(_phantom_camera_manager): + _phantom_camera_manager.pcam_host_layer_changed.emit(self) + +## Enables or disables a given layer of [member host_layers]. +func set_host_layers_value(layer: int, value: bool) -> void: + host_layers = _set_layer(host_layers, layer, value) + +## Gets the current [member host_layers]. +func get_host_layers() -> int: + return host_layers + + +## Gets the current follow mode as an enum int based on [enum FollowMode].[br] +## [b]Note:[/b] Setting [enum FollowMode] purposely not added. +## A separate PCam should be used instead. +func get_follow_mode() -> int: + return follow_mode + + +## Assigns a new [Node2D] as the [member follow_target]. +func set_follow_target(value: Node2D) -> void: + if follow_mode == FollowMode.NONE or follow_mode == FollowMode.GROUP: return + if follow_target == value: return + follow_target = value + _follow_target_physics_based = false + if is_instance_valid(value): + if follow_mode == FollowMode.PATH: + if is_instance_valid(follow_path): + _should_follow = true + else: + _should_follow = false + else: + _should_follow = true + _check_physics_body(value) + if not follow_target.tree_exiting.is_connected(_follow_target_tree_exiting): + follow_target.tree_exiting.connect(_follow_target_tree_exiting.bind(follow_target)) + else: + _should_follow = false + follow_target_changed.emit() + notify_property_list_changed() + +## Erases the current [member follow_target]. +func erase_follow_target() -> void: + if follow_target == null: return + _should_follow = false + follow_target = null + _follow_target_physics_based = false + follow_target_changed.emit() + +## Gets the current [member follow_target]. +func get_follow_target() -> Node2D: + return follow_target + + +## Assigns a new [Path2D] to the [member follow_path]. +func set_follow_path(value: Path2D) -> void: + follow_path = value + if is_instance_valid(follow_path): + _should_follow_checker() + else: + _should_follow = false + +## Erases the current [Path2D] from the [member follow_path] property. +func erase_follow_path() -> void: + follow_path = null + +## Gets the current [Path2D] from the [member follow_path]. +func get_follow_path() -> Path2D: + return follow_path + + +## Assigns a new [param follow_targets] array value. +func set_follow_targets(value: Array[Node2D]) -> void: + if follow_mode != FollowMode.GROUP: return + if follow_targets == value: return + follow_targets = value + _follow_targets_size_check() + +## Appends a single [Node2D] to [member follow_targets]. +func append_follow_targets(value: Node2D) -> void: + if not is_instance_valid(value): + printerr(value, " is not a valid Node2D instance") + return + + if not follow_targets.has(value): + follow_targets.append(value) + _follow_targets_size_check() + else: + printerr(value, " is already part of Follow Group") + +## Adds an Array of type [Node2D] to [member follow_targets]. +func append_follow_targets_array(value: Array[Node2D]) -> void: + for target in value: + if not is_instance_valid(target): continue + if not follow_targets.has(target): + follow_targets.append(target) + _follow_targets_size_check() + else: + printerr(value, " is already part of Follow Group") + +## Removes a [Node2D] from [member follow_targets] array. +func erase_follow_targets(value: Node2D) -> void: + follow_targets.erase(value) + _follow_targets_size_check() + +## Gets all [Node2D] from [member follow_targets] array. +func get_follow_targets() -> Array[Node2D]: + return follow_targets + + +## Assigns a new Vector2 for the Follow Target Offset property. +func set_follow_offset(value: Vector2) -> void: + var temp_offset: Vector2 = follow_offset + + follow_offset = value + + if follow_axis_lock != FollowLockAxis.NONE: + temp_offset = temp_offset - value + match value: + FollowLockAxis.X: + _follow_axis_lock_value.x = _transform_output.origin.x + temp_offset.x + FollowLockAxis.Y: + _follow_axis_lock_value.y = _transform_output.origin.y + temp_offset.y + FollowLockAxis.XY: + _follow_axis_lock_value.x = _transform_output.origin.x + temp_offset.x + _follow_axis_lock_value.y = _transform_output.origin.y + temp_offset.y + + +## Gets the current Vector2 for the Follow Target Offset property. +func get_follow_offset() -> Vector2: + return follow_offset + + +## Enables or disables Follow Damping. +func set_follow_damping(value: bool) -> void: + follow_damping = value + notify_property_list_changed() + +## Gets the current Follow Damping property. +func get_follow_damping() -> bool: + return follow_damping + + +## Assigns new Damping value. +func set_follow_damping_value(value: Vector2) -> void: + ## TODO - Should be using @export_range once minimum version support is Godot 4.3 + if value.x < 0: value.x = 0 + elif value.y < 0: value.y = 0 + follow_damping_value = value + +## Gets the current Follow Damping value. +func get_follow_damping_value() -> Vector2: + return follow_damping_value + + +## Assigns a new [member follow_axis] member. Value is based on [enum FollowLockAxis] enum. +func set_lock_axis(value: FollowLockAxis) -> void: + follow_axis_lock = value + + # Wait for the node to be ready before setting lock + if not is_node_ready(): await ready + + # Prevent axis lock from working in the editor + if value != FollowLockAxis.NONE and not Engine.is_editor_hint(): + _follow_axis_is_locked = true + match value: + FollowLockAxis.X: + _follow_axis_lock_value.x = _transform_output.origin.x + FollowLockAxis.Y: + _follow_axis_lock_value.y = _transform_output.origin.y + FollowLockAxis.XY: + _follow_axis_lock_value.x = _transform_output.origin.x + _follow_axis_lock_value.y = _transform_output.origin.y + else: + _follow_axis_is_locked = false + +## Gets the current [member follow_axis_lock] value. Value is based on [enum FollowLockAxis] enum. +func get_lock_axis() -> FollowLockAxis: + return follow_axis_lock + + +## Enables or disables [member rotate_with_target]. +func set_rotate_with_target(value: bool) -> void: + rotate_with_target = value + notify_property_list_changed() + +## Gets the current [member rotate_with_target] value. +func get_rotate_with_target() -> bool: + return rotate_with_target + + +## Sets the [member rotation_offset]. +func set_rotation_offset(value: float) -> void: + rotation_offset = value + +## Gets the current [member rotation_offset] value. +func get_rotation_offset() -> float: + return rotation_offset + + +## Enables or disables [member rotation_damping]. +func set_rotation_damping(value: bool) -> void: + rotation_damping = value + notify_property_list_changed() + +## Gets the [member rotation_damping] value. +func get_rotation_damping() -> bool: + return rotation_damping + + +## Set the [member rotation_damping_value]. +func set_rotation_damping_value(value: float) -> void: + rotation_damping_value = value + +## Gets the [member rotation_damping_value] value. +func get_rotation_damping_value() -> float: + return rotation_damping_value + + +## Enables or disables [member snap_to_pixel]. +func set_snap_to_pixel(value: bool) -> void: + snap_to_pixel = value + +## Gets the current [member snap_to_pixel] value. +func get_snap_to_pixel() -> bool: + return snap_to_pixel + + +## Enables or disables Auto zoom when using Group Follow. +func set_auto_zoom(value: bool) -> void: + auto_zoom = value + notify_property_list_changed() + +## Gets Auto Zoom state. +func get_auto_zoom() -> bool: + return auto_zoom + + +## Assigns new Min Auto Zoom value. +func set_auto_zoom_min(value: float) -> void: + auto_zoom_min = value + +## Gets Min Auto Zoom value. +func get_auto_zoom_min() -> float: + return auto_zoom_min + + +## Assigns new Max Auto Zoom value. +func set_auto_zoom_max(value: float) -> void: + auto_zoom_max = value + +## Gets Max Auto Zoom value. +func get_auto_zoom_max() -> float: + return auto_zoom_max + + +## Assigns new Zoom Auto Margin value. +func set_auto_zoom_margin(value: Vector4) -> void: + auto_zoom_margin = value + +## Gets Zoom Auto Margin value. +func get_auto_zoom_margin() -> Vector4: + return auto_zoom_margin + + +## Sets a limit side based on the side parameter.[br] +## It's recommended to pass the [enum Side] enum as the sid parameter. +func set_limit(side: int, value: int) -> void: + match side: + SIDE_LEFT: limit_left = value + SIDE_TOP: limit_top = value + SIDE_RIGHT: limit_right = value + SIDE_BOTTOM: limit_bottom = value + _: printerr("Not a valid Side.") + +## Gets the limit side +func get_limit(value: int) -> int: + match value: + SIDE_LEFT: return limit_left + SIDE_TOP: return limit_top + SIDE_RIGHT: return limit_right + SIDE_BOTTOM: return limit_bottom + _: + printerr("Not a valid Side.") + return -1 + + +## Assign a the Camera2D Left Limit Side value. +func set_limit_left(value: int) -> void: + _limit_target_exist_error() + limit_left = value + update_limit_all_sides() + +## Gets the Camera2D Left Limit value. +func get_limit_left() -> int: + return limit_left + + +## Assign a the Camera2D Top Limit Side value. +func set_limit_top(value: int) -> void: + _limit_target_exist_error() + limit_top = value + update_limit_all_sides() + +## Gets the Camera2D Top Limit value. +func get_limit_top() -> int: + return limit_top + + +## Assign a the Camera2D Right Limit Side value. +func set_limit_right(value: int) -> void: + _limit_target_exist_error() + limit_right = value + update_limit_all_sides() + +## Gets the Camera2D Right Limit value. +func get_limit_right() -> int: + return limit_right + + +## Assign a the Camera2D Bottom Limit Side value. +func set_limit_bottom(value: int) -> void: + _limit_target_exist_error() + limit_bottom = value + update_limit_all_sides() + +## Gets the Camera2D Bottom Limit value. +func get_limit_bottom() -> int: + return limit_bottom + + +func _limit_target_exist_error() -> void: + if not limit_target.is_empty(): + printerr("Unable to set Limit Side due to Limit Target ", _limit_node.name, " being assigned") + + +# Sets a [memeber limit_target] node. +func set_limit_target(value: NodePath) -> void: + limit_target = value + + # Waits for PCam2d's _ready() before trying to validate limit_node_path + if not is_node_ready(): await ready + + # Removes signal from existing TileMap node + if is_instance_valid(get_node_or_null(value)): + var prev_limit_node: Node2D = _limit_node + var new_limit_node: Node2D = get_node(value) + + if prev_limit_node: + if prev_limit_node is TileMap or prev_limit_node.is_class("TileMapLayer"): + if prev_limit_node.changed.is_connected(_on_tile_map_changed): + prev_limit_node.changed.disconnect(_on_tile_map_changed) + + if new_limit_node is TileMap or new_limit_node.is_class("TileMapLayer"): + if not new_limit_node.changed.is_connected(_on_tile_map_changed): + new_limit_node.changed.connect(_on_tile_map_changed) + elif new_limit_node is CollisionShape2D: + var col_shape: CollisionShape2D = get_node(value) + + if col_shape.shape == null: + printerr("No Shape2D in: ", col_shape.name) + reset_limit() + limit_target = "" + return + else: + printerr("Limit Target is not a TileMap, TileMapLayer or CollisionShape2D node") + return + elif value == NodePath(""): + reset_limit() + limit_target = "" + else: + printerr("Limit Target cannot be found") + return + + _limit_node = get_node_or_null(value) + + notify_property_list_changed() + update_limit_all_sides() + +## Get [member limit_target] node. +func get_limit_target() -> NodePath: + if not limit_target: # TODO - Fixes an spam error if if limit_taret is empty + return NodePath("") + else: + return limit_target + + +## Set Tile Map Limit Margin. +func set_limit_margin(value: Vector4i) -> void: + limit_margin = value + update_limit_all_sides() +## Get Tile Map Limit Margin. +func get_limit_margin() -> Vector4i: + return limit_margin + + +### Enables or disables the Limit Smoothing beaviour. +#func set_limit_smoothing(value: bool) -> void: + #limit_smoothed = value +### Returns the Limit Smoothing beaviour. +#func get_limit_smoothing() -> bool: + #return limit_smoothed + + +## Sets a [PhantomCameraNoise2D] resource. +func set_noise(value: PhantomCameraNoise2D) -> void: + noise = value + if value != null: + _has_noise_resource = true + noise.set_trauma(1) + else: + _has_noise_resource = false + _transform_noise = Transform2D() + +## Returns the [PhantomCameraNoise2D] resource. +func get_noise() -> PhantomCameraNoise2D: + return noise + +func has_noise_resource() -> bool: + return _has_noise_resource + + +## Sets the [member noise_emitter_layer] value. +func set_noise_emitter_layer(value: int) -> void: + noise_emitter_layer = value + +## Enables or disables a given layer of [member noise_emitter_layer]. +func set_noise_emitter_layer_value(value: int, enabled: bool) -> void: + noise_emitter_layer = _set_layer(noise_emitter_layer, value, enabled) + +## Returns the [member noise_emitter_layer] +func get_noise_emitter_layer() -> int: + return noise_emitter_layer + + +## Sets [member inactive_update_mode] property. +func set_inactive_update_mode(value: int) -> void: + inactive_update_mode = value + +## Gets [enum InactiveUpdateMode] value. +func get_inactive_update_mode() -> int: + return inactive_update_mode + + +func get_follow_target_physics_based() -> bool: + return _follow_target_physics_based + + +func get_class() -> String: + return "PhantomCamera2D" + + +func is_class(value) -> bool: + return value == "PhantomCamera2D" + +#endregion diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd.uid b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd.uid new file mode 100644 index 0000000..66fa7de --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd.uid @@ -0,0 +1 @@ +uid://bhexx6mj1xv3q diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd new file mode 100644 index 0000000..2b4480c --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd @@ -0,0 +1,2279 @@ +@tool +@icon("res://addons/phantom_camera/icons/phantom_camera_3d.svg") +class_name PhantomCamera3D +extends Node3D + +## Controls a scene's [Camera3D] and applies logic to it. +## +## The scene's [Camera3D] will follow the position of the +## [param PhantomCamera3D] with the highest priority. +## Each instance can have different positional and rotational logic applied +## to them. + +#region Constants + +const _constants = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") + +#endregion + +#region Signals + +## Emitted when the [param PhantomCamera3D] becomes active. +signal became_active + +## Emitted when the [param PhantomCamera3D] becomes inactive. +signal became_inactive + +## Emitted when the follow_mode changes. +## Note: This is for internal use only +signal follow_mode_changed + +## Emitted when [member follow_target] changes. +signal follow_target_changed + +## Emitted when [member look_at_target] changes. +signal look_at_target_changed + +## Emitted when dead zones changes.[br] +## [b]Note:[/b] Only applicable in [param Framed] [member FollowMode]. +signal dead_zone_changed + +## Emitted when a target touches the edge of the dead zone in [param Framed] [enum FollowMode]. +signal dead_zone_reached + +## Emitted when the [param Camera3D] starts to tween to another +## [param PhantomCamera3D]. +signal tween_started + +## Emitted when the [param Camera3D] is to tweening towards another +## [param PhantomCamera3D]. +signal is_tweening + +## Emitted when the tween is interrupted due to another [param PhantomCamera3D] +## becoming active. The argument is the [param PhantomCamera3D] that +## interrupted the tween. +signal tween_interrupted(pcam_3d: PhantomCamera3D) + +## Emitted when the [param Camera3D] completes its tween to the +## [param PhantomCamera3D]. +signal tween_completed + +## Emitted when Noise should be applied to the [param Camera3D]. +signal noise_emitted(noise_output: Transform3D) + +signal physics_target_changed + +signal camera_3d_resource_property_changed(property: StringName, value: Variant) +signal camera_3d_resource_changed + +#endregion + + +#region Enums + +## Determines the positional logic for a given [param PhantomCamera3D] +## [br][br] +## The different modes have different functionalities and purposes, so choosing +## the correct one depends on what each [param PhantomCamera3D] is meant to do. +enum FollowMode { + NONE = 0, ## Default - No follow logic is applied. + GLUED = 1, ## Sticks to its target. + SIMPLE = 2, ## Follows its target with an optional offset. + GROUP = 3, ## Follows multiple targets with option to dynamically reframe itself. + PATH = 4, ## Follows a target while being positionally confined to a [Path3D] node. + FRAMED = 5, ## Applies a dead zone on the frame and only follows its target when it tries to leave it. + THIRD_PERSON = 6, ## Applies a [SpringArm3D] node to the target's position and allows for rotating around it. +} + +## Determines the rotational logic for a given [param PhantomCamera3D].[br][br] +## The different modes has different functionalities and purposes, so +## choosing the correct mode depends on what each [param PhantomCamera3D] +## is meant to do. +enum LookAtMode { + NONE = 0, ## Default - No Look At logic is applied. + MIMIC = 1, ## Copies its target's rotational value. + SIMPLE = 2, ## Looks at its target in a straight line. + GROUP = 3, ## Looks at the centre of its targets. +} + +## Determines how often an inactive [param PhantomCamera3D] should update +## its positional and rotational values. This is meant to reduce the amount +## of calculations inactive [param PhantomCamera3D] are doing when idling +## to improve performance. +enum InactiveUpdateMode { + ALWAYS, ## Always updates the [param PhantomCamera3D], even when it's inactive. + NEVER, ## Never updates the [param PhantomCamera3D] when it's inactive. Reduces the amount of computational resources when inactive. +# EXPONENTIALLY, +} + +enum FollowLockAxis { + NONE = 0, + X = 1, + Y = 2, + Z = 3, + XY = 4, + XZ = 5, + YZ = 6, + XYZ = 7, +} + +#endregion + + +#region Exported Properties + +## To quickly preview a [param PhantomCamera3D] without adjusting its +## [member Priority], this property allows the selected [param PhantomCamera3D] +## to ignore the Priority system altogether and forcefully become the active +## one. It's partly designed to work within the [param viewfinder], and will be +## disabled when running a build export of the game. +@export var priority_override: bool = false: + set(value): + priority_override = value + if Engine.is_editor_hint(): + if value: + if not Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): return + Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME).pcam_priority_override.emit(self, priority_override) + else: + if not Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): return + Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME).pcam_priority_override.emit(self, priority_override) + get: + return priority_override + + +## It defines which [param PhantomCamera3D] a scene's [param Camera3D] should +## be corresponding with and be attached to. This is decided by the +## [param PhantomCamera3D] with the highest [param priority]. +## [br][br] +## Changing [param priority] will send an event to the scene's +## [PhantomCameraHost], which will then determine whether if the +## [param priority] value is greater than or equal to the currently +## highest [param PhantomCamera3D]'s in the scene. The +## [param PhantomCamera3D] with the highest value will then reattach the +## Camera accordingly. +@export var priority: int = 0: + set = set_priority, + get = get_priority + + +## Determines the positional logic for a given [param PhantomCamera3D]. +## The different modes have different functionalities and purposes, so +## choosing the correct one depends on what each [param PhantomCamera3D] +## is meant to do. +@export var follow_mode: FollowMode = FollowMode.NONE: + set(value): + follow_mode = value + + if follow_mode == FollowMode.NONE: + _should_follow = false + top_level = false + _is_parents_physics() + notify_property_list_changed() + return + + match follow_mode: + FollowMode.PATH: + if is_instance_valid(follow_path): + _should_follow_checker() + else: + _should_follow = false + FollowMode.GROUP: + _follow_targets_size_check() + _: + _should_follow_checker() + + if follow_mode == FollowMode.FRAMED: + if _follow_framed_initial_set and follow_target: + _follow_framed_initial_set = false + dead_zone_changed.connect(_on_dead_zone_changed) + else: + if dead_zone_changed.is_connected(_on_dead_zone_changed): + dead_zone_changed.disconnect(_on_dead_zone_changed) + + if follow_mode == FollowMode.THIRD_PERSON: + top_level = false + _is_third_person_follow = true + else: + top_level = true + _is_third_person_follow = false + + follow_mode_changed.emit() + notify_property_list_changed() + + ## NOTE - Warning that Look At + Follow Mode hasn't been fully tested together yet + if look_at_mode != LookAtMode.NONE: + print_rich("[color=#EAA15E]Warning: Using both Look At and Follow Mode on the same PCam3D has not been fully tested yet, proceed with caution![/color]") + get: + return follow_mode + +## Determines which target should be followed. +## The [param Camera3D] will follow the position of the Follow Target based on +## the [member follow_mode] type and its parameters. +@export var follow_target: Node3D = null: + set = set_follow_target, + get = get_follow_target + +## Defines the targets that the [param PhantomCamera3D] should be following. +@export var follow_targets: Array[Node3D] = []: + set = set_follow_targets, + get = get_follow_targets + +## Determines the [Path3D] node the [param PhantomCamera3D] +## should be bound to. +## The [param PhantomCamera3D] will follow the position of the +## [member follow_target] while sticking to the closest point on this path. +@export var follow_path: Path3D = null: + set = set_follow_path, + get = get_follow_path + + +## Determines the rotational logic for a given [param PhantomCamera3D]. +## The different modes has different functionalities and purposes, +## so choosing the correct mode depends on what each +## [param PhantomCamera3D] is meant to do. +@export var look_at_mode: LookAtMode = LookAtMode.NONE: + set(value): + look_at_mode = value + + if look_at_mode == LookAtMode.NONE: + _should_look_at = false + notify_property_list_changed() + return + + if not look_at_mode == LookAtMode.GROUP: + if look_at_target is Node3D: + _should_look_at = true + else: # If Look At Group + _look_at_targets_size_check() + notify_property_list_changed() + + ## NOTE - Warning that Look At + Follow Mode hasn't been fully tested together yet + if follow_mode != FollowMode.NONE: + print_rich("[color=#EAA15E]Warning: Using both Look At and Follow Mode on the same PCam3D has not been fully tested yet, proceed with caution![/color]") + get: + return look_at_mode + +## Determines which target should be looked at. +## The [param PhantomCamera3D] will update its rotational value as the +## target changes its position. +@export var look_at_target: Node3D = null: + set = set_look_at_target, + get = get_look_at_target + +## Defines the targets that the camera should looking at. +## It will be looking at the centre of all the assigned targets. +@export var look_at_targets: Array[Node3D] = []: + set = set_look_at_targets, + get = get_look_at_targets + + +## Defines how [param ]PhantomCamera3Ds] transition between one another. +## Changing the tween values for a given [param PhantomCamera3D] +## determines how transitioning to that instance will look like. +## This is a resource type that can be either used for one +## [param PhantomCamera] or reused across multiple - both 2D and 3D. +## By default, all [param PhantomCameras] will use a [param linear] +## transition, [param easeInOut] ease with a [param 1s] duration. +@export var tween_resource: PhantomCameraTween = PhantomCameraTween.new(): + set = set_tween_resource, + get = get_tween_resource + +## If enabled, the moment a [param PhantomCamera3D] is instantiated into +## a scene, and has the highest priority, it will perform its tween transition. +## This is most obvious if a [param PhantomCamera3D] has a long duration and +## is attached to a playable character that can be moved the moment a scene +## is loaded. Disabling the [param tween_on_load] property will +## disable this behaviour and skip the tweening entirely when instantiated. +@export var tween_on_load: bool = true: + set = set_tween_on_load, + get = get_tween_on_load + + +## Determines how often an inactive [param PhantomCamera3D] should update +## its positional and rotational values. This is meant to reduce the amount +## of calculations inactive [param PhantomCamera3Ds] are doing when idling +## to improve performance. +@export var inactive_update_mode: InactiveUpdateMode = InactiveUpdateMode.ALWAYS: + set = set_inactive_update_mode, + get = get_inactive_update_mode + + +## Determines which layers this [param PhantomCamera3D] should be able to communicate with [PhantomCameraHost] nodes.[br] +## A corresponding layer needs to be set on the [PhantomCameraHost] node. +@export_flags_3d_render var host_layers: int = 1: + set = set_host_layers, + get = get_host_layers + + +## A resource type that allows for overriding the [param Camera3D] node's +## properties. +@export var camera_3d_resource: Camera3DResource = null: + set = set_camera_3d_resource, + get = get_camera_3d_resource + + +## Overrides the [member Camera3D.attribuets] resource property. +@export var attributes: CameraAttributes = null: + set = set_attributes, + get = get_attributes + + +## Overrides the [member Camera3D.environment] resource property. +@export var environment: Environment = null: + set = set_environment, + get = get_environment + + +@export_group("Follow Parameters") +## Offsets the [member follow_target] position. +@export var follow_offset: Vector3 = Vector3.ZERO: + set = set_follow_offset, + get = get_follow_offset + +## Applies a damping effect on the camera's movement. +## Leading to heavier / slower camera movement as the targeted node moves around. +## This is useful to avoid sharp and rapid camera movement. +@export var follow_damping: bool = false: + set = set_follow_damping, + get = get_follow_damping + +## Defines the damping amount. The ideal range should be somewhere between 0-1.[br][br] +## The damping amount can be specified in the individual axis.[br][br] +## [b]Lower value[/b] = faster / sharper camera movement.[br] +## [b]Higher value[/b] = slower / heavier camera movement. +@export_custom(PROPERTY_HINT_LINK, "") +var follow_damping_value: Vector3 = Vector3(0.1, 0.1, 0.1): + set = set_follow_damping_value, + get = get_follow_damping_value + + +## Prevents the [param PhantomCamera2D] from moving in a designated axis. +## This can be enabled or disabled at runtime or from the editor directly. +@export var follow_axis_lock: FollowLockAxis = FollowLockAxis.NONE: + set = set_follow_axis_lock, + get = get_follow_axis_lock +var _follow_axis_is_locked: bool = false +var _follow_axis_lock_value: Vector3 = Vector3.ZERO + + +## Sets a distance offset from the centre of the target's position. +## The distance is applied to the [param PhantomCamera3D]'s local z axis. +@export var follow_distance: float = 1: + set = set_follow_distance, + get = get_follow_distance + +## Enables the [param PhantomCamera3D] to automatically distance +## itself as the [param follow targets] move further apart.[br] +## It looks at the longest axis between the different targets and interpolates +## the distance length between the [member auto_follow_distance_min] and +## [member follow_group_distance] properties.[br][br] +## Note: Enabling this property hides and disables the [member follow_distance] +## property as this effectively overrides that property. +@export var auto_follow_distance: bool = false: + set = set_auto_follow_distance, + get = get_auto_follow_distance + +## Sets the minimum distance between the Camera and centre of [AABB]. +## [br][br] +## Note: This distance will only ever be reached when all the targets are in +## the exact same [param Vector3] coordinate, which will very unlikely +## happen, so adjust the value here accordingly. +## [br][br] +## If only one follow target is assigned to [member follow_targets], this value will be used as the `follow_distance`. +@export var auto_follow_distance_min: float = 1: + set = set_auto_follow_distance_min, + get = get_auto_follow_distance_min + +## Sets the maximum distance between the Camera and centre of [AABB]. +@export var auto_follow_distance_max: float = 5: + set = set_auto_follow_distance_max, + get = get_auto_follow_distance_max + +## Determines how fast the [member auto_follow_distance] moves between the +## maximum and minimum distance. The higher the value, the sooner the +## maximum distance is reached.[br][br] +## This value should be based on the sizes of the [member auto_follow_distance_min] +## and [member auto_follow_distance_max].[br] +## E.g. if the value between the [member auto_follow_distance_min] and +## [member auto_follow_distance_max] is small, consider keeping the number low +## and vice versa. +@export var auto_follow_distance_divisor: float = 10: + set = set_auto_follow_distance_divisor, + get = get_auto_follow_distance_divisor + + +@export_subgroup("Dead Zones") +## Defines the horizontal dead zone area. While the target is within it, the +## [param PhantomCamera3D] will not move in the horizontal axis. +## If the targeted node leaves the horizontal bounds, the +## [param PhantomCamera3D] will follow the target horizontally to keep +## it within bounds. +@export_range(0, 1) var dead_zone_width: float = 0: + set(value): + dead_zone_width = value + dead_zone_changed.emit() + get: + return dead_zone_width + +## Defines the vertical dead zone area. While the target is within it, the +## [param PhantomCamera3D] will not move in the vertical axis. +## If the targeted node leaves the vertical bounds, the +## [param PhantomCamera3D] will follow the target horizontally to keep +## it within bounds. +@export_range(0, 1) var dead_zone_height: float = 0: + set(value): + dead_zone_height = value + dead_zone_changed.emit() + get: + return dead_zone_height + +## Enables the dead zones to be visible when running the game from the editor. +## Dead zones will never be visible in build exports. +@export var show_viewfinder_in_play: bool = false + +## Defines the position of the [member follow_target] within the viewport.[br] +## This is only used for when [member follow_mode] is set to [param Framed]. +@export_subgroup("Spring Arm") + +## Applies a rotational offset to the Third Person [member follow_mode] in the [code]X[/code] axis. +@export_range(-360, 360, 0.1,"or_greater", "or_less", "radians_as_degrees") +var vertical_rotation_offset: float = 0: + set = set_vertical_rotation_offset, + get = get_vertical_rotation_offset + +## Applies a rotational offset to the Third Person [member follow_mode] in the [code]Y[/code] axis. +@export_range(-360, 360, 0.1, "or_greater", "or_less", "radians_as_degrees") +var horizontal_rotation_offset: float = 0: + set = set_horizontal_rotation_offset, + get = get_horizontal_rotation_offset + +## Defines the [member SpringArm3D.spring_length]. +@export var spring_length: float = 1: + set = set_spring_length, + get = get_spring_length + +## Defines the [member SpringArm3D.collision_mask] node's Collision Mask. +@export_flags_3d_physics var collision_mask: int = 1: + set = set_collision_mask, + get = get_collision_mask + +## Defines the [member SpringArm3D.shape] node's Shape3D. +@export var shape: Shape3D = null: + set = set_shape, + get = get_shape + +## Defines the [member SpringArm3D.margin] node's Margin. +@export var margin: float = 0.01: + set = set_margin, + get = get_margin + + +@export_group("Look At Parameters") +## Offsets the target's [param Vector3] position that the +## [param PhantomCamera3D] is looking at. +@export var look_at_offset: Vector3 = Vector3.ZERO: + set = set_look_at_offset, + get = get_look_at_offset + +## Applies a damping effect on the camera's rotation. +## Leading to heavier / slower camera movement as the targeted node moves around. +## This is useful to avoid sharp and rapid camera rotation. +@export var look_at_damping: bool = false: + set = set_look_at_damping, + get = get_look_at_damping + +## Defines the Rotational damping amount. The ideal range is typically somewhere between 0-1.[br][br] +## The damping amount can be specified in the individual axis.[br][br] +## [b]Lower value[/b] = faster / sharper camera rotation.[br] +## [b]Higher value[/b] = slower / heavier camera rotation. +@export_range(0.0, 1.0, 0.001, "or_greater") var look_at_damping_value: float = 0.25: + set = set_look_at_damping_value, + get = get_look_at_damping_value + +@export_subgroup("Up Direction") + +## Defines the upward direction of the [param PhantomCamera3D] when [member look_at_mode] is set. [br] +## This value will be overriden if [member up_target] is defined. +@export var up: Vector3 = Vector3.UP: + set = set_up, + get = get_up + +## Applies and continuously updates the [param up] direction of the [param PhantomCamera3D] based on this target when [member look_at_mode] is set.[br] +## Setting a value here will override the [member up] value. +@export var up_target: Node3D = null: + set = set_up_target, + get = get_up_target + + +@export_group("Noise") +## Applies a noise, or shake, to a [Camera3D].[br] +## Once set, the noise will run continuously after the tween to the [PhantomCamera3D] instance is complete. +@export var noise: PhantomCameraNoise3D = null: + set = set_noise, + get = get_noise + +## If true, will trigger the noise while in the editor.[br] +## Useful in cases where you want to temporarily disalbe the noise in the editor without removing +## the resource.[br][br] +## [b]Note:[/b] This property has no effect on runtime behaviour. +@export var _preview_noise: bool = true: + set(value): + _preview_noise = value + if not value: + _transform_noise = Transform3D() + +## Enable a corresponding layer for a [member PhantomCameraNoiseEmitter3D.noise_emitter_layer] +## to make this [PhantomCamera3D] be affect by it. +@export_flags_3d_render var noise_emitter_layer: int = 0: + set = set_noise_emitter_layer, + get = get_noise_emitter_layer + +#endregion + +#region Private Variables + +var _is_active: bool = false + +var _is_third_person_follow: bool = false +var _camera_target: Node3D = self # Calculates the position of the camera in the editor, uses instantiated SpringArm3D node when running the scene + +var _should_follow: bool = false +var _follow_target_physics_based: bool = false +var _physics_interpolation_enabled: bool = false ## TOOD - Should be enbled once toggling physics_interpolation_mode ON, when previously OFF, works in 3D + +var _has_multiple_follow_targets: bool = false +var _follow_targets_single_target_index: int = 0 +var _follow_targets: Array[Node3D] = [] + +var _should_look_at: bool = false +var _look_at_target_physics_based: bool = false + +var _has_multiple_look_at_targets: bool = false +var _look_at_targets_single_target_index: int = 0 + +var _current_rotation: Vector3 = Vector3.ZERO + +var _up: Vector3 = Vector3.UP +var _has_up_target: bool = false + +var _follow_target_position: Vector3 = Vector3.ZERO +var _look_at_target_position: Vector3 = Vector3.ZERO + +var _transform_output: Transform3D = Transform3D() +var _transform_noise: Transform3D = Transform3D() + +var _tween_skip: bool = false + +var _follow_velocity_ref: Vector3 = Vector3.ZERO # Stores and applies the velocity of the movement + +var _follow_framed_initial_set: bool = false +var _follow_framed_offset: Vector3 = Vector3.ZERO + +var _follow_spring_arm: SpringArm3D = null +var _has_follow_spring_arm: bool = false + +var _has_noise_resource: bool = false + + +# NOTE - Temp solution until Godot has better plugin autoload recognition out-of-the-box. +var _phantom_camera_manager: Node = null + +#endregion + +#region Public Variable + +var tween_duration: float: + set = set_tween_duration, + get = get_tween_duration +var tween_transition: PhantomCameraTween.TransitionType: + set = set_tween_transition, + get = get_tween_transition +var tween_ease: PhantomCameraTween.EaseType: + set = set_tween_ease, + get = get_tween_ease + +var keep_aspect: int: + set = set_keep_aspect, + get = get_keep_aspect +var cull_mask: int: + set = set_cull_mask, + get = get_cull_mask +var h_offset: float: + set = set_h_offset, + get = get_h_offset +var v_offset: float: + set = set_v_offset, + get = get_v_offset +var projection: Camera3DResource.ProjectionType: + set = set_projection, + get = get_projection +var fov: float: + set = set_fov, + get = get_fov +var size: float: + set = set_size, + get = get_size +var frustum_offset: Vector2: + set = set_frustum_offset, + get = get_frustum_offset +var far: float: + set = set_far, + get = get_far +var near: float: + set = set_near, + get = get_near + +var viewport_position: Vector2 + +#endregion + + +#region Private Functions + +func _validate_property(property: Dictionary) -> void: + ################ + ## Follow Target + ################ + if property.name == "follow_target": + if follow_mode == FollowMode.NONE or \ + follow_mode == FollowMode.GROUP: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "follow_path" and \ + follow_mode != FollowMode.PATH: + property.usage = PROPERTY_USAGE_NO_EDITOR + + #################### + ## Follow Parameters + #################### + if follow_mode == FollowMode.NONE: + match property.name: + "follow_offset", \ + "follow_damping", \ + "follow_damping_value", \ + "follow_axis_lock": + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "follow_offset": + if follow_mode == FollowMode.PATH or \ + follow_mode == FollowMode.GLUED: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "follow_damping_value" and not follow_damping: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "follow_offset": + if follow_mode == FollowMode.PATH: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "follow_distance": + if not follow_mode == FollowMode.FRAMED: + if not follow_mode == FollowMode.GROUP or \ + auto_follow_distance: \ + property.usage = PROPERTY_USAGE_NO_EDITOR + + ############### + ## Group Follow + ############### + if property.name == "follow_targets" and \ + not follow_mode == FollowMode.GROUP: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "auto_follow_distance" and \ + not follow_mode == FollowMode.GROUP: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if not auto_follow_distance or not follow_mode == FollowMode.GROUP: + match property.name: + "auto_follow_distance_min", \ + "auto_follow_distance_max", \ + "auto_follow_distance_divisor": + property.usage = PROPERTY_USAGE_NO_EDITOR + + ############### + ## Framed Follow + ############### + if not follow_mode == FollowMode.FRAMED: + match property.name: + "dead_zone_width", \ + "dead_zone_height", \ + "show_viewfinder_in_play": + property.usage = PROPERTY_USAGE_NO_EDITOR + + ###################### + ## Third Person Follow + ###################### + if not follow_mode == FollowMode.THIRD_PERSON: + match property.name: + "vertical_rotation_offset", \ + "horizontal_rotation_offset", \ + "spring_length", \ + "collision_mask", \ + "shape", \ + "margin": + property.usage = PROPERTY_USAGE_NO_EDITOR + + ########## + ## Look At + ########## + if look_at_mode == LookAtMode.NONE: + match property.name: + "look_at_target", \ + "look_at_offset" , \ + "look_at_damping", \ + "look_at_damping_value", \ + "up", \ + "up_target": + property.usage = PROPERTY_USAGE_NO_EDITOR + elif look_at_mode == LookAtMode.GROUP: + match property.name: + "look_at_target": + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "look_at_target": + if look_at_mode == LookAtMode.NONE or \ + look_at_mode == LookAtMode.GROUP: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "look_at_targets" and \ + not look_at_mode == LookAtMode.GROUP: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "look_at_damping_value" and \ + not look_at_damping: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "up" and _has_up_target: + property.usage = PROPERTY_USAGE_NO_EDITOR + + +func _enter_tree() -> void: + _phantom_camera_manager = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME) + _tween_skip = !tween_on_load + + _phantom_camera_manager.pcam_added(self) + + priority_override = false + + if not visibility_changed.is_connected(_check_visibility): + visibility_changed.connect(_check_visibility) + + match follow_mode: + FollowMode.NONE: + _is_parents_physics() + FollowMode.PATH: + if is_instance_valid(follow_path): + _should_follow_checker() + else: + _should_follow = false + FollowMode.GROUP: + _follow_targets_size_check() + _should_follow_checker() + _: + _should_follow_checker() + + _should_look_at_checker() + if look_at_mode == LookAtMode.GROUP: + _look_at_targets_size_check() + + #if not get_parent() is SpringArm3D: + #if look_at_target: + #_look_at_target_node = look_at_target + #elif look_at_targets: + #_look_at_group_nodes.clear() + #for path in look_at_targets: + #if not path.is_empty() and path: + #_should_look_at = true + #_has_look_at_targets = true + #_look_at_group_nodes.append(path) + + +func _exit_tree() -> void: + if not follow_mode == FollowMode.GROUP: + follow_targets = [] + + if not is_instance_valid(_phantom_camera_manager): return + _phantom_camera_manager.pcam_removed(self) + + +func _ready(): + match follow_mode: + FollowMode.THIRD_PERSON: + _is_third_person_follow = true + if _should_follow: _transform_output.origin = _get_target_position_offset_distance() + if not Engine.is_editor_hint(): + if not is_instance_valid(_follow_spring_arm): + _follow_spring_arm = SpringArm3D.new() + _follow_spring_arm.top_level = true + _follow_spring_arm.spring_length = spring_length + _follow_spring_arm.collision_mask = collision_mask + _follow_spring_arm.shape = shape + _follow_spring_arm.margin = margin + # Stores the rotation value as the rotation gets skewed after + # the SpringArm3D is instantiated for some reason... + var initial_rotation: Vector3 = global_rotation + if _should_follow: _follow_spring_arm.add_excluded_object(follow_target) + get_parent().add_child.call_deferred(_follow_spring_arm) + + # Waits for the SpringArm3D to be ready and then apply rotation + # Resolves an issue most prominent in Godot 4.4 + await _follow_spring_arm.ready + reparent.call_deferred(_follow_spring_arm) + _camera_target = _follow_spring_arm + _follow_spring_arm.global_position = _get_target_position_offset() if is_instance_valid(follow_target) else global_position + _follow_spring_arm.global_rotation = initial_rotation + _has_follow_spring_arm = true + top_level = false + FollowMode.FRAMED: + if not Engine.is_editor_hint(): + if is_instance_valid(follow_target): + _follow_framed_offset = global_position - _get_target_position_offset() + _current_rotation = global_rotation + FollowMode.GROUP: + _follow_targets_size_check() + _: + if is_instance_valid(follow_target): + _transform_output.origin = _get_target_position_offset() + else: + _transform_output.origin = global_position + + if not Engine.is_editor_hint(): + _preview_noise = true + + ## NOTE - Only here to set position for Framed View on startup. + ## Should be removed once https://github.com/ramokz/phantom-camera/issues/161 is complete + _transform_output = global_transform + + _phantom_camera_manager.noise_3d_emitted.connect(_noise_emitted) + + +func _process(delta: float) -> void: + if _follow_target_physics_based or _is_active: return + process_logic(delta) + + +func _physics_process(delta: float) -> void: + if not _follow_target_physics_based or _is_active: return + process_logic(delta) + + +func process_logic(delta: float) -> void: + if _is_active: + if _has_noise_resource and _preview_noise: + _transform_noise = noise.get_noise_transform(delta) + else: + match inactive_update_mode: + InactiveUpdateMode.NEVER: return + # InactiveUpdateMode.EXPONENTIALLY: + # TODO - Trigger positional updates less frequently as more PCams gets added + + if _should_follow: + _follow(delta) + else: + _transform_output.origin = global_position + + if _should_look_at: + _look_at(delta) + elif not _is_third_person_follow: + _transform_output.basis = global_basis + + if _follow_axis_is_locked: + match follow_axis_lock: + FollowLockAxis.X: + _transform_output.origin.x = _follow_axis_lock_value.x + FollowLockAxis.Y: + _transform_output.origin.y = _follow_axis_lock_value.y + FollowLockAxis.Z: + _transform_output.origin.z = _follow_axis_lock_value.z + FollowLockAxis.XY: + _transform_output.origin.x = _follow_axis_lock_value.x + _transform_output.origin.y = _follow_axis_lock_value.y + FollowLockAxis.XZ: + _transform_output.origin.x = _follow_axis_lock_value.x + _transform_output.origin.z = _follow_axis_lock_value.z + FollowLockAxis.YZ: + _transform_output.origin.y = _follow_axis_lock_value.y + _transform_output.origin.z = _follow_axis_lock_value.z + FollowLockAxis.XYZ: + _transform_output.origin.x = _follow_axis_lock_value.x + _transform_output.origin.y = _follow_axis_lock_value.y + _transform_output.origin.z = _follow_axis_lock_value.z + + +func _follow(delta: float) -> void: + _set_follow_position() + _interpolate_position(delta) + +func _look_at(delta: float) -> void: + _set_look_at_position() + _interpolate_rotation(delta) + + +func _set_follow_position() -> void: + match follow_mode: + FollowMode.GLUED: + _follow_target_position = follow_target.global_position + + FollowMode.SIMPLE: + _follow_target_position = _get_target_position_offset() + + FollowMode.GROUP: + if _has_multiple_follow_targets: + var bounds: AABB = AABB(_follow_targets[0].global_position, Vector3.ZERO) + for target in _follow_targets: + bounds = bounds.expand(target.global_position) + var distance: float + if auto_follow_distance: + distance = lerpf(auto_follow_distance_min, auto_follow_distance_max, bounds.get_longest_axis_size() / auto_follow_distance_divisor) + distance = clampf(distance, auto_follow_distance_min, auto_follow_distance_max) + else: + distance = follow_distance + + _follow_target_position = \ + bounds.get_center() + \ + follow_offset + \ + global_basis.z * \ + distance + else: + _follow_target_position = \ + follow_targets[_follow_targets_single_target_index].global_position + \ + follow_offset + \ + global_basis.z * \ + auto_follow_distance_min + + FollowMode.PATH: + var path_position: Vector3 = follow_path.global_position + _follow_target_position = \ + follow_path.curve.get_closest_point( + follow_target.global_position - path_position + ) + path_position + + FollowMode.FRAMED: + if not Engine.is_editor_hint(): + if not _is_active: + _follow_target_position = _get_target_position_offset_distance() + else: + viewport_position = get_viewport().get_camera_3d().unproject_position(_get_target_position_offset()) + var visible_rect_size: Vector2 = get_viewport().get_visible_rect().size + viewport_position = viewport_position / visible_rect_size + _current_rotation = global_rotation + + if _current_rotation != global_rotation: + _follow_target_position = _get_target_position_offset_distance() + + if _get_framed_side_offset() != Vector2.ZERO: + var target_position: Vector3 = _get_target_position_offset() + _follow_framed_offset + var glo_pos: Vector3 + + if dead_zone_width == 0 || dead_zone_height == 0: + if dead_zone_width == 0 && dead_zone_height != 0: + glo_pos = _get_target_position_offset_distance() + glo_pos.z = target_position.z + _follow_target_position = glo_pos + elif dead_zone_width != 0 && dead_zone_height == 0: + glo_pos = _get_target_position_offset_distance() + glo_pos.x = target_position.x + _follow_target_position = glo_pos + else: + _follow_target_position = _get_target_position_offset_distance() + else: + if _current_rotation != global_rotation: + var opposite: float = sin(-global_rotation.x) * follow_distance + _get_target_position_offset().y + glo_pos.y = _get_target_position_offset().y + opposite + glo_pos.z = sqrt(pow(follow_distance, 2) - pow(opposite, 2)) + _get_target_position_offset().z + glo_pos.x = global_position.x + + _follow_target_position = glo_pos + _current_rotation = global_rotation + else: + dead_zone_reached.emit() + _follow_target_position = target_position + else: + _follow_framed_offset = global_position - _get_target_position_offset() + _current_rotation = global_rotation + return + else: + _follow_target_position = _get_target_position_offset_distance() + var unprojected_position: Vector2 = _get_raw_unprojected_position() + var viewport_width: float = get_viewport().size.x + var viewport_height: float = get_viewport().size.y + var camera_aspect: int = get_viewport().get_camera_3d().keep_aspect + var visible_rect_size: Vector2 = get_viewport().get_visible_rect().size + + unprojected_position = unprojected_position - visible_rect_size / 2 + if camera_aspect == Camera3D.KEEP_HEIGHT: + # Landscape View + var aspect_ratio_scale: float = viewport_width / viewport_height + unprojected_position.x = (unprojected_position.x / aspect_ratio_scale + 1) / 2 + unprojected_position.y = (unprojected_position.y + 1) / 2 + else: + # Portrait View + var aspect_ratio_scale: float = viewport_height / viewport_width + unprojected_position.x = (unprojected_position.x + 1) / 2 + unprojected_position.y = (unprojected_position.y / aspect_ratio_scale + 1) / 2 + + viewport_position = unprojected_position + + FollowMode.THIRD_PERSON: + if not Engine.is_editor_hint(): + if not _has_follow_spring_arm: return + _follow_target_position = _get_target_position_offset() + else: + _follow_target_position = _get_target_position_offset_distance_direction() + + +func _set_look_at_position() -> void: + match look_at_mode: + LookAtMode.MIMIC: + _look_at_target_position = global_position - look_at_target.global_basis.z + + LookAtMode.SIMPLE: + _look_at_target_position =look_at_target.global_position + + LookAtMode.GROUP: + if not _has_multiple_look_at_targets: + _look_at_target_position =look_at_targets[_look_at_targets_single_target_index].global_position + else: + var bounds: AABB = AABB(look_at_targets[0].global_position, Vector3.ZERO) + for node in look_at_targets: + bounds = bounds.expand(node.global_position) + _look_at_target_position =bounds.get_center() + + +func _get_target_position_offset() -> Vector3: + return follow_target.global_position + follow_offset + + +func _get_target_position_offset_distance() -> Vector3: + return _get_target_position_offset() + \ + transform.basis.z * follow_distance + +# Used in the editor for setting initial Third Person position and angle +func _get_target_position_offset_distance_direction() -> Vector3: + return _get_target_position_offset() + \ + follow_target.global_basis.z * \ + follow_distance * \ + Quaternion(follow_target.global_basis.x, vertical_rotation_offset) * \ + Quaternion(follow_target.global_basis.y, horizontal_rotation_offset) + + +func _set_follow_velocity(index: int, value: float) -> void: + _follow_velocity_ref[index] = value + +func _interpolate_position(delta: float) -> void: + if follow_damping and not Engine.is_editor_hint(): + if not _is_third_person_follow: + global_position = _follow_target_position + for i in 3: + _transform_output.origin[i] = _smooth_damp( + global_position[i], + _transform_output.origin[i], + i, + _follow_velocity_ref[i], + _set_follow_velocity, + follow_damping_value[i], + delta + ) + else: + for i in 3: + _camera_target.global_position[i] = _smooth_damp( + _follow_target_position[i], + _camera_target.global_position[i], + i, + _follow_velocity_ref[i], + _set_follow_velocity, + follow_damping_value[i], + delta + ) + _transform_output.origin = global_position + else: + _camera_target.global_position = _follow_target_position + _transform_output.origin = global_position + + if _is_third_person_follow: + var target_quat: Quaternion = _look_at_target_quat(_get_target_position_offset(), follow_target.global_basis.y) + var target_basis: Basis = Basis(target_quat) + _transform_output.basis = target_basis + global_basis = target_basis + + +func _look_at_target_quat(target_position: Vector3, up_direction: Vector3 = Vector3.UP) -> Quaternion: + var direction: Vector3 = -(target_position - global_position + look_at_offset).normalized() + + var basis_z: Vector3 = direction.normalized() + var basis_x: Vector3 = up_direction.cross(basis_z) + var basis_y: Vector3 = basis_z.cross(basis_x.normalized()) + + var target_basis: Basis = Basis(basis_x, basis_y, basis_z) + + if target_basis.determinant() == 0: + if target_basis.z == Vector3.UP: + global_rotation_degrees.x = -90 + else: + global_rotation_degrees.x = 90 + + _transform_output.basis = global_basis + return quaternion + + return target_basis.get_rotation_quaternion().normalized() + +func _interpolate_rotation(delta: float) -> void: + if _has_up_target: + _up = up_target.global_basis.y + + var target_quat: Quaternion = _look_at_target_quat(_look_at_target_position, _up) + + if look_at_damping: + var current_quat: Quaternion = quaternion.normalized() + var damping_time: float = max(0.0001, look_at_damping_value) + var t: float = min(1.0, delta / damping_time) + + var dot: float = current_quat.dot(target_quat) + + if dot < 0.0: + target_quat = -target_quat + dot = -dot + + dot = clampf(dot, -1.0, 1.0) + + var theta: float = acos(dot) * t + var sin_theta: float = sin(theta) + var sin_theta_total: float = sin(acos(dot)) + + if is_zero_approx(sin_theta_total): return + + var ratio_a: float = cos(theta) - dot * sin_theta / sin_theta_total + var ratio_b: float = sin_theta / sin_theta_total + var output: Quaternion = current_quat * ratio_a + target_quat * ratio_b + + _transform_output.basis = Basis(output) + quaternion = output + else: + _transform_output.basis = Basis(target_quat) + quaternion = target_quat + + +func _smooth_damp(target_axis: float, self_axis: float, index: int, current_velocity: float, set_velocity: Callable, damping_time: float, delta: float) -> float: + damping_time = maxf(0.0001, damping_time) + var omega: float = 2 / damping_time + var x: float = omega * delta + var exponential: float = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x) + var diff: float = self_axis - target_axis + var _target_axis: float = target_axis + + var max_change: float = INF * damping_time + diff = clampf(diff, -max_change, max_change) + target_axis = self_axis - diff + + var temp: float = (current_velocity + omega * diff) * delta + set_velocity.call(index, (current_velocity - omega * temp) * exponential) + var output: float = target_axis + (diff + temp) * exponential + + ## To prevent overshooting + if (_target_axis - self_axis > 0.0) == (output > _target_axis): + output = _target_axis + set_velocity.call(index, (output - _target_axis) / delta) + + return output + + +func _get_raw_unprojected_position() -> Vector2: + return get_viewport().get_camera_3d().unproject_position(follow_target.global_position + follow_offset) + + +func _on_dead_zone_changed() -> void: + global_position = _get_target_position_offset_distance() + + +func _get_framed_side_offset() -> Vector2: + var frame_out_bounds: Vector2 + + if viewport_position.x < 0.5 - dead_zone_width / 2: + # Is outside left edge + frame_out_bounds.x = -1 + + if viewport_position.y < 0.5 - dead_zone_height / 2: + # Is outside top edge + frame_out_bounds.y = 1 + + if viewport_position.x > 0.5 + dead_zone_width / 2: + # Is outside right edge + frame_out_bounds.x = 1 + + if viewport_position.y > 0.5001 + dead_zone_height / 2: # 0.501 to resolve an issue where the bottom vertical Dead Zone never becoming 0 when the Dead Zone Vertical parameter is set to 0 + # Is outside bottom edge + frame_out_bounds.y = -1 + + return frame_out_bounds + + +func _set_layer(current_layers: int, layer_number: int, value: bool) -> int: + var mask: int = current_layers + + # From https://github.com/godotengine/godot/blob/51991e20143a39e9ef0107163eaf283ca0a761ea/scene/3d/camera_3d.cpp#L638 + if layer_number < 1 or layer_number > 20: + printerr("Render layer must be between 1 and 20.") + else: + if value: + mask |= 1 << (layer_number - 1) + else: + mask &= ~(1 << (layer_number - 1)) + + return mask + + +func _check_visibility() -> void: + _phantom_camera_manager.pcam_visibility_changed.emit(self) + + +func _follow_target_tree_exiting(target: Node) -> void: + if target == follow_target: + _should_follow = false + if _follow_targets.has(target): + _follow_targets.erase(target) + + +func _should_follow_checker() -> void: + if follow_mode == FollowMode.NONE: + _should_follow = false + return + + if not follow_mode == FollowMode.GROUP: + if is_instance_valid(follow_target): + _should_follow = true + else: + _should_follow = false + + +func _follow_targets_size_check() -> void: + var targets_size: int = 0 + _follow_target_physics_based = false + _follow_targets = [] + for i in follow_targets.size(): + if follow_targets[i] == null: continue + if follow_targets[i].is_inside_tree(): + _follow_targets.append(follow_targets[i]) + targets_size += 1 + _follow_targets_single_target_index = i + _check_physics_body(follow_targets[i]) + if not follow_targets[i].tree_exiting.is_connected(_follow_target_tree_exiting): + follow_targets[i].tree_exiting.connect(_follow_target_tree_exiting.bind(follow_targets[i])) + + match targets_size: + 0: + _should_follow = false + _has_multiple_follow_targets = false + 1: + _should_follow = true + _has_multiple_follow_targets = false + _: + _should_follow = true + _has_multiple_follow_targets = true + + +func _look_at_target_tree_exiting(target: Node) -> void: + if target == look_at_target: + _should_look_at = false + if look_at_targets.has(target): + erase_look_at_targets(target) + +func _up_target_tree_exiting() -> void: + up_target = null + + +func _should_look_at_checker() -> void: + if look_at_mode == LookAtMode.NONE: + _should_look_at = false + return + + if not look_at_mode == LookAtMode.GROUP: + if is_instance_valid(look_at_target): + _should_look_at = true + else: + _should_look_at = false + + +func _look_at_targets_size_check() -> void: + var targets_size: int = 0 + _look_at_target_physics_based = false + + for i in look_at_targets.size(): + if is_instance_valid(look_at_targets[i]): + targets_size += 1 + _look_at_targets_single_target_index = i + _check_physics_body(look_at_targets[i]) + if not look_at_targets[i].tree_exiting.is_connected(_look_at_target_tree_exiting): + look_at_targets[i].tree_exiting.connect(_look_at_target_tree_exiting.bind(look_at_targets[i])) + + match targets_size: + 0: + _should_look_at = false + _has_multiple_look_at_targets = false + 1: + _should_look_at = true + _has_multiple_look_at_targets = false + _: + _should_look_at = true + _has_multiple_look_at_targets = true + + +func _noise_emitted(emitter_noise_output: Transform3D, emitter_layer: int) -> void: + if noise_emitter_layer & emitter_layer != 0: + noise_emitted.emit(emitter_noise_output) + + +func _check_physics_body(target: Node3D) -> void: + if target is PhysicsBody3D: + var show_jitter_tips := ProjectSettings.get_setting("phantom_camera/tips/show_jitter_tips") + var physics_interpolation_enabled := ProjectSettings.get_setting("physics/common/physics_interpolation") + + ## NOTE - Feature Toggle + if Engine.get_version_info().major == 4 and \ + Engine.get_version_info().minor < 4: + if show_jitter_tips == null: # Default value is null when referencing custom Project Setting + print_rich("Following or Looking at a [b]PhysicsBody3D[/b] node will likely result in jitter - on lower physics ticks in particular.") + print_rich("If possible, will recommend upgrading to Godot 4.4, as it has built-in support for 3D Physics Interpolation, which will mitigate this issue.") + print_rich("Until then, try following the guide on the [url=https://phantom-camera.dev/support/faq#i-m-seeing-jitter-what-can-i-do]documentation site[/url] for better results.") + print_rich("This tip can be disabled from within [code]Project Settings / Phantom Camera / Tips / Show Jitter Tips[/code]") + return + ## NOTE - Only supported in Godot 4.4 or above + elif not physics_interpolation_enabled and show_jitter_tips == null: # Default value is null when referencing custom Project Setting + printerr("Physics Interpolation is disabled in the Project Settings, recommend enabling it to smooth out physics-based camera movement") + print_rich("This tip can be disabled from within [code]Project Settings / Phantom Camera / Tips / Show Jitter Tips[/code]") + _follow_target_physics_based = true + else: + _is_parents_physics(target) + physics_target_changed.emit() + + +func _is_parents_physics(target: Node = self) -> void: + var current_node: Node = target + while current_node: + current_node = current_node.get_parent() + if not current_node is PhysicsBody3D: continue + _follow_target_physics_based = true + + +func _camera_resource_changed() -> void: + camera_3d_resource_changed.emit() + +#endregion + +#region Public Functions + +# TBD +#func get_unprojected_position() -> Vector2: + #var unprojected_position: Vector2 = _get_raw_unprojected_position() + #var viewport_width: float = get_viewport().size.x + #var viewport_height: float = get_viewport().size.y + #var camera_aspect: Camera3D.KeepAspect = get_viewport().get_camera_3d().keep_aspect + #var visible_rect_size: Vector2 = get_viewport().size +# + #unprojected_position = unprojected_position - visible_rect_size / 2 + #if camera_aspect == Camera3D.KeepAspect.KEEP_HEIGHT: +## print("Landscape View") + #var aspect_ratio_scale: float = viewport_width / viewport_height + #unprojected_position.x = (unprojected_position.x / aspect_ratio_scale + 1) / 2 + #unprojected_position.y = (unprojected_position.y + 1) / 2 + #else: +## print("Portrait View") + #var aspect_ratio_scale: float = viewport_height / viewport_width + #unprojected_position.x = (unprojected_position.x + 1) / 2 + #unprojected_position.y = (unprojected_position.y / aspect_ratio_scale + 1) / 2 +# + #return unprojected_position + + +## Returns the [Transform3D] value based on the [member follow_mode] / [member look_at_mode] target value. +func get_transform_output() -> Transform3D: + return _transform_output + + +## Returns the noise [Transform3D] value. +func get_noise_transform() -> Transform3D: + return _transform_noise + + +## Emits a noise based on a custom [Transform3D] value.[br] +## Use this function if you wish to make use of external noise patterns from, for example, other addons. +func emit_noise(value: Transform3D) -> void: + noise_emitted.emit(value) + + +## Teleports the [param PhantomCamera3D] and [Camera3D] to their designated position, +## bypassing the damping process. +func teleport_position() -> void: + _follow_velocity_ref = Vector3.ZERO + _set_follow_position() + _transform_output.origin = _follow_target_position + _phantom_camera_manager.pcam_teleport.emit(self) + + +# TODO: Enum link does link to anywhere is being tracked in: https://github.com/godotengine/godot/issues/106828 +## Returns [code]true[/code] if this [param PhantomCamera3D]'s [member follow_mode] is not set to [constant FollowMode.NONE] +## and has a valid [member follow_target]. +func is_following() -> bool: + return _should_follow + +# TODO: Enum link does link to anywhere is being tracked in: https://github.com/godotengine/godot/issues/106828 +## Returns [code]true[/code] if this [param PhantomCamera3D]'s [member look_at_mode] is not set to [constant LookAtMode.NONE] +## and has a valid [member look_at_target]. +func is_looking() -> bool: + return _should_look_at + +#endregion + + +#region Setter & Getter Functions + +## Assigns the value of the [param has_tweened] property.[br] +## [b][color=yellow]Important:[/color][/b] This value can only be changed +## from the [PhantomCameraHost] script. +func set_tween_skip(caller: Node, value: bool) -> void: + if is_instance_of(caller, PhantomCameraHost): + _tween_skip = value + else: + printerr("Can only be called PhantomCameraHost class") +## Returns the current [param has_tweened] value. +func get_tween_skip() -> bool: + return _tween_skip + + +## Assigns new [member priority] value. +func set_priority(value: int) -> void: + priority = maxi(0, value) + if not is_node_ready(): return + if not Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): return + Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME).pcam_priority_changed.emit(self) +## Gets current [param Priority] value. +func get_priority() -> int: + return priority + + +## Assigns a new [PhantomCameraTween] resource to the [param PhantomCamera3D]. +func set_tween_resource(value: PhantomCameraTween) -> void: + tween_resource = value +## Gets the [param PhantomCameraTween] resource assigned to the [param PhantomCamera3D]. +## Returns null if there's nothing assigned to it. +func get_tween_resource() -> PhantomCameraTween: + return tween_resource + +## Assigns a new [param Tween Duration] to the [member tween_resource] value.[br] +## The duration value is in seconds. +func set_tween_duration(value: float) -> void: + tween_resource.duration = value +## Gets the current [param Tween] Duration value. The duration value is in +## [param seconds]. +func get_tween_duration() -> float: + return tween_resource.duration + +## Assigns a new [param Tween Transition] to the [member tween_resource] value.[br] +## The duration value is in seconds. +func set_tween_transition(value: int) -> void: + tween_resource.transition = value +## Gets the current [param Tween Transition] value. +func get_tween_transition() -> int: + return tween_resource.transition + +## Assigns a new [param Tween Ease] to the [member tween_resource] value.[br] +## The duration value is in seconds. +func set_tween_ease(value: int) -> void: + tween_resource.ease = value +## Gets the current [param Tween Ease] value. +func get_tween_ease() -> int: + return tween_resource.ease + +## Sets the [param PhantomCamera3D] active state[br] +## [b][color=yellow]Important:[/color][/b] This value can only be changed +## from the [PhantomCameraHost] script. +func set_is_active(node: Node, value: bool) -> void: + if node is PhantomCameraHost: + _is_active = value + if value: + _should_follow_checker() + else: + printerr("PCams can only be set from the PhantomCameraHost") +## Gets current active state of the [param PhantomCamera3D]. +## If it returns true, it means the [param PhantomCamera3D] is what the +## [param Camera3D] is currently following. +func is_active() -> bool: + return _is_active + + +## Enables or disables the [member tween_on_load]. +func set_tween_on_load(value: bool) -> void: + tween_on_load = value +## Gets the current [member tween_on_load] value. +func get_tween_on_load() -> bool: + return tween_on_load + + +## Sets the [member host_layers] value. +func set_host_layers(value: int) -> void: + host_layers = value + if is_instance_valid(_phantom_camera_manager): + _phantom_camera_manager.pcam_host_layer_changed.emit(self) + +## Enables or disables a given layer of [member host_layers]. +func set_host_layers_value(layer: int, value: bool) -> void: + host_layers = _set_layer(host_layers, layer, value) + +## Gets the current [member host_layers]. +func get_host_layers() -> int: + return host_layers + + +## Gets the current follow mode as an enum int based on [member FollowMode] enum.[br] +## [b]Note:[/b] Setting [member follow_mode] has purposely not been added. +## A separate [param PhantomCamera3D] instance should be used instead. +func get_follow_mode() -> int: + return follow_mode + + +## Assigns a new [Node3D] as the [member follow_target]. +func set_follow_target(value: Node3D) -> void: + if follow_mode == FollowMode.NONE or follow_mode == FollowMode.GROUP: return + if follow_target == value: return + follow_target = value + _follow_target_physics_based = false + if is_instance_valid(value): + if follow_mode == FollowMode.PATH: + if is_instance_valid(follow_path): + _should_follow = true + else: + _should_follow = false + else: + _should_follow = true + _check_physics_body(value) + if follow_mode == FollowMode.THIRD_PERSON and is_instance_valid(_follow_spring_arm): + _follow_spring_arm.add_excluded_object(follow_target) + if not follow_target.tree_exiting.is_connected(_follow_target_tree_exiting): + follow_target.tree_exiting.connect(_follow_target_tree_exiting.bind(follow_target)) + else: + if not follow_mode == FollowMode.GROUP: + _should_follow = false + follow_target_changed.emit() + notify_property_list_changed() +## Removes the current [Node3D] [member follow_target]. +func erase_follow_target() -> void: + follow_target = null +## Gets the current Node3D target. +func get_follow_target() -> Node3D: + return follow_target + + +## Assigns a new [Path3D] to the [member follow_path] property. +func set_follow_path(value: Path3D) -> void: + follow_path = value + if is_instance_valid(follow_path): + _should_follow_checker() + else: + _should_follow = false + +## Erases the current [Path3D] from [member follow_path] property. +func erase_follow_path() -> void: + follow_path = null + +## Gets the current [Path3D] from the [member follow_path] property. +func get_follow_path() -> Path3D: + return follow_path + + +## Assigns a new [param follow_targets] array value. +func set_follow_targets(value: Array[Node3D]) -> void: + if not follow_mode == FollowMode.GROUP: return + if follow_targets == value: return + follow_targets = value + _follow_targets_size_check() + + +## Adds a single [Node3D] to [member follow_targets] array. +func append_follow_targets(value: Node3D) -> void: + if not is_instance_valid(value): + printerr(value, " is not a valid Node3D instance") + return + + if not follow_targets.has(value): + follow_targets.append(value) + _follow_targets_size_check() + else: + printerr(value, " is already part of Follow Group") + +## Adds an Array of type [Node3D] to [member follow_targets] array. +func append_follow_targets_array(value: Array[Node3D]) -> void: + for target in value: + if not is_instance_valid(target): continue + if not follow_targets.has(target): + follow_targets.append(target) + _follow_targets_size_check() + else: + printerr(value, " is already part of Follow Group") + +## Removes [Node3D] from [member follow_targets]. +func erase_follow_targets(value: Node3D) -> void: + follow_targets.erase(value) + _follow_targets_size_check() + + +## Gets all [Node3D] from [follow_targets]. +func get_follow_targets() -> Array[Node3D]: + return follow_targets + + +## Assigns a new [param Vector3] for the [param follow_offset] property. +func set_follow_offset(value: Vector3) -> void: + var temp_offset: Vector3 = follow_offset + follow_offset = value + + if follow_axis_lock != FollowLockAxis.NONE: + temp_offset = temp_offset - value + match value: + FollowLockAxis.X: + _follow_axis_lock_value.x = _transform_output.origin.x + temp_offset.x + FollowLockAxis.Y: + _follow_axis_lock_value.y = _transform_output.origin.y + temp_offset.y + FollowLockAxis.Z: + _follow_axis_lock_value.z = _transform_output.origin.z + temp_offset.z + FollowLockAxis.XY: + _follow_axis_lock_value.x = _transform_output.origin.x + temp_offset.x + _follow_axis_lock_value.y = _transform_output.origin.y + temp_offset.y + FollowLockAxis.XZ: + _follow_axis_lock_value.x = _transform_output.origin.x + temp_offset.x + _follow_axis_lock_value.z = _transform_output.origin.z + temp_offset.z + FollowLockAxis.YZ: + _follow_axis_lock_value.y = _transform_output.origin.y + temp_offset.y + _follow_axis_lock_value.z = _transform_output.origin.z + temp_offset.z + FollowLockAxis.XYZ: + _follow_axis_lock_value.x = _transform_output.origin.x + temp_offset.x + _follow_axis_lock_value.y = _transform_output.origin.y + temp_offset.y + _follow_axis_lock_value.z = _transform_output.origin.z + temp_offset.z + +## Gets the current [param Vector3] for the [param follow_offset] property. +func get_follow_offset() -> Vector3: + return follow_offset + + +## Enables or disables [member follow_damping]. +func set_follow_damping(value: bool) -> void: + follow_damping = value + notify_property_list_changed() + +## Gets the currents [member follow_damping] property. +func get_follow_damping() -> bool: + return follow_damping + + +## Assigns new [member follow_damping_value] value. +func set_follow_damping_value(value: Vector3) -> void: + ## TODO - Should be using @export_range once minimum version support is Godot 4.3 + if value.x < 0: value.x = 0 + elif value.y < 0: value.y = 0 + elif value.z < 0: value.z = 0 + follow_damping_value = value + +## Gets the currents [member follow_damping_value] value. +func get_follow_damping_value() -> Vector3: + return follow_damping_value + + +## Assigns a new [member follow_distance] value. +func set_follow_distance(value: float) -> void: + follow_distance = value + +## Gets [member follow_distance] value. +func get_follow_distance() -> float: + return follow_distance + + +## Enables or disables [member auto_follow_distance] when using Group Follow. +func set_auto_follow_distance(value: bool) -> void: + auto_follow_distance = value + notify_property_list_changed() + +## Gets [member auto_follow_distance] state. +func get_auto_follow_distance() -> bool: + return auto_follow_distance + + +## Assigns new [member auto_follow_distance_min] value. +func set_auto_follow_distance_min(value: float) -> void: + auto_follow_distance_min = value + +## Gets [member auto_follow_distance_min] value. +func get_auto_follow_distance_min() -> float: + return auto_follow_distance_min + + +## Assigns new [member auto_follow_distance_max] value. +func set_auto_follow_distance_max(value: float) -> void: + auto_follow_distance_max = value +## Gets [member auto_follow_distance_max] value. +func get_auto_follow_distance_max() -> float: + return auto_follow_distance_max + + +## Assigns new [member auto_follow_distance_divisor] value. +func set_auto_follow_distance_divisor(value: float) -> void: + auto_follow_distance_divisor = value + +## Gets [member auto_follow_distance_divisor] value. +func get_auto_follow_distance_divisor() -> float: + return auto_follow_distance_divisor + + +## Assigns new rotation (in radians) value to [SpringArm3D] for +## [param ThirdPerson] [enum FollowMode]. +func set_third_person_rotation(value: Vector3) -> void: + if not _is_third_person_follow: + printerr("Follow Mode is not set to Third Person") + return + _follow_spring_arm.rotation = value + +## Gets the rotation value (in radians) from the [SpringArm3D] for +## [param ThirdPerson] [enum FollowMode]. +func get_third_person_rotation() -> Vector3: + if not _is_third_person_follow: + printerr("Follow Mode is not set to Third Person") + return Vector3.ZERO + return _follow_spring_arm.rotation + + +## Assigns new rotation (in degrees) value to [SpringArm3D] for +## [param ThirdPerson] [enum FollowMode]. +func set_third_person_rotation_degrees(value: Vector3) -> void: + if not _is_third_person_follow: + printerr("Follow Mode is not set to Third Person") + return + _follow_spring_arm.rotation_degrees = value + +## Gets the rotation value (in degrees) from the [SpringArm3D] for +## [param ThirdPerson] [enum FollowMode]. +func get_third_person_rotation_degrees() -> Vector3: + if not _is_third_person_follow: + printerr("Follow Mode is not set to Third Person") + return Vector3.ZERO + return _follow_spring_arm.rotation_degrees + + +## Assigns new [Quaternion] value to [SpringArm3D] for [param ThirdPerson] +## [enum FollowMode]. +func set_third_person_quaternion(value: Quaternion) -> void: + if not _is_third_person_follow: + printerr("Follow Mode is not set to Third Person") + return + _follow_spring_arm.quaternion = value + +## Gets the [Quaternion] value of the [SpringArm3D] for [param ThirdPerson] +## [enum Follow mode]. +func get_third_person_quaternion() -> Quaternion: + if not _is_third_person_follow: + printerr("Follow Mode is not set to Third Person") + return Quaternion.IDENTITY + return _follow_spring_arm.quaternion + + +## Assigns a new [member set_vertical_rotation_offset] value. +func set_vertical_rotation_offset(value: float) -> void: + vertical_rotation_offset = value + +## Gets the [member vertical_rotation] value. +func get_vertical_rotation_offset() -> float: + return vertical_rotation_offset + + +func set_horizontal_rotation_offset(value: float) -> void: + horizontal_rotation_offset = value + +## Gets the [member horizontal_rotation] value. +func get_horizontal_rotation_offset() -> float: + return horizontal_rotation_offset + + +## Assigns a new ThirdPerson [member SpringArm3D.length] value. +func set_spring_length(value: float) -> void: + follow_distance = value + if not is_instance_valid(_follow_spring_arm): return + _follow_spring_arm.spring_length = value + +## Gets the [member SpringArm3D.length] +## from a [param ThirdPerson] [enum follow_mode] instance. +func get_spring_length() -> float: + return follow_distance + + +## Assigns a new [member collision_mask] to the [SpringArm3D] when [enum FollowMode] +## is set to [param ThirdPerson]. +func set_collision_mask(value: int) -> void: + collision_mask = value + if not is_instance_valid(_follow_spring_arm): return + _follow_spring_arm.collision_mask = collision_mask + +## Enables or disables a specific [member collision_mask] layer for the +## [SpringArm3D] when [enum FollowMode] is set to [param ThirdPerson]. +func set_collision_mask_value(value: int, enabled: bool) -> void: + collision_mask = _set_layer(collision_mask, value, enabled) + if not is_instance_valid(_follow_spring_arm): return + _follow_spring_arm.collision_mask = collision_mask + +## Gets [member collision_mask] from the [SpringArm3D] when [enum FollowMode] +## is set to [param ThirdPerson]. +func get_collision_mask() -> int: + return collision_mask + + +## Assigns a new [SpringArm3D.shape] when [enum FollowMode] +## is set to [param ThirdPerson]. +func set_shape(value: Shape3D) -> void: + shape = value + if not is_instance_valid(_follow_spring_arm): return + _follow_spring_arm.shape = shape + +## Gets [param ThirdPerson] [member SpringArm3D.shape] value. +func get_shape() -> Shape3D: + return shape + + +## Assigns a new [member SpringArm3D.margin] value when [enum FollowMode] +## is set to [param ThirdPerson]. +func set_margin(value: float) -> void: + margin = value + if not is_instance_valid(_follow_spring_arm): return + _follow_spring_arm.margin = margin + +## Gets the [SpringArm3D.margin] when [enum FollowMode] is set to +## [param ThirdPerson]. +func get_margin() -> float: + return margin + + +## Gets the current [member look_at_mode]. Value is based on [enum LookAtMode] +## enum.[br] +## Note: To set a new [member look_at_mode], a separate [param PhantomCamera3D] should be used. +func get_look_at_mode() -> int: + return look_at_mode + + +## Assigns new [Node3D] as [member look_at_target]. +func set_look_at_target(value: Node3D) -> void: + if look_at_mode == LookAtMode.NONE: return + if look_at_target == value: return + look_at_target = value + if not look_at_mode == LookAtMode.GROUP: + if is_instance_valid(look_at_target): + _should_look_at = true + _check_physics_body(value) + if not look_at_target.tree_exiting.is_connected(_look_at_target_tree_exiting): + look_at_target.tree_exiting.connect(_look_at_target_tree_exiting.bind(look_at_target)) + else: + _should_look_at = false + elif look_at_targets.size() == 0: + _should_look_at = false + + look_at_target_changed.emit() + notify_property_list_changed() + +## Gets current [Node3D] from [member look_at_target] property. +func get_look_at_target() -> Node3D: + return look_at_target + + +## Sets an array of type [Node3D] to [member set_look_at_targets]. +func set_look_at_targets(value: Array[Node3D]) -> void: + if not look_at_mode == LookAtMode.GROUP: return + if look_at_targets == value: return + look_at_targets = value + + _look_at_targets_size_check() + notify_property_list_changed() + +## Appends a [Node3D] to [member look_at_targets] array. +func append_look_at_target(value: Node3D) -> void: + if not is_instance_valid(value): + printerr(value, "is an invalid Node3D instance") + return + + if not look_at_targets.has(value): + look_at_targets.append(value) + _look_at_targets_size_check() + else: + printerr(value, " is already part of Look At Group") + + +## Appends an array of type [Node3D] to [member look_at_targets] array. +func append_look_at_targets_array(value: Array[Node3D]) -> void: + for val in value: + if not is_instance_valid(val): continue + if not look_at_targets.has(val): + look_at_targets.append(val) + _look_at_targets_size_check() + else: + printerr(val, " is already part of Look At Group") + +## Removes [Node3D] from [member look_at_targets] array. +func erase_look_at_targets(value: Node3D) -> void: + if look_at_targets.has(value): + look_at_targets.erase(value) + _look_at_targets_size_check() + else: + printerr(value, " is not part of Look At Group") + + +## Removes [Node3D] from [member look_at_targets] array. [br] +## @deprecated: Use [member erase_look_at_targets] instead. +func erase_look_at_targets_member(value: Node3D) -> void: + printerr("erase_look_at_targets_member is deprecated, use erase_look_at_targets instead") + erase_look_at_targets(value) + +## Gets all the [Node3D] instances in [member look_at_targets]. +func get_look_at_targets() -> Array[Node3D]: + return look_at_targets + + +## Assigns a new [Vector3] to the [member look_at_offset] value. +func set_look_at_offset(value: Vector3) -> void: + look_at_offset = value + +## Gets the current [member look_at_offset] value. +func get_look_at_offset() -> Vector3: + return look_at_offset + + +## Enables or disables [member look_at_damping]. +func set_look_at_damping(value: bool) -> void: + look_at_damping = value + notify_property_list_changed() + +## Gets the currents [member look_at_damping] property. +func get_look_at_damping() -> bool: + return look_at_damping + + +## Assigns new [member look_at_damping_value] value. +func set_look_at_damping_value(value: float) -> void: + look_at_damping_value = value + +## Gets the currents [member look_at_damping_value] value. +func get_look_at_damping_value() -> float: + return look_at_damping_value + +## Assigns the Follow Axis. +func set_follow_axis_lock(value: FollowLockAxis) -> void: + follow_axis_lock = value + + # Wait for the node to be ready before setting lock + if not is_node_ready(): await ready + + # Prevent axis lock from working in the editor + if value != FollowLockAxis.NONE and not Engine.is_editor_hint(): + _follow_axis_is_locked = true + match value: + FollowLockAxis.X: + _follow_axis_lock_value.x = _transform_output.origin.x + FollowLockAxis.Y: + _follow_axis_lock_value.y = _transform_output.origin.y + FollowLockAxis.Z: + _follow_axis_lock_value.z = _transform_output.origin.z + FollowLockAxis.XY: + _follow_axis_lock_value.x = _transform_output.origin.x + _follow_axis_lock_value.y = _transform_output.origin.y + FollowLockAxis.XZ: + _follow_axis_lock_value.x = _transform_output.origin.x + _follow_axis_lock_value.z = _transform_output.origin.z + FollowLockAxis.YZ: + _follow_axis_lock_value.y = _transform_output.origin.y + _follow_axis_lock_value.z = _transform_output.origin.z + FollowLockAxis.XYZ: + _follow_axis_lock_value.x = _transform_output.origin.x + _follow_axis_lock_value.y = _transform_output.origin.y + _follow_axis_lock_value.z = _transform_output.origin.z + else: + _follow_axis_is_locked = false + +## Gets the current [member follow_axis_lock] property. Value is based on [enum FollowLockAxis] enum. +func get_follow_axis_lock() -> FollowLockAxis: + return follow_axis_lock + + +## Sets the [member up] value. +func set_up(value: Vector3) -> void: + if value == Vector3.ZERO: + value = Vector3.UP + push_warning("Up value cannot be (0, 0, 0), resetting to (0, 1, 0).") + + up = value + if not _has_up_target: + _up = value + +## Gets the [member up] value. +func get_up() -> Vector3: + return up + + +## Sets the [member up_target]. +func set_up_target(value: Node3D) -> void: + up_target = value + if is_instance_valid(value): + _has_up_target = true + if not value.tree_exiting.is_connected(_up_target_tree_exiting): + value.tree_exiting.connect(_up_target_tree_exiting) + else: + _has_up_target = false + _up = up + notify_property_list_changed() + +## Gets the [member up_target]. +func get_up_target() -> Node3D: + return up_target + + +## Sets a [PhantomCameraNoise3D] resource. +func set_noise(value: PhantomCameraNoise3D) -> void: + noise = value + if value != null: + _has_noise_resource = true + noise.set_trauma(1) + else: + _has_noise_resource = false + _transform_noise = Transform3D() + +func get_noise() -> PhantomCameraNoise3D: + return noise + +func has_noise_resource() -> bool: + return _has_noise_resource + + +## Sets the [member noise_emitter_layer] value. +func set_noise_emitter_layer(value: int) -> void: + noise_emitter_layer = value + +## Enables or disables a given layer of [member noise_emitter_layer]. +func set_noise_emitter_layer_value(value: int, enabled: bool) -> void: + noise_emitter_layer = _set_layer(noise_emitter_layer, value, enabled) + +## Returns the [member noise_emitter_layer]. +func get_noise_emitter_layer() -> int: + return noise_emitter_layer + + +## Sets [member inactive_update_mode] property. +func set_inactive_update_mode(value: int) -> void: + inactive_update_mode = value + +## Gets [member inactive_update_mode] property. +func get_inactive_update_mode() -> int: + return inactive_update_mode + + +## Assigns a [Camera3DResource]. +func set_camera_3d_resource(value: Camera3DResource) -> void: + camera_3d_resource = value + camera_3d_resource_changed.emit() + if value: + if not camera_3d_resource.changed.is_connected(_camera_resource_changed): + camera_3d_resource.changed.connect(_camera_resource_changed) + +## Gets the [Camera3DResource]. +func get_camera_3d_resource() -> Camera3DResource: + return camera_3d_resource + + +func set_keep_aspect(value: int) -> void: + if not camera_3d_resource: + printerr("Can't assign a keep_aspect value. No Camera3DResource assigned to ", name) + return + keep_aspect = value + camera_3d_resource_property_changed.emit("keep_aspect", value) + +func get_keep_aspect() -> Variant: + if not camera_3d_resource: return null + return camera_3d_resource.keep_aspect + + +## Assigns a new [member Camera3D.cull_mask] value.[br] +## [b]Note:[/b] This will override and make the [param Camera3DResource] unique to +## this [param PhantomCamera3D]. +func set_cull_mask(value: int) -> void: + if not camera_3d_resource: + printerr("Can't assign a cull_mask value. No Camera3DResource assigned to ", name) + return + camera_3d_resource.cull_mask = value + camera_3d_resource_property_changed.emit("cull_mask", value) + +## Enables or disables a specific [member Camera3D.cull_mask] layer.[br] +## [b]Note:[/b] This will override and make the [param Camera3DResource] unique to +## this [param PhantomCamera3D]. +func set_cull_mask_value(layer_number: int, value: bool) -> void: + if not camera_3d_resource: + printerr("Can't assign a cull_mask value. No Camera3DResource assigned to ", name) + return + var mask: int = _set_layer(get_cull_mask(), layer_number, value) + camera_3d_resource.cull_mask = mask + camera_3d_resource_property_changed.emit("cull_mask", mask) + +## Gets the [member Camera3D.cull_mask] value assigned to the [Camera3DResource]. +func get_cull_mask() -> Variant: + if not camera_3d_resource: return null + return camera_3d_resource.cull_mask + + +## Assigns a new [Environment] resource to the [Camera3DResource]. +func set_environment(value: Environment) -> void: + environment = value + camera_3d_resource_property_changed.emit("environment", value) + +## Gets the [Camera3D.environment] value assigned to the [Camera3DResource]. +func get_environment() -> Environment: + return environment + + +## Assigns a new [CameraAttributes] resource to the [Camera3DResource]. +func set_attributes(value: CameraAttributes) -> void: + attributes = value + camera_3d_resource_property_changed.emit("attributes", value) + +## Gets the [Camera3D.attributes] value assigned to the [Camera3DResource]. +func get_attributes() -> CameraAttributes: + return attributes + + +## Assigns a new [member Camera3D.h_offset] value.[br] +## [b]Note:[/b] This will override and make the [param Camera3DResource] unique to +## this [param PhantomCamera3D]. +func set_h_offset(value: float) -> void: + if not camera_3d_resource: + printerr("Can't assign a h_offset value. No Camera3DResource assigned to ", name) + return + camera_3d_resource.h_offset = value + camera_3d_resource_property_changed.emit("h_offset", value) + +## Gets the [member Camera3D.h_offset] value assigned to the [param Camera3DResource]. +func get_h_offset() -> Variant: + if not camera_3d_resource: return null + return camera_3d_resource.h_offset + + +## Assigns a new [Camera3D.v_offset] value.[br] +## [b]Note:[/b] This will override and make the [param Camera3DResource] unique to +## this [param PhantomCamera3D]. +func set_v_offset(value: float) -> void: + if not camera_3d_resource: + printerr("Can't assign a v_offset value. No Camera3DResource assigned to ", name) + return + camera_3d_resource.v_offset = value + camera_3d_resource_property_changed.emit("v_offset", value) + +## Gets the [member Camera3D.v_offset] value assigned to the [param Camera3DResource]. +func get_v_offset() -> Variant: + if not camera_3d_resource: return null + return camera_3d_resource.v_offset + + +## Assigns a new [Camera3D.projection] value.[br] +## [b]Note:[/b] This will override and make the [param Camera3DResource] unique to +## this [param PhantomCamera3D]. +func set_projection(value: int) -> void: + if not camera_3d_resource: + printerr("Can't assign a projection value. No Camera3DResource assigned to ", name) + return + camera_3d_resource.projection = value + camera_3d_resource_property_changed.emit("projection", value) + +## Gets the [member Camera3D.projection] value assigned to the [param Camera3DResource]. +func get_projection() -> Variant: + if not camera_3d_resource: return null + return camera_3d_resource.projection + + +## Assigns a new [member Camera3D.fov] value.[br] +## [b]Note:[/b] This will override and make the [param Camera3DResource] unique to +## this [param PhantomCamera3D]. +func set_fov(value: float) -> void: + if not camera_3d_resource: + printerr("Can't assign a fov value. No Camera3DResource assigned to ", name) + return + camera_3d_resource.fov = value + camera_3d_resource_property_changed.emit("fov", value) + +## Gets the [member Camera3D.fov] value assigned to the [param Camera3DResource]. +func get_fov() -> Variant: + if not camera_3d_resource: return null + return camera_3d_resource.fov + + +## Assigns a new [member Camera3D.size] value.[br] +## [b]Note:[/b] This will override and make the [param Camera3DResource] unique to +## this [param PhantomCamera3D]. +func set_size(value: float) -> void: + if not camera_3d_resource: + printerr("Can't assign a size value. No Camera3DResource assigned to ", name) + return + camera_3d_resource.size = value + camera_3d_resource_property_changed.emit("size", value) + +## Gets the [member Camera3D.size] value assigned to the [param Camera3DResource]. +func get_size() -> Variant: + if not camera_3d_resource: return null + return camera_3d_resource.size + + +## Assigns a new [member Camera3D.frustum_offset] value.[br] +## [b]Note:[/b] This will override and make the [param Camera3DResource] unique to +## this [param PhantomCamera3D]. +func set_frustum_offset(value: Vector2) -> void: + if not camera_3d_resource: + printerr("Can't assign a frustum_offset value. No Camera3DResource assigned to ", name) + return + camera_3d_resource.frustum_offset = value + camera_3d_resource_property_changed.emit("frustum_offset", value) + +## Gets the [member Camera3D.frustum_offset] value assigned to the [param Camera3DResource]. +func get_frustum_offset() -> Variant: + if not camera_3d_resource: return null + return camera_3d_resource.frustum_offset + + +## Assigns a new [member Camera3D.near] value.[br] +## [b]Note:[/b] This will override and make the [param Camera3DResource] unique to +## this [param PhantomCamera3D]. +func set_near(value: float) -> void: + if not camera_3d_resource: + printerr("Can't assign a near value. No Camera3DResource assigned to ", name) + return + camera_3d_resource.near = value + camera_3d_resource_property_changed.emit("near", value) + +## Gets the [member Camera3D.near] value assigned to the [param Camera3DResource]. +func get_near() -> Variant: + if not camera_3d_resource: return null + return camera_3d_resource.near + + +## Assigns a new [member Camera3D.far] value.[br] +## [b]Note:[/b] This will override and make the [param Camera3DResource] unique to +## this [param PhantomCamera3D]. +func set_far(value: float) -> void: + if not camera_3d_resource: + printerr("Can't assign a far value. No Camera3DResource assigned to ", name) + return + camera_3d_resource.far = value + camera_3d_resource_property_changed.emit("far", value) + +## Gets the [member Camera3D.far] value assigned to the [param Camera3DResource]. +func get_far() -> Variant: + if not camera_3d_resource: return null + return camera_3d_resource.far + + +func get_follow_target_physics_based() -> bool: + return _follow_target_physics_based + + +func get_class() -> String: + return "PhantomCamera3D" + + +func is_class(value) -> bool: + return value == "PhantomCamera3D" + +#endregion diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd.uid b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd.uid new file mode 100644 index 0000000..31a2fc9 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd.uid @@ -0,0 +1 @@ +uid://csjccrhj5wnx7 diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd new file mode 100644 index 0000000..43f6cf4 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd @@ -0,0 +1,29 @@ +@tool +extends RefCounted + +#region Constants + +#const PhantomCameraHost: Script = preload("res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd") + +const CAMERA_2D_NODE_NAME: StringName = "Camera2D" +const CAMERA_3D_NODE_NAME: StringName = "Camera3D" +const PCAM_HOST_NODE_NAME: StringName = "PhantomCameraHost" +const PCAM_MANAGER_NODE_NAME: String = "PhantomCameraManager" # TODO - Convert to StringName once https://github.com/godotengine/godot/pull/72702 is merged +const PCAM_2D_NODE_NAME: StringName = "PhantomCamera2D" +const PCAM_3D_NODE_NAME: StringName = "PhantomCamera3D" +const PCAM_HOST: StringName = "phantom_camera_host" + +const COLOR_2D: Color = Color("8DA5F3") +const COLOR_3D: Color = Color("FC7F7F") +const COLOR_PCAM: Color = Color("3AB99A") +const COLOR_PCAM_33: Color = Color("3ab99a33") +const PCAM_HOST_COLOR: Color = Color("E0E0E0") + +#endregion + +#region Group Names + +const PCAM_GROUP_NAME: StringName = "phantom_camera_group" +const PCAM_HOST_GROUP_NAME: StringName = "phantom_camera_host_group" + +#endregion diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd.uid b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd.uid new file mode 100644 index 0000000..b1e3789 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd.uid @@ -0,0 +1 @@ +uid://dn74j5b5hdxu diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd new file mode 100644 index 0000000..7306810 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd @@ -0,0 +1,264 @@ +@tool +@icon("res://addons/phantom_camera/icons/phantom_camera_noise_emitter_2d.svg") +class_name PhantomCameraNoiseEmitter2D +extends Node2D + +## Emits positional and rotational noise to active [PhantomCamera2D]s and its corresponding [Camera2D]. +## +## Is a node meant to apply positional and rotational noise, also referred to as shake, to the [Camera2D]. +## It is designed for use cases such as when hitting or when being hit, earthquakes or to add a +## bit of slight movement to the camera to make it feel less static. +## The emitter can affect multiple [PhantomCamera2D] in a given scene based on which [member noise_emitter_layer] +## are enabled by calling its [method emit] function. At least one corresponding layer has to be +## set on the [PhantomCamera2D] and the emitter node. + +const _constants = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") + +#region Exported Proerpties + +## The [PhantomCameraNoise2D] resource that defines the noise pattern. +@export var noise: PhantomCameraNoise2D = null: + set = set_noise, + get = get_noise + +## If true, previews the noise in the editor - can be seen in the viewfinder. +@export var preview: bool = false: + set(value): + preview = value + _play = value + get: + return preview + +## If true, repeats the noise indefinitely once started. Otherwise, it will only be triggered once. [br] +@export var continuous: bool = false: + set = set_continuous, + get = get_continuous + +## Determines how long the noise should take to reach full [member intensity] once started.[br] +## The value is set in [b]seconds[/b]. +@export_exp_easing("positive_only", "suffix: s") var growth_time: float = 0: + set = set_growth_time, + get = get_growth_time + +## Sets the duration for the camera noise if [member continuous] is set to [b]false[/b].[br][br] +## The value is set in [b]seconds[/b]. +@export_range(0, 10, 0.001, "or_greater", "suffix: s") var duration: float = 1.0: + set = set_duration, + get = get_duration + +## Determines how long the noise should take to come to a full stop.[br] +## The value is set in [b]seconds[/b]. +@export_exp_easing("attenuation", "positive_only", "suffix: s") var decay_time: float = 0: + set = set_decay_time, + get = get_decay_time + +## Enabled layers will affect [PhantomCamera2D] nodes with at least one corresponding layer enabled.[br] +## Enabling multiple corresponding layers on the same [PhantomCamera2D] causes no additional effect. +@export_flags_2d_render var noise_emitter_layer: int = 1: + set = set_noise_emitter_layer, + get = get_noise_emitter_layer + +#endregion + + +#region Private Variables + +var _play: bool = false: + set(value): + _play = value + if value: + _elasped_play_time = 0 + _decay_countdown = 0 + _play = true + _should_grow = true + _start_duration_countdown = false + _should_decay = false + else: + _should_decay = true + if noise.randomize_noise_seed: + noise.noise_seed = randi() & 1000 + else: + noise.reset_noise_time() + get: + return _play + +var _start_duration_countdown: bool = false + +var _decay_countdown: float = 0 + +var _should_grow: bool = false + +var _should_decay: bool = false + +var _elasped_play_time: float = 0 + +var _noise_output: Transform2D = Transform2D() + +# NOTE - Temp solution until Godot has better plugin autoload recognition out-of-the-box. +var _phantom_camera_manager: Node + +#endregion + +#region Private Functions + +func _get_configuration_warnings() -> PackedStringArray: + if noise == null: + return ["Noise resource is required in order to trigger emitter."] + else: + return [] + + +func _validate_property(property) -> void: + if property.name == "duration" and continuous: + property.usage = PROPERTY_USAGE_NO_EDITOR + + +func _enter_tree() -> void: + _phantom_camera_manager = get_tree().root.get_node(_constants.PCAM_MANAGER_NODE_NAME) + + +func _process(delta: float) -> void: + if not _play and not _should_decay: return + if noise == null: + printerr("Noise resource missing in ", name) + _play = false + return + + _elasped_play_time += delta + + if _should_grow: + noise.set_trauma(minf(_elasped_play_time / growth_time, 1)) + if _elasped_play_time >= growth_time: + _should_grow = false + _start_duration_countdown = true + noise.set_trauma(1) + else: + noise.set_trauma(1) + + if not continuous: + if _start_duration_countdown: + if _elasped_play_time >= duration + growth_time: + _should_decay = true + _start_duration_countdown = false + + if _should_decay: + _decay_countdown += delta + noise.set_trauma(maxf(1 - (_decay_countdown / decay_time), 0)) + if _decay_countdown >= decay_time: + noise.set_trauma(0) + _play = false + preview = false + _should_decay = false + _elasped_play_time = 0 + _decay_countdown = 0 + + _noise_output = noise.get_noise_transform(delta) + _phantom_camera_manager.noise_2d_emitted.emit(_noise_output, noise_emitter_layer) + + +func _set_layer(current_layers: int, layer_number: int, value: bool) -> int: + var mask: int = current_layers + + # From https://github.com/godotengine/godot/blob/51991e20143a39e9ef0107163eaf283ca0a761ea/scene/3d/camera_3d.cpp#L638 + if layer_number < 1 or layer_number > 20: + printerr("Layer must be between 1 and 20.") + else: + if value: + mask |= 1 << (layer_number - 1) + else: + mask &= ~(1 << (layer_number - 1)) + + return mask + +#endregion + + +#region Public Functions + +## Emits noise to the [PhantomCamera2D]s that has at least one matching layers. +func emit() -> void: + if _play: _play = false + _play = true + +## Returns the state for the emitter. If true, the emitter is currently emitting. +func is_emitting() -> bool: + return _play + +## Stops the emitter from emitting noise. +func stop(should_decay: bool = true) -> void: + if should_decay: + _should_decay = true + else: + _play = false + +## Toggles the emitter on and off. +func toggle() -> void: + _play = !_play + +#endregion + + +#region Setter & Getter Functions + +## Sets the [member noise] resource. +func set_noise(value: PhantomCameraNoise2D) -> void: + noise = value + update_configuration_warnings() + +## Returns the [member noise] resource. +func get_noise() -> PhantomCameraNoise2D: + return noise + + +## Sets the [member continous] value. +func set_continuous(value: bool) -> void: + continuous = value + notify_property_list_changed() + +## Gets the [member continous] value. +func get_continuous() -> bool: + return continuous + + +## Sets the [member growth_time] value. +func set_growth_time(value: float) -> void: + growth_time = value + +## Returns the [member growth_time] value. +func get_growth_time() -> float: + return growth_time + + +## Sets the [member duration] value. +func set_duration(value: float) -> void: + duration = value + if duration == 0: + duration = 0.001 + +## Returns the [member duration] value. +func get_duration() -> float: + return duration + + +## Sets the [member decay_time] value. +func set_decay_time(value: float) -> void: + decay_time = value + +## Returns the [member decay_time] value. +func get_decay_time() -> float: + return decay_time + + +## Sets the [member noise_emitter_layer] value. +func set_noise_emitter_layer(value: int) -> void: + noise_emitter_layer = value + +## Enables or disables a given layer of [member noise_emitter_layer]. +func set_noise_emitter_value(value: int, enabled: bool) -> void: + noise_emitter_layer = _set_layer(noise_emitter_layer, value, enabled) + +## Returns the [member noise_emitter_layer] value. +func get_noise_emitter_layer() -> int: + return noise_emitter_layer + +#endregion diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd.uid b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd.uid new file mode 100644 index 0000000..19dbc96 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_2d.gd.uid @@ -0,0 +1 @@ +uid://bhd4nuiu23e7l diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd new file mode 100644 index 0000000..cd6c634 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd @@ -0,0 +1,265 @@ +@tool +@icon("res://addons/phantom_camera/icons/phantom_camera_noise_emitter_3d.svg") +class_name PhantomCameraNoiseEmitter3D +extends Node3D + +## Emits positional and rotational noise to active [PhantomCamera3D]s and its corresponding [Camera3D]. +## +## Is a node meant to apply positional and rotational noise, also referred to as shake, to the [Camera3D]. +## It is designed for use cases such as when hitting or when being hit, earthquakes or to add a +## bit of slight movement to the camera to make it feel less static. +## The emitter can affect multiple [PhantomCamera3D] in a given scene based on which [member noise_emitter_layer] +## are enabled by calling its [method emit] function. At least one corresponding layer has to be +## set on the [PhantomCamera3D] and the emitter node. + +const _constants = preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") + +#region Exported Properties + +## The [PhantomCameraNoise3D] resource that defines the noise pattern. +@export var noise: PhantomCameraNoise3D = null: + set = set_noise, + get = get_noise + +## If true, previews the noise in the Viewfinder. +@export var preview: bool = false: + set(value): + preview = value + _play = value + get: + return preview + +## If true, repeats the noise indefinitely once started.Otherwise, it will only be triggered once. [br] +## [b]Note:[/b] This will always be enabled if the resource is assigned the the [PhantomCamera3D]'s +## [member PhantomCamera3D.noise] property. +@export var continuous: bool = false: + set = set_continuous, + get = get_continuous + +## Determines how long the noise should take to reach full [member intensity] once started.[br] +## The value is set in [b]seconds[/b]. +@export_exp_easing("positive_only", "suffix: s") var growth_time: float = 0: + set = set_growth_time, + get = get_growth_time + +## Sets the duration for the camera noise if [member loop] is set to false.[br] +## If the duration is [param 0] then [member continous] becomes enabled.[br] +## The value is set in [b]seconds[/b]. +@export_range(0, 10, 0.001, "or_greater", "suffix: s") var duration: float = 1.0: + set = set_duration, + get = get_duration + +## Determines how long the noise should take to come to a full stop.[br] +## The value is set in [b]seconds[/b]. +@export_exp_easing("attenuation", "positive_only", "suffix: s") var decay_time: float = 0: + set = set_decay_time, + get = get_decay_time + +## Enabled layers will affect [PhantomCamera3D] nodes with at least one corresponding layer enabled.[br] +## Enabling multiple corresponding layers on the same [PhantomCamera3D] causes no additional effect. +@export_flags_3d_render var noise_emitter_layer: int = 1: + set = set_noise_emitter_layer, + get = get_noise_emitter_layer + +#endregion + +#region Private Variables + +var _play: bool = false: + set(value): + _play = value + if value: + _elasped_play_time = 0 + _decay_countdown = 0 + _play = true + _should_grow = true + _start_duration_countdown = false + _should_decay = false + else: + _should_decay = true + if noise.randomize_noise_seed: + noise.noise_seed = randi() & 1000 + else: + noise.reset_noise_time() + get: + return _play + +var _start_duration_countdown: bool = false + +var _decay_countdown: float = 0 + +var _should_grow: bool = false + +var _should_decay: bool = false + +var _elasped_play_time: float = 0 + +var _noise_output: Transform3D = Transform3D() + +# NOTE - Temp solution until Godot has better plugin autoload recognition out-of-the-box. +var _phantom_camera_manager: Node + +#endregion + +#region Private Functions + +func _get_configuration_warnings() -> PackedStringArray: + if noise == null: + return ["Noise resource is required in order to trigger emitter."] + else: + return [] + + +func _validate_property(property) -> void: + if property.name == "duration" and continuous: + property.usage = PROPERTY_USAGE_NO_EDITOR + + +func _enter_tree() -> void: + _phantom_camera_manager = get_tree().root.get_node(_constants.PCAM_MANAGER_NODE_NAME) + + +func _process(delta: float) -> void: + if not _play and not _should_decay: return + if noise == null: + printerr("Noise resource missing in ", name) + _play = false + return + + _elasped_play_time += delta + + if _should_grow: + noise.set_trauma(minf(_elasped_play_time / growth_time, 1)) + if _elasped_play_time >= growth_time: + _should_grow = false + _start_duration_countdown = true + noise.set_trauma(1) + + if not continuous: + if _start_duration_countdown: + if _elasped_play_time >= duration + growth_time: + _should_decay = true + _start_duration_countdown = false + + if _should_decay: + _decay_countdown += delta + noise.set_trauma(maxf(1 - (_decay_countdown / decay_time), 0)) + if _decay_countdown >= decay_time: + noise.set_trauma(0) + _play = false + preview = false + _should_decay = false + _elasped_play_time = 0 + _decay_countdown = 0 + + _noise_output = noise.get_noise_transform(delta) + _phantom_camera_manager.noise_3d_emitted.emit(_noise_output, noise_emitter_layer) + + +func _set_layer(current_layers: int, layer_number: int, value: bool) -> int: + var mask: int = current_layers + + # From https://github.com/godotengine/godot/blob/51991e20143a39e9ef0107163eaf283ca0a761ea/scene/3d/camera_3d.cpp#L638 + if layer_number < 1 or layer_number > 20: + printerr("Layer must be between 1 and 20.") + else: + if value: + mask |= 1 << (layer_number - 1) + else: + mask &= ~(1 << (layer_number - 1)) + + return mask + +#endregion + +#region Public Functions + +## Emits noise to the [PhantomCamera3D]s that has at least one matching layers. +func emit() -> void: + if _play: _play = false + _play = true + + +## Returns the state for the emitter. If true, the emitter is currently emitting. +func is_emitting() -> bool: + return _play + + +## Stops the emitter from emitting noise. +func stop(should_decay: bool = true) -> void: + if should_decay: + _should_decay = true + else: + _play = false + + +## Toggles the emitter on and off.[br] +func toggle() -> void: + _play = !_play + +#endregion + +#region Setter & Getter Functions + +## Sets the [member noise] resource. +func set_noise(value: PhantomCameraNoise3D) -> void: + noise = value + update_configuration_warnings() + +## Returns the [member noise] resource. +func get_noise() -> PhantomCameraNoise3D: + return noise + + +## Sets the [member continous] value. +func set_continuous(value: bool) -> void: + continuous = value + notify_property_list_changed() + +## Gets the [member continous] value. +func get_continuous() -> bool: + return continuous + + +## Sets the [member growth_time] value. +func set_growth_time(value: float) -> void: + growth_time = value + +## Returns the [member growth_time] value. +func get_growth_time() -> float: + return growth_time + + +## Sets the [member duration] value. +func set_duration(value: float) -> void: + duration = value + if duration == 0: + duration = 0.001 + +## Returns the [member duration] value. +func get_duration() -> float: + return duration + + +## Sets the [member decay_time] value. +func set_decay_time(value: float) -> void: + decay_time = value + +## Returns the [member decay_time] value. +func get_decay_time() -> float: + return decay_time + + +## Sets the [member noise_emitter_layer] value. +func set_noise_emitter_layer(value: int) -> void: + noise_emitter_layer = value + +## Enables or disables a given layer of [member noise_emitter_layer]. +func set_noise_emitter_value(value: int, enabled: bool) -> void: + noise_emitter_layer = _set_layer(noise_emitter_layer, value, enabled) + +## Returns the [member noise_emitter_layer] value. +func get_noise_emitter_layer() -> int: + return noise_emitter_layer + + #endregion diff --git a/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd.uid b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd.uid new file mode 100644 index 0000000..aa7e880 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera/phantom_camera_noise_emitter_3d.gd.uid @@ -0,0 +1 @@ +uid://ccmiitq0sdh7j diff --git a/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs b/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs new file mode 100644 index 0000000..be211bd --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs @@ -0,0 +1,128 @@ +using Godot; + +#nullable enable + +namespace PhantomCamera; + +public enum InterpolationMode +{ + Auto, + Idle, + Physics +} + +public static class PhantomCameraHostExtensions +{ + public static PhantomCameraHost AsPhantomCameraHost(this Node node) + { + return new PhantomCameraHost(node); + } +} + +public class PhantomCameraHost() +{ + public Node Node { get; } = null!; + + public PhantomCameraHost(Node node) : this() + { + Node = node; + + _callablePCamBecameActive = Callable.From(pCam => PCamBecameActive?.Invoke(pCam)); + _callablePCamBecameInactive = Callable.From(pCam => PCamBecameInactive?.Invoke(pCam)); + + Node.Connect(SignalName.PCamBecameActive, _callablePCamBecameActive); + Node.Connect(SignalName.PCamBecameInactive, _callablePCamBecameInactive); + } + + ~PhantomCameraHost() + { + Node.Disconnect(SignalName.PCamBecameActive, _callablePCamBecameActive); + Node.Disconnect(SignalName.PCamBecameInactive, _callablePCamBecameInactive); + } + + public delegate void PCamBecameActiveEventHandler(Node pCam); + public delegate void PCamBecameInactiveEventHandler(Node pCam); + + public event PCamBecameActiveEventHandler? PCamBecameActive; + public event PCamBecameInactiveEventHandler? PCamBecameInactive; + + + private readonly Callable _callablePCamBecameActive; + private readonly Callable _callablePCamBecameInactive; + // For when Godot becomes the minimum version + // public InterpolationMode InterpolationMode + // { + // get => (InterpolationMode)(int)Node.Call(MethodName.GetInterpolationMode); + // set => Node.Call(MethodName.SetInterpolationMode, (int)value); + // } + + public int HostLayers + { + get => (int)Node.Call(PhantomCamera.MethodName.GetHostLayers); + set => Node.Call(PhantomCamera.MethodName.SetHostLayers, value); + } + + public void SetHostLayersValue(int layer, bool value) => Node.Call(MethodName.SetHostLayersValue, layer, value); + + public Camera2D? Camera2D => (Camera2D?)Node.Get(PropertyName.Camera2D); + + public Camera3D? Camera3D => (Camera3D?)Node.Get(PropertyName.Camera3D); + + public InterpolationMode InterpolationMode + { + get => (InterpolationMode)(int)Node.Call(MethodName.GetInterpolationMode); + set => Node.Call(MethodName.SetInterpolationMode, (int)value); + } + + public bool TriggerPhantomCameraTween => (bool)Node.Call(MethodName.GetTriggerPhantomCameraTween); + + public ActivePhantomCameraQueryResult? GetActivePhantomCamera() + { + var result = Node.Call(MethodName.GetActivePhantomCamera); + return result.VariantType == Variant.Type.Nil ? null : new ActivePhantomCameraQueryResult(result.AsGodotObject()); + } + + public static class PropertyName + { + public const string Camera2D = "camera_2d"; + public const string Camera3D = "camera_3d"; + } + + public static class MethodName + { + public const string GetActivePhantomCamera = "get_active_pcam"; + public const string GetTriggerPhantomCameraTween = "get_trigger_pcam_tween"; + + public const string GetInterpolationMode = "get_interpolation_mode"; + public const string SetInterpolationMode = "set_interpolation_mode"; + + public const string SetHostLayersValue = "set_host_layers_value"; + } + + public static class SignalName + { + public const string PCamBecameActive = "pcam_became_active"; + public const string PCamBecameInactive = "pcam_became_inactive"; + } +} + +public class ActivePhantomCameraQueryResult(GodotObject godotObject) +{ + public bool Is2D => godotObject.IsClass("Node2D") || ((Node)godotObject).Name.ToString().Contains("PhantomCamera2D") + || ((Node)godotObject).Name.ToString().Contains("PCam2D") + || ((Node)godotObject).Name.ToString().Contains("2D"); + + public bool Is3D => godotObject.IsClass("Node3D") || ((Node)godotObject).Name.ToString().Contains("PhantomCamera3D") + || ((Node)godotObject).Name.ToString().Contains("PCam3D") + || ((Node)godotObject).Name.ToString().Contains("3D"); + + public PhantomCamera2D? AsPhantomCamera2D() + { + return Is2D ? new PhantomCamera2D(godotObject) : null; + } + + public PhantomCamera3D? AsPhantomCamera3D() + { + return Is3D ? new PhantomCamera3D(godotObject) : null; + } +} diff --git a/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs.uid b/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs.uid new file mode 100644 index 0000000..ad4b4f5 --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera_host/PhantomCameraHost.cs.uid @@ -0,0 +1 @@ +uid://cr8brwrls2nn3 diff --git a/addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd b/addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd new file mode 100644 index 0000000..8c6308c --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd @@ -0,0 +1,1416 @@ +@tool +@icon("res://addons/phantom_camera/icons/phantom_camera_host.svg") +class_name PhantomCameraHost +extends Node + +## Controls a scene's [Camera2D] (2D scenes) and [Camera3D] (3D scenes). +## +## All instantiated [param PhantomCameras] in a scene are assigned to a specific layer, where a +## PhantomCameraHost will react to those that corresponds. It is what determines which [param PhantomCamera] should +## be active. + +#region Constants + +const _constants := preload("res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_constants.gd") + +#endregion + + +#region Signals + +## Updates the viewfinder [param dead zones] sizes.[br] +## [b]Note:[/b] This is only being used in the editor viewfinder UI. +#signal update_editor_viewfinder +signal viewfinder_update(check_framed_view: bool) +signal viewfinder_disable_dead_zone + +## Used internally to check if the [param PhantomCameraHost] is valid. +## The result will be visible in the viewfinder when multiple instances are present. +signal has_error() + +## Emitted when a new [param PhantomCamera] becomes active and assigned to this [param PhantomCameraHost]. +signal pcam_became_active(pcam: Node) + +## Emitted when the currently active [param PhantomCamera] goes from being active to inactive. +signal pcam_became_inactive(pcam: Node) + +#endregion + + +#region Enums + +## Dictates whether if [param PhantomCameraHost]'s logic should be called in the physics or idle (process) frames. +enum InterpolationMode { + AUTO = 0, ## Automatically sets the [param Camera]'s logic to run in either physics or idle (process) frames depending on its active [param PhantomCamera]'s [param Follow] / [param Look At] Target + IDLE = 1, ## Always run the [param Camera] logic in idle (process) frames + PHYSICS = 2, ## Always run the [param Camera] logic in physics frames +} + +#endregion + + +#region Public Variables + +## Determines which [PhantomCamera2D] / [PhantomCamera3D] nodes this [param PhantomCameraHost] should recognise. +## At least one corresponding layer needs to be set on the [param PhantomCamera] for the [param PhantomCameraHost] node to work. +@export_flags_2d_render var host_layers: int = 1: + set = set_host_layers, + get = get_host_layers + +## Determines whether the [PhantomCamera2D] / [PhantomCamera3D] nodes this [param PhantomCameraHost] controls should use physics interpolation or not. +@export var interpolation_mode: InterpolationMode = InterpolationMode.AUTO: + set = set_interpolation_mode, + get = get_interpolation_mode + +#endregion + + +#region Private Variables + +var _active_pcam_2d: PhantomCamera2D = null +var _active_pcam_3d: Node = null ## Note: To support disable_3d export templates for 2D projects, this is purposely not strongly typed. +var _active_pcam_priority: int = -1 +var _active_pcam_missing: bool = true +var _active_pcam_has_damping: bool = false +var _follow_target_physics_based: bool = false + +var _prev_active_pcam_2d_transform: Transform2D = Transform2D() +var _prev_active_pcam_3d_transform: Transform3D = Transform3D() + +var _trigger_pcam_tween: bool = false +var _tween_elapsed_time: float = 0 +var _tween_duration: float = 0 +var _tween_is_instant: bool = false + +var _multiple_pcam_hosts: bool = false + +var _is_child_of_camera: bool = false +var _is_2d: bool = false + +var _viewfinder_node: Control = null +var _viewfinder_needed_check: bool = true + +var _camera_zoom: Vector2 = Vector2.ONE + +#region Camera3DResource + +var _prev_cam_attributes: CameraAttributes = null +var _cam_attribute_type: int = 0 # 0 = CameraAttributesPractical, 1 = CameraAttributesPhysical +var _cam_attribute_changed: bool = false +var _cam_attribute_assigned: bool = false + +#region CameraAttributes +var _prev_cam_auto_exposure_scale: float = 0.4 +var _cam_auto_exposure_scale_changed: bool = false + +var _prev_cam_auto_exposure_speed: float = 0.5 +var _cam_auto_exposure_speed_changed: bool = false + +var _prev_cam_exposure_multiplier: float = 1.0 +var _cam_exposure_multiplier_changed: bool = false + +var _prev_cam_exposure_sensitivity: float = 100.0 +var _cam_exposure_sensitivity_changed: bool = false + +#region CameraAttributesPractical +var _prev_cam_exposure_min_sensitivity: float = 0.0 +var _cam_exposure_min_sensitivity_changed: bool = false + +var _prev_cam_exposure_max_sensitivity: float = 800.0 +var _cam_exposure_max_sensitivity_changed: bool = false + +var _prev_cam_dof_blur_amount: float = 0.1 +var _cam_dof_blur_amount_changed: bool = false + +var _cam_dof_blur_far_distance_default: float = 10 +var _prev_cam_dof_blur_far_distance: float = _cam_dof_blur_far_distance_default +var _cam_dof_blur_far_distance_changed: bool = false + +var _cam_dof_blur_far_transition_default: float = 5 +var _prev_cam_dof_blur_far_transition: float = _cam_dof_blur_far_transition_default +var _cam_dof_blur_far_transition_changed: bool = false + +var _cam_dof_blur_near_distance_default: float = 2 +var _prev_cam_dof_blur_near_distance: float = _cam_dof_blur_near_distance_default +var _cam_dof_blur_near_distance_changed: bool = false + +var _cam_dof_blur_near_transition_default: float = 1 +var _prev_cam_dof_blur_near_transition: float = _cam_dof_blur_near_transition_default +var _cam_dof_blur_near_transition_changed: bool = false +#endregion + +#region CameraAttributesPhysical +var _prev_cam_exposure_min_exposure_value: float = 10.0 +var _cam_exposure_min_exposure_value_changed: bool = false + +var _prev_cam_exposure_max_exposure_value: float = -8.0 +var _cam_exposure_max_exposure_value_changed: bool = false + +var _prev_cam_exposure_aperture: float = 16.0 +var _cam_exposure_aperture_changed: bool = false + +var _prev_cam_exposure_shutter_speed: float = 100.0 +var _cam_exposure_shutter_speed_changed: bool = false + +var _prev_cam_frustum_far: float = 4000.0 +var _cam_frustum_far_changed: bool = false + +var _prev_cam_frustum_focal_length: float = 35.0 +var _cam_frustum_focal_length_changed: bool = false + +var _prev_cam_frustum_near: float = 0.05 +var _cam_frustum_near_changed: bool = false + +var _prev_cam_frustum_focus_distance: float = 10.0 +var _cam_frustum_focus_distance_changed: bool = false + +#endregion + +var _prev_cam_h_offset: float = 0 +var _cam_h_offset_changed: bool = false + +var _prev_cam_v_offset: float = 0 +var _cam_v_offset_changed: bool = false + +var _prev_cam_fov: float = 75 +var _cam_fov_changed: bool = false + +var _prev_cam_size: float = 1 +var _cam_size_changed: bool = false + +var _prev_cam_frustum_offset: Vector2 = Vector2.ZERO +var _cam_frustum_offset_changed: bool = false + +var _prev_cam_near: float = 0.05 +var _cam_near_changed: bool = false + +var _prev_cam_far: float = 4000 +var _cam_far_changed: bool = false + +#endregion + +var _active_pcam_2d_glob_transform: Transform2D = Transform2D() +var _active_pcam_3d_glob_transform: Transform3D = Transform3D() + +var _has_noise_emitted: bool = false +var _reset_noise_offset_2d: bool = false +var _noise_emitted_output_2d: Transform2D = Transform2D() +var _noise_emitted_output_3d: Transform3D = Transform3D() + +#endregion + +# NOTE - Temp solution until Godot has better plugin autoload recognition out-of-the-box. +var _phantom_camera_manager: Node = null + +#region Public Variables + +var show_warning: bool = false + +## For 2D scenes, is the [Camera2D] instance the [param PhantomCameraHost] controls. +var camera_2d: Camera2D = null + +## For 3D scenes, is the [Camera3D] instance the [param PhantomCameraHost] controls. +var camera_3d: Node = null ## Note: To support disable_3d export templates for 2D projects, this is purposely not strongly typed. + +#endregion + +#region Private Functions + +## TBD - For when Godot 4.3 becomes a minimum version +#func _validate_property(property: Dictionary) -> void: + #if property.name == "interpolation_mode" and get_parent() is Node3D: + #property.usage = PROPERTY_USAGE_NO_EDITOR + + +func _get_configuration_warnings() -> PackedStringArray: + var parent: Node = get_parent() + var first_pcam_host_child: PhantomCameraHost + + if _is_2d: + if not parent is Camera2D: + show_warning = true + has_error.emit() + return["Needs to be a child of a Camera2D in order to work."] + else: + if not parent.is_class("Camera3D"): ## Note: To support disable_3d export templates for 2D projects, this is purposely not strongly typed. + show_warning = true + has_error.emit() + return["Needs to be a child of a Camera3D in order to work."] + + for child in parent.get_children(): + if not child is PhantomCameraHost: continue + if not is_instance_valid(first_pcam_host_child): + first_pcam_host_child = child + continue + elif not first_pcam_host_child == self: + show_warning = true + has_error.emit() + return["Only the first PhantomCameraHost child will be used."] + child.update_configuration_warnings() + + show_warning = false + has_error.emit() + return[] + + +func _enter_tree() -> void: + var parent: Node = get_parent() + if parent is Camera2D or parent.is_class("Camera3D"): ## Note: To support disable_3d export templates for 2D projects, this is purposely not strongly typed. + _phantom_camera_manager = get_tree().root.get_node(_constants.PCAM_MANAGER_NODE_NAME) + _phantom_camera_manager.pcam_host_added(self) + + _is_child_of_camera = true + if parent is Camera2D: + _is_2d = true + camera_2d = parent + ## Force applies position smoothing to be disabled + ## This is to prevent overlap with the interpolation of the PCam2D. + camera_2d.set_position_smoothing_enabled(false) + else: + _is_2d = false + camera_3d = parent + + if _is_2d: + if not _phantom_camera_manager.get_phantom_camera_2ds().is_empty(): + for pcam in _phantom_camera_manager.get_phantom_camera_2ds(): + _pcam_added_to_scene(pcam) + + if not _phantom_camera_manager.limit_2d_changed.is_connected(_update_limit_2d): + _phantom_camera_manager.limit_2d_changed.connect(_update_limit_2d) + if not _phantom_camera_manager.draw_limit_2d.is_connected(_draw_limit_2d): + _phantom_camera_manager.draw_limit_2d.connect(_draw_limit_2d) + + else: + if not _phantom_camera_manager.get_phantom_camera_3ds().is_empty(): + for pcam in _phantom_camera_manager.get_phantom_camera_3ds(): + _pcam_added_to_scene(pcam) + + +func _exit_tree() -> void: + if is_instance_valid(_phantom_camera_manager): + _phantom_camera_manager.pcam_host_removed(self) + + +func _ready() -> void: + # Waits for the first process tick to finish before initializing any logic + # This should help with avoiding ocassional erratic camera movement upon running a scene + await get_tree().process_frame + + process_priority = 300 + process_physics_priority = 300 + + # PCam Host Signals + if Engine.has_singleton(_constants.PCAM_MANAGER_NODE_NAME): + _phantom_camera_manager = Engine.get_singleton(_constants.PCAM_MANAGER_NODE_NAME) + _phantom_camera_manager.pcam_host_layer_changed.connect(_pcam_host_layer_changed) + + # PCam Signals + _phantom_camera_manager.pcam_added_to_scene.connect(_pcam_added_to_scene) + _phantom_camera_manager.pcam_removed_from_scene.connect(_pcam_removed_from_scene) + + _phantom_camera_manager.pcam_priority_changed.connect(pcam_priority_updated) + _phantom_camera_manager.pcam_priority_override.connect(_pcam_priority_override) + + _phantom_camera_manager.pcam_visibility_changed.connect(_pcam_visibility_changed) + + _phantom_camera_manager.pcam_teleport.connect(_pcam_teleported) + + if _is_2d: + if not _phantom_camera_manager.limit_2d_changed.is_connected(_update_limit_2d): + _phantom_camera_manager.limit_2d_changed.connect(_update_limit_2d) + if not _phantom_camera_manager.draw_limit_2d.is_connected(_draw_limit_2d): + _phantom_camera_manager.draw_limit_2d.connect(_draw_limit_2d) + else: + printerr("Could not find Phantom Camera Manager singleton") + printerr("Make sure the addon is enable or that the singleton hasn't been disabled inside Project Settings / Globals") + + _find_pcam_with_highest_priority() + + if _is_2d: + camera_2d.offset = Vector2.ZERO + if not is_instance_valid(_active_pcam_2d): return + _active_pcam_2d_glob_transform = _active_pcam_2d.get_transform_output() + else: + if not is_instance_valid(_active_pcam_3d): return + _active_pcam_3d_glob_transform = _active_pcam_3d.get_transform_output() + + +func _pcam_host_layer_changed(pcam: Node) -> void: + if _pcam_is_in_host_layer(pcam): + _check_pcam_priority(pcam) + else: + if _is_2d: + if _active_pcam_2d == pcam: + _active_pcam_missing = true + _active_pcam_2d = null + _active_pcam_priority = -1 + pcam.set_is_active(self, false) + else: + if _active_pcam_3d == pcam: + _active_pcam_missing = true + _active_pcam_3d = null + _active_pcam_priority = -1 + pcam.set_is_active(self, false) + _find_pcam_with_highest_priority() + + +func _pcam_is_in_host_layer(pcam: Node) -> bool: + if pcam.host_layers & host_layers != 0: return true + return false + + +func _find_pcam_with_highest_priority() -> void: + var pcam_list: Array + if _is_2d: + pcam_list = _phantom_camera_manager.phantom_camera_2ds + else: + pcam_list = _phantom_camera_manager.phantom_camera_3ds + + for pcam in pcam_list: + _check_pcam_priority(pcam) + + +func _check_pcam_priority(pcam: Node) -> void: + if not _pcam_is_in_host_layer(pcam): return + if not pcam.visible: return # Prevents hidden PCams from becoming active + if pcam.get_priority() > _active_pcam_priority: + _assign_new_active_pcam(pcam) + _active_pcam_missing = false + else: + pcam.set_tween_skip(self, false) + + +func _assign_new_active_pcam(pcam: Node) -> void: + # Only checks if the scene tree is still present. + # Prevents a few errors and checks from happening if the scene is exited. + if not is_inside_tree(): return + var no_previous_pcam: bool + if is_instance_valid(_active_pcam_2d) or is_instance_valid(_active_pcam_3d): + if OS.has_feature("debug"): + viewfinder_disable_dead_zone.emit() + + if _is_2d: + _prev_active_pcam_2d_transform = camera_2d.global_transform + _active_pcam_2d.queue_redraw() + _active_pcam_2d.set_is_active(self, false) + _active_pcam_2d.became_inactive.emit() + pcam_became_inactive.emit(_active_pcam_2d) + + if _active_pcam_2d.physics_target_changed.is_connected(_check_pcam_physics): + _active_pcam_2d.physics_target_changed.disconnect(_check_pcam_physics) + + if _active_pcam_2d.noise_emitted.is_connected(_noise_emitted_2d): + _active_pcam_2d.noise_emitted.disconnect(_noise_emitted_2d) + + if _trigger_pcam_tween: + _active_pcam_2d.tween_interrupted.emit(pcam) + else: + _prev_active_pcam_3d_transform = camera_3d.global_transform + _active_pcam_3d.set_is_active(self, false) + _active_pcam_3d.became_inactive.emit() + pcam_became_inactive.emit(_active_pcam_3d) + + if _active_pcam_3d.physics_target_changed.is_connected(_check_pcam_physics): + _active_pcam_3d.physics_target_changed.disconnect(_check_pcam_physics) + + if _active_pcam_3d.noise_emitted.is_connected(_noise_emitted_3d): + _active_pcam_3d.noise_emitted.disconnect(_noise_emitted_3d) + + if _active_pcam_3d.camera_3d_resource_changed.is_connected(_camera_3d_resource_changed): + _active_pcam_3d.camera_3d_resource_changed.disconnect(_camera_3d_resource_changed) + + if _active_pcam_3d.camera_3d_resource_property_changed.is_connected(_camera_3d_resource_property_changed): + _active_pcam_3d.camera_3d_resource_property_changed.disconnect(_camera_3d_resource_property_changed) + + if _trigger_pcam_tween: + _active_pcam_3d.tween_interrupted.emit(pcam) + + if camera_3d.attributes != null: + var _attributes: CameraAttributes = camera_3d.attributes + + _prev_cam_exposure_multiplier = _attributes.exposure_multiplier + _prev_cam_auto_exposure_scale = _attributes.auto_exposure_scale + _prev_cam_auto_exposure_speed = _attributes.auto_exposure_speed + + if camera_3d.attributes is CameraAttributesPractical: + _attributes = _attributes as CameraAttributesPractical + + _prev_cam_dof_blur_amount = _attributes.dof_blur_amount + + if _attributes.dof_blur_far_enabled: + _prev_cam_dof_blur_far_distance = _attributes.dof_blur_far_distance + _prev_cam_dof_blur_far_transition = _attributes.dof_blur_far_transition + else: + _prev_cam_dof_blur_far_distance = _cam_dof_blur_far_distance_default + _prev_cam_dof_blur_far_transition = _cam_dof_blur_far_transition_default + + if _attributes.dof_blur_near_enabled: + _prev_cam_dof_blur_near_distance = _attributes.dof_blur_near_distance + _prev_cam_dof_blur_near_transition = _attributes.dof_blur_near_transition + else: + _prev_cam_dof_blur_near_distance = _cam_dof_blur_near_distance_default + _prev_cam_dof_blur_near_transition = _cam_dof_blur_near_transition_default + + if _attributes.auto_exposure_enabled: + _prev_cam_exposure_max_sensitivity = _attributes.auto_exposure_max_sensitivity + _prev_cam_exposure_min_sensitivity = _attributes.auto_exposure_min_sensitivity + + elif camera_3d.attributes is CameraAttributesPhysical: + _attributes = _attributes as CameraAttributesPhysical + + _prev_cam_frustum_focus_distance = _attributes.frustum_focus_distance + _prev_cam_frustum_focal_length = _attributes.frustum_focal_length + _prev_cam_frustum_far = _attributes.frustum_far + _prev_cam_frustum_near = _attributes.frustum_near + _prev_cam_exposure_aperture = _attributes.exposure_aperture + _prev_cam_exposure_shutter_speed = _attributes.exposure_shutter_speed + + if _attributes.auto_exposure_enabled: + _prev_cam_exposure_min_exposure_value = _attributes.auto_exposure_min_exposure_value + _prev_cam_exposure_max_exposure_value = _attributes.auto_exposure_max_exposure_value + + _prev_cam_h_offset = camera_3d.h_offset + _prev_cam_v_offset = camera_3d.v_offset + _prev_cam_fov = camera_3d.fov + _prev_cam_size = camera_3d.size + _prev_cam_frustum_offset = camera_3d.frustum_offset + _prev_cam_near = camera_3d.near + _prev_cam_far = camera_3d.far + + else: + no_previous_pcam = true + + ## Assign newly active pcam + if _is_2d: + _active_pcam_2d = pcam + _active_pcam_priority = _active_pcam_2d.priority + _active_pcam_has_damping = _active_pcam_2d.follow_damping + _tween_duration = _active_pcam_2d.tween_duration + + if not _active_pcam_2d.physics_target_changed.is_connected(_check_pcam_physics): + _active_pcam_2d.physics_target_changed.connect(_check_pcam_physics) + + if not _active_pcam_2d.noise_emitted.is_connected(_noise_emitted_2d): + _active_pcam_2d.noise_emitted.connect(_noise_emitted_2d) + else: + _active_pcam_3d = pcam + _active_pcam_priority = _active_pcam_3d.priority + _active_pcam_has_damping = _active_pcam_3d.follow_damping + _tween_duration = _active_pcam_3d.tween_duration + + if not Engine.is_editor_hint(): + # Assigns a default shape to SpringArm3D node is none is supplied + if _active_pcam_3d.follow_mode == _active_pcam_3d.FollowMode.THIRD_PERSON: + if not _active_pcam_3d.shape: + + var pyramid_shape_data = Engine.get_singleton("PhysicsServer3D").call("shape_get_data", + camera_3d.get_pyramid_shape_rid() + ) + var shape = ClassDB.instantiate("ConvexPolygonShape3D") + shape.points = pyramid_shape_data + _active_pcam_3d.shape = shape + + if not _active_pcam_3d.physics_target_changed.is_connected(_check_pcam_physics): + _active_pcam_3d.physics_target_changed.connect(_check_pcam_physics) + + if not _active_pcam_3d.noise_emitted.is_connected(_noise_emitted_3d): + _active_pcam_3d.noise_emitted.connect(_noise_emitted_3d) + + if not _active_pcam_3d.camera_3d_resource_changed.is_connected(_camera_3d_resource_changed): + _active_pcam_3d.camera_3d_resource_changed.connect(_camera_3d_resource_changed) + + if not _active_pcam_3d.camera_3d_resource_property_changed.is_connected(_camera_3d_resource_property_changed): + _active_pcam_3d.camera_3d_resource_property_changed.connect(_camera_3d_resource_property_changed) + + # Checks if the Camera3DResource has changed from the previous active PCam3D + if _active_pcam_3d.camera_3d_resource: + # Signal to detect if the Camera3D properties are being changed in the inspector + # This is to prevent accidential misalignment between the Camera3D and Camera3DResource + if Engine.is_editor_hint(): + if not Engine.get_singleton(&"EditorInterface").get_inspector().property_edited.is_connected(_camera_3d_edited): + Engine.get_singleton(&"EditorInterface").get_inspector().property_edited.connect(_camera_3d_edited) + if _prev_cam_h_offset != _active_pcam_3d.h_offset: + _cam_h_offset_changed = true + if _prev_cam_v_offset != _active_pcam_3d.v_offset: + _cam_v_offset_changed = true + if _prev_cam_fov != _active_pcam_3d.fov: + _cam_fov_changed = true + if _prev_cam_size != _active_pcam_3d.size: + _cam_size_changed = true + if _prev_cam_frustum_offset != _active_pcam_3d.frustum_offset: + _cam_frustum_offset_changed = true + if _prev_cam_near != _active_pcam_3d.near: + _cam_near_changed = true + if _prev_cam_far != _active_pcam_3d.far: + _cam_far_changed = true + else: + _cam_h_offset_changed = false + _cam_v_offset_changed = false + _cam_fov_changed = false + _cam_size_changed = false + _cam_frustum_offset_changed = false + _cam_near_changed = false + _cam_far_changed = false + _cam_attribute_changed = false + if Engine.is_editor_hint(): + if Engine.get_singleton(&"EditorInterface").get_inspector().property_edited.is_connected(_camera_3d_edited): + Engine.get_singleton(&"EditorInterface").get_inspector().property_edited.disconnect(_camera_3d_edited) + + if _active_pcam_3d.attributes == null: + _cam_attribute_changed = false + else: + if _prev_cam_attributes != _active_pcam_3d.attributes: + _prev_cam_attributes = _active_pcam_3d.attributes + _cam_attribute_changed = true + var _attributes: CameraAttributes = _active_pcam_3d.attributes + + if _prev_cam_auto_exposure_scale != _attributes.auto_exposure_scale: + _cam_auto_exposure_scale_changed = true + if _prev_cam_auto_exposure_speed != _attributes.auto_exposure_speed: + _cam_auto_exposure_speed_changed = true + if _prev_cam_exposure_multiplier != _attributes.exposure_multiplier: + _cam_exposure_multiplier_changed = true + if _prev_cam_exposure_sensitivity != _attributes.exposure_sensitivity: + _cam_exposure_sensitivity_changed = true + + if _attributes is CameraAttributesPractical: + _cam_attribute_type = 0 + + if camera_3d.attributes == null: + camera_3d.attributes = CameraAttributesPractical.new() + camera_3d.attributes = _active_pcam_3d.attributes.duplicate() + _cam_attribute_assigned = true + + if _prev_cam_exposure_min_sensitivity != _attributes.auto_exposure_min_sensitivity: + _cam_exposure_min_sensitivity_changed = true + if _prev_cam_exposure_max_sensitivity != _attributes.auto_exposure_max_sensitivity: + _cam_exposure_max_sensitivity_changed = true + + if _prev_cam_dof_blur_amount != _attributes.dof_blur_amount: + _cam_dof_blur_amount_changed = true + + if _prev_cam_dof_blur_far_distance != _attributes.dof_blur_far_distance: + _cam_dof_blur_far_distance_changed = true + camera_3d.attributes.dof_blur_far_enabled = true + if _prev_cam_dof_blur_far_transition != _attributes.dof_blur_far_transition: + _cam_dof_blur_far_transition_changed = true + camera_3d.attributes.dof_blur_far_enabled = true + + if _prev_cam_dof_blur_near_distance != _attributes.dof_blur_near_distance: + _cam_dof_blur_near_distance_changed = true + camera_3d.attributes.dof_blur_near_enabled = true + if _prev_cam_dof_blur_near_transition != _attributes.dof_blur_near_transition: + _cam_dof_blur_near_transition_changed = true + camera_3d.attributes.dof_blur_near_enabled = true + elif _attributes is CameraAttributesPhysical: + _cam_attribute_type = 1 + + if camera_3d.attributes == null: + camera_3d.attributes = CameraAttributesPhysical.new() + camera_3d.attributes = _active_pcam_3d.attributes.duplicate() + + if _prev_cam_exposure_min_exposure_value != _attributes.auto_exposure_min_exposure_value: + _cam_exposure_min_exposure_value_changed = true + if _prev_cam_exposure_max_exposure_value != _attributes.auto_exposure_max_exposure_value: + _cam_exposure_max_exposure_value_changed = true + + if _prev_cam_exposure_aperture != _attributes.exposure_aperture: + _cam_exposure_aperture_changed = true + if _prev_cam_exposure_shutter_speed != _attributes.exposure_shutter_speed: + _cam_exposure_shutter_speed_changed = true + + if _prev_cam_frustum_far != _attributes.frustum_far: + _cam_frustum_far_changed = true + + if _prev_cam_frustum_focal_length != _attributes.frustum_focal_length: + _cam_frustum_focal_length_changed = true + + if _prev_cam_frustum_focus_distance != _attributes.frustum_focus_distance: + _cam_frustum_focus_distance_changed = true + + if _prev_cam_frustum_near != _attributes.frustum_near: + _cam_frustum_near_changed = true + + if OS.has_feature("debug"): + viewfinder_update.emit(false) + + if _is_2d: + if _active_pcam_2d.show_viewfinder_in_play: + _viewfinder_needed_check = true + + _active_pcam_2d.set_is_active(self, true) + _active_pcam_2d.became_active.emit() + pcam_became_active.emit(_active_pcam_2d) + _camera_zoom = camera_2d.zoom + else: + if _active_pcam_3d.show_viewfinder_in_play: + _viewfinder_needed_check = true + + _active_pcam_3d.set_is_active(self, true) + _active_pcam_3d.became_active.emit() + pcam_became_active.emit(_active_pcam_3d) + if _active_pcam_3d.camera_3d_resource: + camera_3d.keep_aspect = _active_pcam_3d.keep_aspect + camera_3d.cull_mask = _active_pcam_3d.cull_mask + camera_3d.projection = _active_pcam_3d.projection + + if no_previous_pcam: + if _is_2d: + _prev_active_pcam_2d_transform = _active_pcam_2d.get_transform_output() + else: + _prev_active_pcam_3d_transform = _active_pcam_3d.get_transform_output() + + if pcam.get_tween_skip() or pcam.tween_duration == 0: + _tween_elapsed_time = pcam.tween_duration + if Engine.get_version_info().major == 4 and \ + Engine.get_version_info().minor >= 3: + _tween_is_instant = true + else: + _tween_elapsed_time = 0 + + _check_pcam_physics() + + _trigger_pcam_tween = true + + +func _check_pcam_physics() -> void: + if _is_2d: + if _active_pcam_2d.get_follow_target_physics_based() and interpolation_mode != InterpolationMode.IDLE: + _follow_target_physics_based = true + camera_2d.reset_physics_interpolation() + camera_2d.physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_ON + if ProjectSettings.get_setting("physics/common/physics_interpolation"): + camera_2d.process_callback = Camera2D.CAMERA2D_PROCESS_PHYSICS # Prevents a warning + else: + camera_2d.process_callback = Camera2D.CAMERA2D_PROCESS_IDLE + else: + _follow_target_physics_based = false + camera_2d.physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_INHERIT + if get_tree().physics_interpolation: + camera_2d.process_callback = Camera2D.CAMERA2D_PROCESS_PHYSICS # Prevents a warning + else: + camera_2d.process_callback = Camera2D.CAMERA2D_PROCESS_IDLE + else: + ## NOTE - Only supported in Godot 4.4 or later + if Engine.get_version_info().major == 4 and \ + Engine.get_version_info().minor >= 4: + if (get_tree().physics_interpolation or _active_pcam_3d.get_follow_target_physics_based()) and interpolation_mode != InterpolationMode.IDLE: + #if get_tree().physics_interpolation or _active_pcam_3d.get_follow_target_physics_based(): + _follow_target_physics_based = true + camera_3d.reset_physics_interpolation() + camera_3d.physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_ON + else: + _follow_target_physics_based = false + camera_3d.physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_INHERIT + + +## TODO - For 0.8 release +#func _find_pcam_with_highest_priority() -> void: + #var highest_priority_pcam: Node + #for pcam in _pcam_list: + #if not pcam.visible: continue # Prevents hidden PCams from becoming active + #if pcam.priority > _active_pcam_priority: + #_active_pcam_priority = pcam.priority + #highest_priority_pcam = pcam + #pcam.set_has_tweened(self, false) +# + #_active_pcam_missing = false +# + #if is_instance_valid(highest_priority_pcam): + #_assign_new_active_pcam(highest_priority_pcam) + #else: + #_active_pcam_missing = true + + +func _process(delta: float) -> void: + if _active_pcam_missing: return + + if not _follow_target_physics_based: _tween_follow_checker(delta) + + +func _physics_process(delta: float) -> void: + if _active_pcam_missing or not _follow_target_physics_based: return + _tween_follow_checker(delta) + + +func _tween_follow_checker(delta: float) -> void: + if _is_2d: + if not is_instance_valid(_active_pcam_2d): + _active_pcam_missing = true + return + + _active_pcam_2d.process_logic(delta) + _active_pcam_2d_glob_transform = _active_pcam_2d.get_transform_output() + + if _reset_noise_offset_2d: + camera_2d.offset = Vector2.ZERO # Resets noise position + _reset_noise_offset_2d = false + else: + if not is_instance_valid(_active_pcam_3d): + _active_pcam_missing = true + return + + _active_pcam_3d.process_logic(delta) + _active_pcam_3d_glob_transform = _active_pcam_3d.get_transform_output() + + if not _trigger_pcam_tween: + # Rechecks physics target if PCam transitioned with an instant tween + if _tween_is_instant: + _check_pcam_physics() + _tween_is_instant = false + _pcam_follow(delta) + else: + _pcam_tween(delta) + + # Camera Noise + if _is_2d: + if not _has_noise_emitted and not _active_pcam_2d.has_noise_resource(): return + camera_2d.offset += _active_pcam_2d.get_noise_transform().origin + _noise_emitted_output_2d.origin + if camera_2d.ignore_rotation and _noise_emitted_output_2d.get_rotation() != 0: + push_warning(camera_2d.name, " has ignore_rotation enabled. Uncheck the property if you want to apply rotational noise.") + else: + camera_2d.rotation += _active_pcam_2d.get_noise_transform().get_rotation() + _noise_emitted_output_2d.get_rotation() + _has_noise_emitted = false + _reset_noise_offset_2d = true + else: + if not _has_noise_emitted and not _active_pcam_3d.has_noise_resource(): return + camera_3d.global_transform *= _active_pcam_3d.get_noise_transform() * _noise_emitted_output_3d + _has_noise_emitted = false + + +func _pcam_follow(_delta: float) -> void: + if _active_pcam_missing or not _is_child_of_camera: return + + if _is_2d: + if _active_pcam_2d.snap_to_pixel: + var snap_to_pixel_glob_transform: Transform2D = _active_pcam_2d_glob_transform + snap_to_pixel_glob_transform.origin = snap_to_pixel_glob_transform.origin.round() + camera_2d.global_transform = snap_to_pixel_glob_transform + else: + camera_2d.global_transform = _active_pcam_2d_glob_transform + camera_2d.zoom = _active_pcam_2d.zoom + else: + camera_3d.global_transform = _active_pcam_3d_glob_transform + + if _viewfinder_needed_check: + _show_viewfinder_in_play() + _viewfinder_needed_check = false + + if Engine.is_editor_hint(): + if not _is_2d: + # TODO - Signal-based solution pending merge of: https://github.com/godotengine/godot/pull/99729 + if _active_pcam_3d.attributes != null: + camera_3d.attributes = _active_pcam_3d.attributes.duplicate() + + # TODO - Signal-based solution pending merge of: https://github.com/godotengine/godot/pull/99873 + if _active_pcam_3d.environment != null: + camera_3d.environment = _active_pcam_3d.environment.duplicate() + + +func _noise_emitted_2d(noise_output: Transform2D) -> void: + _noise_emitted_output_2d = noise_output + _has_noise_emitted = true + + +func _noise_emitted_3d(noise_output: Transform3D) -> void: + _noise_emitted_output_3d = noise_output + _has_noise_emitted = true + + +func _camera_3d_resource_changed() -> void: + if _active_pcam_3d.camera_3d_resource: + if Engine.is_editor_hint(): + if not Engine.get_singleton(&"EditorInterface").get_inspector().property_edited.is_connected(_camera_3d_edited): + Engine.get_singleton(&"EditorInterface").get_inspector().property_edited.connect(_camera_3d_edited) + camera_3d.keep_aspect = _active_pcam_3d.keep_aspect + camera_3d.cull_mask = _active_pcam_3d.cull_mask + camera_3d.h_offset = _active_pcam_3d.h_offset + camera_3d.v_offset = _active_pcam_3d.v_offset + camera_3d.projection = _active_pcam_3d.projection + camera_3d.fov = _active_pcam_3d.fov + camera_3d.size = _active_pcam_3d.size + camera_3d.frustum_offset = _active_pcam_3d.frustum_offset + camera_3d.near = _active_pcam_3d.near + camera_3d.far = _active_pcam_3d.far + else: + if Engine.is_editor_hint(): + if Engine.get_singleton(&"EditorInterface").get_inspector().property_edited.is_connected(_camera_3d_edited): + Engine.get_singleton(&"EditorInterface").get_inspector().property_edited.disconnect(_camera_3d_edited) + +func _camera_3d_edited(value: String) -> void: + if not Engine.get_singleton(&"EditorInterface").get_inspector().get_edited_object() == camera_3d: return + camera_3d.set(value, _active_pcam_3d.camera_3d_resource.get(value)) + push_warning("Camera3D properties are being overridden by ", _active_pcam_3d.name, "'s Camera3DResource") + +func _camera_3d_resource_property_changed(property: StringName, value: Variant) -> void: + camera_3d.set(property, value) + + +func _pcam_tween(delta: float) -> void: + # TODO - Should be optimised + # Run at the first tween frame + if _tween_elapsed_time == 0: + if _is_2d: + _active_pcam_2d.tween_started.emit() + _active_pcam_2d.reset_limit() + else: + _active_pcam_3d.tween_started.emit() + + _tween_elapsed_time = min(_tween_duration, _tween_elapsed_time + delta) + + if _is_2d: + _active_pcam_2d.is_tweening.emit() + var interpolation_destination: Vector2 = _tween_interpolate_value( + _prev_active_pcam_2d_transform.origin, + _active_pcam_2d_glob_transform.origin, + _active_pcam_2d.tween_duration, + _active_pcam_2d.tween_transition, + _active_pcam_2d.tween_ease + ) + + if _active_pcam_2d.snap_to_pixel: + camera_2d.global_position = interpolation_destination.round() + else: + camera_2d.global_position = interpolation_destination + + camera_2d.rotation = _tween_interpolate_value( + _prev_active_pcam_2d_transform.get_rotation(), + _active_pcam_2d_glob_transform.get_rotation(), + _active_pcam_2d.tween_duration, + _active_pcam_2d.tween_transition, + _active_pcam_2d.tween_ease + ) + camera_2d.zoom = _tween_interpolate_value( + _camera_zoom, + _active_pcam_2d.zoom, + _active_pcam_2d.tween_duration, + _active_pcam_2d.tween_transition, + _active_pcam_2d.tween_ease + ) + else: + _active_pcam_3d.is_tweening.emit() + camera_3d.global_position = _tween_interpolate_value( + _prev_active_pcam_3d_transform.origin, + _active_pcam_3d_glob_transform.origin, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + var prev_active_pcam_3d_quat: Quaternion = Quaternion(_prev_active_pcam_3d_transform.basis.orthonormalized()) + camera_3d.quaternion = \ + Tween.interpolate_value( + prev_active_pcam_3d_quat, \ + prev_active_pcam_3d_quat.inverse() * Quaternion(_active_pcam_3d_glob_transform.basis.orthonormalized()), + _tween_elapsed_time, \ + _active_pcam_3d.tween_duration, \ + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + if _cam_attribute_changed: + if _active_pcam_3d.attributes.auto_exposure_enabled: + if _cam_auto_exposure_scale_changed: + camera_3d.attributes.auto_exposure_scale = \ + _tween_interpolate_value( + _prev_cam_auto_exposure_scale, + _active_pcam_3d.attributes.auto_exposure_scale, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_auto_exposure_speed_changed: + camera_3d.attributes.auto_exposure_speed = \ + _tween_interpolate_value( + _prev_cam_auto_exposure_scale, + _active_pcam_3d.attributes.auto_exposure_scale, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + if _cam_attribute_type == 0: # CameraAttributePractical + if _active_pcam_3d.attributes.auto_exposure_enabled: + if _cam_exposure_min_sensitivity_changed: + camera_3d.attributes.auto_exposure_min_sensitivity = \ + _tween_interpolate_value( + _prev_cam_exposure_min_sensitivity, + _active_pcam_3d.attributes.auto_exposure_min_sensitivity, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_exposure_max_sensitivity_changed: + camera_3d.attributes.auto_exposure_max_sensitivity = \ + _tween_interpolate_value( + _prev_cam_exposure_max_sensitivity, + _active_pcam_3d.attributes.auto_exposure_max_sensitivity, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_dof_blur_amount_changed: + camera_3d.attributes.dof_blur_amount = \ + _tween_interpolate_value( + _prev_cam_dof_blur_amount, + _active_pcam_3d.attributes.dof_blur_amount, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_dof_blur_far_distance_changed: + camera_3d.attributes.dof_blur_far_distance = \ + _tween_interpolate_value( + _prev_cam_dof_blur_far_distance, + _active_pcam_3d.attributes.dof_blur_far_distance, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_dof_blur_far_transition_changed: + camera_3d.attributes.dof_blur_far_transition = \ + _tween_interpolate_value( + _prev_cam_dof_blur_far_transition, + _active_pcam_3d.attributes.dof_blur_far_transition, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_dof_blur_near_distance_changed: + camera_3d.attributes.dof_blur_near_distance = \ + _tween_interpolate_value( + _prev_cam_dof_blur_near_distance, + _active_pcam_3d.attributes.dof_blur_near_distance, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_dof_blur_near_transition_changed: + camera_3d.attributes.dof_blur_near_transition = \ + _tween_interpolate_value( + _prev_cam_dof_blur_near_transition, + _active_pcam_3d.attributes.dof_blur_near_transition, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + elif _cam_attribute_type == 1: # CameraAttributePhysical + if _cam_dof_blur_near_transition_changed: + camera_3d.attributes.auto_exposure_max_exposure_value = \ + _tween_interpolate_value( + _prev_cam_exposure_max_exposure_value, + _active_pcam_3d.attributes.auto_exposure_max_exposure_value, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_exposure_min_exposure_value_changed: + camera_3d.attributes.auto_exposure_min_exposure_value = \ + _tween_interpolate_value( + _prev_cam_exposure_min_exposure_value, + _active_pcam_3d.attributes.auto_exposure_min_exposure_value, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_exposure_aperture_changed: + camera_3d.attributes.exposure_aperture = \ + _tween_interpolate_value( + _prev_cam_exposure_aperture, + _active_pcam_3d.attributes.exposure_aperture, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_exposure_shutter_speed_changed: + camera_3d.attributes.exposure_shutter_speed = \ + _tween_interpolate_value( + _prev_cam_exposure_shutter_speed, + _active_pcam_3d.attributes.exposure_shutter_speed, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_frustum_far_changed: + camera_3d.attributes.frustum_far = \ + _tween_interpolate_value( + _prev_cam_frustum_far, + _active_pcam_3d.attributes.frustum_far, + _active_pcam_3d.tween_duration(), + _active_pcam_3d.tween_transition(), + _active_pcam_3d.tween_ease + ) + if _cam_frustum_near_changed: + camera_3d.attributes.frustum_near = \ + _tween_interpolate_value( + _prev_cam_frustum_far, + _active_pcam_3d.attributes.frustum_near, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_frustum_focal_length_changed: + camera_3d.attributes.frustum_focal_length = \ + _tween_interpolate_value( + _prev_cam_frustum_focal_length, + _active_pcam_3d.attributes.frustum_focal_length, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + if _cam_frustum_focus_distance_changed: + camera_3d.attributes.frustum_focus_distance = \ + _tween_interpolate_value( + _prev_cam_frustum_focus_distance, + _active_pcam_3d.attributes.frustum_focus_distance, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + if _cam_h_offset_changed: + camera_3d.h_offset = \ + _tween_interpolate_value( + _prev_cam_h_offset, + _active_pcam_3d.h_offset, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + if _cam_v_offset_changed: + camera_3d.v_offset = \ + _tween_interpolate_value( + _prev_cam_v_offset, + _active_pcam_3d.v_offset, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + if _cam_fov_changed: + camera_3d.fov = \ + _tween_interpolate_value( + _prev_cam_fov, + _active_pcam_3d.fov, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + if _cam_size_changed: + camera_3d.size = \ + _tween_interpolate_value( + _prev_cam_size, + _active_pcam_3d.size, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + if _cam_frustum_offset_changed: + camera_3d.frustum_offset = \ + _tween_interpolate_value( + _prev_cam_frustum_offset, + _active_pcam_3d.frustum_offset, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + if _cam_near_changed: + camera_3d.near = \ + _tween_interpolate_value( + _prev_cam_near, + _active_pcam_3d.near, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + if _cam_far_changed: + camera_3d.far = \ + _tween_interpolate_value( + _prev_cam_far, + _active_pcam_3d.far, + _active_pcam_3d.tween_duration, + _active_pcam_3d.tween_transition, + _active_pcam_3d.tween_ease + ) + + # Forcefully disables physics interpolation when tweens are instant + if _tween_is_instant: + if _is_2d: + camera_2d.physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_OFF + camera_2d.reset_physics_interpolation() + else: + if Engine.get_version_info().major == 4 and \ + Engine.get_version_info().minor >= 4: + camera_3d.physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_OFF + camera_3d.reset_physics_interpolation() + + if _tween_elapsed_time < _tween_duration: return + + _trigger_pcam_tween = false + _tween_elapsed_time = 0 + viewfinder_update.emit(true) + + if _is_2d: + _active_pcam_2d.update_limit_all_sides() + _active_pcam_2d.tween_completed.emit() + _active_pcam_2d.set_tween_skip(self, false) + if Engine.is_editor_hint(): + _active_pcam_2d.queue_redraw() + else: + if _active_pcam_3d.camera_3d_resource and _active_pcam_3d.attributes != null: + if _cam_attribute_type == 0: + if not _active_pcam_3d.attributes.dof_blur_far_enabled: + camera_3d.attributes.dof_blur_far_enabled = false + if not _active_pcam_3d.attributes.dof_blur_near_enabled: + camera_3d.attributes.dof_blur_near_enabled = false + _cam_h_offset_changed = false + _cam_v_offset_changed = false + _cam_fov_changed = false + _cam_size_changed = false + _cam_frustum_offset_changed = false + _cam_near_changed = false + _cam_far_changed = false + _cam_attribute_changed = false + + _active_pcam_3d.set_tween_skip(self, false) + _active_pcam_3d.tween_completed.emit() + + +func _tween_interpolate_value(from: Variant, to: Variant, duration: float, transition_type: int, ease_type: int) -> Variant: + return Tween.interpolate_value( + from, \ + to - from, + _tween_elapsed_time, \ + duration, \ + transition_type, + ease_type, + ) + + +func _show_viewfinder_in_play() -> void: + # Don't show the viewfinder in the actual editor or project builds + if Engine.is_editor_hint() or !OS.has_feature("editor"): return + + # Default the viewfinder node to be hidden + if is_instance_valid(_viewfinder_node): + _viewfinder_node.visible = false + + if _is_2d: + if not _active_pcam_2d.show_viewfinder_in_play: return + if _active_pcam_2d.follow_mode != _active_pcam_2d.FollowMode.FRAMED: return + else: + if not _active_pcam_3d.show_viewfinder_in_play: return + if _active_pcam_3d.follow_mode != _active_pcam_2d.FollowMode.FRAMED: return + + var canvas_layer: CanvasLayer = CanvasLayer.new() + get_tree().get_root().add_child(canvas_layer) + + # Instantiate the viewfinder scene if it isn't already + if not is_instance_valid(_viewfinder_node): + var _viewfinder_scene := load("res://addons/phantom_camera/panel/viewfinder/viewfinder_panel.tscn") + _viewfinder_node = _viewfinder_scene.instantiate() + canvas_layer.add_child(_viewfinder_node) + + _viewfinder_node.visible = true + _viewfinder_node.update_dead_zone() + + +func _update_limit_2d(side: int, limit: int) -> void: + if is_instance_valid(camera_2d): + camera_2d.set_limit(side, limit) + +func _draw_limit_2d(enabled: bool) -> void: + camera_2d.set_limit_drawing_enabled(enabled) + + +## Called when a [param PhantomCamera] is added to the scene.[br] +## [b]Note:[/b] This can only be called internally from a [param PhantomCamera] node. +func _pcam_added_to_scene(pcam: Node) -> void: + if not pcam.is_node_ready(): await pcam.ready + _check_pcam_priority(pcam) + + +## Called when a [param PhantomCamera] is removed from the scene.[br] +## [b]Note:[/b] This can only be called internally from a +## [param PhantomCamera] node. +func _pcam_removed_from_scene(pcam: Node) -> void: + if _is_2d: + if pcam == _active_pcam_2d: + _active_pcam_2d = null + _active_pcam_missing = true + _active_pcam_priority = -1 + _find_pcam_with_highest_priority() + else: + if pcam == _active_pcam_3d: + _active_pcam_3d = null + _active_pcam_missing = true + _active_pcam_priority = -1 + _find_pcam_with_highest_priority() + + +func _pcam_visibility_changed(pcam: Node) -> void: + if pcam == _active_pcam_2d or pcam == _active_pcam_3d: + _active_pcam_priority = -1 + _find_pcam_with_highest_priority() + return + _check_pcam_priority(pcam) + + +func _pcam_teleported(pcam: Node) -> void: + if _is_2d: + if not pcam == _active_pcam_2d: return + if not is_instance_valid(camera_2d): return + camera_2d.global_position = _active_pcam_2d.get_transform_output().origin + camera_2d.reset_physics_interpolation() + else: + if not pcam == _active_pcam_3d: return + if not is_instance_valid(camera_3d): return + camera_3d.global_position = _active_pcam_3d.get_transform_output().origin + camera_3d.reset_physics_interpolation() + + +func _set_layer(current_layers: int, layer_number: int, value: bool) -> int: + var mask: int = current_layers + + # From https://github.com/godotengine/godot/blob/51991e20143a39e9ef0107163eaf283ca0a761ea/scene/3d/camera_3d.cpp#L638 + if layer_number < 1 or layer_number > 20: + printerr("Render layer must be between 1 and 20.") + else: + if value: + mask |= 1 << (layer_number - 1) + else: + mask &= ~(1 << (layer_number - 1)) + + return mask + +#endregion + +#region Public Functions + +## Triggers a recalculation to determine which PhantomCamera has the highest priority. +func pcam_priority_updated(pcam: Node) -> void: + if not is_instance_valid(pcam): return + if not _pcam_is_in_host_layer(pcam): return + + if pcam == _active_pcam_2d or pcam == _active_pcam_3d: + if not pcam.visible: + refresh_pcam_list_priorty() + + if Engine.is_editor_hint(): + if _is_2d: + if not is_instance_valid(_active_pcam_2d): return + if _active_pcam_2d.priority_override: return + else: + if not is_instance_valid(_active_pcam_3d): return + if _active_pcam_3d.priority_override: return + + var current_pcam_priority: int = pcam.priority + + if current_pcam_priority >= _active_pcam_priority: + if _is_2d: + if pcam != _active_pcam_2d: + _assign_new_active_pcam(pcam) + else: + if pcam != _active_pcam_3d: + _assign_new_active_pcam(pcam) + pcam.set_tween_skip(self, false) + _active_pcam_missing = false + + if pcam == _active_pcam_2d or pcam == _active_pcam_3d: + if current_pcam_priority <= _active_pcam_priority: + _active_pcam_priority = current_pcam_priority + _find_pcam_with_highest_priority() + else: + _active_pcam_priority = current_pcam_priority + + +## Updates the viewfinder when a [param PhantomCamera] has its +## [param priority_ovrride] enabled.[br] +## [b]Note:[/b] This only affects the editor. +func _pcam_priority_override(pcam: Node, should_override: bool) -> void: + if not Engine.is_editor_hint(): return + if not _pcam_is_in_host_layer(pcam): return + if should_override: + if _is_2d: + if is_instance_valid(_active_pcam_2d): + if _active_pcam_2d.priority_override: + _active_pcam_2d.priority_override = false + else: + if is_instance_valid(_active_pcam_3d): + if _active_pcam_3d.priority_override: + _active_pcam_3d.priority_override = false + _assign_new_active_pcam(pcam) + else: + _find_pcam_with_highest_priority() + + viewfinder_update.emit(false) + + +## Updates the viewfinder when a [param PhantomCamera] has its +## [param priority_ovrride] disabled.[br] +## [b]Note:[/b] This only affects the editor. +func pcam_priority_override_disabled() -> void: + viewfinder_update.emit(false) + + +## Returns the currently active [param PhantomCamera] +func get_active_pcam() -> Node: + if _is_2d: + return _active_pcam_2d + else: + return _active_pcam_3d + + +## Returns whether if a [param PhantomCamera] should tween when it becomes +## active. If it's already active, the value will always be false. +## [b]Note:[/b] This can only be called internally from a +## [param PhantomCamera] node. +func get_trigger_pcam_tween() -> bool: + return _trigger_pcam_tween + + +## Refreshes the [param PhantomCamera] list and checks for the highest priority. [br] +## [b]Note:[/b] This should [b]not[/b] be necessary to call manually. +func refresh_pcam_list_priorty() -> void: + _active_pcam_priority = -1 + _find_pcam_with_highest_priority() + +#endregion + +#region Setters / Getters + +func set_interpolation_mode(value: int) -> void: + interpolation_mode = value + if is_inside_tree(): + _check_pcam_physics() +func get_interpolation_mode() -> int: + return interpolation_mode + +## Sets the [member host_layers] value. +func set_host_layers(value: int) -> void: + host_layers = value + + if not _is_child_of_camera: return + + if not _active_pcam_missing: + if _is_2d: + _pcam_host_layer_changed(_active_pcam_2d) + else: + _pcam_host_layer_changed(_active_pcam_3d) + else: + _find_pcam_with_highest_priority() + +## Enables or disables a given layer of [member host_layers]. +func set_host_layers_value(layer: int, value: bool) -> void: + host_layers = _set_layer(host_layers, layer, value) + +## Returns the [member host_layers] value. +func get_host_layers() -> int: + return host_layers + +#endregion diff --git a/addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd.uid b/addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd.uid new file mode 100644 index 0000000..e96433d --- /dev/null +++ b/addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd.uid @@ -0,0 +1 @@ +uid://bd046eokvcnu2 diff --git a/addons/phantom_camera/scripts/resources/Camera3DResource.cs b/addons/phantom_camera/scripts/resources/Camera3DResource.cs new file mode 100644 index 0000000..7bd00b5 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/Camera3DResource.cs @@ -0,0 +1,117 @@ +using Godot; + +namespace PhantomCamera; + +public enum KeepAspect +{ + KeepWidth, + KeepHeight +} + +public enum ProjectionType +{ + Perspective, + Orthogonal, + Frustum +} + +public class Camera3DResource(Resource resource) +{ + public readonly Resource Resource = resource; + + public KeepAspect KeepAspect + { + get => (KeepAspect)(int)Resource.Call(MethodName.GetKeepAspect); + set => Resource.Call(MethodName.SetKeepAspect, (int)value); + } + + public int CullMask + { + get => (int)Resource.Call(MethodName.GetCullMask); + set => Resource.Call(MethodName.SetCullMask, value); + } + + public void SetCullMaskValue(int layer, bool value) => Resource.Call(MethodName.SetCullMaskValue, layer, value); + + public float HOffset + { + get => (float)Resource.Call(MethodName.GetHOffset); + set => Resource.Call(MethodName.SetHOffset, value); + } + + public float VOffset + { + get => (float)Resource.Call(MethodName.GetVOffset); + set => Resource.Call(MethodName.SetVOffset, value); + } + + public ProjectionType Projection + { + get => (ProjectionType)(int)Resource.Call(MethodName.GetProjection); + set => Resource.Call(MethodName.SetProjection, (int)value); + } + + public float Fov + { + get => (float)Resource.Call(MethodName.GetFov); + set => Resource.Call(MethodName.SetFov, Mathf.Clamp(value, 1, 179)); + } + + public float Size + { + get => (float)Resource.Call(MethodName.GetSize); + set => Resource.Call(MethodName.SetSize, Mathf.Clamp(value, 0.001f, float.PositiveInfinity)); + } + + public Vector2 FrustumOffset + { + get => (Vector2)Resource.Call(MethodName.GetFrustumOffset); + set => Resource.Call(MethodName.SetFrustumOffset, value); + } + + public float Near + { + get => (float)Resource.Call(MethodName.GetNear); + set => Resource.Call(MethodName.SetNear, Mathf.Clamp(value, 0.001f, float.PositiveInfinity)); + } + + public float Far + { + get => (float)Resource.Call(MethodName.GetFar); + set => Resource.Call(MethodName.SetFar, Mathf.Clamp(value, 0.01f, float.PositiveInfinity)); + } + + public static class MethodName + { + public const string GetKeepAspect = "get_keep_aspect"; + public const string SetKeepAspect = "set_keep_aspect"; + + public const string GetCullMask = "get_cull_mask"; + public const string SetCullMask = "set_cull_mask"; + public const string SetCullMaskValue = "set_cull_mask_value"; + + public const string GetHOffset = "get_h_offset"; + public const string SetHOffset = "set_h_offset"; + + public const string GetVOffset = "get_v_offset"; + public const string SetVOffset = "set_v_offset"; + + public const string GetProjection = "get_projection"; + public const string SetProjection = "set_projection"; + + public const string GetFov = "get_fov"; + public const string SetFov = "set_fov"; + + public const string GetSize = "get_size"; + public const string SetSize = "set_size"; + + public const string GetFrustumOffset = "get_frustum_offset"; + public const string SetFrustumOffset = "set_frustum_offset"; + + public const string GetNear = "get_near"; + public const string SetNear = "set_near"; + + public const string GetFar = "get_far"; + public const string SetFar = "set_far"; + } +} diff --git a/addons/phantom_camera/scripts/resources/Camera3DResource.cs.uid b/addons/phantom_camera/scripts/resources/Camera3DResource.cs.uid new file mode 100644 index 0000000..d66b43e --- /dev/null +++ b/addons/phantom_camera/scripts/resources/Camera3DResource.cs.uid @@ -0,0 +1 @@ +uid://jedyxlihuwbj diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs b/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs new file mode 100644 index 0000000..16b7273 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs @@ -0,0 +1,92 @@ +using Godot; + +namespace PhantomCamera.Noise; + +public class PhantomCameraNoise2D(Resource resource) +{ + public readonly Resource Resource = resource; + + public float Amplitude + { + get => (float)Resource.Call(MethodName.GetAmplitude); + set => Resource.Call(MethodName.SetAmplitude, value); + } + + public float Frequency + { + get => (float)Resource.Call(MethodName.GetFrequency); + set => Resource.Call(MethodName.SetFrequency, value); + } + + public bool RandomizeNoiseSeed + { + get => (bool)Resource.Call(MethodName.GetRandomizeNoiseSeed); + set => Resource.Call(MethodName.SetRandomizeNoiseSeed, value); + } + + public int NoiseSeed + { + get => (int)Resource.Call(MethodName.GetNoiseSeed); + set => Resource.Call(MethodName.SetNoiseSeed, value); + } + + public bool RotationalNoise + { + get => (bool)Resource.Call(MethodName.GetRotationalNoise); + set => Resource.Call(MethodName.SetRotationalNoise, value); + } + + public bool PositionalNoise + { + get => (bool)Resource.Call(MethodName.GetPositionalNoise); + set => Resource.Call(MethodName.SetPositionalNoise, value); + } + + public float RotationalMultiplier + { + get => (float)Resource.Call(MethodName.GetRotationalMultiplier); + set => Resource.Call(MethodName.SetRotationalMultiplier, value); + } + + public float PositionalMultiplierX + { + get => (float)Resource.Call(MethodName.GetPositionalMultiplierX); + set => Resource.Call(MethodName.SetPositionalMultiplierX, value); + } + + public float PositionalMultiplierY + { + get => (float)Resource.Call(MethodName.GetPositionalMultiplierY); + set => Resource.Call(MethodName.SetPositionalMultiplierY, value); + } + + public static class MethodName + { + public const string GetAmplitude = "get_amplitude"; + public const string SetAmplitude = "set_amplitude"; + + public const string GetFrequency = "get_frequency"; + public const string SetFrequency = "set_frequency"; + + public const string GetRandomizeNoiseSeed = "get_randomize_noise_seed"; + public const string SetRandomizeNoiseSeed = "set_randomize_noise_seed"; + + public const string GetNoiseSeed = "get_noise_seed"; + public const string SetNoiseSeed = "set_noise_seed"; + + public const string GetRotationalNoise = "get_rotational_noise"; + public const string SetRotationalNoise = "set_rotational_noise"; + + public const string GetPositionalNoise = "get_positional_noise"; + public const string SetPositionalNoise = "set_positional_noise"; + + public const string GetRotationalMultiplier = "get_rotational_multiplier"; + public const string SetRotationalMultiplier = "set_rotational_multiplier"; + + public const string GetPositionalMultiplierX = "get_positional_multiplier_x"; + public const string SetPositionalMultiplierX = "set_positional_multiplier_x"; + + public const string GetPositionalMultiplierY = "get_positional_multiplier_y"; + public const string SetPositionalMultiplierY = "set_positional_multiplier_y"; + } +} diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs.uid b/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs.uid new file mode 100644 index 0000000..16ddb84 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraNoise2D.cs.uid @@ -0,0 +1 @@ +uid://capjdoxs6gs6r diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs b/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs new file mode 100644 index 0000000..175a427 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs @@ -0,0 +1,119 @@ +using Godot; + +namespace PhantomCamera.Noise; + +public class PhantomCameraNoise3D(Resource resource) +{ + public readonly Resource Resource = resource; + + public float Amplitude + { + get => (float)Resource.Call(MethodName.GetAmplitude); + set => Resource.Call(MethodName.SetAmplitude, value); + } + + public float Frequency + { + get => (float)Resource.Call(MethodName.GetFrequency); + set => Resource.Call(MethodName.SetFrequency, value); + } + + public bool RandomizeNoiseSeed + { + get => (bool)Resource.Call(MethodName.GetRandomizeNoiseSeed); + set => Resource.Call(MethodName.SetRandomizeNoiseSeed, value); + } + + public int NoiseSeed + { + get => (int)Resource.Call(MethodName.GetNoiseSeed); + set => Resource.Call(MethodName.SetNoiseSeed, value); + } + + public bool RotationalNoise + { + get => (bool)Resource.Call(MethodName.GetRotationalNoise); + set => Resource.Call(MethodName.SetRotationalNoise, value); + } + + public bool PositionalNoise + { + get => (bool)Resource.Call(MethodName.GetPositionalNoise); + set => Resource.Call(MethodName.SetPositionalNoise, value); + } + + public float RotationalMultiplierX + { + get => (float)Resource.Call(MethodName.GetRotationalMultiplierX); + set => Resource.Call(MethodName.SetRotationalMultiplierX, value); + } + + public float RotationalMultiplierY + { + get => (float)Resource.Call(MethodName.GetRotationalMultiplierY); + set => Resource.Call(MethodName.SetRotationalMultiplierY, value); + } + + public float RotationalMultiplierZ + { + get => (float)Resource.Call(MethodName.GetRotationalMultiplierZ); + set => Resource.Call(MethodName.SetRotationalMultiplierZ, value); + } + + public float PositionalMultiplierX + { + get => (float)Resource.Call(MethodName.GetPositionalMultiplierX); + set => Resource.Call(MethodName.SetPositionalMultiplierX, value); + } + + public float PositionalMultiplierY + { + get => (float)Resource.Call(MethodName.GetPositionalMultiplierY); + set => Resource.Call(MethodName.SetPositionalMultiplierY, value); + } + + public float PositionalMultiplierZ + { + get => (float)Resource.Call(MethodName.GetPositionalMultiplierZ); + set => Resource.Call(MethodName.SetPositionalMultiplierZ, value); + } + + public static class MethodName + { + public const string GetAmplitude = "get_amplitude"; + public const string SetAmplitude = "set_amplitude"; + + public const string GetFrequency = "get_frequency"; + public const string SetFrequency = "set_frequency"; + + public const string GetRandomizeNoiseSeed = "get_randomize_noise_seed"; + public const string SetRandomizeNoiseSeed = "set_randomize_noise_seed"; + + public const string GetNoiseSeed = "get_noise_seed"; + public const string SetNoiseSeed = "set_noise_seed"; + + public const string GetRotationalNoise = "get_rotational_noise"; + public const string SetRotationalNoise = "set_rotational_noise"; + + public const string GetPositionalNoise = "get_positional_noise"; + public const string SetPositionalNoise = "set_positional_noise"; + + public const string GetRotationalMultiplierX = "get_rotational_multiplier_x"; + public const string SetRotationalMultiplierX = "set_rotational_multiplier_x"; + + public const string GetRotationalMultiplierY = "get_rotational_multiplier_y"; + public const string SetRotationalMultiplierY = "set_rotational_multiplier_y"; + + public const string GetRotationalMultiplierZ = "get_rotational_multiplier_z"; + public const string SetRotationalMultiplierZ = "set_rotational_multiplier_z"; + + public const string GetPositionalMultiplierX = "get_positional_multiplier_x"; + public const string SetPositionalMultiplierX = "set_positional_multiplier_x"; + + public const string GetPositionalMultiplierY = "get_positional_multiplier_y"; + public const string SetPositionalMultiplierY = "set_positional_multiplier_y"; + + public const string GetPositionalMultiplierZ = "get_positional_multiplier_z"; + public const string SetPositionalMultiplierZ = "set_positional_multiplier_z"; + } +} diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs.uid b/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs.uid new file mode 100644 index 0000000..53d184f --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraNoise3D.cs.uid @@ -0,0 +1 @@ +uid://chk7643ynhe4f diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs b/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs new file mode 100644 index 0000000..1c332b7 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs @@ -0,0 +1,64 @@ +using Godot; + +namespace PhantomCamera; + +public enum TransitionType +{ + Linear, + Sine, + Quint, + Quart, + Quad, + Expo, + Elastic, + Cubic, + Circ, + Bounce, + Back +} + +public enum EaseType +{ + EaseIn, + EaseOut, + EaseInOut, + EaseOutIn +} + +public static class PhantomCameraTweenExtensions +{ + public static PhantomCameraTween AsPhantomCameraTween(this Resource resource) + { + return new PhantomCameraTween(resource); + } +} + +public class PhantomCameraTween(Resource tweenResource) +{ + public Resource Resource { get; } = tweenResource; + + public float Duration + { + get => (float)Resource.Get(PropertyName.Duration); + set => Resource.Set(PropertyName.Duration, value); + } + + public TransitionType Transition + { + get => (TransitionType)(int)Resource.Get(PropertyName.Transition); + set => Resource.Set(PropertyName.Transition, (int)value); + } + + public EaseType Ease + { + get => (EaseType)(int)Resource.Get(PropertyName.Ease); + set => Resource.Set(PropertyName.Ease, (int)value); + } + + public static class PropertyName + { + public const string Duration = "duration"; + public const string Transition = "transition"; + public const string Ease = "ease"; + } +} diff --git a/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs.uid b/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs.uid new file mode 100644 index 0000000..dd50ead --- /dev/null +++ b/addons/phantom_camera/scripts/resources/PhantomCameraTween.cs.uid @@ -0,0 +1 @@ +uid://ybr5c2s0tfvx diff --git a/addons/phantom_camera/scripts/resources/camera_3d_resource.gd b/addons/phantom_camera/scripts/resources/camera_3d_resource.gd new file mode 100644 index 0000000..c630e16 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/camera_3d_resource.gd @@ -0,0 +1,110 @@ +@tool +@icon("res://addons/phantom_camera/icons/phantom_camera_camera_3d_resource.svg") +class_name Camera3DResource +extends Resource + +## Resource for [PhantomCamera3D] to override various [Camera3D] properties. +## +## The overrides defined here will be applied to the [Camera3D] upon the +## [PhantomCamera3D] becoming active. + +enum KeepAspect { + KEEP_WIDTH = 0, ## Preserves the horizontal aspect ratio; also known as Vert- scaling. This is usually the best option for projects running in portrait mode, as taller aspect ratios will benefit from a wider vertical FOV. + KEEP_HEIGHT = 1, ## Preserves the vertical aspect ratio; also known as Hor+ scaling. This is usually the best option for projects running in landscape mode, as wider aspect ratios will automatically benefit from a wider horizontal FOV. +} + +enum ProjectionType { + PERSPECTIVE = 0, ## Perspective projection. Objects on the screen becomes smaller when they are far away. + ORTHOGONAL = 1, ## Orthogonal projection, also known as orthographic projection. Objects remain the same size on the screen no matter how far away they are. + FRUSTUM = 2, ## Frustum projection. This mode allows adjusting frustum_offset to create "tilted frustum" effects. +} + +## Overrides [member Camera3D.keep_aspect]. +@export var keep_aspect: KeepAspect = KeepAspect.KEEP_HEIGHT: + set(value): + keep_aspect = value + emit_changed() + get: + return keep_aspect + +## Overrides [member Camera3D.cull_mask]. +@export_flags_3d_render var cull_mask: int = 1048575: + set(value): + cull_mask = value + emit_changed() + get: + return cull_mask + +## Overrides [member Camera3D.h_offset]. +@export_range(0, 1, 0.001, "or_greater", "or_less", "hide_slider", "suffix:m") var h_offset: float = 0: + set(value): + h_offset = value + emit_changed() + get: + return h_offset + +## Overrides [member Camera3D.v_offset]. +@export_range(0, 1, 0.001, "or_greater", "or_less", "hide_slider", "suffix:m") var v_offset: float = 0: + set(value): + v_offset = value + emit_changed() + +## Overrides [member Camera3D.projection]. +@export var projection: ProjectionType = ProjectionType.PERSPECTIVE: + set(value): + projection = value + notify_property_list_changed() + emit_changed() + get: + return projection + +## Overrides [member Camera3D.fov]. +@export_range(1, 179, 0.1, "degrees") var fov: float = 75: + set(value): + fov = value + emit_changed() + get: + return fov + +## Overrides [member Camera3D.size]. +@export_range(0.001, 100, 0.001, "suffix:m", "or_greater") var size: float = 1: + set(value): + size = value + emit_changed() + get: + return size + +## Overrides [member Camera3d.frustum_offset]. +@export var frustum_offset: Vector2 = Vector2.ZERO: + set(value): + frustum_offset = value + emit_changed() + get: + return frustum_offset + +## Overrides [member Camera3D.near]. +@export_range(0.001, 10, 0.001, "suffix:m", "or_greater") var near: float = 0.05: + set(value): + near = value + emit_changed() + get: + return near + +## Overrides [member Camera3D.far]. +@export_range(0.01, 4000, 0.001, "suffix:m","or_greater") var far: float = 4000: + set(value): + far = value + emit_changed() + get: + return far + + +func _validate_property(property: Dictionary) -> void: + if property.name == "fov" and not projection == ProjectionType.PERSPECTIVE: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "size" and projection == ProjectionType.PERSPECTIVE: + property.usage = PROPERTY_USAGE_NO_EDITOR + + if property.name == "frustum_offset" and not projection == ProjectionType.FRUSTUM: + property.usage = PROPERTY_USAGE_NO_EDITOR diff --git a/addons/phantom_camera/scripts/resources/camera_3d_resource.gd.uid b/addons/phantom_camera/scripts/resources/camera_3d_resource.gd.uid new file mode 100644 index 0000000..e8378eb --- /dev/null +++ b/addons/phantom_camera/scripts/resources/camera_3d_resource.gd.uid @@ -0,0 +1 @@ +uid://bc2tn187qiatpcheck diff --git a/addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd b/addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd new file mode 100644 index 0000000..cc87dba --- /dev/null +++ b/addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd @@ -0,0 +1,228 @@ +@tool +@icon("res://addons/phantom_camera/icons/phantom_camera_noise_resource.svg") +class_name PhantomCameraNoise2D +extends Resource + +## A resource type used to apply noise, or shake, to [Camera2D]s that have a [PhantomCameraHost] as a child. +## +## Is a resource type that defines, calculates and outputs the noise values to a [Camera2D] through active +## [PhantomCamera3D].[br] +## It can be applied to either [PhantomCameraNoiseEmitter2D] or a [PhantomCamera2D] noise property directly + +#region Exported Properties + +## Defines the size of the noise pattern.[br] +## Higher values will increase the range the noise can reach. +@export_range(0, 1000, 0.001, "or_greater") var amplitude: float = 10: + set = set_amplitude, + get = get_amplitude + +## Sets the density of the noise pattern.[br] +## Higher values will result in more erratic noise. +@export_range(0, 10, 0.001, "or_greater") var frequency: float = 0.5: + set = set_frequency, + get = get_frequency + +## If true, randomizes the noise pattern every time the noise is run.[br] +## If disabled, [member seed] can be used to define a fixed noise pattern. +@export var randomize_noise_seed: bool = true: + set = set_randomize_noise_seed, + get = get_randomize_noise_seed + +## Sets a predetermined seed noise value.[br] +## Useful if wanting to achieve a persistent noise pattern every time the noise is emitted. +@export var noise_seed: int = 0: + set = set_noise_seed, + get = get_noise_seed + +## Enables noise changes to the [member Camera2D.offset] position. +@export var positional_noise: bool = true: + set = set_positional_noise, + get = get_positional_noise + +## Enables noise changes to the [Camera2D]'s rotation. +@export var rotational_noise: bool = false: + set = set_rotational_noise, + get = get_rotational_noise + +@export_group("Positional Multiplier") +## Multiplies positional noise amount in the X-axis.[br] +## Set the value to [param 0] to disable noise in the axis. +@export_range(0, 1, 0.001, "or_greater") var positional_multiplier_x: float = 1: + set = set_positional_multiplier_x, + get = get_positional_multiplier_x + +## Multiplies positional noise amount in the Y-axis.[br] +## Set the value to [param 0] to disable noise in the axis. +@export_range(0, 1, 0.001, "or_greater") var positional_multiplier_y: float = 1: + set = set_positional_multiplier_y, + get = get_positional_multiplier_y + +@export_group("Rotational Multiplier") +## Multiplies rotational noise amount. +@export_range(0, 1, 0.001, "or_greater") var rotational_multiplier: float = 1: + set = set_rotational_multiplier, + get = get_rotational_multiplier + +#endregion + +#region Private Variables + +var _noise_algorithm: FastNoiseLite = FastNoiseLite.new() + +var _noise_positional_multiplier: Vector2 = Vector2( + positional_multiplier_x, + positional_multiplier_y +) + +var _trauma: float = 0.0: + set(value): + _trauma = value + +var _noise_time: float = 0.0 + +#endregion + +#region Private Functions + +func _init(): + _noise_algorithm.noise_type = FastNoiseLite.TYPE_PERLIN + if randomize_noise_seed: _noise_algorithm.seed = randi() + _noise_algorithm.frequency = frequency + + +func _validate_property(property: Dictionary) -> void: + if randomize_noise_seed and property.name == "noise_seed": + property.usage = PROPERTY_USAGE_NO_EDITOR + + if not rotational_noise and property.name == "rotational_multiplier": + property.usage = PROPERTY_USAGE_NO_EDITOR + + if not positional_noise: + match property.name: + "positional_multiplier_x", \ + "positional_multiplier_y": + property.usage = PROPERTY_USAGE_NO_EDITOR + + +func _get_noise_from_seed(noise_seed: int) -> float: + return _noise_algorithm.get_noise_2d(noise_seed, _noise_time) * amplitude + + +func set_trauma(value: float) -> void: + _trauma = value + +#endregion + +#region Public Functions + +func get_noise_transform(delta: float) -> Transform2D: + var output_position: Vector2 = Vector2.ZERO + var output_rotation: float = 0.0 + _noise_time += delta + _trauma = maxf(_trauma, 0.0) + + if positional_noise: + for i in 2: + output_position[i] = _noise_positional_multiplier[i] * pow(_trauma, 2) * _get_noise_from_seed(i + noise_seed) + if rotational_noise: + output_rotation = rotational_multiplier / 100 * pow(_trauma, 2) * _get_noise_from_seed(noise_seed) + + return Transform2D(output_rotation, output_position) + + +func reset_noise_time() -> void: + _noise_time = 0 + +#endregion + +#region Setters & Getters + +## Sets the [member amplitude] value. +func set_amplitude(value: float) -> void: + amplitude =value + +## Returns the [member amplitude] value. +func get_amplitude() -> float: + return amplitude + + +## Sets the [member frequency] value. +func set_frequency(value: float) -> void: + frequency = value + _noise_algorithm.frequency = value + +## Returns the [member frequency] value. +func get_frequency() -> float: + return frequency + + +## Sets the [member randomize_seed] value. +func set_randomize_noise_seed(value: int) -> void: + randomize_noise_seed = value + if value: _noise_algorithm.seed = randi() + notify_property_list_changed() + +## Returns the [member randomize_seed] value. +func get_randomize_noise_seed() -> int: + return randomize_noise_seed + + +## Sets the [member randomize_seed] value. +func set_noise_seed(value: int) -> void: + noise_seed = value + +## Returns the [member seed] value. +func get_noise_seed() -> int: + return noise_seed + + +## Sets the [member positional_noise] value. +func set_positional_noise(value: bool) -> void: + positional_noise = value + notify_property_list_changed() + +## Returns the [member positional_noise] value. +func get_positional_noise() -> bool: + return positional_noise + + +## Sets the [member rotational_noise] value. +func set_rotational_noise(value: bool) -> void: + rotational_noise = value + notify_property_list_changed() + +## Returns the [member rotational_noise] value. +func get_rotational_noise() -> bool: + return rotational_noise + + +## Sets the [member positional_multiplier_x] value. +func set_positional_multiplier_x(value: float) -> void: + positional_multiplier_x = value + _noise_positional_multiplier.x = value + +## Returns the [member positional_multiplier_x] value. +func get_positional_multiplier_x() -> float: + return positional_multiplier_x + + +## Sets the [member positional_multiplier_y] value. +func set_positional_multiplier_y(value: float) -> void: + positional_multiplier_y = value + _noise_positional_multiplier.y = value + +## Returns the [member positional_multiplier_y] value. +func get_positional_multiplier_y() -> float: + return positional_multiplier_y + + +## Sets the [member rotational_multiplier] value. +func set_rotational_multiplier(value: float) -> void: + rotational_multiplier = value + +## Returns the [member rotational_multiplier] value. +func get_rotational_multiplier() -> float: + return rotational_multiplier + +#endregion diff --git a/addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd.uid b/addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd.uid new file mode 100644 index 0000000..45ae480 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/phantom_camera_noise_2d.gd.uid @@ -0,0 +1 @@ +uid://dimvdouy8g0sv diff --git a/addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd b/addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd new file mode 100644 index 0000000..6cf840f --- /dev/null +++ b/addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd @@ -0,0 +1,301 @@ +@tool +@icon("res://addons/phantom_camera/icons/phantom_camera_noise_resource.svg") +class_name PhantomCameraNoise3D +extends Resource + +## A resource type used to apply noise, or shake, to [Camera3D]s that have a [PhantomCameraHost] as a child. +## +## Is a resource type that defines, calculates and outputs the noise values to a [Camera3D] through active +## [PhantomCamera3D].[br] +## It can be applied to either [PhantomCameraNoiseEmitter3D] or a [PhantomCamera3D] noise property directly + +#region Exported Properties + +## Defines the size of the noise pattern.[br] +## Higher values will increase the range the noise can reach. +@export_range(0, 100, 0.001, "or_greater") var amplitude: float = 10: + set = set_amplitude, + get = get_amplitude + +## Sets the density of the noise pattern.[br] +## Higher values will result in more erratic noise. +@export_range(0, 10, 0.001, "or_greater") var frequency: float = 0.2: + set = set_frequency, + get = get_frequency + +## If true, randomizes the noise pattern every time the noise is run.[br] +## If disabled, [member seed] can be used to define a fixed noise pattern. +@export var randomize_noise_seed: bool = true: + set = set_randomize_noise_seed, + get = get_randomize_noise_seed + +## Sets a predetermined seed noise value.[br] +## Useful if wanting to achieve a persistent noise pattern every time the noise is emitted. +@export var noise_seed: int = 0: + set = set_noise_seed, + get = get_noise_seed + +## Enables noise changes to the [Camera3D]'s rotation. +@export var rotational_noise: bool = true: + set = set_rotational_noise, + get = get_rotational_noise + +## Enables noise changes to the camera's position.[br][br] +## [b]Important[/b][br]This can cause geometry clipping if the camera gets too close while this is active. +@export var positional_noise: bool = false: + set = set_positional_noise, + get = get_positional_noise + +@export_group("Rotational Multiplier") +## Multiplies rotational noise amount in the X-axis.[br] +## Set the value to [param 0] to disable noise in the axis. +@export_range(0, 1, 0.001, "or_greater") var rotational_multiplier_x: float = 1: + set = set_rotational_multiplier_x, + get = get_rotational_multiplier_x + +## Multiplies rotational noise amount in the Y-axis.[br] +## Set the value to [param 0] to disable noise in the axis. +@export_range(0, 1, 0.001, "or_greater") var rotational_multiplier_y: float = 1: + set = set_rotational_multiplier_y, + get = get_rotational_multiplier_y + +## Multiplies rotational noise amount in the Z-axis.[br] +## Set the value to [param 0] to disable noise in the axis. +@export_range(0, 1, 0.001, "or_greater") var rotational_multiplier_z: float = 1: + set = set_rotational_multiplier_z, + get = get_rotational_multiplier_z + +@export_group("Positional Multiplier") +## Multiplies positional noise amount in the X-axis.[br] +## Set the value to [param 0] to disable noise in the axis.[br] +## [b]Note:[/b] Rotational Offset is recommended to avoid potential camera clipping with the environment. +@export_range(0, 1, 0.001, "or_greater") var positional_multiplier_x: float = 1: + set = set_positional_multiplier_x, + get = get_positional_multiplier_x + +## Multiplies positional noise amount in the Y-axis.[br] +## Set the value to [param 0] to disable noise in the axis.[br] +## [b]Note:[/b] Rotational Offset is recommended to avoid potential camera clipping with the environment. +@export_range(0, 1, 0.001, "or_greater") var positional_multiplier_y: float = 1: + set = set_positional_multiplier_y, + get = get_positional_multiplier_y + +## Multiplies positional noise amount in the Z-axis.[br] +## Set the value to [param 0] to disable noise in the axis.[br] +## [b]Note:[/b] Rotational Offset is recommended to avoid potential camera clipping with the environment. +@export_range(0, 1, 0.001, "or_greater") var positional_multiplier_z: float = 1: + set = set_positional_multiplier_z, + get = get_positional_multiplier_z + +#endregion + +#region Private Variables + +var _noise_algorithm: FastNoiseLite = FastNoiseLite.new() + +var _noise_rotational_multiplier: Vector3 = Vector3( + rotational_multiplier_x, + rotational_multiplier_y, + rotational_multiplier_z, +) + +var _noise_positional_multiplier: Vector3 = Vector3( + positional_multiplier_x, + positional_multiplier_y, + positional_multiplier_z, +) + +var _trauma: float = 0.0: + set(value): + _trauma = value + if _trauma == 0.0: + _noise_time = 0.0 + +var _noise_time: float = 0.0 + +#endregion + +#region Private Functions + +func _init(): + _noise_algorithm.noise_type = FastNoiseLite.TYPE_PERLIN + + if randomize_noise_seed: _noise_algorithm.seed = randi() + _noise_algorithm.frequency = frequency + + +func _validate_property(property: Dictionary) -> void: + if randomize_noise_seed and property.name == "noise_seed": + property.usage = PROPERTY_USAGE_NO_EDITOR + + if not rotational_noise: + match property.name: + "rotational_multiplier_x", \ + "rotational_multiplier_y", \ + "rotational_multiplier_z": + property.usage = PROPERTY_USAGE_NO_EDITOR + + if not positional_noise: + match property.name: + "positional_multiplier_x", \ + "positional_multiplier_y", \ + "positional_multiplier_z": + property.usage = PROPERTY_USAGE_NO_EDITOR + + +func _get_noise_from_seed(noise_seed: int) -> float: + return _noise_algorithm.get_noise_2d(noise_seed, _noise_time) * amplitude + + +func set_trauma(value: float) -> void: + _trauma = value + +#endregion + +#region Public Functions + +func get_noise_transform(delta: float) -> Transform3D: + var output_rotation: Vector3 = Vector3.ZERO + var output_position: Vector3 = Vector3.ZERO + _noise_time += delta + _trauma = maxf(_trauma, 0.0) + + for i in 3: + if rotational_noise: + output_rotation[i] = deg_to_rad( + _noise_rotational_multiplier[i] * pow(_trauma, 2) * _get_noise_from_seed(i + noise_seed) + ) + + if positional_noise: + output_position[i] += _noise_positional_multiplier[i] / 10 * \ + pow(_trauma, 2) * _get_noise_from_seed(i + noise_seed) + + return Transform3D(Quaternion.from_euler(output_rotation), output_position) + + +func reset_noise_time() -> void: + _noise_time = 0 + +#endregion + +#region Setters & Getters + +## Sets the [member amplitude] value. +func set_amplitude(value: float) -> void: + amplitude =value + +## Returns the [member amplitude] value. +func get_amplitude() -> float: + return amplitude + + +## Sets the [member frequency] value. +func set_frequency(value: float) -> void: + frequency = value + _noise_algorithm.frequency = value + +## Returns the [member frequency] value. +func get_frequency() -> float: + return frequency + + +## Sets the [member randomize_seed] value. +func set_randomize_noise_seed(value: int) -> void: + randomize_noise_seed = value + if value: _noise_algorithm.seed = randi() + notify_property_list_changed() + +## Returns the [member randomize_seed] value. +func get_randomize_noise_seed() -> int: + return randomize_noise_seed + + +## Sets the [member randomize_seed] value. +func set_noise_seed(value: int) -> void: + noise_seed = value + +## Returns the [member seed] value. +func get_noise_seed() -> int: + return noise_seed + + +## Sets the [member positional_noise] value. +func set_positional_noise(value: bool) -> void: + positional_noise = value + notify_property_list_changed() + +## Returns the [member positional_noise] value. +func get_positional_noise() -> bool: + return positional_noise + + +## Sets the [member rotational_noise] value. +func set_rotational_noise(value: bool) -> void: + rotational_noise = value + notify_property_list_changed() + +## Returns the [member rotational_noise] value. +func get_rotational_noise() -> bool: + return rotational_noise + + +## Sets the [member positional_multiplier_x] value. +func set_positional_multiplier_x(value: float) -> void: + positional_multiplier_x = value + _noise_positional_multiplier.x = value + +## Returns the [member positional_multiplier_x] value. +func get_positional_multiplier_x() -> float: + return positional_multiplier_x + + +## Sets the [member positional_multiplier_y] value. +func set_positional_multiplier_y(value: float) -> void: + positional_multiplier_y = value + _noise_positional_multiplier.y = value + +## Returns the [member positional_multiplier_y] value. +func get_positional_multiplier_y() -> float: + return positional_multiplier_y + + +## Sets the [member positional_multiplier_z] value. +func set_positional_multiplier_z(value: float) -> void: + positional_multiplier_z = value + _noise_positional_multiplier.z = value + +## Returns the [member positional_multiplier_z] value. +func get_positional_multiplier_z() -> float: + return positional_multiplier_z + + +## Sets the [member rotational_multiplier_x] value. +func set_rotational_multiplier_x(value: float) -> void: + rotational_multiplier_x = value + _noise_rotational_multiplier.x = value + +## Returns the [member rotational_multiplier_x] value. +func get_rotational_multiplier_x() -> float: + return rotational_multiplier_x + + +## Sets the [member rotational_multiplier_y] value. +func set_rotational_multiplier_y(value: float) -> void: + rotational_multiplier_y = value + _noise_rotational_multiplier.y = value + +## Returns the [member rotational_multiplier_y] value. +func get_rotational_multiplier_y() -> float: + return rotational_multiplier_y + + +## Sets the [member rotational_multiplier_z] value. +func set_rotational_multiplier_z(value: float) -> void: + rotational_multiplier_z = value + _noise_rotational_multiplier.z = value + +## Returns the [member rotational_multiplier_z] value. +func get_rotational_multiplier_z() -> float: + return rotational_multiplier_z + + #endregion diff --git a/addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd.uid b/addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd.uid new file mode 100644 index 0000000..42a0694 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/phantom_camera_noise_3d.gd.uid @@ -0,0 +1 @@ +uid://cuffvge5ad4aa diff --git a/addons/phantom_camera/scripts/resources/tween_resource.gd b/addons/phantom_camera/scripts/resources/tween_resource.gd new file mode 100644 index 0000000..0a3b46f --- /dev/null +++ b/addons/phantom_camera/scripts/resources/tween_resource.gd @@ -0,0 +1,41 @@ +@icon("res://addons/phantom_camera/icons/phantom_camera_tween.svg") +class_name PhantomCameraTween +extends Resource + +## Tweening resource for [PhantomCamera2D] and [PhantomCamera3D]. +## +## Defines how [param PhantomCameras] transition between one another. +## Changing the tween values for a given [param PhantomCamera] determines how +## transitioning to that instance will look like. + +enum TransitionType { + LINEAR = 0, ## The animation is interpolated linearly. + SINE = 1, ## The animation is interpolated using a sine function. + QUINT = 2, ## The animation is interpolated with a quintic (to the power of 5) function. + QUART = 3, ## The animation is interpolated with a quartic (to the power of 4) function. + QUAD = 4, ## The animation is interpolated with a quadratic (to the power of 2) function. + EXPO = 5, ## The animation is interpolated with an exponential (to the power of x) function. + ELASTIC = 6, ## The animation is interpolated with elasticity, wiggling around the edges. + CUBIC = 7, ## The animation is interpolated with a cubic (to the power of 3) function. + CIRC = 8, ## The animation is interpolated with a function using square roots. + BOUNCE = 9, ## The animation is interpolated by bouncing at the end. + BACK = 10, ## The animation is interpolated backing out at ends. +# CUSTOM = 11, +# NONE = 12, +} + +enum EaseType { + EASE_IN = 0, ## The interpolation starts slowly and speeds up towards the end. + EASE_OUT = 1, ## The interpolation starts quickly and slows down towards the end. + EASE_IN_OUT = 2, ## A combination of EASE_IN and EASE_OUT. The interpolation is slowest at both ends. + EASE_OUT_IN = 3, ## A combination of EASE_IN and EASE_OUT. The interpolation is fastest at both ends. +} + +## The time it takes to tween to this PhantomCamera in [param seconds]. +@export var duration: float = 1.0 + +## The transition bezier type for the tween. The options are defined in the [enum TransitionType]. +@export var transition: TransitionType = TransitionType.LINEAR + +## The ease type for the tween. The options are defined in the [enum EaseType]. +@export var ease: EaseType = EaseType.EASE_IN_OUT diff --git a/addons/phantom_camera/scripts/resources/tween_resource.gd.uid b/addons/phantom_camera/scripts/resources/tween_resource.gd.uid new file mode 100644 index 0000000..a0f2cf1 --- /dev/null +++ b/addons/phantom_camera/scripts/resources/tween_resource.gd.uid @@ -0,0 +1 @@ +uid://8umksf8e80fw diff --git a/addons/phantom_camera/themes/button_focus.tres b/addons/phantom_camera/themes/button_focus.tres new file mode 100644 index 0000000..e6fcc45 --- /dev/null +++ b/addons/phantom_camera/themes/button_focus.tres @@ -0,0 +1,17 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://p058hmj3uut0"] + +[resource] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 diff --git a/addons/phantom_camera/themes/button_hover.tres b/addons/phantom_camera/themes/button_hover.tres new file mode 100644 index 0000000..9d37a86 --- /dev/null +++ b/addons/phantom_camera/themes/button_hover.tres @@ -0,0 +1,13 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://5weqvkjsfso3"] + +[resource] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.960784, 0.960784, 0.960784, 1) +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 diff --git a/addons/phantom_camera/themes/button_normal.tres b/addons/phantom_camera/themes/button_normal.tres new file mode 100644 index 0000000..4eae33d --- /dev/null +++ b/addons/phantom_camera/themes/button_normal.tres @@ -0,0 +1,17 @@ +[gd_resource type="StyleBoxFlat" format=3 uid="uid://bclbwo3xrdat0"] + +[resource] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 diff --git a/addons/phantom_camera/themes/theme.tres b/addons/phantom_camera/themes/theme.tres new file mode 100644 index 0000000..7ce53d8 --- /dev/null +++ b/addons/phantom_camera/themes/theme.tres @@ -0,0 +1,102 @@ +[gd_resource type="Theme" load_steps=12 format=3 uid="uid://bhppejri5dbsf"] + +[ext_resource type="FontFile" uid="uid://dve7mgsjik4dg" path="res://addons/phantom_camera/fonts/Nunito-Regular.ttf" id="1_5rtjh"] +[ext_resource type="StyleBox" uid="uid://5weqvkjsfso3" path="res://addons/phantom_camera/themes/button_hover.tres" id="2_du6h5"] +[ext_resource type="StyleBox" uid="uid://bclbwo3xrdat0" path="res://addons/phantom_camera/themes/button_normal.tres" id="3_a8j1f"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ek0y3"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rjkuq"] +content_margin_left = 8.0 +content_margin_top = 4.0 +content_margin_right = 8.0 +content_margin_bottom = 4.0 +bg_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_x7u0w"] +content_margin_top = 2.0 +content_margin_right = 8.0 +bg_color = Color(0.0784314, 0.109804, 0.129412, 1) +border_width_top = 2 +border_width_right = 2 +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_right = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dln2q"] +content_margin_top = 8.0 +content_margin_bottom = 8.0 +draw_center = false + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wk7ot"] +bg_color = Color(0.227451, 0.72549, 0.603922, 1) +border_color = Color(0.227451, 0.72549, 0.603922, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jidrt"] +bg_color = Color(0.960784, 0.960784, 0.960784, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_o2xwc"] +bg_color = Color(0.960784, 0.960784, 0.960784, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ul127"] +draw_center = false +border_width_left = 4 +border_width_right = 4 +border_color = Color(0.8, 0.8, 0.8, 0) + +[resource] +default_font = ExtResource("1_5rtjh") +Button/colors/font_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/colors/font_focus_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/font_hover_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/font_hover_pressed_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/font_pressed_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/icon_focus_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/icon_hover_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/icon_hover_pressed_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/colors/icon_normal_color = Color(0.0784314, 0.109804, 0.129412, 1) +Button/colors/icon_pressed_color = Color(0.227451, 0.72549, 0.603922, 1) +Button/styles/focus = SubResource("StyleBoxFlat_ek0y3") +Button/styles/hover = ExtResource("2_du6h5") +Button/styles/hover_pressed = null +Button/styles/normal = ExtResource("3_a8j1f") +Button/styles/pressed = SubResource("StyleBoxFlat_rjkuq") +PanelContainer/styles/panel = SubResource("StyleBoxFlat_x7u0w") +ScrollContainer/styles/panel = SubResource("StyleBoxFlat_dln2q") +VBoxContainer/constants/separation = 8 +VScrollBar/styles/grabber = SubResource("StyleBoxFlat_wk7ot") +VScrollBar/styles/grabber_highlight = SubResource("StyleBoxFlat_jidrt") +VScrollBar/styles/grabber_pressed = SubResource("StyleBoxFlat_o2xwc") +VScrollBar/styles/scroll = SubResource("StyleBoxFlat_ul127") diff --git a/addons/reedcomponent/SingleComponentRemotor.gd b/addons/reedcomponent/SingleComponentRemotor.gd new file mode 100644 index 0000000..c608109 --- /dev/null +++ b/addons/reedcomponent/SingleComponentRemotor.gd @@ -0,0 +1,42 @@ +@tool +extends RemoteTransform2D +class_name SingleComponentRemotor + +@export var observed_remote_path: NodePath: + set(value): + remote_path = value + _update_remotor_name() + get: + return remote_path + +var _observed_node: Node = null + +func _ready(): + _update_remotor_name() + +func _update_remotor_name(): + if not Engine.is_editor_hint(): + return + + # 清理旧连接 + if is_instance_valid(_observed_node): + _observed_node.disconnect("renamed", Callable(self, "_on_observed_node_renamed")) + + if remote_path.is_empty(): + name = "Remotor[NONE]" + _observed_node = null + return + + var remote_node := get_node_or_null(remote_path) + if remote_node: + name = "Remotor[%s]" % remote_node.name + _observed_node = remote_node + if not _observed_node.is_connected("renamed", Callable(self, "_on_observed_node_renamed")): + _observed_node.connect("renamed", Callable(self, "_on_observed_node_renamed")) + else: + name = "Remotor[INVALID]" + _observed_node = null + +func _on_observed_node_renamed(): + if _observed_node: + name = "Remotor[%s]" % _observed_node.name diff --git a/addons/reedcomponent/SingleComponentRemotor.gd.uid b/addons/reedcomponent/SingleComponentRemotor.gd.uid new file mode 100644 index 0000000..6e7b875 --- /dev/null +++ b/addons/reedcomponent/SingleComponentRemotor.gd.uid @@ -0,0 +1 @@ +uid://bijoqygv6tncj diff --git a/addons/reedcomponent/component_base.gd b/addons/reedcomponent/component_base.gd new file mode 100644 index 0000000..8893dc5 --- /dev/null +++ b/addons/reedcomponent/component_base.gd @@ -0,0 +1,24 @@ +@abstract +class_name ComponentBase extends Node + +@export_category("Component Base Setting") +@export var component_owner : Node + +##改变量用来控制组件是否启用 +@export var is_active : bool = true: + set(value): + set_physics_process(value) + set_process(value) + is_active = value + + +func _ready() -> void: + if not component_owner: + component_owner = owner + + #组件在初始化时都会等待character的加载 + if not component_owner.is_node_ready() : await component_owner.ready + _init_component() + +@abstract +func _init_component() -> void diff --git a/addons/reedcomponent/component_base.gd.uid b/addons/reedcomponent/component_base.gd.uid new file mode 100644 index 0000000..df371ac --- /dev/null +++ b/addons/reedcomponent/component_base.gd.uid @@ -0,0 +1 @@ +uid://6ujeccql58s0 diff --git a/addons/reedcomponent/grap_hook/SpawnHookComponent.tscn b/addons/reedcomponent/grap_hook/SpawnHookComponent.tscn new file mode 100644 index 0000000..06f548c --- /dev/null +++ b/addons/reedcomponent/grap_hook/SpawnHookComponent.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://psbg4jgpd4no"] + +[ext_resource type="Script" uid="uid://bkkkyugppu7sl" path="res://addons/reedcomponent/grap_hook/spawn_hook_component.gd" id="1_m123t"] + +[node name="SpawnHookComponent" type="Node"] +script = ExtResource("1_m123t") diff --git a/addons/reedcomponent/grap_hook/grapping_hook.gd b/addons/reedcomponent/grap_hook/grapping_hook.gd new file mode 100644 index 0000000..c59a9e7 --- /dev/null +++ b/addons/reedcomponent/grap_hook/grapping_hook.gd @@ -0,0 +1,103 @@ +class_name GrappingHook extends Node2D + +@export var min_rope_length := 20 +@export var max_rope_length := 200 + +@onready var anchor: StaticBody2D = %Anchor +@onready var pin_joint_2d: PinJoint2D = %PinJoint2D +@onready var player_anchor: RigidBody2D = %PlayerAnchor +@onready var line_2d: Line2D = %Line2D + +const speed = 30 + +var _binded_hook_comp:SpawnHookComponet +var m_update_rope_with_nodes: bool = false + +func init(hook_comp:SpawnHookComponet): + _binded_hook_comp = hook_comp + +##默认以PLAYER类开始Hook +func start_hook(hookPosition): + anchor.global_position = hookPosition + + var player = get_tree().get_first_node_in_group("PLAYER") as CharacterBody2D + player_anchor.global_position = player.global_position + player.reparent(player_anchor) + +##以注册者开始Hook +func start_hook_with_instigator(hookPosition:Vector2,instigator:Node2D): + anchor.global_position = hookPosition + + var i = instigator + if not i: return + + player_anchor.global_position = i.global_position + i.reparent(player_anchor) + +##离开Hook +func _leave_rope(): + await get_tree().create_timer(.1).timeout + + var player: Node2D + if _binded_hook_comp: + player = _binded_hook_comp.component_owner + + player.reparent(get_tree().current_scene) + #player.set_active(true) + player.rotation = 0 + + queue_free() + +##此函數通過外部的修改可以驅動物體在繩子上移動。 +func move_hook(input_dir: Vector2, delta: float) -> void: + if input_dir == Vector2.ZERO: + return + + var distance_to_anchor := player_anchor.global_position.distance_to(anchor.global_position) + + # === 左右摆动(切向力)=== + if input_dir.x != 0.0: + var tangent := player_anchor.global_transform.x + player_anchor.apply_central_impulse( + tangent * input_dir.x * speed * delta + ) + + # === 上下:改变绳长 === + if input_dir.y != 0.0: + # y < 0 → 上(收绳) + # y > 0 → 下(放绳) + var rope_dir := player_anchor.global_transform.y as Vector2 + var rope_delta := rope_dir * input_dir.y * speed * delta * 0.5 as Vector2 + + if input_dir.y > 0.0 and distance_to_anchor >= max_rope_length: + return + if input_dir.y < 0.0 and distance_to_anchor <= min_rope_length: + return + + # 暂时解绑 joint,手动移动 anchor + pin_joint_2d.node_b = NodePath("") + player_anchor.global_position += rope_delta + pin_joint_2d.node_b = player_anchor.get_path() + +##更新特定点的位置 +func update_line_target_pos_with_index(point_index: int, target_pos: Vector2) -> void: + line_2d.set_point_position( + point_index, + target_pos - global_position + ) + +##更新锚点的位置 +func update_line_anchor_pos(target_pos: Vector2) -> void: + update_line_target_pos_with_index(0,target_pos) + +##重置所有点的位置到指定的位置 +func reset_line_points_to_target(target_pos: Vector2)-> void: + for i in range(line_2d.points.size()): + update_line_target_pos_with_index(i, target_pos) + +func _process(delta: float) -> void: + ##如果不更新,直接返回。 + if not m_update_rope_with_nodes: return + + update_line_target_pos_with_index(0,player_anchor.global_position) + update_line_target_pos_with_index(1,anchor.global_position) diff --git a/addons/reedcomponent/grap_hook/grapping_hook.gd.uid b/addons/reedcomponent/grap_hook/grapping_hook.gd.uid new file mode 100644 index 0000000..21b8761 --- /dev/null +++ b/addons/reedcomponent/grap_hook/grapping_hook.gd.uid @@ -0,0 +1 @@ +uid://d02c2hmup0axx diff --git a/addons/reedcomponent/grap_hook/grapping_hook.tscn b/addons/reedcomponent/grap_hook/grapping_hook.tscn new file mode 100644 index 0000000..f22003a --- /dev/null +++ b/addons/reedcomponent/grap_hook/grapping_hook.tscn @@ -0,0 +1,33 @@ +[gd_scene load_steps=4 format=3 uid="uid://wlbuqjf2rg03"] + +[ext_resource type="Script" uid="uid://d02c2hmup0axx" path="res://addons/reedcomponent/grap_hook/grapping_hook.gd" id="1_4k3sh"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_rrx75"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_4k3sh"] + +[node name="GrappingHook" type="Node2D"] +script = ExtResource("1_4k3sh") + +[node name="Anchor" type="StaticBody2D" parent="."] +unique_name_in_owner = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Anchor"] +shape = SubResource("RectangleShape2D_rrx75") + +[node name="PinJoint2D" type="PinJoint2D" parent="Anchor"] +unique_name_in_owner = true +node_a = NodePath("..") +node_b = NodePath("../../PlayerAnchor") + +[node name="PlayerAnchor" type="RigidBody2D" parent="."] +unique_name_in_owner = true +position = Vector2(0, 80) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerAnchor"] +shape = SubResource("RectangleShape2D_4k3sh") + +[node name="Line2D" type="Line2D" parent="."] +unique_name_in_owner = true +points = PackedVector2Array(0, 0, 0, 80) +width = 4.0 diff --git a/addons/reedcomponent/grap_hook/spawn_hook_component.gd b/addons/reedcomponent/grap_hook/spawn_hook_component.gd new file mode 100644 index 0000000..ce5ce6f --- /dev/null +++ b/addons/reedcomponent/grap_hook/spawn_hook_component.gd @@ -0,0 +1,101 @@ +class_name SpawnHookComponet extends ComponentBase + +##SpawnHookComponent必须绑定一个相关的RayCast2D,用来控制射线想要检测的位置。 +@export var binded_hook_ray_cast_2d : RayCast2D +##可以通過在這裏添加一個ComponentOwner默認的字段名來讀取輸入方向,默認是為空的。 +@export var binded_hook_move_input_property_name: StringName + +##用於Grapping Hook的基本Instance +const GRAPPING_HOOK = preload("uid://wlbuqjf2rg03") + +var _ray_direction: Vector2 +var _ray_reference: RayCast2D +var _ray_length: float = 100 + +##當前的Graphook的實例 +var _current_grap_hook_inst: GrappingHook + +##钩爪伸长达到动画位置 +signal hook_reach_finished + +func _physics_process(delta: float) -> void: + + #更新當前的grap_hook的移動 + update_grap_physics(get_grap_move_input(),delta) + +##用来设置绑定的Ray的方向。 +func set_ray_direction(in_direction: Vector2) -> Vector2: + + if _ray_direction == in_direction: + return _ray_direction + + _ray_direction = in_direction + + if _ray_reference: + _ray_reference.target_position = Vector2( + _ray_direction.x, + _ray_direction.y + ) * _ray_length + + return _ray_direction + +##生成一个Grap Hook +func spawn_grap_hook_inst() -> GrappingHook: + ##如果沒有正確的和任何可以抓取的物體發生碰撞,會直接返回 + if not _ray_reference.is_colliding(): return null + + var i = GRAPPING_HOOK.instantiate() as GrappingHook + i.init(self) + get_tree().current_scene.add_child(i) + i.start_hook_with_instigator(_ray_reference.get_collision_point(),component_owner) + _current_grap_hook_inst = i + return _current_grap_hook_inst + +func grap_reach_target(duration: float) -> bool: + if not _ray_reference or not _current_grap_hook_inst:return false + + ##重置所有Points的坐标点位置。 + _current_grap_hook_inst.reset_line_points_to_target(component_owner.global_position) + + var start_pos: Vector2 = component_owner.global_position + var target_pos: Vector2 = _ray_reference.get_collision_point() + + var t := get_tree().create_tween() + t.set_trans(Tween.TRANS_SINE) + t.set_ease(Tween.EASE_OUT) + + t.tween_method( + _current_grap_hook_inst.update_line_anchor_pos, + start_pos, + target_pos, + duration + ) + + ##结束时会发送广播 + t.finished.connect(_on_hook_reach_finished) + + return true + +##更新GrapHook的物理 +func update_grap_physics(input: Vector2,delta: float) -> void: + if input.is_zero_approx(): return + if not _current_grap_hook_inst: return + + var i = input.normalized() + _current_grap_hook_inst.move_hook(input,delta) + +##此函數默認為Vector.Zeor,子類可以重寫以得到一個全新的結果,也可以通過綁定的方式獲得一個結果。 +func get_grap_move_input() -> Vector2: + + #如果我們在組件裏綁定了Component上的一個字段,也可以直接獲取。 + if binded_hook_move_input_property_name in component_owner: + return component_owner.get(binded_hook_move_input_property_name) + + return Vector2.ZERO + +func _on_hook_reach_finished() -> void: + _current_grap_hook_inst.m_update_rope_with_nodes = true + hook_reach_finished.emit() + +func _init_component() -> void: + _ray_reference = binded_hook_ray_cast_2d diff --git a/addons/reedcomponent/grap_hook/spawn_hook_component.gd.uid b/addons/reedcomponent/grap_hook/spawn_hook_component.gd.uid new file mode 100644 index 0000000..04b11c4 --- /dev/null +++ b/addons/reedcomponent/grap_hook/spawn_hook_component.gd.uid @@ -0,0 +1 @@ +uid://bkkkyugppu7sl diff --git a/addons/reedcomponent/locomotion/LocomotionComponentDebugger.tscn b/addons/reedcomponent/locomotion/LocomotionComponentDebugger.tscn new file mode 100644 index 0000000..781fa72 --- /dev/null +++ b/addons/reedcomponent/locomotion/LocomotionComponentDebugger.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=2 format=3 uid="uid://ckwle1vxsxs8y"] + +[ext_resource type="Script" uid="uid://c7dyfxj7x8yn3" path="res://addons/reedcomponent/locomotion/locomotion_component_debugger.gd" id="1_ikmwp"] + +[node name="LocomotionComponentDebugger" type="CanvasLayer"] +script = ExtResource("1_ikmwp") + +[node name="Control" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 0 +offset_right = 184.0 +offset_bottom = 155.0 diff --git a/addons/reedcomponent/locomotion/climb_component.gd b/addons/reedcomponent/locomotion/climb_component.gd new file mode 100644 index 0000000..5df1292 --- /dev/null +++ b/addons/reedcomponent/locomotion/climb_component.gd @@ -0,0 +1,68 @@ +class_name ClimbComponent extends ComponentBase + +var characterbody: CharacterBody2D + +@export var climb_max_stamina: float +@export var climb_max_speed_upward: float = 45.0 +@export var climb_max_speed_downward: float = 80.0 +@export var climb_acceleration: float = 900.0 + + +var _climb_input: float +var _can_climb: bool = false + +func _init_component()-> void: + characterbody = component_owner as CharacterBody2D + assert(characterbody,"组件没有正确的绑定CharacterBody2D") + + +func _physics_process(delta: float) -> void: + if not _can_climb: return + + print("攀爬更新中") + _update_climb(delta) + characterbody.move_and_slide() #移动更新 + +func _update_climb(delta) -> void: + + var target_abs: float + + #更新目标速度 + if sign(_climb_input) == .0: + target_abs = 0 + elif sign(_climb_input) > 0: + target_abs = climb_max_speed_downward + else: + target_abs = climb_max_speed_upward + + var target = target_abs * _climb_input + characterbody.velocity.y = speed_approach(characterbody.velocity.y,target,climb_acceleration * delta) + +func add_climb_input(input: float) -> bool: + _climb_input = input + return true + +func start_climb(force_reset: bool = false) -> void: + if force_reset: + characterbody.velocity = Vector2.ZERO + characterbody.move_and_slide() + + _can_climb = true + +func suspend_climb() -> void: + _can_climb = false + +#region Helper Function +func speed_approach(current: float, target: float, delta: float) -> float: + if current < target: + return min(current + delta, target) + elif current > target: + return max(current - delta, target) + return target + +func velocity_approach(current: Vector2, target: Vector2, delta: float) -> Vector2: + var result = current + result.x = speed_approach(current.x, target.x, delta) + result.y = speed_approach(current.y, target.y, delta) + return result +#endregion diff --git a/addons/reedcomponent/locomotion/climb_component.gd.uid b/addons/reedcomponent/locomotion/climb_component.gd.uid new file mode 100644 index 0000000..9b1162b --- /dev/null +++ b/addons/reedcomponent/locomotion/climb_component.gd.uid @@ -0,0 +1 @@ +uid://d4lk1iek61kit diff --git a/addons/reedcomponent/locomotion/dash_component.gd b/addons/reedcomponent/locomotion/dash_component.gd new file mode 100644 index 0000000..47be5ff --- /dev/null +++ b/addons/reedcomponent/locomotion/dash_component.gd @@ -0,0 +1,113 @@ +'''冲刺控制组件 + 注:该组件只适用于继承自CharaterBody2D的角色。 + + 基础移动控制: + + 外部调用移动: + dash() + full_recover_dash_count() + recover_dash_count() + + 内部调用: + speed_approach() 此函数将当前速度趋近向目标速度 +''' +class_name DashComponent extends ComponentBase + +##最大的冲刺次数 +@export var maxium_dash_count:int = 1 +##Dash时的速度 +@export var dash_speed: float = 240 +##结束Dash的速度 +@export var end_dash_speed: float = 160 +##Dash的冷却时间 +@export var dash_cold_down: float = .2 +##是否在组件ready时自动补充所有的Dash次数 +@export var auto_recover_dash_count_at_ready: bool = true + +var characterbody:CharacterBody2D + +var last_dash_count: int + +##此变量为总开关,如果关闭,则在物理更新里无论如何也是不会更新Dash的,这里默认为false,因为Dash需要手动触发,最好不要常开 +var can_dash: bool = false + +var _dash_timer: float #Dash计时器 +var _is_dashing: bool = false #标记Dash状态 +var _dash_direction: Vector2 #存储Dash的Direction + +##当Dash count 重置为最大时,发出 +signal dash_count_recovered +signal dash_brusted +signal dash_prepared + +func _init_component()-> void: + characterbody = component_owner as CharacterBody2D + assert(characterbody,"组件没有正确的绑定CharacterBody2D") + + if auto_recover_dash_count_at_ready: + full_recover_dash_count() + +func _physics_process(delta: float) -> void: + if Engine.is_editor_hint(): + return + + #不允许Dash则直接return + if not can_dash: return + + _update_dash(delta) + characterbody.move_and_slide() + +func _update_dash(delta) -> void: + return + +##整合之后的函数,如果不需要额外的逻辑,可以直接通过这个触发Dash +func integrate_dash(dash_dir: Vector2) -> bool: + if not predash(dash_dir): + return false + await get_tree().process_frame #等待一帧 + can_dash = true + brust_dash() + return true + +##dash函数,输入一个Dash的方向,返回是否成功 +func brust_dash() -> bool: + var old: Vector2 = characterbody.velocity; + var burst: Vector2 = _dash_direction.normalized() * dash_speed; + + if sign(old.x) == sign(burst.x) and abs(old.x) > abs(burst.x): + burst.x = old.x + + characterbody.velocity = burst + dash_brusted.emit() + return true + +##dash准备函数,需要在dash的前一帧触发 +func predash(dash_dir: Vector2) -> bool: + if not get_can_dash(): + return false + + print("Dash更新中") + last_dash_count = maxi(last_dash_count -1,0) + _is_dashing = true + + _dash_direction = dash_dir + return true + +##停止Dash,实际上是关闭Dash标识符 +func stop_dash(force_stop: bool = false) -> void: + if force_stop: + characterbody.velocity = Vector2.ZERO + characterbody.move_and_slide() + _is_dashing = false + +##完全回复的Dash次数 +func full_recover_dash_count() -> void: + last_dash_count = maxium_dash_count + +##回复指定数量的Dash次数 +func recover_dash_count(recover_count : int) -> void: + last_dash_count = clampi(last_dash_count+ recover_count, 0,maxium_dash_count) + +##子类可以重写此方法以自定义Dash的条件 +func get_can_dash() -> bool: + return last_dash_count > 0 diff --git a/addons/reedcomponent/locomotion/dash_component.gd.uid b/addons/reedcomponent/locomotion/dash_component.gd.uid new file mode 100644 index 0000000..26652b1 --- /dev/null +++ b/addons/reedcomponent/locomotion/dash_component.gd.uid @@ -0,0 +1 @@ +uid://ct8ki6hyhryqa diff --git a/addons/reedcomponent/locomotion/jump_locomotion.gd b/addons/reedcomponent/locomotion/jump_locomotion.gd new file mode 100644 index 0000000..a52112f --- /dev/null +++ b/addons/reedcomponent/locomotion/jump_locomotion.gd @@ -0,0 +1,95 @@ +'''Agens移动控制组件 + + Extra: + jump() 基础的跳跃,可以往上跳跃 + stop_jump() 停止跳跃 + walL_jump() 墙跳 +''' +class_name JumpLocomotionComponent extends LocomotionComponent + +# <-- JUMP & FALL PROPOTIY --> +@export_category("Jump Properties") +##跳跃力度,在调用跳跃方法时自动处理为负,无需 * -1 +@export var jump_force : float = 280 +##跳跃极限时间,超过这个时间则无法继续监听跳跃输入 +@export var jump_hold_maxium_time : float = .18 +##跳跃时对移动输入的补正 +@export var jump_horizontal_Boost : float = 80 +##Jump时是否还需要受到重力影响 +@export var jump_effected_by_gravity : bool = true +##半重力触发阈值,当速度小于这个数值时,会将角色的重力减半 +@export var light_gravity_threshold: float = 80 +##半重力乘量,默认.5 +@export var light_gravity_mult: float = .5 + +@export_category("Wall Properties") +##如果apply,则在墙壁下滑时,会额外受到摩擦而保持wall slide speed +@export var apply_wall_slide_gravity: bool = true +##在墙壁下滑时的速度最大值 +@export var wall_slide_fall_maxium_speed: float = 105 +@export var wall_jump_base_force_x : float = 380 +@export var wall_jump_base_force_y : float = -1 + +var _jump_timer : float +var _is_jumping : bool = false +var _is_wall_jumping: bool = false + + +##跳跃 +func jump() -> bool: + if _is_jumping : return false + + #给与一个跳跃的补正速度 + characterbody.velocity.x = _movement_input * jump_horizontal_Boost # 跳跃的水平补正速度 + + _jump_timer = jump_hold_maxium_time + _is_jumping = true + characterbody.velocity.y = _get_jump_force() + + return true + +##停止跳跃,实际的功能是重置跳跃相关的标识符 +func stop_jump() -> void: + _is_jumping = false + _is_wall_jumping = false + +##墙跳 +func wall_jump() -> void: + if not characterbody.is_on_wall_only(): return + + characterbody.velocity.x = characterbody.get_wall_normal().x * wall_jump_base_force_x #基础的wall jump force + characterbody.velocity.y = _get_jump_force() + _jump_timer = jump_hold_maxium_time + _is_jumping = true + _is_wall_jumping = true + +func _update_gravity(delta: float) -> void: + if _jump_timer >= 0: + if _is_jumping: + characterbody.velocity.y = _get_jump_force() + _jump_timer -= delta + + #如果不希望jump时受到重力影响,可以关闭此开关 + if not jump_effected_by_gravity: return + + super._update_gravity(delta) + +##重写重力乘量函数 +func _get_gravity_scale() -> float: + var c = absf(characterbody.velocity.y) <= light_gravity_threshold && _is_jumping + return light_gravity_mult if c else default_gravity_scale + +##重写最大下落速度 +func _get_max_fall_speed() -> float: + var wall_normal_x = characterbody.get_wall_normal().x + if -1 * sign(_movement_input) == wall_normal_x and characterbody.is_on_wall(): + return wall_slide_fall_maxium_speed + else: + return fall_maxium_speed + +##设定jump的力度 +func _get_jump_force() -> float: + var result: float = jump_force + if _is_wall_jumping and wall_jump_base_force_y > 0: + result = wall_jump_base_force_y + return -1.0 * result diff --git a/addons/reedcomponent/locomotion/jump_locomotion.gd.uid b/addons/reedcomponent/locomotion/jump_locomotion.gd.uid new file mode 100644 index 0000000..0449f4e --- /dev/null +++ b/addons/reedcomponent/locomotion/jump_locomotion.gd.uid @@ -0,0 +1 @@ +uid://b1driaa67qnsu diff --git a/addons/reedcomponent/locomotion/locomotion_component.gd b/addons/reedcomponent/locomotion/locomotion_component.gd new file mode 100644 index 0000000..8c1f9da --- /dev/null +++ b/addons/reedcomponent/locomotion/locomotion_component.gd @@ -0,0 +1,171 @@ +'''移动控制组件 + 注:该组件只适用于继承自CharaterBody2D的角色。 + + 基础移动控制: + + 外部调用移动: + add_movement_input() + stop_movement() 停止运动,可以根据输入的Flag来决定是否要完全打断运动 + + 内部调用: + speed_approach() 此函数将当前速度趋近向目标速度 +''' +class_name LocomotionComponent extends ComponentBase + +@export_category("Component Setting") +##如果设置为false,则角色将完全不能移动 +@export var _can_move : bool = true + +@export_category("Gravity Properties") +@export_subgroup("Fall") +##角色受到的重力乘量 +@export var default_gravity_scale: float = 1.0 +##如果设置为false,则角色将不会应用重力 +@export var should_apply_gravity : bool = true +##角色下落的最大速度 +@export var fall_maxium_speed : float = 480 +##当空中速度超过了阈值速度时,降速的加速度 +@export var fall_reduce_acceleration: float = 4000 +##空中控制乘量,在空中移动时修改 +@export var air_control_mult : float = .65 +#基础的乘量,对所有Character相同 +const GRAVITY_BASIC_MULT_FACTOR : float = 2.1 +#下坠速度和最大下坠速度的阈值,超过了这个阈值会开启下坠速度修正,主要取决于设备的刷新率固写死。 +const FALL_SPEED_EXCEED_TOLERANCE_THRESHOLD = 40 + +@export_category("Locomotion Properties") +@export_subgroup("Move") +@export var run_accel : float = 1200 +@export var run_reduce : float = 1600 +@export var move_speed_max : float = 280 + +var characterbody: CharacterBody2D + +var _movement_input : float = 0.0 +var _was_moving : bool = false +var _in_pivoting : bool = false +var last_frame_character_on_floor: bool = false +var is_first_update: bool = false + +signal move_dir_changed_in_moving(direction : float) +signal start_move(direction : float) +signal ground_state_changed(is_leave: bool) + +func _init_component() -> void: + characterbody = component_owner as CharacterBody2D + assert(characterbody,"组件没有正确的绑定CharacterBody2D") + +#region 外部调用函数 +##外部每帧调用这个方法,以让角色移动 +func add_movement_input(input : float) -> void: + _movement_input = input + +#外部调用这个函数,强制让角色停住 +func stop_movement(force_static: bool = false) -> void: + if force_static: #如果希望角色强制停下,则设置为真 + characterbody.velocity = Vector2.ZERO + characterbody.move_and_slide() + # 立即重置输入状态 + _movement_input = 0.0 + +func suspend_movement() -> void: + characterbody.velocity = Vector2.ZERO + characterbody.move_and_slide() + _can_move = false + +func enable_movement() -> void: + _can_move = true + +#endregion + +func _physics_process(delta: float) -> void: + if !_can_move : + return #不允许移动,直接停止退出 + print("Loco 更新中") + + _update_movement(delta) #更新移动输入 + _update_gravity(delta) #更新重力 + + characterbody.move_and_slide() #移动更新 + _handle_body_ground_state(delta) + +##更新重力相关的函数 +func _update_gravity(delta: float) -> void: + + var speed_on_gravity_dir = characterbody.velocity.dot(characterbody.get_gravity().normalized()) + if should_apply_gravity and speed_on_gravity_dir <= _get_max_fall_speed(): + characterbody.velocity += characterbody.get_gravity() * GRAVITY_BASIC_MULT_FACTOR * _get_gravity_scale() * delta + + if (abs(characterbody.velocity.dot(characterbody.get_gravity().normalized()))- _get_max_fall_speed()) > FALL_SPEED_EXCEED_TOLERANCE_THRESHOLD: + characterbody.velocity = velocity_approach(characterbody.velocity,characterbody.get_gravity().normalized() * _get_max_fall_speed(), fall_reduce_acceleration * delta) + +##更新移动相关的函数 +func _update_movement(delta : float) -> void: + + var input_dir = sign(_movement_input) as float + var current_dir = characterbody.velocity.normalized().x as float + var accel: float + if abs(characterbody.velocity.x) > move_speed_max and input_dir * current_dir > 0: + accel = run_reduce + else: + accel = run_accel + + #如果检测到当前速度和加速度方向不同,则发送移动方向更改event + if current_dir * input_dir < 0 and not _in_pivoting: + move_dir_changed_in_moving.emit(input_dir) + _in_pivoting = true + + if current_dir * input_dir >= 0: + _in_pivoting = false + + var applyed_air_control = 1 if characterbody.is_on_floor() else air_control_mult + var target_move_speed = move_speed_max * input_dir * applyed_air_control + + characterbody.velocity.x = speed_approach(characterbody.velocity.x,target_move_speed,accel * delta) + + #检测是否这帧开始了移动 + _check_is_start_move() + +##用来检测玩家是否当前帧改变了状态。 +func _handle_body_ground_state(delta: float) -> void: + if is_first_update: + is_first_update = false + last_frame_character_on_floor = characterbody.is_on_floor() + return + + if last_frame_character_on_floor != characterbody.is_on_floor(): + ground_state_changed.emit(last_frame_character_on_floor) + last_frame_character_on_floor = characterbody.is_on_floor() + +func _get_gravity_scale() -> float: + return default_gravity_scale + +func _get_max_fall_speed() -> float: + return fall_maxium_speed + +# -----------HELPER----------- +##将一个速度持续Lerp向目标速度 +func speed_approach(current: float, target: float, delta: float) -> float: + if current < target: + return min(current + delta, target) + elif current > target: + return max(current - delta, target) + return target + +##将一个向量速度持续lerp向目标向量速度 +func velocity_approach(current: Vector2, target: Vector2, delta: float) -> Vector2: + var result = current + result.x = speed_approach(current.x, target.x, delta) + result.y = speed_approach(current.y, target.y, delta) + return result + +##用于检测是否开始移动 +func _check_is_start_move() -> void: + # 判断是否开始移动 + var is_moving_now = not is_zero_approx(characterbody.velocity.x) + + if is_moving_now and not _was_moving: + start_move.emit(sign(characterbody.velocity.x)) # 发送开始移动事件 + + _was_moving = is_moving_now +# -----------HELPER----------- diff --git a/addons/reedcomponent/locomotion/locomotion_component.gd.uid b/addons/reedcomponent/locomotion/locomotion_component.gd.uid new file mode 100644 index 0000000..e6e4c91 --- /dev/null +++ b/addons/reedcomponent/locomotion/locomotion_component.gd.uid @@ -0,0 +1 @@ +uid://d3p38ku8kxc0g diff --git a/addons/reedcomponent/locomotion/locomotion_component_debugger.gd b/addons/reedcomponent/locomotion/locomotion_component_debugger.gd new file mode 100644 index 0000000..5512a0a --- /dev/null +++ b/addons/reedcomponent/locomotion/locomotion_component_debugger.gd @@ -0,0 +1,7 @@ +extends CanvasLayer + +@export var monitor_locomotion_component_owner: Node2D + +func _ready() -> void: + if not monitor_locomotion_component_owner: + return diff --git a/addons/reedcomponent/locomotion/locomotion_component_debugger.gd.uid b/addons/reedcomponent/locomotion/locomotion_component_debugger.gd.uid new file mode 100644 index 0000000..446425c --- /dev/null +++ b/addons/reedcomponent/locomotion/locomotion_component_debugger.gd.uid @@ -0,0 +1 @@ +uid://c7dyfxj7x8yn3 diff --git a/addons/reedcomponent/locomotion/wall_detector.gd b/addons/reedcomponent/locomotion/wall_detector.gd new file mode 100644 index 0000000..5695625 --- /dev/null +++ b/addons/reedcomponent/locomotion/wall_detector.gd @@ -0,0 +1,122 @@ +class_name WallDetector extends Node2D + +@onready var up_r: RayCast2D = $UpRayCast2D +@onready var mid_r: RayCast2D = $MidRayCast2D +@onready var down_r: RayCast2D = $DownRayCast2D + +var flip_h: bool = false: + set(value): + if flip_h == value: + return + else: + flip_h = value + flip(flip_h) + return + +signal wall_state_changed(enter_wall: bool) + +signal up_ray_state_changed(enter_wall: bool) +signal mid_ray_state_changed(enter_wall: bool) +signal down_ray_state_changed(enter_wall: bool) + +var is_on_wall: bool = false : set = _change_wall_state +var up_ray_on_wall: bool = false: + set(value): + if up_ray_on_wall == value: + return + else: + up_ray_on_wall = value + up_ray_state_changed.emit(value) +var mid_ray_on_wall: bool = false: + set(value): + if mid_ray_on_wall == value: + return + else: + mid_ray_on_wall = value + mid_ray_state_changed.emit(value) +var down_ray_on_wall: bool = false: + set(value): + if down_ray_on_wall == value: + return + else: + down_ray_on_wall = value + down_ray_state_changed.emit(value) + + + +func _physics_process(delta: float) -> void: + var n1 = up_r.get_collision_normal() as Vector2 + var n2 = mid_r.get_collision_normal() as Vector2 + var n3 = down_r.get_collision_normal() as Vector2 + + ##更新其他的射线的OnWall状态 + up_ray_on_wall = up_r.is_colliding() and is_nearly_vertical_plane(n1) + mid_ray_on_wall = mid_r.is_colliding() and is_nearly_vertical_plane(n2) + down_ray_on_wall = down_r.is_colliding() and is_nearly_vertical_plane(n3) + + var all_collid = up_r.is_colliding() and mid_r.is_colliding() and down_r.is_colliding() as bool + var vertical_plane = is_nearly_vertical_plane(n1) and is_nearly_vertical_plane(n2) and is_nearly_vertical_plane(n3) as bool + + is_on_wall = all_collid and vertical_plane + +##修改wall state的函数,如果需要改就在这里改 +func _change_wall_state(inis_on_wall: bool) -> void: + if inis_on_wall: #如果在wall上的状态为真,则检测现在的状态是不是在wall上,如果不是,则发送状态改变 + if is_on_wall: + return + else: + wall_state_changed.emit(true) + is_on_wall = true + else: #如果在wall上的状态为false,则检测现在的状态是不是不在wall上,如果不是,则发送状态改变 + if not is_on_wall: + return + else: + wall_state_changed.emit(false) + is_on_wall = false + +##修改ray state的函数,如果需要改就在这里改 +func _change_ray_state(inis_on_wall: bool,field_name: StringName,signal_name:StringName) -> void: + var current_state = get(field_name) + if inis_on_wall: + if current_state: return + else: + emit_signal(signal_name,true) + set(field_name,true) + else: + if not current_state: return + else: + emit_signal(signal_name,false) + set(field_name,false) + +func flip(flip: bool) -> void: + var r = Vector2(-1,1) if flip else Vector2(1,1) + + up_r.scale = r + mid_r.scale = r + down_r.scale = r + +##Helper函数,判断是否是几乎垂直的面 +func is_nearly_vertical_plane(normal: Vector2) -> bool: + # 定义一个容忍度/阈值,例如 0.1 (表示角度偏离 90 度最多约 5.7 度) + # 90 度的法线夹角意味着点积为 0。 + # 我们要找的是法线接近水平的情况,即法线与 Y 轴(垂直)的点积接近 0。 + + # 垂直向量 (Y 轴) + var world_up = Vector2.UP # (0, -1) 或 Vector2.DOWN (0, 1),取决于你的坐标系 + # 为了代码健壮性,我们检查法线与垂直方向的点积的绝对值是否小于一个很小的阈值。 + # 点积接近 0 => 向量(法线)和垂直向量接近正交(即法线接近水平)。 + + var dot_product_with_vertical = abs(normal.dot(world_up)) + + # 设定一个阈值 (epsilon),例如 0.1 + # 如果点积的绝对值很小(接近 0),说明法线与世界Y轴接近垂直,即平面接近水平 + # **更正:如果点积接近 0,说明法线与Y轴垂直,即平面是水平的。** + + # 我们要找的是“几乎垂直的平面”,这意味着法线接近水平方向 (X 轴) + var world_right = Vector2.RIGHT # (1, 0) + var dot_product_with_horizontal = abs(normal.dot(world_right)) + + const VERTICAL_PLANE_THRESHOLD = 0.9 # 阈值设为接近 1 + + # 如果法线与水平向量的点积绝对值很大(接近 1),则平面接近垂直 + return dot_product_with_horizontal >= VERTICAL_PLANE_THRESHOLD diff --git a/addons/reedcomponent/locomotion/wall_detector.gd.uid b/addons/reedcomponent/locomotion/wall_detector.gd.uid new file mode 100644 index 0000000..945198a --- /dev/null +++ b/addons/reedcomponent/locomotion/wall_detector.gd.uid @@ -0,0 +1 @@ +uid://dpa58q47hfdvy diff --git a/addons/reedcomponent/locomotion/wall_detector.tscn b/addons/reedcomponent/locomotion/wall_detector.tscn new file mode 100644 index 0000000..a124432 --- /dev/null +++ b/addons/reedcomponent/locomotion/wall_detector.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=2 format=3 uid="uid://blm8q46h3v2im"] + +[ext_resource type="Script" uid="uid://dpa58q47hfdvy" path="res://addons/reedcomponent/locomotion/wall_detector.gd" id="1_wmygx"] + +[node name="WallDetector" type="Node2D"] +script = ExtResource("1_wmygx") + +[node name="UpRayCast2D" type="RayCast2D" parent="."] +position = Vector2(0, -15) +target_position = Vector2(7, 0) +collision_mask = 4 + +[node name="MidRayCast2D" type="RayCast2D" parent="."] +position = Vector2(0, -1) +target_position = Vector2(7, 0) +collision_mask = 4 + +[node name="DownRayCast2D" type="RayCast2D" parent="."] +position = Vector2(0, 11) +target_position = Vector2(6, 0) +collision_mask = 4 diff --git a/addons/reedcomponent/plugin.cfg b/addons/reedcomponent/plugin.cfg new file mode 100644 index 0000000..abdedaa --- /dev/null +++ b/addons/reedcomponent/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="ReedComponent" +description="" +author="ReedZhu" +version=".01" +script="reedcomponent.gd" diff --git a/addons/reedcomponent/reedcomponent.gd b/addons/reedcomponent/reedcomponent.gd new file mode 100644 index 0000000..8ecc6d4 --- /dev/null +++ b/addons/reedcomponent/reedcomponent.gd @@ -0,0 +1,22 @@ +@tool +extends EditorPlugin + + +func _enable_plugin() -> void: + # Add autoloads here. + pass + + +func _disable_plugin() -> void: + # Remove autoloads here. + pass + + +func _enter_tree() -> void: + # Initialization of the plugin goes here. + pass + + +func _exit_tree() -> void: + # Clean-up of the plugin goes here. + pass diff --git a/addons/reedcomponent/reedcomponent.gd.uid b/addons/reedcomponent/reedcomponent.gd.uid new file mode 100644 index 0000000..0b6ccac --- /dev/null +++ b/addons/reedcomponent/reedcomponent.gd.uid @@ -0,0 +1 @@ +uid://cqmwr51llpodi diff --git a/addons/reedfx/plugin.cfg b/addons/reedfx/plugin.cfg new file mode 100644 index 0000000..fa8eef0 --- /dev/null +++ b/addons/reedfx/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="ReedFX" +description="A Plugin that easily manage all effects." +author="ReedZhu" +version=".1" +script="reedfx.gd" diff --git a/addons/reedfx/reedfx.gd b/addons/reedfx/reedfx.gd new file mode 100644 index 0000000..2422adf --- /dev/null +++ b/addons/reedfx/reedfx.gd @@ -0,0 +1,14 @@ +@tool +extends EditorPlugin + +const AUTOLOAD_NAME := "ReedVFX" +const AUTOLOAD_PATH := "res://addons/reedfx/vfx/ReedVFXSystem.tscn" + +func _enter_tree() -> void: + # 1) 自动加载单例 + if not ProjectSettings.has_setting("autoload/%s" % AUTOLOAD_NAME): + add_autoload_singleton(AUTOLOAD_NAME, AUTOLOAD_PATH) + +func _exit_tree() -> void: + if ProjectSettings.has_setting("autoload/%s" % AUTOLOAD_NAME): + remove_autoload_singleton(AUTOLOAD_NAME) diff --git a/addons/reedfx/reedfx.gd.uid b/addons/reedfx/reedfx.gd.uid new file mode 100644 index 0000000..cfa94dc --- /dev/null +++ b/addons/reedfx/reedfx.gd.uid @@ -0,0 +1 @@ +uid://dxbpmpbb4aqg6 diff --git a/addons/reedfx/sfx/ReedSFXSystem.gd b/addons/reedfx/sfx/ReedSFXSystem.gd new file mode 100644 index 0000000..43847ff --- /dev/null +++ b/addons/reedfx/sfx/ReedSFXSystem.gd @@ -0,0 +1,56 @@ +extends Node +class_name ReedSFXSystem + +# ========================= +# 可选:统一音频 Bus +# ========================= +@export var default_bus := "SFX" + + +# ========================= +# 在世界坐标播放音效 +# ========================= +func play_sfx_at_pos( + stream: AudioStream, + world_pos: Vector2, + volume_db: float = 0.0, + pitch_scale: float = 1.0 +) -> void: + if not stream: + return + + var player := AudioStreamPlayer2D.new() + player.stream = stream + player.bus = default_bus + player.volume_db = volume_db + player.pitch_scale = pitch_scale + player.global_position = world_pos + + add_child(player) + player.play() + + # 播放完自动回收 + player.finished.connect(player.queue_free) + + +# ========================= +# 全局 / UI 音效(不受 位置 影响) +# ========================= +func play_sfx_global( + stream: AudioStream, + volume_db: float = 0.0, + pitch_scale: float = 1.0 +) -> void: + if not stream: + return + + var player := AudioStreamPlayer.new() + player.stream = stream + player.bus = default_bus + player.volume_db = volume_db + player.pitch_scale = pitch_scale + + add_child(player) + player.play() + + player.finished.connect(player.queue_free) diff --git a/addons/reedfx/sfx/ReedSFXSystem.gd.uid b/addons/reedfx/sfx/ReedSFXSystem.gd.uid new file mode 100644 index 0000000..ff78c62 --- /dev/null +++ b/addons/reedfx/sfx/ReedSFXSystem.gd.uid @@ -0,0 +1 @@ +uid://c2bvlnq5cuuq1 diff --git a/addons/reedfx/sfx/ReedSFXSystem.tscn b/addons/reedfx/sfx/ReedSFXSystem.tscn new file mode 100644 index 0000000..6bdf415 --- /dev/null +++ b/addons/reedfx/sfx/ReedSFXSystem.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://j1jedhehwy06"] + +[ext_resource type="Script" uid="uid://c2bvlnq5cuuq1" path="res://addons/reedfx/sfx/ReedSFXSystem.gd" id="1_vbuwn"] + +[node name="ReedSfxSystem" type="Node" groups=["ReedSFX"]] +script = ExtResource("1_vbuwn") diff --git a/addons/reedfx/sfx/SFXManager.gd b/addons/reedfx/sfx/SFXManager.gd new file mode 100644 index 0000000..128c33e --- /dev/null +++ b/addons/reedfx/sfx/SFXManager.gd @@ -0,0 +1,90 @@ +'''音效播放管理器 + 可以通過預設的音效表和對應Node的Signal播放對應的音效 +''' + +class_name ReedSFXManager extends Node + + +@export var bindings: Array[SFXSignalBinding] = [] +@export var enable_debug: bool = true + +func _ready() -> void: + _bind_all() + +func _bind_all() -> void: + print("[SFX] binding count =", bindings.size(), " manager path=", get_path()) + + for binding in bindings: + print("[SFX] try bind: target_node=", binding.target_node, " signal=", binding.signal_name) + + if not has_node(binding.target_node): + push_warning("[SFX] target node not found: %s (manager=%s)" % [binding.target_node, get_path()]) + continue + + var target := get_node(binding.target_node) + print("[SFX] target resolved:", target, " path=", target.get_path()) + + if not target.has_signal(binding.signal_name): + push_warning("[SFX] signal not found: %s on %s" % [binding.signal_name, target.get_path()]) + continue + + # 🔥 关键:lambda 包一层 + 打印确认 + var cb := func(ctx = null): + print("[SFX] callback fired! binding=", binding, " ctx=", ctx) + _on_sfx_signal(binding, ctx) + + # 防止重复连接 + if target.is_connected(binding.signal_name, cb): + print("[SFX] already connected, skip:", binding.signal_name) + else: + var err := target.connect(binding.signal_name, cb) + print("[SFX] connect result =", err, " (OK=0)") + +func _on_sfx_signal(binding: SFXSignalBinding, args: Variant) -> void: + if enable_debug and binding.debug_print: + print_debug(binding.get_debug_message()) + + match binding.spawn_space: + SFXSignalBinding.SpawnSpace.GLOBAL: + _play_global(binding) + + SFXSignalBinding.SpawnSpace.WORLD_POSITION: + if args is Dictionary and args.has("world_pos"): + _play_at_position(binding, args["world_pos"]) + +# ----------------------------- +# 播放逻辑 +# ----------------------------- + +func _play_global(binding: SFXSignalBinding) -> void: + var target := get_node(binding.target_node) + if not binding.audio_stream: + return + + var player := _create_player(binding) + add_child(player) + + player.global_position = target.global_position + binding.offset + if binding.autoplay: + player.play() + + +func _play_at_position(binding: SFXSignalBinding, pos: Vector2) -> void: + if not binding.audio_stream: + return + + + var player := _create_player(binding) + add_child(player) + + player.global_position = pos + binding.offset + if binding.autoplay: + player.play() + +func _create_player(binding: SFXSignalBinding) -> AudioStreamPlayer2D: + var player := AudioStreamPlayer2D.new() + player.stream = binding.audio_stream + player.volume_db = binding.volume_db + player.pitch_scale = binding.pitch_scale + player.finished.connect(player.queue_free) + return player diff --git a/addons/reedfx/sfx/SFXManager.gd.uid b/addons/reedfx/sfx/SFXManager.gd.uid new file mode 100644 index 0000000..b44f736 --- /dev/null +++ b/addons/reedfx/sfx/SFXManager.gd.uid @@ -0,0 +1 @@ +uid://lp1ge1qbyfr3 diff --git a/addons/reedfx/sfx/SFXSignalBinding.gd b/addons/reedfx/sfx/SFXSignalBinding.gd new file mode 100644 index 0000000..fee0ebb --- /dev/null +++ b/addons/reedfx/sfx/SFXSignalBinding.gd @@ -0,0 +1,30 @@ +extends Resource +class_name SFXSignalBinding + +@export var target_node: NodePath +@export var signal_name: StringName + +@export var audio_stream: AudioStream + +## VFX 播放位置来源 +enum SpawnSpace { + ##如果是跟随Target,不需要额外的参数 + GLOBAL, + + ##如果是直接Spawn在World,需要提供一个额外的全局坐标 + WORLD_POSITION +} + +@export var spawn_space := SpawnSpace.GLOBAL +@export var offset := Vector2.ZERO +@export var debug_print:= false + +## 音效参数 +@export var volume_db: float = 0.0 +@export var pitch_scale: float = 1.0 +@export var autoplay: bool = true + +func get_debug_message() -> String: + var target_str = "UnknownTarget" if target_node.is_empty() else str(target_node) + var signal_str = "UnknownSignal" if signal_name.is_empty() else str(signal_name) + return "[SFX] Played triggered by signal \"%s\" on node \"%s\"" % [signal_str, target_str] diff --git a/addons/reedfx/sfx/SFXSignalBinding.gd.uid b/addons/reedfx/sfx/SFXSignalBinding.gd.uid new file mode 100644 index 0000000..1f53bb1 --- /dev/null +++ b/addons/reedfx/sfx/SFXSignalBinding.gd.uid @@ -0,0 +1 @@ +uid://du267phqvtqyr diff --git a/addons/reedfx/vfx/CPUVFXTemplate.gd b/addons/reedfx/vfx/CPUVFXTemplate.gd new file mode 100644 index 0000000..4a7bf61 --- /dev/null +++ b/addons/reedfx/vfx/CPUVFXTemplate.gd @@ -0,0 +1,80 @@ +class_name CPUVFXTemplate extends CPUParticles2D + + +## ========================= +## 播放模式 +## ========================= +enum PlayMode { + ##播放一次 + ONLY_ONCE, + ##永久播放 + INFINITE, + ##播放固定次数 + FIXED_TIMES +} + +##可选择的播放模式 +@export var play_mode: PlayMode = PlayMode.ONLY_ONCE + +## 仅在 FIXED_TIMES 模式下生效 +@export var fixed_times: int = 1 + +## ========================= +## 内部状态 +## ========================= +var _played_times: int = 0 +var _life_timer: float = 0.0 +var _playing: bool = false + +## ========================= +## 生命周期 +## ========================= +func _ready() -> void: + _play() + +func _process(delta: float) -> void: + if not _playing: + return + + match play_mode: + PlayMode.ONLY_ONCE: + _update_only_once(delta) + + PlayMode.FIXED_TIMES: + _update_fixed_times(delta) + + PlayMode.INFINITE: + pass # 什么都不用做 + + +## ========================= +## 播放控制 +## ========================= +func _play() -> void: + emitting = true + _playing = true + _life_timer = 0.0 + _played_times = 0 + + +func stop_and_free() -> void: + emitting = false + queue_free() + + +## ========================= +## 模式逻辑 +## ========================= +func _update_only_once(delta: float) -> void: + _life_timer += delta + if _life_timer >= lifetime: + stop_and_free() + +func _update_fixed_times(delta: float) -> void: + _life_timer += delta + if _life_timer >= lifetime: + _played_times += 1 + _life_timer = 0.0 + + if _played_times >= fixed_times: + stop_and_free() diff --git a/addons/reedfx/vfx/CPUVFXTemplate.gd.uid b/addons/reedfx/vfx/CPUVFXTemplate.gd.uid new file mode 100644 index 0000000..f7bc58a --- /dev/null +++ b/addons/reedfx/vfx/CPUVFXTemplate.gd.uid @@ -0,0 +1 @@ +uid://cpuc3qq7pd7lk diff --git a/addons/reedfx/vfx/ReedVFXSystem.gd b/addons/reedfx/vfx/ReedVFXSystem.gd new file mode 100644 index 0000000..38f88f3 --- /dev/null +++ b/addons/reedfx/vfx/ReedVFXSystem.gd @@ -0,0 +1,20 @@ +extends Node + +@onready var vfx_canvas: CanvasLayer = %VFXLayer + +func spawn_vfx_at_pos(vfx_scene: PackedScene,position: Vector2) -> void: + + var vfx := vfx_scene.instantiate() as Node2D + vfx.add_to_group("ReedVFX") + vfx_canvas.add_child(vfx) + + vfx.global_position = position + + +func clear_all(): + for child in vfx_canvas.get_children(): + child.queue_free() + + +func get_canvas() -> CanvasLayer: + return vfx_canvas diff --git a/addons/reedfx/vfx/ReedVFXSystem.gd.uid b/addons/reedfx/vfx/ReedVFXSystem.gd.uid new file mode 100644 index 0000000..d7a7aca --- /dev/null +++ b/addons/reedfx/vfx/ReedVFXSystem.gd.uid @@ -0,0 +1 @@ +uid://c4qis85u5dc1l diff --git a/addons/reedfx/vfx/ReedVFXSystem.tscn b/addons/reedfx/vfx/ReedVFXSystem.tscn new file mode 100644 index 0000000..28ccbba --- /dev/null +++ b/addons/reedfx/vfx/ReedVFXSystem.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=3 uid="uid://bnrt4tipppi56"] + +[ext_resource type="Script" uid="uid://c4qis85u5dc1l" path="res://addons/reedfx/vfx/ReedVFXSystem.gd" id="1_c7ksf"] +[ext_resource type="Script" uid="uid://bwvbeodhvhrmw" path="res://addons/reedfx/vfx/VFXLayer.gd" id="1_rdp6u"] + +[node name="ReedVFXSystem" type="Node" groups=["ReedVFX"]] +script = ExtResource("1_c7ksf") + +[node name="VFXLayer" type="CanvasLayer" parent="."] +unique_name_in_owner = true +layer = 2 +follow_viewport_enabled = true +script = ExtResource("1_rdp6u") diff --git a/addons/reedfx/vfx/VFXLayer.gd b/addons/reedfx/vfx/VFXLayer.gd new file mode 100644 index 0000000..d8eecde --- /dev/null +++ b/addons/reedfx/vfx/VFXLayer.gd @@ -0,0 +1,13 @@ +'''此类会在插件被启用时自动加入ProjectSetting,用来播放特效。 + 所有的特效组件,都会被放置于VFX Layer之下,且被添加入ReedVFX这个组 +''' +@tool +class_name ReedVFXLayer +extends CanvasLayer + +func _enter_tree() -> void: + _add_to_vfx_group() + +func _add_to_vfx_group() -> void: + if not is_in_group("ReedVFX"): + add_to_group("ReedVFX") diff --git a/addons/reedfx/vfx/VFXLayer.gd.uid b/addons/reedfx/vfx/VFXLayer.gd.uid new file mode 100644 index 0000000..b524431 --- /dev/null +++ b/addons/reedfx/vfx/VFXLayer.gd.uid @@ -0,0 +1 @@ +uid://bwvbeodhvhrmw diff --git a/addons/reedfx/vfx/VFXManager.gd b/addons/reedfx/vfx/VFXManager.gd new file mode 100644 index 0000000..08faffd --- /dev/null +++ b/addons/reedfx/vfx/VFXManager.gd @@ -0,0 +1,59 @@ +''' +特效播放管理器 +可以通过预设的特效表和对应 Node 的 Signal +播放对应的特效 +''' +extends Node +class_name ReedVFXManager + +@export var bindings: Array[VFXSignalBinding] = [] +@export var enable_debug: bool = true + + +func _ready() -> void: + _bind_all() + + +func _bind_all() -> void: + for binding in bindings: + if not has_node(binding.target_node): + push_warning("VFXManager: target node not found: %s" % binding.target_node) + continue + + var target := get_node(binding.target_node) + if not target.has_signal(binding.signal_name): + push_warning("VFXManager: signal not found: %s" % binding.signal_name) + continue + + # 用 lambda 包一层 + var cb := func(ctx): + _on_vfx_signal(binding, ctx) + + target.connect(binding.signal_name, cb) + +func _on_vfx_signal(binding: VFXSignalBinding, ctx: Dictionary) -> void: + if enable_debug and binding.debug_print: + print_debug(binding.get_debug_message()) + + match binding.spawn_space: + VFXSignalBinding.SpawnSpace.TARGET_NODE: + _spawn_at_target(binding) + + VFXSignalBinding.SpawnSpace.WORLD_POSITION: + if ctx.has("world_pos"): + _spawn_at_position(binding, ctx["world_pos"]) + + +func _spawn_at_target(binding: VFXSignalBinding) -> void: + var target := get_node(binding.target_node) + if not binding.vfx_scene: + return + + #var vfx := binding.vfx_scene.instantiate() as Node2D + #add_child(vfx) +# + #vfx.global_position = target.global_position + binding.offset + + +func _spawn_at_position(binding: VFXSignalBinding, pos: Vector2) -> void: + ReedVFX.spawn_vfx_at_pos(binding.vfx_scene,pos + binding.offset) diff --git a/addons/reedfx/vfx/VFXManager.gd.uid b/addons/reedfx/vfx/VFXManager.gd.uid new file mode 100644 index 0000000..f9f89ae --- /dev/null +++ b/addons/reedfx/vfx/VFXManager.gd.uid @@ -0,0 +1 @@ +uid://ta2r2bc1nrwe diff --git a/addons/reedfx/vfx/VFXSignalBinding.gd b/addons/reedfx/vfx/VFXSignalBinding.gd new file mode 100644 index 0000000..0264171 --- /dev/null +++ b/addons/reedfx/vfx/VFXSignalBinding.gd @@ -0,0 +1,26 @@ +extends Resource +class_name VFXSignalBinding + +@export var target_node: NodePath +@export var signal_name: StringName + +@export var vfx_scene: PackedScene + +## VFX 播放位置来源 +enum SpawnSpace { + + ##如果是跟随Target,不需要额外的参数 + TARGET_NODE, + + ##如果是直接Spawn在World,需要提供一个额外的全局坐标 + WORLD_POSITION +} + +@export var spawn_space := SpawnSpace.TARGET_NODE +@export var offset := Vector2.ZERO +@export var debug_print:= false + +func get_debug_message() -> String: + var target_str = "UnknownTarget" if target_node.is_empty() else str(target_node) + var signal_str = "UnknownSignal" if signal_name.is_empty() else str(signal_name) + return "[VFX] Spawned triggered by signal \"%s\" on node \"%s\"" % [signal_str, target_str] diff --git a/addons/reedfx/vfx/VFXSignalBinding.gd.uid b/addons/reedfx/vfx/VFXSignalBinding.gd.uid new file mode 100644 index 0000000..c03842c --- /dev/null +++ b/addons/reedfx/vfx/VFXSignalBinding.gd.uid @@ -0,0 +1 @@ +uid://dipfdfnp506hl diff --git a/addons/reedinput/action_def.gd b/addons/reedinput/action_def.gd new file mode 100644 index 0000000..908ea82 --- /dev/null +++ b/addons/reedinput/action_def.gd @@ -0,0 +1,8 @@ +extends Resource +class_name ActionDef + +@export var id: String = "" # 例如 "Jump", "MoveX" +@export_enum("button", "axis") var kind: String = "button" # 动作类型(按钮/轴) + +func is_valid() -> bool: + return id != "" and (kind == "button" or kind == "axis") diff --git a/addons/reedinput/action_def.gd.uid b/addons/reedinput/action_def.gd.uid new file mode 100644 index 0000000..927b800 --- /dev/null +++ b/addons/reedinput/action_def.gd.uid @@ -0,0 +1 @@ +uid://bgpje4ak3vi5u diff --git a/addons/reedinput/action_profile.gd b/addons/reedinput/action_profile.gd new file mode 100644 index 0000000..2f11b2f --- /dev/null +++ b/addons/reedinput/action_profile.gd @@ -0,0 +1,89 @@ +@tool +extends Resource +class_name ActionProfile + +@export var profile_name: String = "Default" + +@export var actions: Array[ActionDef] = [] +@export var key_bindings: Array[KeyBinding] = [] +@export var joy_bindings: Array[JoyAxisBinding] = [] + +# —— 基础校验:在 Inspector 里点“Validate”用,或运行时装载前自测 —— +func validate_profile() -> Array[String]: + var errors: Array[String] = [] + + # 1) 动作合法性 & 唯一性 + var ids := {} + for a in actions: + if a == null or not a.is_valid(): + errors.append("Invalid ActionDef found (empty id or bad kind).") + continue + if ids.has(a.id): + errors.append("Duplicate Action id: %s" % a.id) + else: + ids[a.id] = a.kind + + # 2) 键盘绑定合法性 & 指向存在的动作 + for kb in key_bindings: + if kb == null or not kb.is_valid(): + errors.append("Invalid KeyBinding for action '%s'." % (kb if kb == null else kb.action_id)) + continue + if not ids.has(kb.action_id): + errors.append("KeyBinding refers to unknown action '%s'." % kb.action_id) + elif kb.type == "button" and ids[kb.action_id] != "button": + errors.append("KeyBinding(button) mapped to non-button action '%s'." % kb.action_id) + elif kb.type == "axis_pair" and ids[kb.action_id] != "axis": + errors.append("KeyBinding(axis_pair) mapped to non-axis action '%s'." % kb.action_id) + + # 3) 手柄轴绑定合法性 & 指向存在的动作 + for jb in joy_bindings: + if jb == null or not jb.is_valid(): + errors.append("Invalid JoyAxisBinding.") + continue + if not ids.has(jb.action_id): + errors.append("JoyAxisBinding refers to unknown action '%s'." % jb.action_id) + elif ids[jb.action_id] != "axis": + errors.append("JoyAxisBinding mapped to non-axis action '%s'." % jb.action_id) + + return errors + +# —— 便于 InputComponent 读取的“拍扁”结构(不会创建任何监听,只做数据整形)—— +func flatten() -> Dictionary: + # 输出: + # { + # "actions": { id: { "kind": "button"|"axis" } }, + # "keys_button": { keycode: [action_id, ...] }, + # "keys_axispair": { axis_id: { "neg": keycode|0, "pos": keycode|0 } }, + # "joy_axes": { axis_id: { "axis": int, "deadzone": float } } + # } + var out := { + "actions": {}, + "keys_button": {}, + "keys_axispair": {}, + "joy_axes": {} + } + + for a in actions: + if a and a.is_valid(): + out.actions[a.id] = { "kind": a.kind } + + for kb in key_bindings: + if kb and kb.is_valid(): + if kb.type == "button": + if not out.keys_button.has(kb.key): + out.keys_button[kb.key] = [] + out.keys_button[kb.key].append(kb.action_id) + elif kb.type == "axis_pair": + out.keys_axispair[kb.action_id] = { + "neg": kb.neg_key, + "pos": kb.pos_key + } + + for jb in joy_bindings: + if jb and jb.is_valid(): + out.joy_axes[jb.action_id] = { + "axis": jb.axis, + "deadzone": jb.deadzone + } + + return out diff --git a/addons/reedinput/action_profile.gd.uid b/addons/reedinput/action_profile.gd.uid new file mode 100644 index 0000000..f690533 --- /dev/null +++ b/addons/reedinput/action_profile.gd.uid @@ -0,0 +1 @@ +uid://cs4rtrvvnlek diff --git a/addons/reedinput/joy_axis_binding.gd b/addons/reedinput/joy_axis_binding.gd new file mode 100644 index 0000000..796fc1a --- /dev/null +++ b/addons/reedinput/joy_axis_binding.gd @@ -0,0 +1,9 @@ +extends Resource +class_name JoyAxisBinding + +@export var action_id: String = "" # 绑定到哪个动作(通常是 axis 类型) +@export var axis: int = JOY_AXIS_LEFT_X # 例如 JOY_AXIS_LEFT_X +@export_range(0.0, 0.5, 0.01) var deadzone: float = 0.15 + +func is_valid() -> bool: + return action_id != "" diff --git a/addons/reedinput/joy_axis_binding.gd.uid b/addons/reedinput/joy_axis_binding.gd.uid new file mode 100644 index 0000000..f57b3d3 --- /dev/null +++ b/addons/reedinput/joy_axis_binding.gd.uid @@ -0,0 +1 @@ +uid://cjtjqke0dk1oa diff --git a/addons/reedinput/key_binding.gd b/addons/reedinput/key_binding.gd new file mode 100644 index 0000000..820d62a --- /dev/null +++ b/addons/reedinput/key_binding.gd @@ -0,0 +1,21 @@ +extends Resource +class_name KeyBinding + +@export var action_id: String = "" # 绑定到哪个动作 +@export_enum("button", "axis_pair") var type: String = "button" + +# 按钮型:用 key +@export var key: int = KEY_NONE # 例如 KEY_SPACE + +# 轴型(成对键):用 neg_key / pos_key +@export var neg_key: int = KEY_NONE # 例如 KEY_A +@export var pos_key: int = KEY_NONE # 例如 KEY_D + +func is_valid() -> bool: + if action_id == "": + return false + if type == "button": + return key != KEY_NONE + if type == "axis_pair": + return neg_key != KEY_NONE or pos_key != KEY_NONE + return false diff --git a/addons/reedinput/key_binding.gd.uid b/addons/reedinput/key_binding.gd.uid new file mode 100644 index 0000000..d46d2ca --- /dev/null +++ b/addons/reedinput/key_binding.gd.uid @@ -0,0 +1 @@ +uid://cotu8n0ktqqx5 diff --git a/addons/reedinput/plugin.cfg b/addons/reedinput/plugin.cfg new file mode 100644 index 0000000..4f6207a --- /dev/null +++ b/addons/reedinput/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="ReedInput" +description="Phamton Agnes Input Plugin" +author="ReedZhu" +version=".01" +script="reedinput.gd" diff --git a/addons/reedinput/reedinput.gd b/addons/reedinput/reedinput.gd new file mode 100644 index 0000000..8ecc6d4 --- /dev/null +++ b/addons/reedinput/reedinput.gd @@ -0,0 +1,22 @@ +@tool +extends EditorPlugin + + +func _enable_plugin() -> void: + # Add autoloads here. + pass + + +func _disable_plugin() -> void: + # Remove autoloads here. + pass + + +func _enter_tree() -> void: + # Initialization of the plugin goes here. + pass + + +func _exit_tree() -> void: + # Clean-up of the plugin goes here. + pass diff --git a/addons/reedinput/reedinput.gd.uid b/addons/reedinput/reedinput.gd.uid new file mode 100644 index 0000000..59a1745 --- /dev/null +++ b/addons/reedinput/reedinput.gd.uid @@ -0,0 +1 @@ +uid://67k8j8qfhxsd diff --git a/addons/reedscene/plugin.cfg b/addons/reedscene/plugin.cfg new file mode 100644 index 0000000..6ca7ff7 --- /dev/null +++ b/addons/reedscene/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="ReedScene" +description="" +author="ReedZhu" +version="" +script="reedscene.gd" diff --git a/addons/reedscene/reedscene.gd b/addons/reedscene/reedscene.gd new file mode 100644 index 0000000..8ecc6d4 --- /dev/null +++ b/addons/reedscene/reedscene.gd @@ -0,0 +1,22 @@ +@tool +extends EditorPlugin + + +func _enable_plugin() -> void: + # Add autoloads here. + pass + + +func _disable_plugin() -> void: + # Remove autoloads here. + pass + + +func _enter_tree() -> void: + # Initialization of the plugin goes here. + pass + + +func _exit_tree() -> void: + # Clean-up of the plugin goes here. + pass diff --git a/addons/reedscene/reedscene.gd.uid b/addons/reedscene/reedscene.gd.uid new file mode 100644 index 0000000..b3da432 --- /dev/null +++ b/addons/reedscene/reedscene.gd.uid @@ -0,0 +1 @@ +uid://vhh6g4ugijhl diff --git a/addons/reedscene/scene/SceneManager.gd b/addons/reedscene/scene/SceneManager.gd new file mode 100644 index 0000000..177b337 --- /dev/null +++ b/addons/reedscene/scene/SceneManager.gd @@ -0,0 +1,74 @@ +@tool +class_name SceneManager +extends Node + +@export var MainNodes: Array[Node] +@export var GameView: Node +@export var TransitionNode: Node + +func _enter_tree() -> void: + check() + +func _ready() -> void: + if !Engine.is_editor_hint(): + add_to_group("SceneManager") + get_tree().node_removed.connect(check) + +# ========================= +# 对外 API +# ========================= +static func change(scene_path: String) -> void: + var mgr := get_instance() + if mgr: + mgr._change(scene_path) + else: + push_error("SceneManager not found in scene tree") + +# ========================= +# 内部逻辑 +# ========================= +func _change(scene_path: String) -> void: + if GameView == null: + push_error("SceneManager: GameView is null") + return + + # 清空旧场景 + for child in GameView.get_children(): + child.queue_free() + + # 加载新场景 + var packed: PackedScene = load(scene_path) + if packed == null: + push_error("Failed to load scene: %s" % scene_path) + return + + var instance := packed.instantiate() + GameView.add_child(instance) + + print_debug("SceneManager: Changed scene to ", scene_path) + +# ========================= +# 结构检查 / 自修复 +# ========================= +func check(node: Node = null) -> void: + if TransitionNode == node: + TransitionNode = null + + var tr := find_child("Transition") + if tr != null: + if TransitionNode == null: + TransitionNode = tr + else: + if TransitionNode == null: + var transition := Control.new() + transition.name = "Transition" + add_child.call_deferred(transition) + transition.set_owner.call_deferred(self) + TransitionNode = transition + +# ========================= +# 工具 +# ========================= +static func get_instance() -> SceneManager: + var tree := Engine.get_main_loop() as SceneTree + return tree.get_first_node_in_group("SceneManager") as SceneManager diff --git a/addons/reedscene/scene/SceneManager.gd.uid b/addons/reedscene/scene/SceneManager.gd.uid new file mode 100644 index 0000000..d868d35 --- /dev/null +++ b/addons/reedscene/scene/SceneManager.gd.uid @@ -0,0 +1 @@ +uid://dn0ksjoswquf5 diff --git a/addons/reedscene/view/GameView.gd b/addons/reedscene/view/GameView.gd new file mode 100644 index 0000000..61510e1 --- /dev/null +++ b/addons/reedscene/view/GameView.gd @@ -0,0 +1 @@ +extends Node diff --git a/addons/reedscene/view/GameView.gd.uid b/addons/reedscene/view/GameView.gd.uid new file mode 100644 index 0000000..43fb49e --- /dev/null +++ b/addons/reedscene/view/GameView.gd.uid @@ -0,0 +1 @@ +uid://c0yvg1m6ot83j diff --git a/addons/reedscene/view/GameViewContainer.gd b/addons/reedscene/view/GameViewContainer.gd new file mode 100644 index 0000000..aa16bd3 --- /dev/null +++ b/addons/reedscene/view/GameViewContainer.gd @@ -0,0 +1 @@ +class_name GameViewContainer extends SubViewportContainer diff --git a/addons/reedscene/view/GameViewContainer.gd.uid b/addons/reedscene/view/GameViewContainer.gd.uid new file mode 100644 index 0000000..50c8692 --- /dev/null +++ b/addons/reedscene/view/GameViewContainer.gd.uid @@ -0,0 +1 @@ +uid://du4xgapk8c7vb diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..a4ff5ba --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c673bap4b12fx" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..30899db --- /dev/null +++ b/project.godot @@ -0,0 +1,95 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="PhantomAgnes" +run/main_scene="uid://3vc8ojbiyy5w" +config/features=PackedStringArray("4.5", "Forward Plus") +config/icon="res://icon.svg" + +[autoload] + +PhantomCameraManager="*res://addons/phantom_camera/scripts/managers/phantom_camera_manager.gd" +CameraSystem="*res://_shared/CameraSystem.tscn" +RoomSystem="*res://_shared/room_system.gd" +GlobalEvent="*res://_shared/global_event.gd" +ReedVFX="*res://addons/reedfx/vfx/ReedVFXSystem.tscn" + +[display] + +window/size/viewport_width=640 +window/size/viewport_height=360 +window/size/window_width_override=1920 +window/size/window_height_override=1080 +window/stretch/mode="canvas_items" + +[editor_plugins] + +enabled=PackedStringArray("res://addons/phantom_camera/plugin.cfg", "res://addons/reedcomponent/plugin.cfg", "res://addons/reedfx/plugin.cfg", "res://addons/reedinput/plugin.cfg", "res://addons/reedscene/plugin.cfg") + +[global_group] + +ROOM="房间分组,其下存在所有的Room" +PLAYER="玩家分组,其下只存在玩家控制器" + +[input] + +move_right={ +"deadzone": 0.2, +"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,"location":0,"echo":false,"script":null) +] +} +move_left={ +"deadzone": 0.2, +"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,"location":0,"echo":false,"script":null) +] +} +move_up={ +"deadzone": 0.2, +"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,"location":0,"echo":false,"script":null) +] +} +move_down={ +"deadzone": 0.2, +"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,"location":0,"echo":false,"script":null) +] +} +jump={ +"deadzone": 0.2, +"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,"location":0,"echo":false,"script":null) +, 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":74,"key_label":0,"unicode":106,"location":0,"echo":false,"script":null) +] +} +dash={ +"deadzone": 0.2, +"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":75,"key_label":0,"unicode":107,"location":0,"echo":false,"script":null) +] +} +climb={ +"deadzone": 0.2, +"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":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +move={ +"deadzone": 0.2, +"events": [] +} +grap_hook={ +"deadzone": 0.2, +"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":76,"key_label":0,"unicode":108,"location":0,"echo":false,"script":null) +] +} + +[layer_names] + +2d_physics/layer_2="Player" +2d_physics/layer_3="Environment" +2d_physics/layer_4="Damage" diff --git a/update.md b/update.md new file mode 100644 index 0000000..960deab --- /dev/null +++ b/update.md @@ -0,0 +1,94 @@ +# 蔚蓝Like 项目策划书 + +## 更新日志 + +V0.1.1 + +- 完成了角色冲刺的功能,使用component的架构设置了一个Dash Component +- 重构了一下角色的HSM,留出了一个给Dead state的状态 +- 添加了角色趴住墙的逻辑,可以在墙上上下移动 + +v0.1.2 + +- 添加了一个WallDetector,用来检测墙壁,计划抛弃原版的is_on_wall + +v0.1.3 + +- 完善了WallDetector的功能,添加了一个climb hop,climb jump等逻辑,具体手感优化得再关卡里做测试 + +v0.2.1 + +- + +## 更新计划 + +V0.1 + +主要的工作是复刻蔚蓝的移动代码逻辑,反向出硬核平台跳跃游戏那种手感 + +- [x] 角色墙滑 + - [x] 墙滑代码拆解 + - [x] 墙滑功能实现 +- [x] 角色墙滑跳 + - [x] 墙滑跳代码拆解 + - [x] 墙滑跳功能实现 +- [x] 角色冲刺 + - [x] 角色冲刺代码拆解 + - [x] 角色冲刺功能实现 +- [x] 角色扒墙 + - [x] 角色扒墙代码拆解 + - [x] 角色扒墙代码实现 + - [x] 角色扒墙跳代码实现 + - [x] 角色爬墙到极限时候自动跳上平台 +- [ ] ~~手感优化~~ + - [ ] ~~跳跃手感优化~~ + - [ ] ~~墙跳手感优化~~ + - [ ] ~~贴墙上跳会额外受到贴墙重力导致上不去的BUG~~ + +V0.2 + +主要是实现蔚蓝的地图相关的功能,比如穿过一个入口之后时间缓速并切换场景,等 + +- [x] Phantom Camera 插件接入 +- [ ] 相机功能 + - [ ] 相机追随 + - [ ] 相机震动 + +- [ ] 地图功能 + - [ ] 地图美术功能 + - [ ] 地图物件功能 + +- [ ] 玩家死亡和重生的逻辑 +- [ ] Room功能:一个Level由n个Room组成,Room存在一个Entrance,玩家进入Entrance会让Entrance向上传输消息给Room并让镜头切换到对应的Room + - [ ] entrance的对应不同的复活点,从不同的entrance进入会让玩家死亡后在不同的复活点复活 + + +V0.3 + +主要是复刻蔚蓝的一些VFX,包括: + +- 全局的VFX管理器: + +- [x] VFX Manager + - [x] 可以實現在場景中根據預設播放VFX + - [ ] 將所有的VFX放置在一個插件專屬的Layer + +- [ ] SFX Manager + - [ ] 可以實現在場景中根據預設播放SFX + - [ ] 可以播放一個隨機的SFX Asset + - [ ] 不同的SFX預設 + +- [ ] CameraShake Manager + - [ ] 可以通過signal播放不同的相機震動 + - [ ] 可以播放一個隨機的SFX Asset + - [ ] 不同的SFX預設 + +- [ ] GlobalTime Manager + - [ ] 可以通過signal播放不同的相機震動 + - [ ] 可以播放一個隨機的SFX Asset + - [ ] 不同的SFX預設 + +V0.4 +主要是拓展基于项目的特殊需求,包括: + +- [ ] 钩爪功能基本实现