commit a5634c46198756f66e5843d099543306a111b24c Author: Phil Date: Sun Jul 20 10:34:21 2025 +0200 first commit 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/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..ac794b3 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +ko_fi: cntwister +buy_me_a_coffee: twister 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/DocEditorSettings.md b/DocEditorSettings.md new file mode 100644 index 0000000..c388cce --- /dev/null +++ b/DocEditorSettings.md @@ -0,0 +1,76 @@ +# Script Spliter in Editor Settings +Each plugin configuration parameter is documented here. + +**Root of EditorSettings**: *plugin/script_spliter/** + +| Setting | Description | +| ------------ | ------------ | +| Row | (Work on start/Managed by Plugin) Initial rows, if it is zero it will be equal to 1 | +| Column | (Work on start/Managed by Plugin) Initial columns, if it is zero it will be equal to 1 | +| Save Rows Columns Count on exit | Save the current columns and rows you split before exiting to open them on next startup | + +### Behaviour +| Setting | Description | +| ------------ | ------------ | +| Refresh Warnings On Save | Check on save if all scripts has new errors/warnings| + +### Window +| Setting | Description | +| ------------ | ------------ | +| Use Highlight Selected | Show fade color when focus a window| +| Highlight Selected Color | Color of the fader when focus | + +### Editor +| Setting | Description | +| ------------ | ------------ | +| Minimap for unfocus window | Hide minimap of the script when focus another window | +| Out Focus Color Enabled | Enable set a modulate color when focus another window | +| Out Focus Color Value | Modulate color when focus another window | + +### Editor/Behaviour +| Setting | Description | +| ------------ | ------------ | +| Expand on focus | Enable expand when focus a split window shrunk | +| Can expand on same focus | Force Expand if the window current focused is shrunk | +| Smooth expand | Enable Smooth when expand the window shrunk | +| Smooth expand time| Total time for complete expand the window shrunk| +| Swap by double click separator button | Enable swap between windows when double click in separator button | + +### Editor/Behaviour/Back And Forward +| Setting | Description | +| ------------ | ------------ | +| Handle Back And Forward | Enable handler event of back and forward by internal function addon | +| History Size | Max buffer size history of scripts/documents recent opened by the window split (Are stored independently by window) +| Using As Next And Back Tab| Change Behaviour and use back and forward as next or back aviable tab | +| Backward Key Button Path| Path of resource setting of backward key button | +| Forward Key Button Path| Path of resource setting of forward key button | +| Backward Mouse Button Path| Path of resource setting of backward mouse button | +| Forward Mouse Button Path| Path of resource setting of forward mouse button | +| Use Native Handler When There Are No More Tabs| Enable leave to godot handle the back and forward when not exist more tabs in the focused window | + +### Editor/Split +This section work only when you add new split/s. +in old versions < 0.3 was more useful. + +| Setting | Description | +| ------------ | ------------ | +| Reopen Last Closed Editor On Add Split | Enable open a script recent used and closed (Only for script / unless you make a request on github and change your mind)| +| Remember Last Used Editor Buffer Size | Max last scripts for remember, maybe you want increase if you usually work with more than 4 windows | + + +### Line +| Setting | Description | +| ------------ | ------------ | +| Size | Line width | +| Color | Color of the Line, magenta is default that mean use editor color | +| Draggable | Allow drag the Line pressing the primary mouse button | +| Expand by Double Click | When you press with mouse (double click) the line back to initial position | + +### Button +| Setting | Description | +| ------------ | ------------ | +| Size | Button width | +| Modulate | Modulate Button Color | +| Icon Path | Texture path for the button | +# +Script Spliter tool plugin for Community Of Godot 4, created by Twister. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..53978e5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Twister + +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/README.md b/README.md new file mode 100644 index 0000000..c9c228b --- /dev/null +++ b/README.md @@ -0,0 +1,153 @@ +# Script-Spliter +Tool addon for Godot 4, this addon allow split the script editor window. + +[![Godot Engine 4.3](https://img.shields.io/badge/Godot_Engine-4.x-blue)](https://godotengine.org/) ![ToolHack](https://img.shields.io/badge/Tool-Addon-green) ![Copyrights License](https://img.shields.io/badge/License-MIT-blue) + + +## Table of contents + +- [Preview](#preview-) +- [News](#news-) +- [Features](#features-) +- [Roadmap](#roadmap) +- [How-Work](#how-work) +- [Know Issues](#know-issues-) +- [Special Thanks](#special-thanks-) + + +# Preview [↑](#table-of-contents) + +### V0.2 Video Preview +[![video preview](https://github.com/user-attachments/assets/636cddf4-815e-4bf3-acab-13c26ff21318)](https://youtu.be/ISSu45qzWWw) + +### V0.1 Image Preview +![image](https://github.com/user-attachments/assets/a6e1dea8-74cf-4fd9-b0b4-ec7d65ea3995) + +# NEWS [↑](#table-of-contents) + +### V0.3 +

+ +

+Introduction to using tabs + +* Tabs can be dragged to another window, now you can move one document from a window split to another window split. +* Backward and Forward has an internal function with the plugin. (Thanks to [@adancau](https://github.com/adancau)) + +>*I had initially planned to create a Notepad++ like functionality as a reference for version 0.3, but it has been decided to maintain the functionality and backward compatibility to avoid confusion for those using the plugin since version 0.1.* + +### Drag and Drop +You can use tabs to drag and drop into another split window to switch between editors or you can drag directly from the script list and drop into the split window. + +### Modify Backward and Forward buttons +You can modify the buttons by input resources in "script_spliter/io" folder, +seen in [Backward/Forward Request](https://github.com/CodeNameTwister/Script-Spliter/issues/9#issuecomment-2917555511) + +### Using Backward/Forward +It is per-window history, this means that if you've navigated through three different scripts within the window, moving back will only move between those three. The same happens when moving forward, and it's not affected by any other movements you've made in another window. +>[!TIP] +>In editor settings you have the checkbox: "using_as_next_and_back_tab" if you want use Backward/Forward move like Back/Next Tab. +# + +### V0.2 +

+ +

+The internal workflow has been modified, but the functionality of its predecessor version has been maintained. + +This has been done to maintain compatibility when using shorteners like Ctrl + [1, 2, 3, 4] to change the split style, this might be broken in version 0.3, see the roadmap for details. + +### Differences with version 0.1 +* It more closely resembles the default editor window. +* Reduces window switching time. +* Allows you to zoom in on all windows. +* You may have a separate script documentation help window. +* Some visual aspects and configurable parameters in Editor Settings. +* More Features and Split Options. + +>[!NOTE] +>This plugin uses another built-in plugin created by me called [Multi Split Container](https://github.com/CodeNameTwister/Multi-Split-Container) + + +# Features [↑](#table-of-contents) +* Split Window of Document Files Like Script/Document Helper Window. +* Split Two Window Horizontal/Vertical. +* Split Three Window Horizontal/Vertical. +* Split Four Window Squared. +* Split Custom Window defined by you. *(using RMB context menu or Tool Menu)* +* Plugins Setting in Editor Settings. *(In the section Plugin, you can see with advance option enabled!)* +* Pop Script: Make Floating Script in Separate Window using RMB context menu. +* Refresh Warnings changes in all opened windows when project is saved *(Errors/Warning Script)* +* Reopen recently closed/changed scripts when adding a split. (Suggestion: [#5](https://github.com/CodeNameTwister/Script-Spliter/issues/5)) +* Swap between windows by double-clicking the draggable button. (Suggestion: [#8](https://github.com/CodeNameTwister/Script-Spliter/issues/8])) +* Back and Forward between script opened by the window splited. (Suggestion: [#9](https://github.com/CodeNameTwister/Script-Spliter/issues/9])) +* Drag and Drop tabs between windows. +* Tabs close options using (RMB) context menu. + +>[!WARNING] +>Experimental Refresh Warnings *(This option can be disabled on Editor Settings)* + +>[!NOTE] +>In [DocEditorSettings.md](DocEditorSettings.md) you can see the description of the settings. + + + +# ROADMAP +* Version >= 0.2.3: ~Flying scripts; Allow split in separate windows.~ +* Version >= 0.3: + * ~Change logo/colors: Currently the pet I use on github is placed and it is planned to change it to one more suitable for the plugin.~ + * ~Using tabs for drag and drop between windows.~ *~(WARNING! : Some features offered in previous versions may change)~* +* Version >= 0.4: Revisit Pop Scripts Issues. + +# How Work + +>[!TIP] +> Now you can add or remove split with using context menu, the popup menu appear using the RMB (Right mouse button) in the editor. +> +> * Use Add/Remove split if you want increase or decrease the auto split window function. + +>[!NOTE] +> Keep in mind, the style when appear new window (As Column or Row) depend of you configuration split style! +> +> *This may change in future releases.* + +### Enable by shortcut [↑](#table-of-contents) +* Press shortcut (**Ctrl + 1**) for set one window. +* Press shortcut (**Ctrl + 2**) for set one split of two windows: Horizontal. +* Press shortcut (**Ctrl + 3**) for set one split of two windows: Vertical. +* Press shortcut (**Ctrl + 4**) for set two split of three windows: Horizontal. +* Press shortcut (**Ctrl + 5**) for set two split of three windows: Vertical. +* Press shortcut (**Ctrl + 6**) for set three split of four windows: Squared split. + +### Enable by Tool Menu [↑](#table-of-contents) +For enable the Script spliter menu go to **Project > Tools > Script Spliter**. + +![image](images/img0.png) + +You can select split type and disabled, see the image. + +![image](images/img1.png) + +Once activated, you'll see a draggable line like the one in the image, indicating that the plugin is active. + +>[!IMPORTANT] +>This section will automatically expand when you open **two scripts**. + +The position of the line will vary depending on the selection of horizontal or vertical. + +![image](images/img2.png) + +# Know Issues [↑](#table-of-contents) +### Version 0.2.3 +The **PopScripts** (Floating Scripts) +It still has some issues related to the editor focus, which means that if you switch scenes, some features like the search engine within the PopScript may be affected and become unresponsive. + +# Special Thanks 📜 +This section lists users who have contributed to improving the quality of this project. + +[@adancau](https://github.com/adancau) + +# +Copyrights (c) CodeNameTwister. See [LICENSE](LICENSE) for details. + +[godot engine]: https://godotengine.org/ diff --git a/addons/godot-git-plugin/LICENSE b/addons/godot-git-plugin/LICENSE new file mode 100644 index 0000000..f153fb8 --- /dev/null +++ b/addons/godot-git-plugin/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016-2023 The Godot Engine community + +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/godot-git-plugin/THIRDPARTY.md b/addons/godot-git-plugin/THIRDPARTY.md new file mode 100644 index 0000000..837488f --- /dev/null +++ b/addons/godot-git-plugin/THIRDPARTY.md @@ -0,0 +1,1349 @@ +# Third-Party Notices + +The Godot Git Plugin source code uses the following third-party source code: + +1. godotengine/godot-cpp - MIT License - https://github.com/godotengine/godot-cpp/tree/02336831735fd6affbe0a6fa252ec98d3e78120c +2. libgit2/libgit2 - GPLv2 with a special Linking Exception - https://github.com/libgit2/libgit2/tree/b7bad55e4bb0a285b073ba5e02b01d3f522fc95d +3. libssh2/libssh2 - BSD-3-Clause License - https://github.com/libssh2/libssh2/tree/635caa90787220ac3773c1d5ba11f1236c22eae8 + +We also link to these third-party libraries (only in the compiled binary form): + +1. OpenSSL - Only on Linux and MacOS - OpenSSL License - http://www.openssl.org/source/openssl-1.1.1s.tar.gz + +## License Texts + +### godotengine/godot-cpp + +``` +# MIT License + +Copyright (c) 2017-2022 Godot Engine 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. +``` + +### libgit2/libgit2 + +``` + libgit2 is Copyright (C) the libgit2 contributors, + unless otherwise stated. See the AUTHORS file for details. + + Note that the only valid version of the GPL as far as this project + is concerned is _this_ particular version of the license (ie v2, not + v2.2 or v3.x or whatever), unless explicitly otherwise stated. + +---------------------------------------------------------------------- + + LINKING EXCEPTION + + In addition to the permissions in the GNU General Public License, + the authors give you unlimited permission to link the compiled + version of this library into combinations with other programs, + and to distribute those combinations without any restriction + coming from the use of this file. (The General Public License + restrictions do apply in other respects; for example, they cover + modification of the file, and distribution when not linked into + a combined executable.) + +---------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +---------------------------------------------------------------------- + +The bundled ZLib code is licensed under the ZLib license: + +Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +---------------------------------------------------------------------- + +The Clar framework is licensed under the ISC license: + +Copyright (c) 2011-2015 Vicent Marti + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +---------------------------------------------------------------------- + +The regex library (deps/regex/) is licensed under the GNU LGPL +(available at the end of this file). + +Definitions for data structures and routines for the regular +expression library. + +Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006,2008 +Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with the GNU C Library; if not, write to the Free +Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +---------------------------------------------------------------------- + +The bundled winhttp definition files (deps/winhttp/) are licensed under +the GNU LGPL (available at the end of this file). + +Copyright (C) 2007 Francois Gouget + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +---------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + +---------------------------------------------------------------------- + +The bundled SHA1 collision detection code is licensed under the MIT license: + +MIT License + +Copyright (c) 2017: + Marc Stevens + Cryptology Group + Centrum Wiskunde & Informatica + P.O. Box 94079, 1090 GB Amsterdam, Netherlands + marc@marc-stevens.nl + + Dan Shumow + Microsoft Research + danshu@microsoft.com + +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. + +---------------------------------------------------------------------- + +The bundled wildmatch code is licensed under the BSD license: + +Copyright Rich Salz. +All rights reserved. + +Redistribution and use in any form are permitted provided that the +following restrictions are are met: + +1. Source distributions must retain this entire copyright notice + and comment. +2. Binary distributions must include the acknowledgement ``This + product includes software developed by Rich Salz'' in the + documentation or other materials provided with the + distribution. This must not be represented as an endorsement + or promotion without specific prior written permission. +3. The origin of this software must not be misrepresented, either + by explicit claim or by omission. Credits must appear in the + source and documentation. +4. Altered versions must be plainly marked as such in the source + and documentation and must not be misrepresented as being the + original software. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +---------------------------------------------------------------------- + +Portions of the OpenSSL headers are included under the OpenSSL license: + +Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +All rights reserved. + +This package is an SSL implementation written +by Eric Young (eay@cryptsoft.com). +The implementation was written so as to conform with Netscapes SSL. + +This library is free for commercial and non-commercial use as long as +the following conditions are aheared to. The following conditions +apply to all code found in this distribution, be it the RC4, RSA, +lhash, DES, etc., code; not just the SSL code. The SSL documentation +included with this distribution is covered by the same copyright terms +except that the holder is Tim Hudson (tjh@cryptsoft.com). + +Copyright remains Eric Young's, and as such any Copyright notices in +the code are not to be removed. +If this package is used in a product, Eric Young should be given attribution +as the author of the parts of the library used. +This can be in the form of a textual message at program startup or +in documentation (online or textual) provided with the package. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + "This product includes cryptographic software written by + Eric Young (eay@cryptsoft.com)" + The word 'cryptographic' can be left out if the rouines from the library + being used are not cryptographic related :-). +4. If you include any Windows specific code (or a derivative thereof) from + the apps directory (application code) you must include an acknowledgement: + "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + +THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +The licence and distribution terms for any publically available version or +derivative of this code cannot be changed. i.e. this code cannot simply be +copied and put under another distribution licence +[including the GNU Public Licence.] + +==================================================================== +Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + "This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + +4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + endorse or promote products derived from this software without + prior written permission. For written permission, please contact + openssl-core@openssl.org. + +5. Products derived from this software may not be called "OpenSSL" + nor may "OpenSSL" appear in their names without prior written + permission of the OpenSSL Project. + +6. Redistributions of any form whatsoever must retain the following + acknowledgment: + "This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit (http://www.openssl.org/)" + +THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. +``` + +### libssh2/libssh2 + +``` +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2005,2006 Mikhail Gusarov + * Copyright (c) 2006-2007 The Written Word, Inc. + * Copyright (c) 2007 Eli Fant + * Copyright (c) 2009-2021 Daniel Stenberg + * Copyright (C) 2008, 2009 Simon Josefsson + * Copyright (c) 2000 Markus Friedl + * Copyright (c) 2015 Microsoft Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ +``` + +### OpenSSL + +``` + + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a double license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +``` diff --git a/addons/godot-git-plugin/git_plugin.gdextension b/addons/godot-git-plugin/git_plugin.gdextension new file mode 100644 index 0000000..49fffbf --- /dev/null +++ b/addons/godot-git-plugin/git_plugin.gdextension @@ -0,0 +1,12 @@ +[configuration] + +entry_symbol = "git_plugin_init" +compatibility_minimum = "4.1.0" + +[libraries] + +macos.editor = "macos/libgit_plugin.macos.editor.universal.dylib" +windows.editor.x86_64 = "win64/libgit_plugin.windows.editor.x86_64.dll" +linux.editor.x86_64 = "linux/libgit_plugin.linux.editor.x86_64.so" +linux.editor.arm64 = "linux/libgit_plugin.linux.editor.arm64.so" +linux.editor.rv64 = "" diff --git a/addons/godot-git-plugin/git_plugin.gdextension.uid b/addons/godot-git-plugin/git_plugin.gdextension.uid new file mode 100644 index 0000000..9464b12 --- /dev/null +++ b/addons/godot-git-plugin/git_plugin.gdextension.uid @@ -0,0 +1 @@ +uid://36b2j720125r diff --git a/addons/godot-git-plugin/linux/libgit_plugin.linux.editor.x86_64.so b/addons/godot-git-plugin/linux/libgit_plugin.linux.editor.x86_64.so new file mode 100644 index 0000000..8dab6db Binary files /dev/null and b/addons/godot-git-plugin/linux/libgit_plugin.linux.editor.x86_64.so differ diff --git a/addons/godot-git-plugin/macos/libgit_plugin.macos.editor.universal.dylib b/addons/godot-git-plugin/macos/libgit_plugin.macos.editor.universal.dylib new file mode 100644 index 0000000..644aa2a Binary files /dev/null and b/addons/godot-git-plugin/macos/libgit_plugin.macos.editor.universal.dylib differ diff --git a/addons/godot-git-plugin/plugin.cfg b/addons/godot-git-plugin/plugin.cfg new file mode 100644 index 0000000..9c4e36f --- /dev/null +++ b/addons/godot-git-plugin/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Godot Git Plugin" +description="This plugin lets you interact with Git without leaving the Godot editor. More information can be found at https://github.com/godotengine/godot-git-plugin/wiki" +author="twaritwaikar" +version="v3.1.1" +script="godot-git-plugin.gd" diff --git a/addons/godot-git-plugin/win64/libgit_plugin.windows.editor.x86_64.dll b/addons/godot-git-plugin/win64/libgit_plugin.windows.editor.x86_64.dll new file mode 100644 index 0000000..47bbb1d Binary files /dev/null and b/addons/godot-git-plugin/win64/libgit_plugin.windows.editor.x86_64.dll differ diff --git a/addons/godot-git-plugin/win64/libgit_plugin.windows.editor.x86_64.exp b/addons/godot-git-plugin/win64/libgit_plugin.windows.editor.x86_64.exp new file mode 100644 index 0000000..6c68d89 Binary files /dev/null and b/addons/godot-git-plugin/win64/libgit_plugin.windows.editor.x86_64.exp differ diff --git a/addons/godot-git-plugin/win64/libgit_plugin.windows.editor.x86_64.lib b/addons/godot-git-plugin/win64/libgit_plugin.windows.editor.x86_64.lib new file mode 100644 index 0000000..4537929 Binary files /dev/null and b/addons/godot-git-plugin/win64/libgit_plugin.windows.editor.x86_64.lib differ diff --git a/addons/kenney_prototype_textures/LICENSE.txt b/addons/kenney_prototype_textures/LICENSE.txt new file mode 100644 index 0000000..839f104 --- /dev/null +++ b/addons/kenney_prototype_textures/LICENSE.txt @@ -0,0 +1,23 @@ + + + Prototype Textures 1.0 + + Created/distributed by Kenney (www.kenney.nl) + Creation date: 08-04-2020 + + ------------------------------ + + License: (Creative Commons Zero, CC0) + http://creativecommons.org/publicdomain/zero/1.0/ + + This content is free to use in personal, educational and commercial projects. + Support us by crediting Kenney or www.kenney.nl (this is not mandatory) + + ------------------------------ + + Donate: http://support.kenney.nl + Request: http://request.kenney.nl + Patreon: http://patreon.com/kenney/ + + Follow on Twitter for updates: + http://twitter.com/KenneyNL diff --git a/addons/kenney_prototype_textures/dark/texture_01.png b/addons/kenney_prototype_textures/dark/texture_01.png new file mode 100644 index 0000000..14a9811 Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_01.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_01.png.import b/addons/kenney_prototype_textures/dark/texture_01.png.import new file mode 100644 index 0000000..fa96d24 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_01.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cc51mfc3keg8n" +path.s3tc="res://.godot/imported/texture_01.png-60e3b3d3143b179c069dbcbff77ff160.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-60e3b3d3143b179c069dbcbff77ff160.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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/kenney_prototype_textures/dark/texture_02.png b/addons/kenney_prototype_textures/dark/texture_02.png new file mode 100644 index 0000000..d6a2a21 Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_02.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_02.png.import b/addons/kenney_prototype_textures/dark/texture_02.png.import new file mode 100644 index 0000000..568a9c1 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dqd87erh4csqq" +path="res://.godot/imported/texture_02.png-814d4f515892bb8274d285748f4a73a0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-814d4f515892bb8274d285748f4a73a0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_03.png b/addons/kenney_prototype_textures/dark/texture_03.png new file mode 100644 index 0000000..4aa482d Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_03.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_03.png.import b/addons/kenney_prototype_textures/dark/texture_03.png.import new file mode 100644 index 0000000..7155063 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://uap1mefe1d5h" +path="res://.godot/imported/texture_03.png-eef45c22e5a84c5df22e7f80e41112c6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-eef45c22e5a84c5df22e7f80e41112c6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_04.png b/addons/kenney_prototype_textures/dark/texture_04.png new file mode 100644 index 0000000..1e0a8f9 Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_04.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_04.png.import b/addons/kenney_prototype_textures/dark/texture_04.png.import new file mode 100644 index 0000000..85338ae --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://gr2ubf2bma80" +path="res://.godot/imported/texture_04.png-af505c12b2a7903458bb29299e718506.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-af505c12b2a7903458bb29299e718506.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_05.png b/addons/kenney_prototype_textures/dark/texture_05.png new file mode 100644 index 0000000..cd01f8c Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_05.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_05.png.import b/addons/kenney_prototype_textures/dark/texture_05.png.import new file mode 100644 index 0000000..8e93600 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dks4lyr4vghid" +path="res://.godot/imported/texture_05.png-ed8122ecdc41ff5aeccab84e8db1e4f0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-ed8122ecdc41ff5aeccab84e8db1e4f0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_06.png b/addons/kenney_prototype_textures/dark/texture_06.png new file mode 100644 index 0000000..4e8f53c Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_06.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_06.png.import b/addons/kenney_prototype_textures/dark/texture_06.png.import new file mode 100644 index 0000000..740b304 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dl0fcwo4640og" +path="res://.godot/imported/texture_06.png-004ed3d5b88361cdfb83a20714e917e7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-004ed3d5b88361cdfb83a20714e917e7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_07.png b/addons/kenney_prototype_textures/dark/texture_07.png new file mode 100644 index 0000000..d00973e Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_07.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_07.png.import b/addons/kenney_prototype_textures/dark/texture_07.png.import new file mode 100644 index 0000000..4975bb0 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bqvwy7apnxxur" +path="res://.godot/imported/texture_07.png-7c77ff22e41b4a54319073cb71530d81.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-7c77ff22e41b4a54319073cb71530d81.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_08.png b/addons/kenney_prototype_textures/dark/texture_08.png new file mode 100644 index 0000000..72dd6c0 Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_08.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_08.png.import b/addons/kenney_prototype_textures/dark/texture_08.png.import new file mode 100644 index 0000000..a36834d --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bqx8k6mdsxo2s" +path="res://.godot/imported/texture_08.png-5883ddd047173c8b118ead887054e6fc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-5883ddd047173c8b118ead887054e6fc.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_09.png b/addons/kenney_prototype_textures/dark/texture_09.png new file mode 100644 index 0000000..e81fa1a Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_09.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_09.png.import b/addons/kenney_prototype_textures/dark/texture_09.png.import new file mode 100644 index 0000000..3d3c6d0 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://deb6wofcw0ua6" +path="res://.godot/imported/texture_09.png-8e25cd5657e2d326068eb27bfa1aacec.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-8e25cd5657e2d326068eb27bfa1aacec.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_10.png b/addons/kenney_prototype_textures/dark/texture_10.png new file mode 100644 index 0000000..682088c Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_10.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_10.png.import b/addons/kenney_prototype_textures/dark/texture_10.png.import new file mode 100644 index 0000000..b294d93 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c6j6dlv4c8ji" +path="res://.godot/imported/texture_10.png-1e788999a192eabd201c3b3435475799.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-1e788999a192eabd201c3b3435475799.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_11.png b/addons/kenney_prototype_textures/dark/texture_11.png new file mode 100644 index 0000000..f0571a1 Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_11.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_11.png.import b/addons/kenney_prototype_textures/dark/texture_11.png.import new file mode 100644 index 0000000..0ac9cb7 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d33jitpb31io5" +path="res://.godot/imported/texture_11.png-f61ad46caf1a41d85454e490ec43c8ec.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-f61ad46caf1a41d85454e490ec43c8ec.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_12.png b/addons/kenney_prototype_textures/dark/texture_12.png new file mode 100644 index 0000000..b797dbe Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_12.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_12.png.import b/addons/kenney_prototype_textures/dark/texture_12.png.import new file mode 100644 index 0000000..448fdf1 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cvr2tiukhl7ob" +path="res://.godot/imported/texture_12.png-aa893b2c5354267551e55ec14bb1999b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-aa893b2c5354267551e55ec14bb1999b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/dark/texture_13.png b/addons/kenney_prototype_textures/dark/texture_13.png new file mode 100644 index 0000000..6e8aff4 Binary files /dev/null and b/addons/kenney_prototype_textures/dark/texture_13.png differ diff --git a/addons/kenney_prototype_textures/dark/texture_13.png.import b/addons/kenney_prototype_textures/dark/texture_13.png.import new file mode 100644 index 0000000..a7bf590 --- /dev/null +++ b/addons/kenney_prototype_textures/dark/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bb8memucrt4oc" +path="res://.godot/imported/texture_13.png-51cb3f38ea774c85cb3ad561d20c5b53.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/dark/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-51cb3f38ea774c85cb3ad561d20c5b53.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_01.png b/addons/kenney_prototype_textures/green/texture_01.png new file mode 100644 index 0000000..7d53fe7 Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_01.png differ diff --git a/addons/kenney_prototype_textures/green/texture_01.png.import b/addons/kenney_prototype_textures/green/texture_01.png.import new file mode 100644 index 0000000..8e60842 --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_01.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://e4ll1gwx8gb2" +path="res://.godot/imported/texture_01.png-94ebd82494c839e91a05b9e1cc2750ca.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-94ebd82494c839e91a05b9e1cc2750ca.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_02.png b/addons/kenney_prototype_textures/green/texture_02.png new file mode 100644 index 0000000..15ceaa8 Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_02.png differ diff --git a/addons/kenney_prototype_textures/green/texture_02.png.import b/addons/kenney_prototype_textures/green/texture_02.png.import new file mode 100644 index 0000000..494ffb0 --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dstjsf26qdahx" +path="res://.godot/imported/texture_02.png-aa1bb055b55bdc7c20e196b7286eebdf.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-aa1bb055b55bdc7c20e196b7286eebdf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_03.png b/addons/kenney_prototype_textures/green/texture_03.png new file mode 100644 index 0000000..90eedc6 Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_03.png differ diff --git a/addons/kenney_prototype_textures/green/texture_03.png.import b/addons/kenney_prototype_textures/green/texture_03.png.import new file mode 100644 index 0000000..6836bcf --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://hxo4syuq6wic" +path="res://.godot/imported/texture_03.png-3fec31a20982e9bd2e5e1aa731ea99cf.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-3fec31a20982e9bd2e5e1aa731ea99cf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_04.png b/addons/kenney_prototype_textures/green/texture_04.png new file mode 100644 index 0000000..aed20f4 Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_04.png differ diff --git a/addons/kenney_prototype_textures/green/texture_04.png.import b/addons/kenney_prototype_textures/green/texture_04.png.import new file mode 100644 index 0000000..bc91fe1 --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dr1sbuiq1pbtk" +path="res://.godot/imported/texture_04.png-4678cc1dfb831f775bdc30cfd7f78769.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-4678cc1dfb831f775bdc30cfd7f78769.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_05.png b/addons/kenney_prototype_textures/green/texture_05.png new file mode 100644 index 0000000..c89df69 Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_05.png differ diff --git a/addons/kenney_prototype_textures/green/texture_05.png.import b/addons/kenney_prototype_textures/green/texture_05.png.import new file mode 100644 index 0000000..64dc7cf --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cr5yc2qmkrhrd" +path="res://.godot/imported/texture_05.png-8448519b39c1d98d64cf807b48969765.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-8448519b39c1d98d64cf807b48969765.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_06.png b/addons/kenney_prototype_textures/green/texture_06.png new file mode 100644 index 0000000..59e0df0 Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_06.png differ diff --git a/addons/kenney_prototype_textures/green/texture_06.png.import b/addons/kenney_prototype_textures/green/texture_06.png.import new file mode 100644 index 0000000..1097ac8 --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cfqiqndvv3ugt" +path="res://.godot/imported/texture_06.png-01c48f82ab8bc613ec4efc2c2c669b12.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-01c48f82ab8bc613ec4efc2c2c669b12.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_07.png b/addons/kenney_prototype_textures/green/texture_07.png new file mode 100644 index 0000000..7a4bdaf Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_07.png differ diff --git a/addons/kenney_prototype_textures/green/texture_07.png.import b/addons/kenney_prototype_textures/green/texture_07.png.import new file mode 100644 index 0000000..98adf67 --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://btxiade5yibys" +path="res://.godot/imported/texture_07.png-eec10b758cacbb71a02166a7f8cee6c0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-eec10b758cacbb71a02166a7f8cee6c0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_08.png b/addons/kenney_prototype_textures/green/texture_08.png new file mode 100644 index 0000000..8e4f320 Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_08.png differ diff --git a/addons/kenney_prototype_textures/green/texture_08.png.import b/addons/kenney_prototype_textures/green/texture_08.png.import new file mode 100644 index 0000000..ee4359b --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bdtam6u0rbgwk" +path="res://.godot/imported/texture_08.png-d1888869b0d1d3a0ab2d517cbac7820a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-d1888869b0d1d3a0ab2d517cbac7820a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_09.png b/addons/kenney_prototype_textures/green/texture_09.png new file mode 100644 index 0000000..0a7eddb Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_09.png differ diff --git a/addons/kenney_prototype_textures/green/texture_09.png.import b/addons/kenney_prototype_textures/green/texture_09.png.import new file mode 100644 index 0000000..35d6cad --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cmj6iqast80up" +path="res://.godot/imported/texture_09.png-a21adfe1a090b0dd8f0d376d9ee5f68e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-a21adfe1a090b0dd8f0d376d9ee5f68e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_10.png b/addons/kenney_prototype_textures/green/texture_10.png new file mode 100644 index 0000000..559a7c1 Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_10.png differ diff --git a/addons/kenney_prototype_textures/green/texture_10.png.import b/addons/kenney_prototype_textures/green/texture_10.png.import new file mode 100644 index 0000000..ef15d8c --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b7sy3g065xxa" +path="res://.godot/imported/texture_10.png-3f72abba172432380bd86a508e997833.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-3f72abba172432380bd86a508e997833.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_11.png b/addons/kenney_prototype_textures/green/texture_11.png new file mode 100644 index 0000000..119294d Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_11.png differ diff --git a/addons/kenney_prototype_textures/green/texture_11.png.import b/addons/kenney_prototype_textures/green/texture_11.png.import new file mode 100644 index 0000000..51133a0 --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://lo5qcb5u2w5b" +path="res://.godot/imported/texture_11.png-ad76ef70f9eb459fb1e8d9ba9cc092c4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-ad76ef70f9eb459fb1e8d9ba9cc092c4.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_12.png b/addons/kenney_prototype_textures/green/texture_12.png new file mode 100644 index 0000000..5991228 Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_12.png differ diff --git a/addons/kenney_prototype_textures/green/texture_12.png.import b/addons/kenney_prototype_textures/green/texture_12.png.import new file mode 100644 index 0000000..0606cb6 --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bhcndpilrqdgk" +path="res://.godot/imported/texture_12.png-d4577347200436d9060aa21fce76cd93.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-d4577347200436d9060aa21fce76cd93.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/green/texture_13.png b/addons/kenney_prototype_textures/green/texture_13.png new file mode 100644 index 0000000..9c57c6e Binary files /dev/null and b/addons/kenney_prototype_textures/green/texture_13.png differ diff --git a/addons/kenney_prototype_textures/green/texture_13.png.import b/addons/kenney_prototype_textures/green/texture_13.png.import new file mode 100644 index 0000000..c32cc6b --- /dev/null +++ b/addons/kenney_prototype_textures/green/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://mckhv20eo4eq" +path="res://.godot/imported/texture_13.png-f5b9867fd39cd83793f3a92217d9eac6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/green/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-f5b9867fd39cd83793f3a92217d9eac6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_01.png b/addons/kenney_prototype_textures/light/texture_01.png new file mode 100644 index 0000000..9e93d3e Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_01.png differ diff --git a/addons/kenney_prototype_textures/light/texture_01.png.import b/addons/kenney_prototype_textures/light/texture_01.png.import new file mode 100644 index 0000000..489f963 --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_01.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cne1u50n7fayy" +path="res://.godot/imported/texture_01.png-e10423e44834e1b4a90c3134e446b32d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-e10423e44834e1b4a90c3134e446b32d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_02.png b/addons/kenney_prototype_textures/light/texture_02.png new file mode 100644 index 0000000..c52d0d2 Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_02.png differ diff --git a/addons/kenney_prototype_textures/light/texture_02.png.import b/addons/kenney_prototype_textures/light/texture_02.png.import new file mode 100644 index 0000000..90d5fe5 --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b54ihylsliykx" +path="res://.godot/imported/texture_02.png-ffde4d38b35463525c3815b255790206.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-ffde4d38b35463525c3815b255790206.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_03.png b/addons/kenney_prototype_textures/light/texture_03.png new file mode 100644 index 0000000..5960eca Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_03.png differ diff --git a/addons/kenney_prototype_textures/light/texture_03.png.import b/addons/kenney_prototype_textures/light/texture_03.png.import new file mode 100644 index 0000000..e290236 --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://du5n86es7sech" +path="res://.godot/imported/texture_03.png-6e55012c4e1c3f4d809747f3852d75ad.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-6e55012c4e1c3f4d809747f3852d75ad.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_04.png b/addons/kenney_prototype_textures/light/texture_04.png new file mode 100644 index 0000000..0b9a1d5 Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_04.png differ diff --git a/addons/kenney_prototype_textures/light/texture_04.png.import b/addons/kenney_prototype_textures/light/texture_04.png.import new file mode 100644 index 0000000..272cd54 --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dq7yl4uev1gkn" +path="res://.godot/imported/texture_04.png-201edfe05d5c4f7f54049864048cfaf1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-201edfe05d5c4f7f54049864048cfaf1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_05.png b/addons/kenney_prototype_textures/light/texture_05.png new file mode 100644 index 0000000..88f2e5c Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_05.png differ diff --git a/addons/kenney_prototype_textures/light/texture_05.png.import b/addons/kenney_prototype_textures/light/texture_05.png.import new file mode 100644 index 0000000..e5082be --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dhlmecos1g88i" +path="res://.godot/imported/texture_05.png-07ce2eafef84a176bcf77bc59cb1f6ec.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-07ce2eafef84a176bcf77bc59cb1f6ec.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_06.png b/addons/kenney_prototype_textures/light/texture_06.png new file mode 100644 index 0000000..374a5d0 Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_06.png differ diff --git a/addons/kenney_prototype_textures/light/texture_06.png.import b/addons/kenney_prototype_textures/light/texture_06.png.import new file mode 100644 index 0000000..2708e75 --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cqvwtuww7rh6i" +path="res://.godot/imported/texture_06.png-88331a9f246e47943dc01d0128a4ca4e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-88331a9f246e47943dc01d0128a4ca4e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_07.png b/addons/kenney_prototype_textures/light/texture_07.png new file mode 100644 index 0000000..34400e3 Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_07.png differ diff --git a/addons/kenney_prototype_textures/light/texture_07.png.import b/addons/kenney_prototype_textures/light/texture_07.png.import new file mode 100644 index 0000000..5e89f54 --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://vubwinsj1soq" +path="res://.godot/imported/texture_07.png-ab5f4a6ad655d06104ea7939a06ec496.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-ab5f4a6ad655d06104ea7939a06ec496.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_08.png b/addons/kenney_prototype_textures/light/texture_08.png new file mode 100644 index 0000000..c5bbc74 Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_08.png differ diff --git a/addons/kenney_prototype_textures/light/texture_08.png.import b/addons/kenney_prototype_textures/light/texture_08.png.import new file mode 100644 index 0000000..901b4b7 --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://1p7oitc018q4" +path="res://.godot/imported/texture_08.png-7b5c5c16cd076d2bbc9eeb33a454861b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-7b5c5c16cd076d2bbc9eeb33a454861b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_09.png b/addons/kenney_prototype_textures/light/texture_09.png new file mode 100644 index 0000000..435e19e Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_09.png differ diff --git a/addons/kenney_prototype_textures/light/texture_09.png.import b/addons/kenney_prototype_textures/light/texture_09.png.import new file mode 100644 index 0000000..29deabf --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ha1p5e7p4b53" +path="res://.godot/imported/texture_09.png-53f655f3d7e1722128f99e8aff9071f9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-53f655f3d7e1722128f99e8aff9071f9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_10.png b/addons/kenney_prototype_textures/light/texture_10.png new file mode 100644 index 0000000..25ac8ae Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_10.png differ diff --git a/addons/kenney_prototype_textures/light/texture_10.png.import b/addons/kenney_prototype_textures/light/texture_10.png.import new file mode 100644 index 0000000..859cd40 --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c7rtmuxalybla" +path="res://.godot/imported/texture_10.png-499479b9aaf089d55adf67874bc0ff66.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-499479b9aaf089d55adf67874bc0ff66.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_11.png b/addons/kenney_prototype_textures/light/texture_11.png new file mode 100644 index 0000000..7d4aebb Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_11.png differ diff --git a/addons/kenney_prototype_textures/light/texture_11.png.import b/addons/kenney_prototype_textures/light/texture_11.png.import new file mode 100644 index 0000000..57e8bf6 --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ikd2rj1djdmn" +path="res://.godot/imported/texture_11.png-4e4ade9ab136614b6cf0b0e879f1d510.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-4e4ade9ab136614b6cf0b0e879f1d510.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_12.png b/addons/kenney_prototype_textures/light/texture_12.png new file mode 100644 index 0000000..6bd3926 Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_12.png differ diff --git a/addons/kenney_prototype_textures/light/texture_12.png.import b/addons/kenney_prototype_textures/light/texture_12.png.import new file mode 100644 index 0000000..892750b --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ckuug4ri55io5" +path="res://.godot/imported/texture_12.png-8fe800bbb69d01cae0c0d84c062244bf.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-8fe800bbb69d01cae0c0d84c062244bf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/light/texture_13.png b/addons/kenney_prototype_textures/light/texture_13.png new file mode 100644 index 0000000..74515a7 Binary files /dev/null and b/addons/kenney_prototype_textures/light/texture_13.png differ diff --git a/addons/kenney_prototype_textures/light/texture_13.png.import b/addons/kenney_prototype_textures/light/texture_13.png.import new file mode 100644 index 0000000..d2134f5 --- /dev/null +++ b/addons/kenney_prototype_textures/light/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bemf5miughsac" +path="res://.godot/imported/texture_13.png-a43b6ac63b0fe1c4a3f66335474e59b6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/light/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-a43b6ac63b0fe1c4a3f66335474e59b6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_01.png b/addons/kenney_prototype_textures/orange/texture_01.png new file mode 100644 index 0000000..3eda5cd Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_01.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_01.png.import b/addons/kenney_prototype_textures/orange/texture_01.png.import new file mode 100644 index 0000000..2a33a57 --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_01.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://oh0q8v8hjc7c" +path.s3tc="res://.godot/imported/texture_01.png-2bf7db98e09b5b5073e8e8ca66419718.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-2bf7db98e09b5b5073e8e8ca66419718.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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/kenney_prototype_textures/orange/texture_02.png b/addons/kenney_prototype_textures/orange/texture_02.png new file mode 100644 index 0000000..1460f2b Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_02.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_02.png.import b/addons/kenney_prototype_textures/orange/texture_02.png.import new file mode 100644 index 0000000..b27af79 --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ccejsqqeo5w4g" +path="res://.godot/imported/texture_02.png-4eab4e19c2171e5b0668b65373b74c6d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-4eab4e19c2171e5b0668b65373b74c6d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_03.png b/addons/kenney_prototype_textures/orange/texture_03.png new file mode 100644 index 0000000..09975cc Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_03.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_03.png.import b/addons/kenney_prototype_textures/orange/texture_03.png.import new file mode 100644 index 0000000..5dec21b --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c2vctq22dfkm1" +path="res://.godot/imported/texture_03.png-129b8387293b325752961580c78873e2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-129b8387293b325752961580c78873e2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_04.png b/addons/kenney_prototype_textures/orange/texture_04.png new file mode 100644 index 0000000..8ac9527 Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_04.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_04.png.import b/addons/kenney_prototype_textures/orange/texture_04.png.import new file mode 100644 index 0000000..73d7898 --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bltlpgjdhtysa" +path="res://.godot/imported/texture_04.png-e978f0e00463b6cfc60da06ec0abdb7a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-e978f0e00463b6cfc60da06ec0abdb7a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_05.png b/addons/kenney_prototype_textures/orange/texture_05.png new file mode 100644 index 0000000..e7bb6d9 Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_05.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_05.png.import b/addons/kenney_prototype_textures/orange/texture_05.png.import new file mode 100644 index 0000000..a64dcd8 --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bsx2ulvqdl5ch" +path="res://.godot/imported/texture_05.png-57f4196ea276097368d03084372aa101.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-57f4196ea276097368d03084372aa101.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_06.png b/addons/kenney_prototype_textures/orange/texture_06.png new file mode 100644 index 0000000..2a18cf7 Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_06.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_06.png.import b/addons/kenney_prototype_textures/orange/texture_06.png.import new file mode 100644 index 0000000..f2f7d05 --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c28jd04t0tix3" +path="res://.godot/imported/texture_06.png-96fbf63c84855b5763ca7a9239b4162f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-96fbf63c84855b5763ca7a9239b4162f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_07.png b/addons/kenney_prototype_textures/orange/texture_07.png new file mode 100644 index 0000000..0d1f229 Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_07.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_07.png.import b/addons/kenney_prototype_textures/orange/texture_07.png.import new file mode 100644 index 0000000..703c45b --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1e1u0l6vxssg" +path="res://.godot/imported/texture_07.png-3fa938673385861e205adbc05b5cb69f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-3fa938673385861e205adbc05b5cb69f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_08.png b/addons/kenney_prototype_textures/orange/texture_08.png new file mode 100644 index 0000000..b53b56d Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_08.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_08.png.import b/addons/kenney_prototype_textures/orange/texture_08.png.import new file mode 100644 index 0000000..e4918c2 --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1labp6wb2f11" +path="res://.godot/imported/texture_08.png-9f039f47cba295ef5881d7b94c369b5d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-9f039f47cba295ef5881d7b94c369b5d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_09.png b/addons/kenney_prototype_textures/orange/texture_09.png new file mode 100644 index 0000000..a7f8b0b Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_09.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_09.png.import b/addons/kenney_prototype_textures/orange/texture_09.png.import new file mode 100644 index 0000000..dd530f8 --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://csinmsuma3lxb" +path="res://.godot/imported/texture_09.png-d3e0d0da868b68102c983480f9cde71d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-d3e0d0da868b68102c983480f9cde71d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_10.png b/addons/kenney_prototype_textures/orange/texture_10.png new file mode 100644 index 0000000..979733a Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_10.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_10.png.import b/addons/kenney_prototype_textures/orange/texture_10.png.import new file mode 100644 index 0000000..a924e89 --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://nl13ts21ta6w" +path="res://.godot/imported/texture_10.png-6f0f09db66c0562f01b2d2954722e3af.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-6f0f09db66c0562f01b2d2954722e3af.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_11.png b/addons/kenney_prototype_textures/orange/texture_11.png new file mode 100644 index 0000000..d52081b Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_11.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_11.png.import b/addons/kenney_prototype_textures/orange/texture_11.png.import new file mode 100644 index 0000000..bed3cf1 --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://o6yur64a6wte" +path="res://.godot/imported/texture_11.png-ebf2797e5f22648b239ddd9dce347372.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-ebf2797e5f22648b239ddd9dce347372.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_12.png b/addons/kenney_prototype_textures/orange/texture_12.png new file mode 100644 index 0000000..b7e5781 Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_12.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_12.png.import b/addons/kenney_prototype_textures/orange/texture_12.png.import new file mode 100644 index 0000000..278f74c --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cxtn8ps0mjk1p" +path="res://.godot/imported/texture_12.png-079a27ce3f0ee0e1854090577bd0ba2a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-079a27ce3f0ee0e1854090577bd0ba2a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/orange/texture_13.png b/addons/kenney_prototype_textures/orange/texture_13.png new file mode 100644 index 0000000..57dba8c Binary files /dev/null and b/addons/kenney_prototype_textures/orange/texture_13.png differ diff --git a/addons/kenney_prototype_textures/orange/texture_13.png.import b/addons/kenney_prototype_textures/orange/texture_13.png.import new file mode 100644 index 0000000..6425746 --- /dev/null +++ b/addons/kenney_prototype_textures/orange/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c2tvyait4kfda" +path="res://.godot/imported/texture_13.png-a11a0cfe132bc07bf4c480fd4334a284.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/orange/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-a11a0cfe132bc07bf4c480fd4334a284.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_01.png b/addons/kenney_prototype_textures/purple/texture_01.png new file mode 100644 index 0000000..7c56da6 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_01.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_01.png.import b/addons/kenney_prototype_textures/purple/texture_01.png.import new file mode 100644 index 0000000..811248b --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_01.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bnqlcijxxwthc" +path="res://.godot/imported/texture_01.png-38f28acdb9a95ea2efd835531b47e519.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-38f28acdb9a95ea2efd835531b47e519.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_02.png b/addons/kenney_prototype_textures/purple/texture_02.png new file mode 100644 index 0000000..e6e092e Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_02.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_02.png.import b/addons/kenney_prototype_textures/purple/texture_02.png.import new file mode 100644 index 0000000..da40b02 --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c3ke2aqgm0gcb" +path="res://.godot/imported/texture_02.png-fcb52d424cd62d43221e4153fa3176f8.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-fcb52d424cd62d43221e4153fa3176f8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_03.png b/addons/kenney_prototype_textures/purple/texture_03.png new file mode 100644 index 0000000..3874868 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_03.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_03.png.import b/addons/kenney_prototype_textures/purple/texture_03.png.import new file mode 100644 index 0000000..dde3beb --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bpe0p6m32sjpg" +path="res://.godot/imported/texture_03.png-10a2d13d96fe9dba00c822080243f048.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-10a2d13d96fe9dba00c822080243f048.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_04.png b/addons/kenney_prototype_textures/purple/texture_04.png new file mode 100644 index 0000000..6177824 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_04.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_04.png.import b/addons/kenney_prototype_textures/purple/texture_04.png.import new file mode 100644 index 0000000..d205796 --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b3ue5awg6fgq2" +path="res://.godot/imported/texture_04.png-6783bd4aa338a51e03fa71a2a0ba6c73.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-6783bd4aa338a51e03fa71a2a0ba6c73.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_05.png b/addons/kenney_prototype_textures/purple/texture_05.png new file mode 100644 index 0000000..5b82830 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_05.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_05.png.import b/addons/kenney_prototype_textures/purple/texture_05.png.import new file mode 100644 index 0000000..a6d3b9f --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cqmqgicmp26ji" +path="res://.godot/imported/texture_05.png-888b467a21712cbc594106138f9173b8.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-888b467a21712cbc594106138f9173b8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_06.png b/addons/kenney_prototype_textures/purple/texture_06.png new file mode 100644 index 0000000..befbe88 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_06.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_06.png.import b/addons/kenney_prototype_textures/purple/texture_06.png.import new file mode 100644 index 0000000..dd66239 --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c2krtsfxj3umm" +path="res://.godot/imported/texture_06.png-352782bc60b4b3fe4a632b0a6af5553d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-352782bc60b4b3fe4a632b0a6af5553d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_07.png b/addons/kenney_prototype_textures/purple/texture_07.png new file mode 100644 index 0000000..a0c9df1 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_07.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_07.png.import b/addons/kenney_prototype_textures/purple/texture_07.png.import new file mode 100644 index 0000000..20c2e33 --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://de52cdt25f10t" +path="res://.godot/imported/texture_07.png-042b529a59b56931d5b854290aa24a7f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-042b529a59b56931d5b854290aa24a7f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_08.png b/addons/kenney_prototype_textures/purple/texture_08.png new file mode 100644 index 0000000..eb556d6 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_08.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_08.png.import b/addons/kenney_prototype_textures/purple/texture_08.png.import new file mode 100644 index 0000000..6017832 --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cbt5aue6buruv" +path="res://.godot/imported/texture_08.png-ae3e54cc23ad438ea83a8932fe526f9f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-ae3e54cc23ad438ea83a8932fe526f9f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_09.png b/addons/kenney_prototype_textures/purple/texture_09.png new file mode 100644 index 0000000..c831a43 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_09.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_09.png.import b/addons/kenney_prototype_textures/purple/texture_09.png.import new file mode 100644 index 0000000..637593f --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d3udlfv4f5oyd" +path="res://.godot/imported/texture_09.png-bfc57ad7b0bd0aecb6d4584eb0197660.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-bfc57ad7b0bd0aecb6d4584eb0197660.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_10.png b/addons/kenney_prototype_textures/purple/texture_10.png new file mode 100644 index 0000000..95be188 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_10.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_10.png.import b/addons/kenney_prototype_textures/purple/texture_10.png.import new file mode 100644 index 0000000..276a47c --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dn7hfx787grso" +path="res://.godot/imported/texture_10.png-6ebba9cac53386550299b9fc7ba436fd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-6ebba9cac53386550299b9fc7ba436fd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_11.png b/addons/kenney_prototype_textures/purple/texture_11.png new file mode 100644 index 0000000..b1c3704 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_11.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_11.png.import b/addons/kenney_prototype_textures/purple/texture_11.png.import new file mode 100644 index 0000000..d681a0b --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cjc3qop36wu5b" +path="res://.godot/imported/texture_11.png-0fd2ee750e7568773caf6d873885f437.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-0fd2ee750e7568773caf6d873885f437.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_12.png b/addons/kenney_prototype_textures/purple/texture_12.png new file mode 100644 index 0000000..0269e59 Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_12.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_12.png.import b/addons/kenney_prototype_textures/purple/texture_12.png.import new file mode 100644 index 0000000..f5de3ab --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b28edsi0q2uon" +path="res://.godot/imported/texture_12.png-8a7cfbfe5b83f5813249f6314841357c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-8a7cfbfe5b83f5813249f6314841357c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/purple/texture_13.png b/addons/kenney_prototype_textures/purple/texture_13.png new file mode 100644 index 0000000..3b944cb Binary files /dev/null and b/addons/kenney_prototype_textures/purple/texture_13.png differ diff --git a/addons/kenney_prototype_textures/purple/texture_13.png.import b/addons/kenney_prototype_textures/purple/texture_13.png.import new file mode 100644 index 0000000..75056ab --- /dev/null +++ b/addons/kenney_prototype_textures/purple/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://k4c2p4ef7vcp" +path="res://.godot/imported/texture_13.png-ae54826bbb20288cf5ae03de2f2de21d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/purple/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-ae54826bbb20288cf5ae03de2f2de21d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_01.png b/addons/kenney_prototype_textures/red/texture_01.png new file mode 100644 index 0000000..1f9c506 Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_01.png differ diff --git a/addons/kenney_prototype_textures/red/texture_01.png.import b/addons/kenney_prototype_textures/red/texture_01.png.import new file mode 100644 index 0000000..0515edf --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_01.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d4d4805bhqiic" +path="res://.godot/imported/texture_01.png-44f9331a67ce6f062549bc436289d3c9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-44f9331a67ce6f062549bc436289d3c9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_02.png b/addons/kenney_prototype_textures/red/texture_02.png new file mode 100644 index 0000000..12e67bc Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_02.png differ diff --git a/addons/kenney_prototype_textures/red/texture_02.png.import b/addons/kenney_prototype_textures/red/texture_02.png.import new file mode 100644 index 0000000..ec78818 --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://okhfmeyw5nkc" +path="res://.godot/imported/texture_02.png-bb6eefc15212ba5b8098e9e672c21f12.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-bb6eefc15212ba5b8098e9e672c21f12.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_03.png b/addons/kenney_prototype_textures/red/texture_03.png new file mode 100644 index 0000000..11a9f85 Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_03.png differ diff --git a/addons/kenney_prototype_textures/red/texture_03.png.import b/addons/kenney_prototype_textures/red/texture_03.png.import new file mode 100644 index 0000000..172ead5 --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bkv73ahkilhgr" +path="res://.godot/imported/texture_03.png-dcaf463e914c7896b38a95f49416e75a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-dcaf463e914c7896b38a95f49416e75a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_04.png b/addons/kenney_prototype_textures/red/texture_04.png new file mode 100644 index 0000000..0ebe2fb Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_04.png differ diff --git a/addons/kenney_prototype_textures/red/texture_04.png.import b/addons/kenney_prototype_textures/red/texture_04.png.import new file mode 100644 index 0000000..d8e9034 --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://gjqh6tvis472" +path="res://.godot/imported/texture_04.png-1d63b32ccdbf1561b92a917dfb5f84ea.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-1d63b32ccdbf1561b92a917dfb5f84ea.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_05.png b/addons/kenney_prototype_textures/red/texture_05.png new file mode 100644 index 0000000..038af13 Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_05.png differ diff --git a/addons/kenney_prototype_textures/red/texture_05.png.import b/addons/kenney_prototype_textures/red/texture_05.png.import new file mode 100644 index 0000000..3320863 --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ui00huvmll10" +path="res://.godot/imported/texture_05.png-a44b3d75bc02c9b33606b6fe46e8c886.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-a44b3d75bc02c9b33606b6fe46e8c886.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_06.png b/addons/kenney_prototype_textures/red/texture_06.png new file mode 100644 index 0000000..4239985 Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_06.png differ diff --git a/addons/kenney_prototype_textures/red/texture_06.png.import b/addons/kenney_prototype_textures/red/texture_06.png.import new file mode 100644 index 0000000..13a0e45 --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cc3t1xpaxt070" +path="res://.godot/imported/texture_06.png-566b521660a0c01cabf8778c12eb1f51.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-566b521660a0c01cabf8778c12eb1f51.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_07.png b/addons/kenney_prototype_textures/red/texture_07.png new file mode 100644 index 0000000..99dcffd Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_07.png differ diff --git a/addons/kenney_prototype_textures/red/texture_07.png.import b/addons/kenney_prototype_textures/red/texture_07.png.import new file mode 100644 index 0000000..6b16485 --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://r0v50emth5ah" +path="res://.godot/imported/texture_07.png-ba1d32ad61ab49ac0edaf4930e4d081f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-ba1d32ad61ab49ac0edaf4930e4d081f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_08.png b/addons/kenney_prototype_textures/red/texture_08.png new file mode 100644 index 0000000..45ebb31 Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_08.png differ diff --git a/addons/kenney_prototype_textures/red/texture_08.png.import b/addons/kenney_prototype_textures/red/texture_08.png.import new file mode 100644 index 0000000..7ace887 --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dgte7sklfw3bd" +path="res://.godot/imported/texture_08.png-add0c08e78cde6ad4eaac64e7b9a9204.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-add0c08e78cde6ad4eaac64e7b9a9204.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_09.png b/addons/kenney_prototype_textures/red/texture_09.png new file mode 100644 index 0000000..347aad7 Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_09.png differ diff --git a/addons/kenney_prototype_textures/red/texture_09.png.import b/addons/kenney_prototype_textures/red/texture_09.png.import new file mode 100644 index 0000000..56db92c --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bk0bvtlv30kul" +path="res://.godot/imported/texture_09.png-4fe3f0e3bd94fb29789b41c9100c3ac9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-4fe3f0e3bd94fb29789b41c9100c3ac9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_10.png b/addons/kenney_prototype_textures/red/texture_10.png new file mode 100644 index 0000000..3448667 Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_10.png differ diff --git a/addons/kenney_prototype_textures/red/texture_10.png.import b/addons/kenney_prototype_textures/red/texture_10.png.import new file mode 100644 index 0000000..348d195 --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://boui2vkputd0d" +path="res://.godot/imported/texture_10.png-6fd251723c4fc19b26785b571c62b6ac.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-6fd251723c4fc19b26785b571c62b6ac.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_11.png b/addons/kenney_prototype_textures/red/texture_11.png new file mode 100644 index 0000000..3cfb7f6 Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_11.png differ diff --git a/addons/kenney_prototype_textures/red/texture_11.png.import b/addons/kenney_prototype_textures/red/texture_11.png.import new file mode 100644 index 0000000..51e0378 --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dwcxsoydf2ilk" +path="res://.godot/imported/texture_11.png-44ab559d4c1ab996ce064426a9e01b38.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-44ab559d4c1ab996ce064426a9e01b38.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_12.png b/addons/kenney_prototype_textures/red/texture_12.png new file mode 100644 index 0000000..d247946 Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_12.png differ diff --git a/addons/kenney_prototype_textures/red/texture_12.png.import b/addons/kenney_prototype_textures/red/texture_12.png.import new file mode 100644 index 0000000..3e2652c --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dru343o14xfss" +path="res://.godot/imported/texture_12.png-6af19821abb02cb29bb6ed24ee4670e0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-6af19821abb02cb29bb6ed24ee4670e0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/kenney_prototype_textures/red/texture_13.png b/addons/kenney_prototype_textures/red/texture_13.png new file mode 100644 index 0000000..9154c3b Binary files /dev/null and b/addons/kenney_prototype_textures/red/texture_13.png differ diff --git a/addons/kenney_prototype_textures/red/texture_13.png.import b/addons/kenney_prototype_textures/red/texture_13.png.import new file mode 100644 index 0000000..d9ba13d --- /dev/null +++ b/addons/kenney_prototype_textures/red/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://djkm77sy6ygla" +path="res://.godot/imported/texture_13.png-891332ffbf32d9b94212aaf3a11a15a9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/kenney_prototype_textures/red/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-891332ffbf32d9b94212aaf3a11a15a9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 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..6958702 --- /dev/null +++ b/addons/limboai/README.md @@ -0,0 +1,142 @@ +

+ LimboAI logo +

+ +# LimboAI - Behavior Trees & State Machines for Godot 4 + +[![🔗 All builds](https://github.com/limbonaut/limboai/actions/workflows/all_builds.yml/badge.svg)](https://github.com/limbonaut/limboai/actions/workflows/all_builds.yml) +[![🔎 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** (v1.4.0+) | **4.3** (v1.2, v1.3) | **4.2** (v1.1) + +**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) + +>**🛈 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 + + + + + + + + + +## 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/contributing/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/libliblimboai.windows.editor.x86_64.a b/addons/limboai/bin/libliblimboai.windows.editor.x86_64.a new file mode 100644 index 0000000..8b30b58 Binary files /dev/null and b/addons/limboai/bin/libliblimboai.windows.editor.x86_64.a differ diff --git a/addons/limboai/bin/libliblimboai.windows.template_release.x86_64.a b/addons/limboai/bin/libliblimboai.windows.template_release.x86_64.a new file mode 100644 index 0000000..63013a8 Binary files /dev/null and b/addons/limboai/bin/libliblimboai.windows.template_release.x86_64.a differ 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..587be42 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..6d1c455 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..10f8330 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..5eb80ef 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..11e2d08 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..7aa256f 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..03a2999 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..4168377 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..75b194d 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..5564d44 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..9e9a490 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..24dd82f 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.x86_64.so b/addons/limboai/bin/liblimboai.linux.editor.x86_64.so new file mode 100644 index 0000000..fe6ed24 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.x86_64.so b/addons/limboai/bin/liblimboai.linux.template_release.x86_64.so new file mode 100644 index 0000000..99049d9 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..672dad3 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..bf7950c 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.wasm b/addons/limboai/bin/liblimboai.web.editor.wasm32.wasm new file mode 100644 index 0000000..7768dc9 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.wasm b/addons/limboai/bin/liblimboai.web.template_release.wasm32.wasm new file mode 100644 index 0000000..e1aa167 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..e061d2c 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..b47fec4 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..a404920 --- /dev/null +++ b/addons/limboai/bin/limboai.gdextension @@ -0,0 +1,100 @@ +[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.wasm" +web.release.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..a41dd1d --- /dev/null +++ b/addons/limboai/bin/limboai.gdextension.uid @@ -0,0 +1 @@ +uid://dwg0cix6bdrrp 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..1b13fdd --- /dev/null +++ b/addons/limboai/icons/BTAction.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b4uwrfbi2kl15" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..f33980d --- /dev/null +++ b/addons/limboai/icons/BTAlwaysFail.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b06w00040sm1r" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..450cd6c --- /dev/null +++ b/addons/limboai/icons/BTAlwaysSucceed.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cdh68bjwonahh" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..8660713 --- /dev/null +++ b/addons/limboai/icons/BTAwaitAnimation.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c86g16vstgbxo" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..22c9fe1 --- /dev/null +++ b/addons/limboai/icons/BTCallMethod.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://baln0ulkj4mws" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..60bb703 --- /dev/null +++ b/addons/limboai/icons/BTCheckAgentProperty.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://blb8r1fymbp6o" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..f11f1d2 --- /dev/null +++ b/addons/limboai/icons/BTCheckTrigger.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://v6qtq3fxp2rl" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..ea71334 --- /dev/null +++ b/addons/limboai/icons/BTCheckVar.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c43lghm3kcv3l" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..73ab9c2 --- /dev/null +++ b/addons/limboai/icons/BTComment.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ctwtqejfei03d" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..fed46bc --- /dev/null +++ b/addons/limboai/icons/BTCondition.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://db77hecrh2ep5" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..046e979 --- /dev/null +++ b/addons/limboai/icons/BTConsolePrint.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://7keuf7x1nkq1" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..9c29cff --- /dev/null +++ b/addons/limboai/icons/BTCooldown.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cmxvojf8fkp4s" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..edd562c --- /dev/null +++ b/addons/limboai/icons/BTDecorator.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://vxll5q5p1e82" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..763f1b6 --- /dev/null +++ b/addons/limboai/icons/BTDelay.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://mwxl0slnjq4m" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..eb30365 --- /dev/null +++ b/addons/limboai/icons/BTDynamicSelector.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://blhahvh61np1e" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..59ac7a6 --- /dev/null +++ b/addons/limboai/icons/BTDynamicSequence.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://2687mr08gd80" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..05df8fe --- /dev/null +++ b/addons/limboai/icons/BTEvaluateExpression.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dqxv7g40xdle6" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..25afafa --- /dev/null +++ b/addons/limboai/icons/BTFail.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dresyr8ndlkbq" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..cf38ba2 --- /dev/null +++ b/addons/limboai/icons/BTForEach.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bw7y7q481b1ji" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..813767f --- /dev/null +++ b/addons/limboai/icons/BTInvert.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dnu2rk87hm7v4" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..221c88a --- /dev/null +++ b/addons/limboai/icons/BTNewScope.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cnyeikt0b8k1i" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..669d249 --- /dev/null +++ b/addons/limboai/icons/BTParallel.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bl4dpope1s0wu" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..fc8b411 --- /dev/null +++ b/addons/limboai/icons/BTPauseAnimation.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://whox6yjwdu1b" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..e7af45a --- /dev/null +++ b/addons/limboai/icons/BTPlayAnimation.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://booij256guqn4" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..541f8e0 --- /dev/null +++ b/addons/limboai/icons/BTPlayer.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://jd0icnkf4qvi" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..e8aa856 --- /dev/null +++ b/addons/limboai/icons/BTProbability.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dqqapx0xaqxp1" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..b21fa1e --- /dev/null +++ b/addons/limboai/icons/BTProbabilitySelector.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cckfytll0o3ki" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..ec436d7 --- /dev/null +++ b/addons/limboai/icons/BTRandomSelector.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dbjvwjueyn352" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..3201974 --- /dev/null +++ b/addons/limboai/icons/BTRandomSequence.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://s7j6hwadgr0i" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..bd08692 --- /dev/null +++ b/addons/limboai/icons/BTRandomWait.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dr2fot2qxk8ld" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..27bab12 --- /dev/null +++ b/addons/limboai/icons/BTRepeat.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c042mgwhr06gi" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..c0b2deb --- /dev/null +++ b/addons/limboai/icons/BTRepeatUntilFailure.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c7kh3xs11njn5" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..d6c12a7 --- /dev/null +++ b/addons/limboai/icons/BTRepeatUntilSuccess.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bk6qi2mulvh0" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..6a91abe --- /dev/null +++ b/addons/limboai/icons/BTRunLimit.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bc1rem8gs44lw" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..9acf2bd --- /dev/null +++ b/addons/limboai/icons/BTSelector.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bglc510pxxxrf" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..38d6468 --- /dev/null +++ b/addons/limboai/icons/BTSequence.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b71e0cpg6ecu3" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..9c41fcd --- /dev/null +++ b/addons/limboai/icons/BTSetAgentProperty.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b3r4q840mgwpv" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..a82e5bb --- /dev/null +++ b/addons/limboai/icons/BTSetVar.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b87mxoew368pg" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..3b54a50 --- /dev/null +++ b/addons/limboai/icons/BTState.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://i48m24a03uir" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..6e5681d --- /dev/null +++ b/addons/limboai/icons/BTStopAnimation.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ol274gjkebyn" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..b0981be --- /dev/null +++ b/addons/limboai/icons/BTSubtree.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ddu6gidosejs2" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..1e27588 --- /dev/null +++ b/addons/limboai/icons/BTTimeLimit.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://hymw2my6ucd6" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..5486fd9 --- /dev/null +++ b/addons/limboai/icons/BTWait.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://uu2yey1lyyc" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..246c6eb --- /dev/null +++ b/addons/limboai/icons/BTWaitTicks.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ccbm7033n7cxt" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..16edbba --- /dev/null +++ b/addons/limboai/icons/BehaviorTree.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bag4r57u43elu" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..df7abd5 --- /dev/null +++ b/addons/limboai/icons/BehaviorTreeView.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bkld314vtxjfy" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..ebfe261 --- /dev/null +++ b/addons/limboai/icons/BlackboardPlan.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://daqt8y1hvqwj0" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..6f9e92d --- /dev/null +++ b/addons/limboai/icons/LimboAI.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://8qlwxlsomxbu" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..2754cd7 --- /dev/null +++ b/addons/limboai/icons/LimboDeselectAll.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://iq8qmgu4rc7x" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..6cb8efe --- /dev/null +++ b/addons/limboai/icons/LimboEditBlackboard.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cg3k4e5m1bj01" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..96afb6b --- /dev/null +++ b/addons/limboai/icons/LimboExtraBlackboard.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://m2t1t0ymg1wu" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..2c328c1 --- /dev/null +++ b/addons/limboai/icons/LimboExtraClock.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dtg302basd8gc" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..54315b4 --- /dev/null +++ b/addons/limboai/icons/LimboExtraVariable.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dgwmtgnqttgr5" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..34e7c78 --- /dev/null +++ b/addons/limboai/icons/LimboExtractSubtree.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dohnk7d62jxd2" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..7633fb1 --- /dev/null +++ b/addons/limboai/icons/LimboHSM.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://chyhrsmjboxtu" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..18e507f --- /dev/null +++ b/addons/limboai/icons/LimboPercent.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bix1fequar2cp" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..b71fc13 --- /dev/null +++ b/addons/limboai/icons/LimboSelectAll.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dmdos2iiij4d1" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..23c5bfc --- /dev/null +++ b/addons/limboai/icons/LimboState.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bh75gxq1flhrj" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..b6d196a --- /dev/null +++ b/addons/limboai/icons/LimboVarAdd.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cenls143nh2c2" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..6ae195b --- /dev/null +++ b/addons/limboai/icons/LimboVarEmpty.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cmb3xkxi50uwi" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..66daabb --- /dev/null +++ b/addons/limboai/icons/LimboVarError.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cmiihhf1i35i7" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..72f6d46 --- /dev/null +++ b/addons/limboai/icons/LimboVarExists.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://377rl3nfm4ji" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..9b314c6 --- /dev/null +++ b/addons/limboai/icons/LimboVarNotFound.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bb7uh1lny51ct" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..e34de70 --- /dev/null +++ b/addons/limboai/icons/LimboVarPrivate.svg.import @@ -0,0 +1,38 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://nut2dnjhvskx" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..66d62a8 --- /dev/null +++ b/addons/limboai/version.txt @@ -0,0 +1 @@ +v1.4.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..ad3a214 --- /dev/null +++ b/addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png.import @@ -0,0 +1,34 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 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..dd6f1a4 --- /dev/null +++ b/addons/phantom_camera/assets/PhantomCameraBtnPrimaryHover.png.import @@ -0,0 +1,34 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 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..72be1e5 --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/inventory_container.png.import @@ -0,0 +1,34 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 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..520372a --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/level_spritesheet.png.import @@ -0,0 +1,34 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 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..425002e --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/phantom_camera_2d_sprite.png.import @@ -0,0 +1,34 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 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..84c750b --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/player_sprite.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..a5799d3 --- /dev/null +++ b/addons/phantom_camera/examples/textures/2D/sign_prompt.png.import @@ -0,0 +1,34 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 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..e80c132 --- /dev/null +++ b/addons/phantom_camera/examples/textures/3D/checker_pattern_dark.png.import @@ -0,0 +1,35 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=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..6de0861 --- /dev/null +++ b/addons/phantom_camera/examples/textures/3D/target.png.import @@ -0,0 +1,35 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=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..8e68c5f --- /dev/null +++ b/addons/phantom_camera/fonts/Nunito-Black.ttf.import @@ -0,0 +1,35 @@ +[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 +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..11c0c62 --- /dev/null +++ b/addons/phantom_camera/fonts/Nunito-Regular.ttf.import @@ -0,0 +1,35 @@ +[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 +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..d78acf5 --- /dev/null +++ b/addons/phantom_camera/icons/misc/PriorityOverride.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..724069f --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_2d.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..eedbd2f --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_3d.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..4b0e8bc --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_camera_3d_resource.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..7b49608 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_gizmo.svg.import @@ -0,0 +1,38 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=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..d68be86 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_glow_logo.png.import @@ -0,0 +1,34 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 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..430d67d --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_host.svg.import @@ -0,0 +1,38 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..6f51cf4 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_logo.png.import @@ -0,0 +1,34 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 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..c24e060 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_emitter_2d.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..de23002 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_emitter_3d.svg.import @@ -0,0 +1,38 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=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..4dd736b --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_emitter_gizmo.svg.import @@ -0,0 +1,38 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=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..8cefc36 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_noise_resource.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..3db67fb --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_tween.svg.import @@ -0,0 +1,38 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..c182784 --- /dev/null +++ b/addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..e8fb35d --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Camera2DIcon.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..79708e2 --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Camera3DIcon.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..364c4ed --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/SceneTypesIcon.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..81b41c9 --- /dev/null +++ b/addons/phantom_camera/icons/viewfinder/Select.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..2895b37 --- /dev/null +++ b/addons/phantom_camera/icons/warning.svg.import @@ -0,0 +1,37 @@ +[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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..64c4600 --- /dev/null +++ b/addons/phantom_camera/panel/viewfinder/host_list/host_list_item_group.tres @@ -0,0 +1,3 @@ +[gd_resource type="ButtonGroup" 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/script_spliter/assets/dd.png b/addons/script_spliter/assets/dd.png new file mode 100644 index 0000000..0ad944c Binary files /dev/null and b/addons/script_spliter/assets/dd.png differ diff --git a/addons/script_spliter/assets/dd.png.import b/addons/script_spliter/assets/dd.png.import new file mode 100644 index 0000000..109c980 --- /dev/null +++ b/addons/script_spliter/assets/dd.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cxds5tr6aq5v3" +path="res://.godot/imported/dd.png-3704eaaffe380d5ad414e6e7fce28e96.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/assets/dd.png" +dest_files=["res://.godot/imported/dd.png-3704eaaffe380d5ad414e6e7fce28e96.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/script_spliter/assets/github_CodeNameTwister.png b/addons/script_spliter/assets/github_CodeNameTwister.png new file mode 100644 index 0000000..540b1cd Binary files /dev/null and b/addons/script_spliter/assets/github_CodeNameTwister.png differ diff --git a/addons/script_spliter/assets/github_CodeNameTwister.png.import b/addons/script_spliter/assets/github_CodeNameTwister.png.import new file mode 100644 index 0000000..12689b6 --- /dev/null +++ b/addons/script_spliter/assets/github_CodeNameTwister.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://tgaoyybc2iji" +path="res://.godot/imported/github_CodeNameTwister.png-88287e5d04f5b5c67334953a8a4ce6f2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/assets/github_CodeNameTwister.png" +dest_files=["res://.godot/imported/github_CodeNameTwister.png-88287e5d04f5b5c67334953a8a4ce6f2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/script_spliter/assets/tab_icon.svg b/addons/script_spliter/assets/tab_icon.svg new file mode 100644 index 0000000..2ba2fc4 --- /dev/null +++ b/addons/script_spliter/assets/tab_icon.svg @@ -0,0 +1 @@ + diff --git a/addons/script_spliter/assets/tab_icon.svg.import b/addons/script_spliter/assets/tab_icon.svg.import new file mode 100644 index 0000000..b42f4a4 --- /dev/null +++ b/addons/script_spliter/assets/tab_icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bmhixx87f787y" +path="res://.godot/imported/tab_icon.svg-1187d0207b55f861d54b7b960e0aafec.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/assets/tab_icon.svg" +dest_files=["res://.godot/imported/tab_icon.svg-1187d0207b55f861d54b7b960e0aafec.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/script_spliter/context/_POPGDScript_.gd b/addons/script_spliter/context/_POPGDScript_.gd new file mode 100644 index 0000000..c808c54 --- /dev/null +++ b/addons/script_spliter/context/_POPGDScript_.gd @@ -0,0 +1,4 @@ +@warning_ignore("empty_file") +# This script is only placeholder for handle pop script input. + +# This should closed and removed after closing the pop-up. diff --git a/addons/script_spliter/context/_POPGDScript_.gd.uid b/addons/script_spliter/context/_POPGDScript_.gd.uid new file mode 100644 index 0000000..d5bdb69 --- /dev/null +++ b/addons/script_spliter/context/_POPGDScript_.gd.uid @@ -0,0 +1 @@ +uid://bkfdswehvs8sf diff --git a/addons/script_spliter/context/btn_callback.gd b/addons/script_spliter/context/btn_callback.gd new file mode 100644 index 0000000..f84628c --- /dev/null +++ b/addons/script_spliter/context/btn_callback.gd @@ -0,0 +1,17 @@ +@tool +extends Button +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +func _pressed() -> void: + var parent : Node = owner + if parent == null: + parent = get_parent() + if parent: + if parent.has_method(name): + parent.call(name) diff --git a/addons/script_spliter/context/btn_callback.gd.uid b/addons/script_spliter/context/btn_callback.gd.uid new file mode 100644 index 0000000..3e8f5b4 --- /dev/null +++ b/addons/script_spliter/context/btn_callback.gd.uid @@ -0,0 +1 @@ +uid://bo38caobn2x7a diff --git a/addons/script_spliter/context/context_window.gd b/addons/script_spliter/context/context_window.gd new file mode 100644 index 0000000..a3dc1d3 --- /dev/null +++ b/addons/script_spliter/context/context_window.gd @@ -0,0 +1,36 @@ +@tool +extends EditorContextMenuPlugin +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +var CONTEXT : String = "CUSTOM" +var ICON : Texture = null +var SHORTCUT : Shortcut = null +var CALLABLE : Callable +var VALIDATOR : Callable + +func _init(context : String, handle : Callable, validator : Callable, icon : Texture, input_key : Array[InputEvent] = []): + CONTEXT = context + CALLABLE = handle + ICON = icon + VALIDATOR = validator + if input_key.size() > 0: + SHORTCUT = Shortcut.new() + SHORTCUT.events = input_key + add_menu_shortcut(SHORTCUT, handle) + +func _popup_menu(paths : PackedStringArray): + if VALIDATOR.is_valid(): + if !VALIDATOR.call(paths): + return + if SHORTCUT: + add_context_menu_item_from_shortcut(CONTEXT, SHORTCUT, ICON) + else: + if CALLABLE.is_valid(): + add_context_menu_item(CONTEXT, CALLABLE, ICON) + else: + push_error("Not valid callaback!") diff --git a/addons/script_spliter/context/context_window.gd.uid b/addons/script_spliter/context/context_window.gd.uid new file mode 100644 index 0000000..3a74739 --- /dev/null +++ b/addons/script_spliter/context/context_window.gd.uid @@ -0,0 +1 @@ +uid://dmf7coyb6hgbe diff --git a/addons/script_spliter/context/custom_options.gd b/addons/script_spliter/context/custom_options.gd new file mode 100644 index 0000000..83b7853 --- /dev/null +++ b/addons/script_spliter/context/custom_options.gd @@ -0,0 +1,22 @@ +@tool +extends Control +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +@export var columns : SpinBox +@export var rows : SpinBox + +func set_values(_columns : int, _rows : int) -> void: + columns.value = _columns + rows.value = _rows + +func get_columns_value() -> int: + return max(columns.value, 1) + +func get_rows_value() -> int: + return max(rows.value, 1) diff --git a/addons/script_spliter/context/custom_options.gd.uid b/addons/script_spliter/context/custom_options.gd.uid new file mode 100644 index 0000000..9db38fd --- /dev/null +++ b/addons/script_spliter/context/custom_options.gd.uid @@ -0,0 +1 @@ +uid://y3jbguu2nw5c diff --git a/addons/script_spliter/context/flying_script.gd b/addons/script_spliter/context/flying_script.gd new file mode 100644 index 0000000..5ee2f45 --- /dev/null +++ b/addons/script_spliter/context/flying_script.gd @@ -0,0 +1,177 @@ +@tool +extends Window +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4f +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +signal on_close(window : Window) + +@export var _container : Control = null +@export var _base_control : TabContainer = null +@export var _always_top : Button = null +@export var _close : Button = null +@export var _root : Control = null + +var proxy : Control = null +var replacer : Node = null +var controller : Object = null + +func set_base_control(node : Node) -> void: + if _base_control: + _base_control.queue_sort() + _base_control = node + if _container: + _container.add_child(node) + return + add_child(node) + + if node is Control: + node.size = node.get_parent().size + +func get_base_control() -> TabContainer: + return _base_control + +func _init() -> void: + visible = false + close_requested.connect(_on_close) + visibility_changed.connect(_on_visibility) + focus_entered.connect(_on_focus) + focus_exited.connect(_on_focus_exited) + +func _get_edit(n : Node) -> CodeEdit: + if n is CodeEdit: + return n + for x : Node in n.get_children(): + return _get_edit(x) + return null + +func _on_focus() -> void: + if replacer == null: + var script_editor: ScriptEditor = EditorInterface.get_script_editor() + var root : Node = script_editor.get_child(0).get_child(1).get_child(1) + if root.get_child_count() > 2: + replacer = root.get_child(2) + if "FindReplaceBar" in replacer.name: + replacer.get_parent().remove_child(replacer) + + if is_instance_valid(_root): + _root.add_child(replacer) + else: + add_child(replacer) + + if is_instance_valid(controller): + controller.emit_signal.call_deferred(&"focus", controller) + +func _update_name() -> void: + if is_queued_for_deletion(): + return + if is_instance_valid(_base_control): + if _base_control.current_tab > -1: + title = "Script-Spliter: {0}".format([_base_control.get_tab_title(_base_control.current_tab)]) + return + title = "Script-Spliter: Pop Script" + +func _on_tabity(__ : int) -> void: + _update_name.call_deferred() + +func _on_always_top() -> void: + if transient: + return + always_on_top = !always_on_top + +func _shortcut_input(event: InputEvent) -> void: + if is_instance_valid(proxy): + var vp : Viewport = proxy.get_viewport() + if vp and vp != get_viewport(): + vp.push_input(event) + +func _ready() -> void: + set_process_shortcut_input(true) + if _always_top: + if !_always_top.pressed.is_connected(_on_always_top): + _always_top.pressed.connect(_on_always_top) + if _close: + if !_close.pressed.is_connected(_on_close): + _close.pressed.connect(_on_close) + if _base_control: + if !_base_control.tab_changed.is_connected(_on_tabity): + _base_control.tab_changed.connect(_on_tabity) + if !_base_control.child_entered_tree.is_connected(_on_child): + _base_control.child_entered_tree.connect(_on_child) + if !_base_control.child_exiting_tree.is_connected(_out_child): + _base_control.child_exiting_tree.connect(_out_child) + + var root : Control = EditorInterface.get_base_control() + if root: + add_theme_stylebox_override(&"Panel",root.get_theme_stylebox("panel", "PanelContainer")) + +func _connect(n : Node, e : bool) -> void: + if n is CodeEdit: + if e: + if !n.focus_entered.is_connected(_on_focus): + n.focus_entered.connect(_on_focus) + else: + if n.focus_entered.is_connected(_on_focus): + n.focus_entered.disconnect(_on_focus) + return + for x : Node in n.get_children(): + _connect(x, e) + +func _on_child(n : Node) -> void: + if n is Control: + _connect(n, true) + +func _out_child(n : Node) -> void: + if n is Control: + _connect(n, false) + +func _on_visibility() -> void: + if !visible: + _on_focus_exited() + _on_close() + return + set_deferred(&"always_top", false) + set_process(true) + _update_name.call_deferred() + +func _on_close() -> void: + on_close.emit(self) + + if _base_control and _base_control.get_child_count() < 1: + queue_free() + +func _on_focus_exited() -> void: + if replacer != null: + var script_editor: ScriptEditor = EditorInterface.get_script_editor() + var root : Node = script_editor.get_child(0).get_child(1).get_child(1) + + var parent : Node = replacer.get_parent() + if parent != root: + if is_instance_valid(parent): + parent.remove_child(replacer) + root.add_child(replacer) + replacer = null + +func _notification(what: int) -> void: + if what == NOTIFICATION_PREDELETE: + if is_instance_valid(replacer): + var script_editor: ScriptEditor = EditorInterface.get_script_editor() + var root : Node = script_editor.get_child(0).get_child(1).get_child(1) + + var parent : Node = replacer.get_parent() + if parent != root: + if is_instance_valid(parent): + parent.remove_child(replacer) + root.add_child(replacer) + replacer = null + if is_instance_valid(controller): + controller.call(&"reset") + +func _move_to_center() -> void: + move_to_center() + +func _alpha_value(v : float) -> void: + get_child(0).modulate.a = v diff --git a/addons/script_spliter/context/flying_script.gd.uid b/addons/script_spliter/context/flying_script.gd.uid new file mode 100644 index 0000000..0300abb --- /dev/null +++ b/addons/script_spliter/context/flying_script.gd.uid @@ -0,0 +1 @@ +uid://dbkyfe5ri2p73 diff --git a/addons/script_spliter/context/flying_script.tscn b/addons/script_spliter/context/flying_script.tscn new file mode 100644 index 0000000..915c3c8 --- /dev/null +++ b/addons/script_spliter/context/flying_script.tscn @@ -0,0 +1,69 @@ +[gd_scene load_steps=5 format=3 uid="uid://cr2xovtt6uo7s"] + +[ext_resource type="Script" uid="uid://dbkyfe5ri2p73" path="res://addons/script_spliter/context/flying_script.gd" id="1_wfm3d"] +[ext_resource type="Texture2D" uid="uid://r6u1jtnbr4eg" path="res://addons/script_spliter/context/icons/atop.png" id="2_q3d74"] +[ext_resource type="Script" uid="uid://bo38caobn2x7a" path="res://addons/script_spliter/context/btn_callback.gd" id="3_1p1sv"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q3d74"] +content_margin_left = 3.0 +content_margin_top = 3.0 +content_margin_right = 3.0 +content_margin_bottom = 3.0 +bg_color = Color(0.1155, 0.132, 0.1595, 1) +corner_detail = 1 +anti_aliasing = false + +[node name="FlyingScript" type="Window" node_paths=PackedStringArray("_container", "_always_top", "_close", "_root")] +title = "Script-Spliter: Pop Script" +initial_position = 4 +size = Vector2i(805, 512) +visible = false +wrap_controls = true +script = ExtResource("1_wfm3d") +_container = NodePath("PanelContainer/VC") +_always_top = NodePath("PanelContainer/VC/HB/AlwaysTop") +_close = NodePath("PanelContainer/VC/HB/Close") +_root = NodePath("PanelContainer/VC") + +[node name="PanelContainer" type="PanelContainer" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_q3d74") + +[node name="VC" type="VBoxContainer" parent="PanelContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="HB" type="HBoxContainer" parent="PanelContainer/VC"] +layout_mode = 2 +theme_override_constants/separation = 8 + +[node name="AlwaysTop" type="Button" parent="PanelContainer/VC/HB"] +layout_mode = 2 +tooltip_text = "Set always front visible the current window" +theme_override_font_sizes/font_size = 12 +toggle_mode = true +text = "Always Top" +icon = ExtResource("2_q3d74") +flat = true + +[node name="_move_to_center" type="Button" parent="PanelContainer/VC/HB"] +layout_mode = 2 +tooltip_text = "Move the window to center" +theme_override_font_sizes/font_size = 12 +toggle_mode = true +text = "Move To Center" +flat = true +script = ExtResource("3_1p1sv") + +[node name="Close" type="Button" parent="PanelContainer/VC/HB"] +visible = false +custom_minimum_size = Vector2(32, 0) +layout_mode = 2 +size_flags_horizontal = 10 +tooltip_text = "Close the window" +text = "X" diff --git a/addons/script_spliter/context/flying_script_font.tres b/addons/script_spliter/context/flying_script_font.tres new file mode 100644 index 0000000..1bd1d94 --- /dev/null +++ b/addons/script_spliter/context/flying_script_font.tres @@ -0,0 +1,4 @@ +[gd_resource type="LabelSettings" format=3 uid="uid://cdrt4b0qrb77v"] + +[resource] +font_size = 12 diff --git a/addons/script_spliter/context/icons/atop.png b/addons/script_spliter/context/icons/atop.png new file mode 100644 index 0000000..9f417c6 Binary files /dev/null and b/addons/script_spliter/context/icons/atop.png differ diff --git a/addons/script_spliter/context/icons/atop.png.import b/addons/script_spliter/context/icons/atop.png.import new file mode 100644 index 0000000..d0f81c5 --- /dev/null +++ b/addons/script_spliter/context/icons/atop.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://r6u1jtnbr4eg" +path="res://.godot/imported/atop.png-1d61cb69aae60a076cd60a0a3f1cc72c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/atop.png" +dest_files=["res://.godot/imported/atop.png-1d61cb69aae60a076cd60a0a3f1cc72c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/script_spliter/context/icons/expand.svg b/addons/script_spliter/context/icons/expand.svg new file mode 100644 index 0000000..c642cd7 --- /dev/null +++ b/addons/script_spliter/context/icons/expand.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/addons/script_spliter/context/icons/expand.svg.import b/addons/script_spliter/context/icons/expand.svg.import new file mode 100644 index 0000000..9fdc5d8 --- /dev/null +++ b/addons/script_spliter/context/icons/expand.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cractge21enk" +path="res://.godot/imported/expand.svg-963ea7d55c7ac4362bba429ef9c40e46.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/expand.svg" +dest_files=["res://.godot/imported/expand.svg-963ea7d55c7ac4362bba429ef9c40e46.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/script_spliter/context/icons/sp_2H.png b/addons/script_spliter/context/icons/sp_2H.png new file mode 100644 index 0000000..5610001 Binary files /dev/null and b/addons/script_spliter/context/icons/sp_2H.png differ diff --git a/addons/script_spliter/context/icons/sp_2H.png.import b/addons/script_spliter/context/icons/sp_2H.png.import new file mode 100644 index 0000000..6eca151 --- /dev/null +++ b/addons/script_spliter/context/icons/sp_2H.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c1kjfqirfexvp" +path="res://.godot/imported/sp_2H.png-c589a7f8579a9ee26d2875c35e52e183.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/sp_2H.png" +dest_files=["res://.godot/imported/sp_2H.png-c589a7f8579a9ee26d2875c35e52e183.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/script_spliter/context/icons/sp_2V.png b/addons/script_spliter/context/icons/sp_2V.png new file mode 100644 index 0000000..2337a6c Binary files /dev/null and b/addons/script_spliter/context/icons/sp_2V.png differ diff --git a/addons/script_spliter/context/icons/sp_2V.png.import b/addons/script_spliter/context/icons/sp_2V.png.import new file mode 100644 index 0000000..7105bf4 --- /dev/null +++ b/addons/script_spliter/context/icons/sp_2V.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1r72ixdgbwl6" +path="res://.godot/imported/sp_2V.png-39915ece37e791e8d9a130c4c3240f49.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/sp_2V.png" +dest_files=["res://.godot/imported/sp_2V.png-39915ece37e791e8d9a130c4c3240f49.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/script_spliter/context/icons/sp_3H.png b/addons/script_spliter/context/icons/sp_3H.png new file mode 100644 index 0000000..6add8d9 Binary files /dev/null and b/addons/script_spliter/context/icons/sp_3H.png differ diff --git a/addons/script_spliter/context/icons/sp_3H.png.import b/addons/script_spliter/context/icons/sp_3H.png.import new file mode 100644 index 0000000..0089345 --- /dev/null +++ b/addons/script_spliter/context/icons/sp_3H.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://32xnl4cu46pj" +path="res://.godot/imported/sp_3H.png-09e8b9f9a346f328495f443e565ad878.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/sp_3H.png" +dest_files=["res://.godot/imported/sp_3H.png-09e8b9f9a346f328495f443e565ad878.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/script_spliter/context/icons/sp_3V.png b/addons/script_spliter/context/icons/sp_3V.png new file mode 100644 index 0000000..05c3061 Binary files /dev/null and b/addons/script_spliter/context/icons/sp_3V.png differ diff --git a/addons/script_spliter/context/icons/sp_3V.png.import b/addons/script_spliter/context/icons/sp_3V.png.import new file mode 100644 index 0000000..c0576a5 --- /dev/null +++ b/addons/script_spliter/context/icons/sp_3V.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b4cmfno0ixqnm" +path="res://.godot/imported/sp_3V.png-6984dd1b3c8e11f26b5964981b46a4b8.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/sp_3V.png" +dest_files=["res://.godot/imported/sp_3V.png-6984dd1b3c8e11f26b5964981b46a4b8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/script_spliter/context/icons/sp_4S.png b/addons/script_spliter/context/icons/sp_4S.png new file mode 100644 index 0000000..3406a22 Binary files /dev/null and b/addons/script_spliter/context/icons/sp_4S.png differ diff --git a/addons/script_spliter/context/icons/sp_4S.png.import b/addons/script_spliter/context/icons/sp_4S.png.import new file mode 100644 index 0000000..cb4427c --- /dev/null +++ b/addons/script_spliter/context/icons/sp_4S.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bf2bjkoock7re" +path="res://.godot/imported/sp_4S.png-38dbb9b7da5a9846aab652bf564a4249.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/sp_4S.png" +dest_files=["res://.godot/imported/sp_4S.png-38dbb9b7da5a9846aab652bf564a4249.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/script_spliter/context/icons/sp_custom.png b/addons/script_spliter/context/icons/sp_custom.png new file mode 100644 index 0000000..e2be1e6 Binary files /dev/null and b/addons/script_spliter/context/icons/sp_custom.png differ diff --git a/addons/script_spliter/context/icons/sp_custom.png.import b/addons/script_spliter/context/icons/sp_custom.png.import new file mode 100644 index 0000000..bea325e --- /dev/null +++ b/addons/script_spliter/context/icons/sp_custom.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bdxvp5dyj8y0r" +path="res://.godot/imported/sp_custom.png-91b7ef0ad7d63ebf7700a2047739db70.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/sp_custom.png" +dest_files=["res://.godot/imported/sp_custom.png-91b7ef0ad7d63ebf7700a2047739db70.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/script_spliter/context/icons/sp_disable.png b/addons/script_spliter/context/icons/sp_disable.png new file mode 100644 index 0000000..c069a76 Binary files /dev/null and b/addons/script_spliter/context/icons/sp_disable.png differ diff --git a/addons/script_spliter/context/icons/sp_disable.png.import b/addons/script_spliter/context/icons/sp_disable.png.import new file mode 100644 index 0000000..61f24cd --- /dev/null +++ b/addons/script_spliter/context/icons/sp_disable.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dmvcijsjhb5pc" +path="res://.godot/imported/sp_disable.png-d75c06feba36dd2af819e235b22c2ea6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/sp_disable.png" +dest_files=["res://.godot/imported/sp_disable.png-d75c06feba36dd2af819e235b22c2ea6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/script_spliter/context/icons/split_cminus.svg b/addons/script_spliter/context/icons/split_cminus.svg new file mode 100644 index 0000000..94efd74 --- /dev/null +++ b/addons/script_spliter/context/icons/split_cminus.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + split-screen + + + + + + + split-screen + + + + diff --git a/addons/script_spliter/context/icons/split_cminus.svg.import b/addons/script_spliter/context/icons/split_cminus.svg.import new file mode 100644 index 0000000..c3c6bf4 --- /dev/null +++ b/addons/script_spliter/context/icons/split_cminus.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c1b7aoplxr0x7" +path="res://.godot/imported/split_cminus.svg-3d236e355acd272b8108cca3f8e1c7f3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/split_cminus.svg" +dest_files=["res://.godot/imported/split_cminus.svg-3d236e355acd272b8108cca3f8e1c7f3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=8.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/script_spliter/context/icons/split_cplus.svg b/addons/script_spliter/context/icons/split_cplus.svg new file mode 100644 index 0000000..7b80214 --- /dev/null +++ b/addons/script_spliter/context/icons/split_cplus.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + split-screen + + + + + + + + split-screen + + + + diff --git a/addons/script_spliter/context/icons/split_cplus.svg.import b/addons/script_spliter/context/icons/split_cplus.svg.import new file mode 100644 index 0000000..7817ddf --- /dev/null +++ b/addons/script_spliter/context/icons/split_cplus.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bvyjqo1dus1xu" +path="res://.godot/imported/split_cplus.svg-5f233626ec643447e303aa2d98ed8d14.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/split_cplus.svg" +dest_files=["res://.godot/imported/split_cplus.svg-5f233626ec643447e303aa2d98ed8d14.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=8.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/script_spliter/context/icons/split_rminus.svg b/addons/script_spliter/context/icons/split_rminus.svg new file mode 100644 index 0000000..1eb578c --- /dev/null +++ b/addons/script_spliter/context/icons/split_rminus.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + split-screen + + + + + + + split-screen + + + + diff --git a/addons/script_spliter/context/icons/split_rminus.svg.import b/addons/script_spliter/context/icons/split_rminus.svg.import new file mode 100644 index 0000000..040a557 --- /dev/null +++ b/addons/script_spliter/context/icons/split_rminus.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bvjk4po8w2m2j" +path="res://.godot/imported/split_rminus.svg-6f9fc75a64032d6fe5bdcc9bc3bf399d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/split_rminus.svg" +dest_files=["res://.godot/imported/split_rminus.svg-6f9fc75a64032d6fe5bdcc9bc3bf399d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=8.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/script_spliter/context/icons/split_rplus.svg b/addons/script_spliter/context/icons/split_rplus.svg new file mode 100644 index 0000000..4e0bbb0 --- /dev/null +++ b/addons/script_spliter/context/icons/split_rplus.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + split-screen + + + + + + + + split-screen + + + + diff --git a/addons/script_spliter/context/icons/split_rplus.svg.import b/addons/script_spliter/context/icons/split_rplus.svg.import new file mode 100644 index 0000000..0848cc5 --- /dev/null +++ b/addons/script_spliter/context/icons/split_rplus.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://1sqajw0mikdj" +path="res://.godot/imported/split_rplus.svg-a26b8d20ca41f0ec060d5e021092eced.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/context/icons/split_rplus.svg" +dest_files=["res://.godot/imported/split_rplus.svg-a26b8d20ca41f0ec060d5e021092eced.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=8.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/script_spliter/context/menu_tool.gd b/addons/script_spliter/context/menu_tool.gd new file mode 100644 index 0000000..9bf07df --- /dev/null +++ b/addons/script_spliter/context/menu_tool.gd @@ -0,0 +1,81 @@ +@tool +extends Window +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +@export var _container : Node +@export var _custom_options : Control + +var _plugin : Object = null + +func _init_1() -> void: + if _container and _plugin: + var columns : int = _plugin.call(&"get_split_columns") + var rows : int = _plugin.call(&"get_split_rows") + set_split_value(columns, rows) + +func _ready() -> void: + if _custom_options: + _custom_options.visible = false + + if !visibility_changed.is_connected(_on_visibility_change): + visibility_changed.connect(_on_visibility_change) + + _init_1() + +func set_plugin(current_plugin : Object) -> void: + _plugin = current_plugin + +func _on_visibility_change() -> void: + if !visible: return + if !_plugin: + return + + _init_1() + +func enable_options() -> void: + var custom : CheckBox = _container.get_child(_container.get_child_count() - 1) + for c : Node in _container.get_children(): + if c is CheckBox: + c.button_pressed = false + + _custom_options.visible = true + custom.button_pressed = true + +func set_split_value(columns : int, rows : int) -> void: + var current : Node = null + var custom : CheckBox = _container.get_child(_container.get_child_count() - 1) + for c : Node in _container.get_children(): + if c is CheckBox: + if c.columns == columns and c.rows == rows: + current = c + c.button_pressed = true + continue + c.button_pressed = false + + if columns < 2 and rows < 2: + current = _container.get_child(0) + if current is CheckBox: + current.button_pressed = true + else: + current = null + + _custom_options.visible = current == null + custom.button_pressed = _custom_options.visible + _custom_options.set_values(columns, rows) + +func _on_ok_pressed() -> void: + var columns : int = _custom_options.get_columns_value() + var rows : int = _custom_options.get_rows_value() + if !_plugin: + push_error("[ERROR] Can not set split type!") + else: + _plugin.call(&"set_type_split", columns, rows) + hide() + +func _on_cancel_pressed() -> void: + hide() diff --git a/addons/script_spliter/context/menu_tool.gd.uid b/addons/script_spliter/context/menu_tool.gd.uid new file mode 100644 index 0000000..ad9ccaf --- /dev/null +++ b/addons/script_spliter/context/menu_tool.gd.uid @@ -0,0 +1 @@ +uid://4wllvh127dwh diff --git a/addons/script_spliter/context/menu_tool.tscn b/addons/script_spliter/context/menu_tool.tscn new file mode 100644 index 0000000..67ff322 --- /dev/null +++ b/addons/script_spliter/context/menu_tool.tscn @@ -0,0 +1,226 @@ +[gd_scene load_steps=15 format=3 uid="uid://csu7djr8m1mgb"] + +[ext_resource type="Script" uid="uid://4wllvh127dwh" path="res://addons/script_spliter/context/menu_tool.gd" id="1_00j1l"] +[ext_resource type="Texture2D" uid="uid://tgaoyybc2iji" path="res://addons/script_spliter/assets/github_CodeNameTwister.png" id="2_bi1if"] +[ext_resource type="Texture2D" uid="uid://dmvcijsjhb5pc" path="res://addons/script_spliter/context/icons/sp_disable.png" id="2_le2a0"] +[ext_resource type="Script" uid="uid://bobw4q6hrbbox" path="res://addons/script_spliter/context/split_type_button.gd" id="3_h7rbp"] +[ext_resource type="Texture2D" uid="uid://c1kjfqirfexvp" path="res://addons/script_spliter/context/icons/sp_2H.png" id="3_o7fne"] +[ext_resource type="Texture2D" uid="uid://d1r72ixdgbwl6" path="res://addons/script_spliter/context/icons/sp_2V.png" id="4_js2dr"] +[ext_resource type="Texture2D" uid="uid://32xnl4cu46pj" path="res://addons/script_spliter/context/icons/sp_3H.png" id="5_h32ac"] +[ext_resource type="Texture2D" uid="uid://b4cmfno0ixqnm" path="res://addons/script_spliter/context/icons/sp_3V.png" id="6_h7rbp"] +[ext_resource type="Texture2D" uid="uid://bf2bjkoock7re" path="res://addons/script_spliter/context/icons/sp_4S.png" id="7_bi1if"] +[ext_resource type="Texture2D" uid="uid://bdxvp5dyj8y0r" path="res://addons/script_spliter/context/icons/sp_custom.png" id="10_0n25h"] +[ext_resource type="Script" uid="uid://y3jbguu2nw5c" path="res://addons/script_spliter/context/custom_options.gd" id="11_2o3ku"] + +[sub_resource type="LabelSettings" id="LabelSettings_00j1l"] +font_size = 28 +outline_size = 4 +outline_color = Color(0, 0, 0, 1) + +[sub_resource type="LabelSettings" id="LabelSettings_2o3ku"] +font_size = 12 +font_color = Color(1, 1, 1, 0.4) + +[sub_resource type="LabelSettings" id="LabelSettings_0n25h"] +font_size = 12 + +[node name="MenuTool" type="PopupPanel" node_paths=PackedStringArray("_container", "_custom_options")] +title = "Script Splitter Menu" +position = Vector2i(0, 36) +size = Vector2i(602, 382) +visible = true +script = ExtResource("1_00j1l") +_container = NodePath("MarginContainer/MenContainer/Body") +_custom_options = NodePath("MarginContainer/MenContainer/COptions") + +[node name="BG" type="ColorRect" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 4.0 +offset_top = 4.0 +offset_right = -4.0 +offset_bottom = -4.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.249011, 0.114569, 0.435571, 1) + +[node name="BGTX" type="TextureRect" parent="."] +modulate = Color(1, 1, 1, 0.34902) +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 4.0 +offset_top = 4.0 +offset_right = -4.0 +offset_bottom = -4.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("2_bi1if") +stretch_mode = 3 + +[node name="MarginContainer" type="MarginContainer" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 4.0 +offset_top = 4.0 +offset_right = -4.0 +offset_bottom = -4.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 4 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 4 +theme_override_constants/margin_bottom = 4 + +[node name="MenContainer" type="VBoxContainer" parent="MarginContainer"] +layout_mode = 2 + +[node name="PanelContainer2" type="PanelContainer" parent="MarginContainer/MenContainer"] +layout_mode = 2 + +[node name="Tittle" type="Label" parent="MarginContainer/MenContainer/PanelContainer2"] +layout_mode = 2 +text = "Menu Split Selection" +label_settings = SubResource("LabelSettings_00j1l") +horizontal_alignment = 1 +uppercase = true + +[node name="Label" type="Label" parent="MarginContainer/MenContainer"] +visible = false +layout_mode = 2 +text = "Version 0.2 +Rows are created based on the maximum number of columns reached. +Example: If you want two vertical scripts, you must define a maximum of one column." +label_settings = SubResource("LabelSettings_2o3ku") +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="Body" type="GridContainer" parent="MarginContainer/MenContainer"] +layout_mode = 2 +size_flags_horizontal = 4 +size_flags_vertical = 6 +theme_override_constants/h_separation = 8 +theme_override_constants/v_separation = 8 +columns = 2 + +[node name="splited_off" type="CheckBox" parent="MarginContainer/MenContainer/Body"] +layout_mode = 2 +tooltip_text = "Disabled Splited" +button_pressed = true +text = "Disabled" +icon = ExtResource("2_le2a0") +script = ExtResource("3_h7rbp") + +[node name="splited_two_horizontal" type="CheckBox" parent="MarginContainer/MenContainer/Body"] +layout_mode = 2 +tooltip_text = "Two Horizontal Splited" +text = "Two Horizontal" +icon = ExtResource("3_o7fne") +script = ExtResource("3_h7rbp") +columns = 2 +rows = 1 + +[node name="splited_two_vertical" type="CheckBox" parent="MarginContainer/MenContainer/Body"] +layout_mode = 2 +tooltip_text = "Two Vertical Splited" +text = "Two Vertical" +icon = ExtResource("4_js2dr") +script = ExtResource("3_h7rbp") +columns = 1 +rows = 2 + +[node name="splited_three_horizontal" type="CheckBox" parent="MarginContainer/MenContainer/Body"] +layout_mode = 2 +tooltip_text = "Three Horizontal Splited" +text = "Three Horizontal" +icon = ExtResource("5_h32ac") +script = ExtResource("3_h7rbp") +columns = 3 +rows = 1 + +[node name="splited_three_vertical" type="CheckBox" parent="MarginContainer/MenContainer/Body"] +layout_mode = 2 +tooltip_text = "Three Vertical Splited" +text = "Three Vertical" +icon = ExtResource("6_h7rbp") +script = ExtResource("3_h7rbp") +columns = 1 +rows = 3 + +[node name="splited_four_square" type="CheckBox" parent="MarginContainer/MenContainer/Body"] +layout_mode = 2 +tooltip_text = "Square Splited" +text = "Four Squared" +icon = ExtResource("7_bi1if") +script = ExtResource("3_h7rbp") +columns = 2 +rows = 2 + +[node name="CheckBox" type="CheckBox" parent="MarginContainer/MenContainer/Body"] +layout_mode = 2 +text = "Custom Split" +icon = ExtResource("10_0n25h") +script = ExtResource("3_h7rbp") +is_custom = true + +[node name="COptions" type="VBoxContainer" parent="MarginContainer/MenContainer" node_paths=PackedStringArray("columns", "rows")] +visible = false +layout_mode = 2 +script = ExtResource("11_2o3ku") +columns = NodePath("ValueOptions/ColumnsValue") +rows = NodePath("ValueOptions/RowsValue") + +[node name="Label" type="Label" parent="MarginContainer/MenContainer/COptions"] +layout_mode = 2 +text = "Custom Split Options" +label_settings = SubResource("LabelSettings_0n25h") +horizontal_alignment = 1 + +[node name="TextureRect" type="TextureRect" parent="MarginContainer/MenContainer/COptions"] +layout_mode = 2 +texture = ExtResource("10_0n25h") +expand_mode = 1 +stretch_mode = 5 + +[node name="ValueOptions" type="HBoxContainer" parent="MarginContainer/MenContainer/COptions"] +layout_mode = 2 + +[node name="ColumnsValue" type="SpinBox" parent="MarginContainer/MenContainer/COptions/ValueOptions"] +layout_mode = 2 +size_flags_horizontal = 3 +min_value = 1.0 +max_value = 30.0 +value = 1.0 +alignment = 1 +prefix = "Columns" + +[node name="RowsValue" type="SpinBox" parent="MarginContainer/MenContainer/COptions/ValueOptions"] +layout_mode = 2 +size_flags_horizontal = 3 +min_value = 1.0 +max_value = 30.0 +value = 1.0 +alignment = 1 +prefix = "Rows" + +[node name="Separator" type="HSeparator" parent="MarginContainer/MenContainer"] +layout_mode = 2 +size_flags_vertical = 8 + +[node name="Footer" type="HBoxContainer" parent="MarginContainer/MenContainer"] +layout_mode = 2 + +[node name="OK" type="Button" parent="MarginContainer/MenContainer/Footer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Accept" + +[node name="Cancel" type="Button" parent="MarginContainer/MenContainer/Footer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Exit" + +[connection signal="pressed" from="MarginContainer/MenContainer/Footer/OK" to="." method="_on_ok_pressed"] +[connection signal="pressed" from="MarginContainer/MenContainer/Footer/Cancel" to="." method="_on_cancel_pressed"] diff --git a/addons/script_spliter/context/panel_preview.tscn b/addons/script_spliter/context/panel_preview.tscn new file mode 100644 index 0000000..105f74d --- /dev/null +++ b/addons/script_spliter/context/panel_preview.tscn @@ -0,0 +1,26 @@ +[gd_scene format=3 uid="uid://di83u5ac2jww6"] + +[node name="PanelPreview" type="ColorRect"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(1.27546e-06, 0.644043, 0.17534, 0.4) + +[node name="Label" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -44.5 +offset_top = -11.5 +offset_right = 44.5 +offset_bottom = 11.5 +grow_horizontal = 2 +grow_vertical = 2 +text = "DROP HERE" +horizontal_alignment = 1 +vertical_alignment = 1 diff --git a/addons/script_spliter/context/split_type_button.gd b/addons/script_spliter/context/split_type_button.gd new file mode 100644 index 0000000..7bee02f --- /dev/null +++ b/addons/script_spliter/context/split_type_button.gd @@ -0,0 +1,24 @@ +@tool +extends CheckBox +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +## V0.2 Used now as max columns by row!, 0 as infinite horizontal. +@export var columns : int = 0 +## V0.2: Used now only as extra container if row > 1 +@export var rows : int = 0 + +@export var is_custom : bool = false + +func _pressed() -> void: + if is_custom: + if owner.has_method(&"enable_options"): + owner.call(&"enable_options") + else: + if owner.has_method(&"set_split_value"): + owner.call(&"set_split_value", columns, rows) diff --git a/addons/script_spliter/context/split_type_button.gd.uid b/addons/script_spliter/context/split_type_button.gd.uid new file mode 100644 index 0000000..57afbbf --- /dev/null +++ b/addons/script_spliter/context/split_type_button.gd.uid @@ -0,0 +1 @@ +uid://bobw4q6hrbbox diff --git a/addons/script_spliter/core/DDContainer.gd b/addons/script_spliter/core/DDContainer.gd new file mode 100644 index 0000000..99c0248 --- /dev/null +++ b/addons/script_spliter/core/DDContainer.gd @@ -0,0 +1,142 @@ +@tool +extends TabContainer +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +@warning_ignore("unused_signal") +signal on_dragging(e : Control) +signal out_dragging(e : Control) + +const DDTAB : Script = preload("res://addons/script_spliter/core/DDTAB.gd") + +var _buffer_editors : Array[Object] = [] + +#static var _tab_focus : StyleBox = null +#static var _tab_disabled : StyleBox = null +#static var _tab_selected : StyleBox = null +#static var _tab_hovered : StyleBox = null +#static var _tab_unselected : StyleBox = null + +func _config_tab(_tab : StyleBox) -> void: + if _tab is StyleBoxFlat: + _tab.skew.x = 0.5 + _tab.border_color = Color.AQUA + #_tab.border_width_left = 0.0 + #_tab.border_width_right = 0.0 + #_tab.border_width_top = 0.0 + #_tab.border_width_bottom = 0.1 + +func _ready() -> void: + pass + #var root : Control = EditorInterface.get_base_control() + #if root: + #if _tab_focus == null: + #_tab_focus = root.get_theme_stylebox(&"panel", &"tab_focus") + #if _tab_focus is StyleBoxFlat: + #_tab_focus = _tab_focus.duplicate() + #_config_tab(_tab_focus) + #if _tab_disabled == null: + #_tab_disabled = root.get_theme_stylebox(&"panel", &"tab_disabled") + #if _tab_disabled is StyleBoxFlat: + #_tab_disabled = _tab_disabled.duplicate() + #_config_tab(_tab_disabled) + #if _tab_selected == null: + #_tab_selected = root.get_theme_stylebox(&"panel", &"tab_selected") + #if _tab_selected is StyleBoxFlat: + #_tab_selected = _tab_selected.duplicate() + #_config_tab(_tab_selected) + #if _tab_hovered == null: + #_tab_hovered = root.get_theme_stylebox(&"panel", &"tab_hovered") + #if _tab_hovered is StyleBoxFlat: + #_tab_hovered = _tab_hovered.duplicate() + #_config_tab(_tab_hovered) + #if _tab_unselected == null: + #_tab_unselected = root.get_theme_stylebox(&"panel", &"tab_unselected") + #if _tab_unselected is StyleBoxFlat: + #_tab_unselected = _tab_unselected.duplicate() + #_config_tab(_tab_unselected) + #set(&"theme_override_styles/tab_focus", _tab_focus) + #set(&"theme_override_styles/tab_disabled", _tab_disabled) + #set(&"theme_override_styles/tab_selected", _tab_selected) + #set(&"theme_override_styles/tab_hovered", _tab_hovered) + #set(&"theme_override_styles/tab_unselected", _tab_unselected) + +func reset() -> void: + for x : Node in get_children(true): + if x is TabBar: + if x.get_script() == DDTAB: + x.reset() + +func clear_editors() -> void: + _buffer_editors.clear() + +func add_editor(o : Object, limit : int) -> Object: + if is_instance_valid(o): + if limit > 0: + var i : int = _buffer_editors.find(o) + if i > -1: + _buffer_editors.remove_at(i) + _buffer_editors.append(o) + if limit > -1: + while _buffer_editors.size() > limit: + _buffer_editors.remove_at(0) + return o + +func remove_editor(o : Object) -> void: + _buffer_editors.erase(o) + +func backward_editor() -> Object: + if _buffer_editors.size() > 1: + var o : Variant = _buffer_editors.pop_back() + while !is_instance_valid(o) and _buffer_editors.size() > 0: + o = _buffer_editors.pop_back() + if is_instance_valid(o): + _buffer_editors.push_front(o) + return o + return null + +func forward_editor() -> Object: + if _buffer_editors.size() > 1: + var o : Object = _buffer_editors.pop_front() + while !is_instance_valid(o) and _buffer_editors.size() > 0: + o = _buffer_editors.pop_front() + if is_instance_valid(o): + _buffer_editors.push_back(o) + return o + return null + + +func _on_child(n : Node) -> void: + if n is TabBar: + if n.get_script() != DDTAB: + n.set_script(DDTAB) + + if !n.on_start_drag.is_connected(_on_start_drag): + n.on_start_drag.connect(_on_start_drag) + if !n.on_stop_drag.is_connected(_on_stop_drag): + n.on_stop_drag.connect(_on_stop_drag) + +func _out_child(n : Node) -> void: + if n is TabBar: + + if n.on_start_drag.is_connected(_on_start_drag): + n.on_start_drag.disconnect(_on_start_drag) + if n.on_stop_drag.is_connected(_on_stop_drag): + n.on_stop_drag.disconnect(_on_stop_drag) + if n.get_script() == DDTAB: + n.set_script(null) + +func _on_stop_drag(tab : TabBar) -> void: + out_dragging.emit(tab) + +func _on_start_drag(tab : TabBar) -> void: + on_dragging.emit(tab) + +func _init() -> void: + child_entered_tree.connect(_on_child) + child_exiting_tree.connect(_out_child) diff --git a/addons/script_spliter/core/DDContainer.gd.uid b/addons/script_spliter/core/DDContainer.gd.uid new file mode 100644 index 0000000..672dee0 --- /dev/null +++ b/addons/script_spliter/core/DDContainer.gd.uid @@ -0,0 +1 @@ +uid://chk1nts3d41v8 diff --git a/addons/script_spliter/core/DDItem.gd b/addons/script_spliter/core/DDItem.gd new file mode 100644 index 0000000..2933695 --- /dev/null +++ b/addons/script_spliter/core/DDItem.gd @@ -0,0 +1,59 @@ +@tool +extends ItemList +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + +signal on_start_drag(t : ItemList) +signal on_stop_drag(t : ItemList) + +var is_drag : bool = false: + set(e): + is_drag = e + if is_drag: + Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN) + else: + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) + +var _fms : float = 0.0 + +func _init() -> void: + if is_node_ready(): + _ready() + +func _ready() -> void: + set_process(false) + setup() + +func _process(delta: float) -> void: + _fms += delta + if _fms > 0.24: + if is_drag: + if !Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): + set_process(false) + is_drag = false + on_stop_drag.emit(self) + else: + on_start_drag.emit(self) + is_drag = true + +func setup() -> void: + if !gui_input.is_connected(_on_input): + gui_input.connect(_on_input) + +func _on_input(e : InputEvent) -> void: + if e is InputEventMouseButton: + if e.button_index == 1: + if e.pressed: + _fms = 0.0 + is_drag = false + set_process(true) + else: + set_process(false) + if _fms >= 0.24: + on_stop_drag.emit(self) diff --git a/addons/script_spliter/core/DDItem.gd.uid b/addons/script_spliter/core/DDItem.gd.uid new file mode 100644 index 0000000..38314ad --- /dev/null +++ b/addons/script_spliter/core/DDItem.gd.uid @@ -0,0 +1 @@ +uid://ci8kq81lonwua diff --git a/addons/script_spliter/core/DDTAB.gd b/addons/script_spliter/core/DDTAB.gd new file mode 100644 index 0000000..feeef08 --- /dev/null +++ b/addons/script_spliter/core/DDTAB.gd @@ -0,0 +1,76 @@ +@tool +extends TabBar +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + +signal on_start_drag(t : TabBar) +signal on_stop_drag(t : TabBar) + +var is_drag : bool = false: + set(e): + is_drag = e + if is_drag: + Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN) + else: + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) + +var _fms : float = 0.0 + +func reset() -> void: + if is_drag: + set_process(false) + is_drag = false + if is_inside_tree(): + on_stop_drag.emit(null) + +func _init() -> void: + if is_node_ready(): + _ready() + +func _ready() -> void: + set_process(false) + setup() + +func _enter_tree() -> void: + if !is_in_group(&"__SPLITER_TAB__"): + add_to_group(&"__SPLITER_TAB__") + +func _exit_tree() -> void: + if is_in_group(&"__SPLITER_TAB__"): + remove_from_group(&"__SPLITER_TAB__") + +func _process(delta: float) -> void: + _fms += delta + if _fms > 0.24: + if is_drag: + if !Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): + set_process(false) + is_drag = false + on_stop_drag.emit(self) + else: + on_start_drag.emit(self) + is_drag = true + +func setup() -> void: + if !gui_input.is_connected(_on_input): + gui_input.connect(_on_input) + if !is_in_group(&"__SPLITER_TAB__"): + add_to_group(&"__SPLITER_TAB__") + +func _on_input(e : InputEvent) -> void: + if e is InputEventMouseButton: + if e.button_index == 1: + is_drag = false + if e.pressed: + _fms = 0.0 + set_process(true) + else: + set_process(false) + if _fms >= 0.24: + on_stop_drag.emit(self) diff --git a/addons/script_spliter/core/DDTAB.gd.uid b/addons/script_spliter/core/DDTAB.gd.uid new file mode 100644 index 0000000..8d6939d --- /dev/null +++ b/addons/script_spliter/core/DDTAB.gd.uid @@ -0,0 +1 @@ +uid://cma5va5lbj5it diff --git a/addons/script_spliter/core/DaemonChaser.gd b/addons/script_spliter/core/DaemonChaser.gd new file mode 100644 index 0000000..9757942 --- /dev/null +++ b/addons/script_spliter/core/DaemonChaser.gd @@ -0,0 +1,44 @@ +@tool +extends Node +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +var callback : Callable +var end_callback : Callable +var index : int = 0 +var back_to : int = 0 +var buffer : Dictionary + +func set_current_index(current : int) -> void: + back_to = current + +func run(new_callback : Callable, new_end_callback : Callable) -> void: + callback = new_callback + end_callback = new_end_callback + index = 0 + set_process(true) + +func _ready() -> void: + set_process(false) + +func _back() -> void: + if callback.is_valid(): + callback.call(back_to, false) + +func update_index() -> int: + index = callback.call(index, true) + return index + +func _process(__: float) -> void: + if !callback.is_valid() or 0 > update_index(): + set_process(false) + _back() + if end_callback.is_valid(): + end_callback.call(buffer) + buffer = {} + return + index += 1 diff --git a/addons/script_spliter/core/DaemonChaser.gd.uid b/addons/script_spliter/core/DaemonChaser.gd.uid new file mode 100644 index 0000000..e166a9f --- /dev/null +++ b/addons/script_spliter/core/DaemonChaser.gd.uid @@ -0,0 +1 @@ +uid://dbiugbnirptj8 diff --git a/addons/script_spliter/core/EditorContainer.gd b/addons/script_spliter/core/EditorContainer.gd new file mode 100644 index 0000000..52c5cfa --- /dev/null +++ b/addons/script_spliter/core/EditorContainer.gd @@ -0,0 +1,43 @@ +@tool +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +extends "res://addons/script_spliter/core/ui/multi_split_container.gd" + +const PREVIEW : PackedScene = preload("res://addons/script_spliter/context/panel_preview.tscn") + +var preview : Control = null + +func get_total_containers() -> int: + var total : int = 0 + for x : Node in get_children(): + if x is SplitContainerItem: + if x.get_child_count() > 0: + total += 1 + return total + +func _notification(what: int) -> void: + if what == NOTIFICATION_PREDELETE: + if is_instance_valid(preview) and !preview.is_queued_for_deletion(): + preview.queue_free() + +func make_split_container_item() -> Control: + var x : SplitContainerItem = SplitContainerItem.new() + x.size_flags_horizontal = Control.SIZE_FILL + x.size_flags_vertical = Control.SIZE_FILL + x.custom_minimum_size = Vector2.ZERO + x.clip_contents = true + x.visible = false + return x + +func has_items() -> bool: + return get_child_count() > 0 + +func is_split_container_item(x : Object) -> bool: + return x is SplitContainerItem + diff --git a/addons/script_spliter/core/EditorContainer.gd.uid b/addons/script_spliter/core/EditorContainer.gd.uid new file mode 100644 index 0000000..f5b5723 --- /dev/null +++ b/addons/script_spliter/core/EditorContainer.gd.uid @@ -0,0 +1 @@ +uid://ds3bvm7nwsq2s diff --git a/addons/script_spliter/core/builder.gd b/addons/script_spliter/core/builder.gd new file mode 100644 index 0000000..d420bab --- /dev/null +++ b/addons/script_spliter/core/builder.gd @@ -0,0 +1,2355 @@ +@tool +extends Object +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +const EditorContainer : Script = preload("res://addons/script_spliter/core/EditorContainer.gd") +const DD : Script = preload("res://addons/script_spliter/core/DDContainer.gd") +const DDO : PackedScene = preload("res://addons/script_spliter/core/ui/dd.tscn") +const DDITEM : Script = preload("res://addons/script_spliter/core/DDItem.gd") + +#region POPSC +const FLYING_SCRIPT : PackedScene = preload("res://addons/script_spliter/context/flying_script.tscn") +const _POP_SCRIPT_PLACEHOLDER : String = "_POPGDScript_" +var _pop_scripts : Array[Window] = [] +var _pop_script_placeholder : bool = false +#endregion + +const GLOBALS : PackedStringArray = ["_GlobalScope", "_GDScript"] + +var _plugin : Node = null + +var _root : Node = null +var _main : EditorContainer = null +var _container : Root = null +var _editor : TabContainer = null + +var _code_editors : Array[Mickeytools] = [] + +var _last_local_tool : Mickeytools = null +var _last_tool : Mickeytools = null: + set(e): + _last_tool = e + if is_instance_valid(_last_tool): + if !_last_tool.is_floating(): + _last_local_tool = _last_tool + +var _tweener : ReTweener = null +var _item_list : ItemList = null: + set(e): + + if e == null and is_instance_valid(_item_list): + if _item_list.has_signal(&"on_start_drag") and _item_list.is_connected(&"on_start_drag", _on_drag): + _item_list.disconnect(&"on_start_drag", _on_drag) + if _item_list.has_signal(&"on_stop_drag") and _item_list.is_connected(&"on_stop_drag", _out_drag): + _item_list.disconnect(&"on_stop_drag", _out_drag) + + if _item_list.get_script() == DDITEM: + _item_list.set_script(null) + _item_list = null + else: + _item_list = e + if is_instance_valid(_item_list) and _item_list.get_script() != DDITEM: + _item_list.set_script(DDITEM) + + if _item_list.has_signal(&"on_start_drag") and !_item_list.is_connected(&"on_start_drag", _on_drag): + _item_list.connect(&"on_start_drag", _on_drag) + if _item_list.has_signal(&"on_stop_drag") and !_item_list.is_connected(&"on_stop_drag", _out_drag): + _item_list.connect(&"on_stop_drag", _out_drag) + + + get: + if !is_instance_valid(_item_list): + var script_editor: ScriptEditor = EditorInterface.get_script_editor() + var items : Array[Node] = script_editor.find_children("*", "ItemList", true, false) + if items.size() > 0: + _item_list = items[0] + else: + push_warning("[Script-Spliter] Can not find item list!") + return _item_list + +#region __CONFIG__ +var _SPLIT_USE_HIGHLIGHT_SELECTED : bool = true +var _MINIMAP_4_UNFOCUS_WINDOW : bool = false + +var _SPLIT_HIGHLIGHT_COLOR : Color = Color.MEDIUM_SLATE_BLUE + +var _SEPARATOR_LINE_SIZE : int = 8 +var _SEPARATOR_LINE_COLOR : Color = Color.MAGENTA +var _SEPARATOR_BUTTON_SIZE : int = 19 +var _SEPARATOR_BUTTON_MODULATE : Color = Color.WHITE +var _SEPARATOR_BUTTON_ICON : String = "res://addons/script_spliter/context/icons/expand.svg" + +var _SEPARATOR_LINE_MOVEMENT : bool = true +var _SEPARATOR_LINE_DOUBLE_CLICK : bool = true + +var _BEHAVIOUR_CAN_EXPAND_ON_FOCUS : bool = true +var _BEHAVIOUR_CAN_EXPAND_SAME_ON_FOCUS : bool = false + +var _SEPARATOR_SMOOTH_EXPAND : bool = true +var _SEPARATOR_SMOOTH_EXPAND_TIME : float = 0.24 + +var _OUT_FOCUS_COLORED : bool = true +var _UNFOCUS_COLOR : Color = Color.GRAY + +var _SWAP_BY_BUTTON : bool = true + +#region _9_ +var HANDLE_BACK_FORWARD_BUTTONS : bool = true +var HANDLE_BACKWARD_FORWARD_AS_NEXT_BACK_TAB : bool = false +var HANDLE_BACK_FORWARD_BUFFER : int = 20 +var USE_NATIVE_ON_NOT_TABS : bool = true +var _HANDLE_BACKWARD_KEY_PATH : String = "res://addons/script_spliter/io/backward_key_button.tres" +var _HANDLE_FORWARD_KEY_PATH : String = "res://addons/script_spliter/io/forward_key_button.tres" +var _HANDLE_BACKWARD_MOUSE_BUTTON_PATH : String = "res://addons/script_spliter/io/backward_mouse_button.tres" +var _HANDLE_FORWARD_MOUSE_BUTTON_PATH : String = "res://addons/script_spliter/io/forward_mouse_button.tres" +#endregion + +# CURRENT CONFIG +var current_columns : int = 1 +var current_rows : int = 1 + +# FLAG +var _chaser_enabled : bool = false +var _focus_queue : bool = false + +# REF +var _wm : Window = null + +var is_dd_handled : bool = false +var _last_dd_root : Control = null +var _ddo : Control = null + +signal tool_added(tool : Mickeytools) + +func _get_data_cfg() -> Array[Array]: + const CFG : Array[Array] = [ + [&"plugin/script_spliter/window/use_highlight_selected", &"_SPLIT_USE_HIGHLIGHT_SELECTED"] + ,[&"plugin/script_spliter/window/highlight_selected_color",&"_SPLIT_HIGHLIGHT_COLOR"] + + ,[&"plugin/script_spliter/editor/minimap_for_unfocus_window", &"_MINIMAP_4_UNFOCUS_WINDOW"] + ,[&"plugin/script_spliter/editor/out_focus_color_enabled", &"_OUT_FOCUS_COLORED"] + ,[&"plugin/script_spliter/editor/out_focus_color_value", &"_UNFOCUS_COLOR"] + ,[&"plugin/script_spliter/editor/split/reopen_last_closed_editor_on_add_split", &"_SHOULD_OPEN_CLOSED_EDITOR_SCRIPT"] + ,[&"plugin/script_spliter/editor/split/remember_last_used_editor_buffer_size", &"_LAST_USED_EDITOR_SIZE"] + + ,[&"plugin/script_spliter/line/size", &"_SEPARATOR_LINE_SIZE"] + ,[&"plugin/script_spliter/line/color", &"_SEPARATOR_LINE_COLOR"] + ,[&"plugin/script_spliter/line/draggable", &"_SEPARATOR_LINE_MOVEMENT"] + ,[&"plugin/script_spliter/line/expand_by_double_click", &"_SEPARATOR_LINE_DOUBLE_CLICK"] + + ,[&"plugin/script_spliter/line/button/size", &"_SEPARATOR_BUTTON_SIZE"] + ,[&"plugin/script_spliter/line/button/modulate", &"_SEPARATOR_BUTTON_MODULATE"] + ,[&"plugin/script_spliter/line/button/icon_path", &"_SEPARATOR_BUTTON_ICON"] + + ,[&"plugin/script_spliter/editor/behaviour/expand_on_focus", &"_BEHAVIOUR_CAN_EXPAND_ON_FOCUS"] + ,[&"plugin/script_spliter/editor/behaviour/can_expand_on_same_focus", &"_BEHAVIOUR_CAN_EXPAND_SAME_ON_FOCUS"] + ,[&"plugin/script_spliter/editor/behaviour/smooth_expand", &"_SEPARATOR_SMOOTH_EXPAND"] + ,[&"plugin/script_spliter/editor/behaviour/smooth_expand_time", &"_SEPARATOR_SMOOTH_EXPAND_TIME"] + ,[&"plugin/script_spliter/editor/behaviour/swap_by_double_click_separator_button", &"_SWAP_BY_BUTTON"] + ,[&"plugin/script_spliter/editor/behaviour/back_and_forward/handle_back_and_forward", &"HANDLE_BACK_FORWARD_BUTTONS"] + ,[&"plugin/script_spliter/editor/behaviour/back_and_forward/history_size", &"HANDLE_BACK_FORWARD_BUFFER"] + ,[&"plugin/script_spliter/editor/behaviour/back_and_forward/using_as_next_and_back_tab", &"HANDLE_BACKWARD_FORWARD_AS_NEXT_BACK_TAB"] + ,[&"plugin/script_spliter/editor/behaviour/back_and_forward/backward_key_button_path", &"_HANDLE_BACKWARD_KEY_PATH"] + ,[&"plugin/script_spliter/editor/behaviour/back_and_forward/forward_key_button_path", &"_HANDLE_FORWARD_KEY_PATH"] + ,[&"plugin/script_spliter/editor/behaviour/back_and_forward/backward_mouse_button_path", &"_HANDLE_BACKWARD_MOUSE_BUTTON_PATH"] + ,[&"plugin/script_spliter/editor/behaviour/back_and_forward/forward_mouse_button_path", &"_HANDLE_FORWARD_MOUSE_BUTTON_PATH"] + ,[&"plugin/script_spliter/editor/behaviour/back_and_forward/use_native_handler_when_there_are_no_more_tabs", &"USE_NATIVE_ON_NOT_TABS"] + ] + return CFG + +func _on_wm_foucs() -> void: + if !is_instance_valid(_last_tool) or _last_tool.is_floating(): + if is_instance_valid(_last_local_tool): + _last_local_tool.focus.emit(_last_local_tool) + else: + for x : Mickeytools in _code_editors: + if !x.is_floating(): + x.focus.emit(x) + return + +func _out_wm_focus() -> void: + return + +func show_dd(root : Control) -> void: + var dd : Control = null + for xx : Node in _main.get_children(): + if xx is Control and !xx.visible: + continue + for x : Node in xx.get_children(): + if x is Control and x.visible: + var mp : Vector2i = x.get_global_mouse_position() + if x.get_global_rect().has_point(mp): + dd = xx + break + if dd == null or _last_dd_root == dd: + return + _last_dd_root = dd + + var node : Node = _last_tool.get_root() + + if node == root: + return + if node: + if dd.find_child(node.name, true, false) != null: + if is_instance_valid(_ddo): + var p : Node = _ddo.get_parent() + if p: + p.remove_child(_ddo) + return + if !is_instance_valid(_ddo): + _ddo = DDO.instantiate() + else: + var p : Node = _ddo.get_parent() + if p: + p.remove_child(_ddo) + dd.add_child(_ddo) + _ddo.visible = true + +func set_item_list(o : ItemList) -> void: + _item_list = o + +func init_1() -> void: + var settings : EditorSettings = EditorInterface.get_editor_settings() + var vp : Viewport = _plugin.get_viewport() + if vp: + _wm = vp.get_window() + + if !_wm.focus_entered.is_connected(_on_wm_foucs): + _wm.focus_entered.connect(_on_wm_foucs) + if !_wm.focus_exited.is_connected(_out_wm_focus): + _wm.focus_exited.connect(_out_wm_focus) + + + for x : Array in _get_data_cfg(): + if !settings.has_setting(x[0]): + settings.set_setting(x[0], get(x[1])) + else: + set(x[1], settings.get_setting(x[0])) + + settings.add_property_info({ + "name": &"plugin/script_spliter/window/highlight_selected_color", + "type": TYPE_COLOR + }) + settings.add_property_info({ + "name": &"plugin/script_spliter/line/button/modulate", + "type": TYPE_COLOR + }) +#endregion + +#region _FEATURE#5_ +var _SHOULD_OPEN_CLOSED_EDITOR_SCRIPT : bool = false +var _LAST_USED_EDITOR_SIZE : int = 4 + +var _lifo_src : PackedStringArray = [] + +func add_last_script_used(src : String) -> void: + if _LAST_USED_EDITOR_SIZE > 0: + if src.is_empty(): + return + + var x : int = _lifo_src.find(src) + if x > -1: + _lifo_src.remove_at(x) + + _lifo_src.append(src) + var total : int = maxi(_LAST_USED_EDITOR_SIZE, 0) + while _lifo_src.size() > total: + _lifo_src.remove_at(0) + +func get_last_script_used() -> String: + var size : int = _lifo_src.size() + var result : String = "" + if size > 0: + size -= 1 + result = _lifo_src[size] + _lifo_src.remove_at(size) + return result +#region + +func update_config() -> void: + var settings : EditorSettings = EditorInterface.get_editor_settings() + var changes : PackedStringArray = settings.get_changed_settings() + + var _dirty_colored : bool = _OUT_FOCUS_COLORED + + for x : Array in _get_data_cfg(): + if x[0] in changes: + set(x[1], settings.get_setting(x[0])) + + _update_container() + + if _dirty_colored and !_OUT_FOCUS_COLORED: + for x : Mickeytools in _code_editors: + var gui : Node = x.get_control() + if is_instance_valid(gui) and gui is Control: + gui.modulate = Color.WHITE + + for x : String in changes: + if "button_path" in x: + if !InputMap.has_action(&"ui_script_spliter_forward"): + InputMap.add_action(&"ui_script_spliter_forward") + else: + InputMap.action_erase_events(&"ui_script_spliter_forward") + + var key_0 : InputEventKey = ResourceLoader.load(_HANDLE_FORWARD_KEY_PATH) + var key_1 : InputEventMouseButton = ResourceLoader.load(_HANDLE_FORWARD_MOUSE_BUTTON_PATH) + InputMap.action_add_event(&"ui_script_spliter_forward", key_0) + InputMap.action_add_event(&"ui_script_spliter_forward", key_1) + + if !InputMap.has_action(&"ui_script_spliter_backward"): + InputMap.add_action(&"ui_script_spliter_backward") + else: + InputMap.action_erase_events(&"ui_script_spliter_backward") + + key_0 = ResourceLoader.load(_HANDLE_BACKWARD_KEY_PATH) + key_1 = ResourceLoader.load(_HANDLE_BACKWARD_MOUSE_BUTTON_PATH) + InputMap.action_add_event(&"ui_script_spliter_backward", key_0) + InputMap.action_add_event(&"ui_script_spliter_backward", key_1) + break + +func _update_container() -> void: + if !is_instance_valid(_main): + return + _main.separator_line_size = _SEPARATOR_LINE_SIZE + _main.separator_line_color = _SEPARATOR_LINE_COLOR + _main.drag_button_size = _SEPARATOR_BUTTON_SIZE + _main.drag_button_modulate = _SEPARATOR_BUTTON_MODULATE + _main.behaviour_expand_smoothed = _SEPARATOR_SMOOTH_EXPAND + _main.behaviour_expand_smoothed_time = _SEPARATOR_SMOOTH_EXPAND_TIME + _main.behaviour_expand_on_focus = _BEHAVIOUR_CAN_EXPAND_ON_FOCUS + _main.behaviour_can_expand_focus_same_container = _BEHAVIOUR_CAN_EXPAND_SAME_ON_FOCUS + _main.behaviour_expand_on_double_click = _SEPARATOR_LINE_DOUBLE_CLICK + _main.behaviour_can_move_by_line = _SEPARATOR_LINE_MOVEMENT + + if !_SEPARATOR_BUTTON_ICON.is_empty(): + if FileAccess.file_exists(_SEPARATOR_BUTTON_ICON): + var text : Variant = ResourceLoader.load(_SEPARATOR_BUTTON_ICON) + if text is Texture: + _main.drag_button_icon = text + else: + push_warning("[Script-Spliter] The resource is not a texture imported ", _SEPARATOR_BUTTON_ICON) + else: + push_warning("[Script-Spliter] Can not find the resource ", _SEPARATOR_BUTTON_ICON) + +func _init(plugin : Object) -> void: + _plugin = plugin + +func init_0() -> void: + if is_instance_valid(_tweener): + _tweener.clear() + _tweener = null + + if is_instance_valid(_ddo): + if !_ddo.is_queued_for_deletion(): + _ddo.queue_free() + + if is_instance_valid(_wm): + if _wm.focus_entered.is_connected(_on_wm_foucs): + _wm.focus_entered.disconnect(_on_wm_foucs) + if _wm.focus_exited.is_connected(_out_wm_focus): + _wm.focus_exited.disconnect(_out_wm_focus) + + if is_instance_valid(_editor): + if _editor.tree_exiting.is_connected(_on_container_exit): + _editor.tree_exiting.disconnect(_on_container_exit) + if _editor.tree_entered.is_connected(_on_container_entered): + _editor.tree_entered.disconnect(_on_container_entered) + + + if is_instance_valid(_root) and _root is Control: + if _root.item_rect_changed.is_connected(update_rect): + _root.item_rect_changed.disconnect(update_rect) + + for x : Mickeytools in _code_editors: + x.reset(false) + x.free() + _code_editors.clear() + + if is_instance_valid(_container): + var parent : Node = _container.get_parent() + _container.visible = false + if is_instance_valid(parent): + parent.remove_child(_container) + _container.queue_free() + + if is_instance_valid(_editor): + _setup(_editor, false) + _editor.visible = true + + _item_list = null + + for x : Window in _pop_scripts: + if is_instance_valid(x) and !x.is_queued_for_deletion(): + x.queue_free() + _pop_scripts.clear() + + +func _clear() -> void: + for z : int in range(_code_editors.size() - 1, -1 , -1): + var x : Mickeytools = _code_editors[z] + var dirty : bool = false + for e : Node in _editor.get_children(): + if x.is_equal(e): + dirty = true + break + if !dirty: + _code_editors[z].reset() + _code_editors.remove_at(z) + + for x : Window in _pop_scripts: + var node : Node = x.get_base_control() + for y : Node in node.get_children(): + var dirty : bool = false + for t : Mickeytools in _code_editors: + if t.get_control() == y: + dirty = true + if !dirty: + for zx : Node in _editor.get_children(): + if y == zx: + dirty = true + break + if dirty: + y.queue_free.call_deferred() + if node.get_child_count() < 1: + _pop_scripts.erase(x) + x.queue_free() + + for x : Node in _main.get_children(): + if x is TabContainer:continue + for y : Node in x.get_children(): + for z : Node in y.get_children(): + var dirty : bool = false + for t : Mickeytools in _code_editors: + if t.get_control() == z: + dirty = true + if !dirty: + for zx : Node in _editor.get_children(): + if z == zx: + dirty = true + break + if dirty: + z.queue_free.call_deferred() + else: + y.remove_child(z) + +func get_editors() -> Array[Mickeytools]: + return _code_editors + +func _get_editor_root() -> Node: + var aviable : Node = get_aviable() + if is_instance_valid(aviable): + return aviable + if is_instance_valid(_last_tool): + return _last_tool.get_root() + return null + +func get_last_tool() -> Mickeytools: + return _last_tool + +func update_info(root : TabContainer, index : int , src : String) -> void: + if !is_instance_valid(root): + return + var item_list : Control = _item_list + if !src.is_empty(): + if is_instance_valid(item_list): + var indx : int = -1 + for x : int in item_list.item_count: + if item_list.get_item_tooltip(x) == src: + indx = x + break + if indx > -1: + var text : String = _item_list.get_item_text(indx) + if text.is_empty() or text.begins_with("@"): + text = item_list.get_item_tooltip(index).get_file() + text = text.trim_suffix("(*)") + root.set_tab_title(index, text) + root.set_tab_icon(index, item_list.get_item_icon(indx)) + + + +class Root extends MarginContainer: + var _helper : Object = null + + func _init(helper : Object) -> void: + _helper = helper + + func _get_index(x : Mickeytools) -> int: + var gui : Control = x.get_gui() + if is_instance_valid(gui): + var root : Control = x.get_root() + if root: + root = root.get_parent() + if is_instance_valid(root): + return root.get_index() + return -1 + + func _fwrd() -> bool: + if _helper._chaser_enabled: + return true + + var tool : Mickeytools = _helper.get_last_tool() + if !is_instance_valid(tool): + return false + + var root : Variant = tool.get_root() + if !is_instance_valid(root): + return false + + if !_helper.HANDLE_BACKWARD_FORWARD_AS_NEXT_BACK_TAB: + for __ : int in range(0, 2): + if root == null: + return false + elif root.has_method(&"forward_editor"): + var o : Object = root.call(&"forward_editor") + if o and o.has_signal(&"focus"): + o.emit_signal(&"focus", o, false) + return true + return false + root = root.get_parent() + else: + var control : TabContainer = root + var count : int = control.get_tab_count() + if count > 1: + var current : int = wrapi(control.current_tab + 1, 0, count) + if current > -1 and current < control.get_child_count(): + var gui : Node = control.get_child(current) + for x : Mickeytools in _helper.get_editors(): + var ctrl : Control = x.get_control() + if gui == ctrl or gui.find_child(ctrl.name): + x.focus.emit.call_deferred(x) + return true + return false + + func _bkt() -> bool: + if _helper._chaser_enabled: + return false + var tool : Mickeytools = _helper.get_last_tool() + if !is_instance_valid(tool): + return false + + var root : Variant = tool.get_root() + if !is_instance_valid(root): + return false + + if !_helper.HANDLE_BACKWARD_FORWARD_AS_NEXT_BACK_TAB: + for __ : int in range(0, 2): + if root == null: + return false + elif root.has_method(&"backward_editor"): + var o : Object = root.call(&"backward_editor") + if o and o.has_signal(&"focus"): + o.emit_signal(&"focus", o, false) + return true + return false + root = root.get_parent() + else: + var control : TabContainer = root + var count : int = control.get_tab_count() + if count > 1: + var current : int = wrapi(control.current_tab - 1, 0, count) + if current > -1 and current < control.get_child_count(): + var gui : Node = control.get_child(current) + for x : Mickeytools in _helper.get_editors(): + var ctrl : Control = x.get_control() + if gui == ctrl or gui.find_child(ctrl.name): + x.focus.emit.call_deferred(x) + return true + return false + + func _input(event: InputEvent) -> void: + if _helper.HANDLE_BACK_FORWARD_BUTTONS: + if event.is_action_pressed(&"ui_script_spliter_backward"): + if _bkt() or !_helper.USE_NATIVE_ON_NOT_TABS: + event.alt_pressed = false + get_viewport().set_input_as_handled() + return + elif event.is_action_pressed(&"ui_script_spliter_forward"): + if _fwrd() or !_helper.USE_NATIVE_ON_NOT_TABS: + event.alt_pressed = false + get_viewport().set_input_as_handled() + if _helper.is_dd_handled: + _helper.show_dd(self) + +class Mickeytools extends Object: + signal focus(_self : Mickeytools) + signal tool_updated() + + var _helper : Object = null + + var _root : Node = null + var _parent : Node = null + var _reference : Node = null + var _control : Node = null + var _gui : Node = null + var _index : int = 0 + var _src : String = "" + + func set_src(src : String) -> void: + _src = src + + func get_src() -> String: + return _src + + func get_title_name() -> String: + if is_instance_valid(_reference): + if _reference.get_parent() != null: + return _helper.get_item_text(_src) + return "" + + func has_focus() -> bool: + if is_instance_valid(_reference): + if _reference.get_parent() != null: + return _helper.get_selected_item() == _reference.get_index() + return false + + func get_gui() -> Node: + return _gui + + func is_floating() -> bool: + return _root and _root.get_parent().owner is Window + + func grab_focus(should_grab_focus : bool) -> void: + var root : TabContainer = _root + if is_instance_valid(root) and is_instance_valid(_control): + if _control.get_parent() == null: + return + var index : int = _control.get_index() + if !_helper._chaser_enabled: + for x : Node in root.get_children(): + if x == _control: + if index > -1 and index < root.get_child_count(): + root.current_tab = index + break + + if should_grab_focus: + if is_instance_valid(_gui) and _gui.is_inside_tree(): + var control : Control = _gui + if control.focus_mode != Control.FOCUS_NONE: + control.grab_focus.call_deferred() + elif _control.focus_mode != Control.FOCUS_NONE: + _control.grab_focus.call_deferred() + + if is_instance_valid(_gui): + var vp : Viewport = _gui.get_viewport() + if is_instance_valid(vp): + var wm : Window = vp.get_window() + if wm and !wm.has_focus(): + wm.grab_focus() + + func get_origin() -> Node: + return _parent + + func get_control() -> Node: + return _control + + func get_root() -> Node: + return _root + + func get_reference() -> Node: + return _reference + + func is_equal(reference : Node) -> bool: + return _reference == reference + + func __hey_listen(c : Control, out : Array[CodeEdit]) -> bool: + if c is CodeEdit and out.size() > 0: + out[0] = c + return true + for x : Node in c.get_children(): + if __hey_listen(x, out): + return true + return false + + func _i_like_coffe() -> void: + focus.emit(self) + var tab : TabContainer = _root + + var parent : Node = tab.get_parent() + if parent and parent.has_method(&"show_splited_container"): + parent.call(&"show_splited_container") + + update() + _helper.update_queue() + + func _init(helper : Object, root : Node, control : Control) -> void: + _helper = helper + set_root(root) + set_reference(control) + + func set_root(root : Node) -> void: + if root != _root: + if is_instance_valid(_root): + if _root.has_method(&"remove_editor"): + _root.call(&"remove_editor", self) + _root = root + + func _context_update(window : Window, control : Control) -> void: + if is_instance_valid(window) and is_instance_valid(control) and is_instance_valid(_root): + var root : Viewport= _root.get_viewport() + var gvp : Vector2 = control.get_global_mouse_position() + gvp.x += (window.size.x/ 4.0) + gvp.y = min(gvp.y, root.size.y-window.size.y + 16.0) + gvp.x = min(gvp.x, root.size.x-window.size.x + 16.0) + + window.set_deferred(&"position", gvp) + + + + func _on_input(input : InputEvent) -> void: + if input is InputEventMouseMotion: + return + + if input is InputEventMouseButton: + if input.pressed and input.button_index == 2: + if _reference.get_child_count() > 1: + var variant : Node = _reference.get_child(1) + if variant is Window and _gui is Control: + _context_update.call_deferred(variant, _gui) + + if _helper.can_expand_same_focus(): + var tab : TabContainer = _root + + var parent : Node = tab.get_parent() + if parent and parent.has_method(&"show_splited_container"): + parent.call(&"show_splited_container") + + func _on_symb(symbol: String, line : int, column: int, edit : CodeEdit = null) -> void: + const BREAKERS : PackedStringArray = [" ", "\n", "\t"] + if edit: + var txt : String = edit.get_text_for_symbol_lookup() + if !txt.is_empty(): + var pck : PackedStringArray = txt.split('\n') + if column > -1 and line > -1 and pck.size() > line: + var cline : String = pck[line] + while column > -1: + var _char : String = cline[column] + if _char in BREAKERS: + break + if _char == "@": + symbol = str("@", symbol) + break + column -= 1 + _helper.set_search_symbol(symbol) + + func set_reference(control : Node) -> void: + if !is_instance_valid(control): + return + if _reference == control: + return + elif is_instance_valid(_reference): + reset() + + if is_instance_valid(_gui) and _gui.gui_input.is_connected(_on_input): + _gui.gui_input.disconnect(_on_input) + + _reference = control + _control = null + _gui = null + + if control is ScriptEditorBase: + _gui = control.get_base_editor() + + if _gui is CodeEdit: + var carets : PackedInt32Array = _gui.get_sorted_carets() + if carets.size() > 0: + var sc : ScriptEditor = EditorInterface.get_script_editor() + if is_instance_valid(sc): + var line : int = _gui.get_caret_line(0) + if line > _gui.get_line_count(): + line = _gui.get_line_count() - 1 + if line > -1: + sc.goto_line(line) + if !_gui.symbol_lookup.is_connected(_on_symb): + _gui.symbol_lookup.connect(_on_symb.bind(_gui)) + _control = _gui.get_parent() + var __parent : Node = _control.get_parent() + if __parent is VSplitContainer: + _index = _control.get_index() + _control = VSplitContainer.new() + _parent = __parent + + var childs : Array[Node] = __parent.get_children() + if __parent.is_inside_tree() and _control.is_inside_tree(): + for x : Node in childs: + x.reparent(_control) + else: + for x : Node in childs: + _parent.remove_child(x) + _control.add_child(x) + else: + for x : Node in control.get_children(): + if x is RichTextLabel: + if _reference is CanvasItem: + var canvas : VBoxContainer = VBoxContainer.new() + canvas.size_flags_vertical = Control.SIZE_EXPAND_FILL + canvas.size_flags_vertical = Control.SIZE_EXPAND_FILL + _root.add_child(canvas) + canvas.size = _root.size + + + if canvas.get_child_count() < 1: + var childs : Array[Node] = _reference.get_children() + if _reference.is_inside_tree() and canvas.is_inside_tree(): + for n : Node in childs: + n.reparent(canvas) + else: + for n : Node in childs: + _reference.remove_child(n) + canvas.add_child(n) + + x.size = canvas.size + _gui = canvas + _control = canvas + _helper.search_by_symbol(control) + else: + _gui = x + _control = x + break + + if _control == null: + _gui = control + if control.get_child_count() > 0: + _gui = control.get_child(0) + _control = _gui + + var parent : Node = _control.get_parent() + if null != parent: + _parent = parent + + + if parent != _root: + if parent != null: + if !parent.is_inside_tree() or !_root.is_inside_tree(): + parent.remove_child(_control) + _root.add_child(_control) + else: + _control.reparent(_root) + else: + _root.add_child(_control) + if _gui: + var gui : Control = _gui + + if gui.focus_mode != Control.FOCUS_NONE: + if !gui.gui_input.is_connected(_on_input): + gui.gui_input.connect(_on_input) + + if gui is VBoxContainer: + gui = gui.get_child(0) + if !gui.focus_entered.is_connected(_i_like_coffe): + gui.focus_entered.connect(_i_like_coffe) + if !gui.is_node_ready(): + await gui.ready + if is_instance_valid(gui): + focus.emit(self) + tool_updated.emit() + + func update() -> void: + if is_instance_valid(_control) and is_instance_valid(_reference): + var root : TabContainer = _root + if is_instance_valid(root): + if _control.get_parent() == root and _reference.get_parent() != null: + _helper.update_info.call_deferred(root, _control.get_index(), _src) + + func kill() -> void: + for x : Node in [_gui, _reference]: + if is_instance_valid(x) and x.is_queued_for_deletion(): + x.queue_free() + + func reset(disconnect_signals : bool = true) -> void: + if is_instance_valid(_gui): + if disconnect_signals and _gui.is_inside_tree(): + var gui : Control = _gui + if gui is VBoxContainer: + gui = gui.get_child(0) + if gui.focus_entered.is_connected(_i_like_coffe): + gui.focus_entered.disconnect(_i_like_coffe) + if gui.gui_input.is_connected(_on_input): + gui.gui_input.disconnect(_on_input) + if gui is CodeEdit: + if gui.symbol_lookup.is_connected(_on_symb): + gui.symbol_lookup.disconnect(_on_symb) + _gui.modulate = Color.WHITE + + if _gui is VBoxContainer: + if _gui.is_inside_tree() and _reference.is_inside_tree(): + for x : Node in _gui.get_children(): + x.reparent(_reference) + else: + var childs : Array[Node] = _gui.get_children() + for x : Node in childs: + _gui.remove_child(x) + _reference.add_child(x) + if _gui != _control: + _gui.queue_free() + _gui = null + _control.queue_free() + _control = null + + if is_instance_valid(_control): + if is_instance_valid(_parent): + var parent : Node = _control.get_parent() + if parent != _parent: + if _control is VSplitContainer: + if !_control.is_inside_tree() or !_parent.is_inside_tree(): + var childs : Array[Node] = _control.get_children() + for c : Node in childs: + _control.remove_child(c) + _parent.add_child(c) + else: + for c : Node in _control.get_children(): + c.reparent(_parent) + _control.queue_free() + else: + _helper.control_reparent.call_deferred(_index, _control, parent, _parent) + _gui = null + _parent = null + _control = null + _reference = null + _index = 0 + + if is_instance_valid(_helper) and !_helper.is_queued_for_deletion(): + if _helper.add_last_script_used.is_valid(): + _helper.add_last_script_used(_src) + +func control_reparent(_index : int, _control : Object, parent : Object, _parent : Object) -> void: + if !is_instance_valid(_control): + return + + if !is_instance_valid(_parent): + return + + if _parent != _control.get_parent(): + if is_instance_valid(parent): + if _control.is_inside_tree() and _parent.is_inside_tree(): + _control.reparent(_parent) + else: + parent.remove_child(_control) + _parent.add_child(_control) + else: + _parent.add_child(_control) + if _parent.is_inside_tree(): + if _index > -1 and _index < _parent.get_child_count(): + _parent.move_child(_control, _index) + +class ReTweener extends RefCounted: + var _tween : Tween = null + var _ref : Control = null + var color : Color = Color.MEDIUM_SLATE_BLUE + + func create_tween(control : Control) -> void: + if !is_instance_valid(control) or control.is_queued_for_deletion() or !control.is_inside_tree(): + return + + if _ref == control: + return + clear() + _tween = control.get_tree().create_tween() + _ref = control + _tween.tween_method(_callback, color, Color.WHITE, 0.35) + + func _callback(c : Color) -> void: + if is_instance_valid(_ref) and _ref.is_inside_tree(): + _ref.modulate = c + return + clear() + + func secure_clear(ref : Object) -> void: + if !is_instance_valid(_ref) or _ref == ref: + clear() + + func clear() -> void: + if _tween: + if _tween.is_valid(): + _tween.kill() + _tween = null + if is_instance_valid(_ref): + _ref.modulate = Color.WHITE + +func _set_focus(tool : Mickeytools, txt : String = "", items : PackedStringArray = [], refresh_history : bool = true) -> void: + if !is_instance_valid(tool): + return + + _last_tool = tool + if !_chaser_enabled: + var ctrl : Variant = tool.get_control() + if is_instance_valid(ctrl) and ctrl.is_inside_tree(): + var root : Control = tool.get_root() + if root is TabContainer and ctrl.get_parent() == root: + var indx : int = ctrl.get_index() + if root.current_tab != indx: + root.current_tab = indx + if refresh_history: + var current : Node = root + for __ : int in range(0, 2): + if current == null: + break + elif current.has_method(&"add_editor"): + current.call(&"add_editor", tool, HANDLE_BACK_FORWARD_BUFFER) + break + current = current.get_parent() + + var ref : Node = _last_tool.get_reference() + if ref.get_parent() == null: + return + + var index : int = ref.get_index() + if index < 0: + return + + for x : Node in _editor.get_children(): + if x == ref: + if index > -1 and is_instance_valid(_item_list): + if _item_list.item_count > index: + _item_list.item_selected.emit(index) + break + + if _SPLIT_USE_HIGHLIGHT_SELECTED and _code_editors.size() > 1: + var control : Node = _last_tool.get_gui() + if is_instance_valid(control) and control.is_inside_tree(): + if _tweener == null: + _tweener = ReTweener.new() + _tweener.color = _SPLIT_HIGHLIGHT_COLOR + _tweener.create_tween(control) + + var gui : Node = _last_tool.get_gui() + if is_instance_valid(gui) and should_grab_focus(): + if !_MINIMAP_4_UNFOCUS_WINDOW and _OUT_FOCUS_COLORED: + for x : Mickeytools in _code_editors: + if is_instance_valid(x): + var _gui : Variant = x.get_gui() + if is_instance_valid(_gui) and _gui is CodeEdit: + _gui.modulate = _UNFOCUS_COLOR + _gui.minimap_draw = false + + if gui is CodeEdit: + gui.modulate = Color.WHITE + gui.minimap_draw = true + + elif !_MINIMAP_4_UNFOCUS_WINDOW: + for x : Mickeytools in _code_editors: + if is_instance_valid(x): + var _gui : Variant = x.get_gui() + if is_instance_valid(_gui) and _gui is CodeEdit: + _gui.minimap_draw = false + if gui is CodeEdit: + gui.minimap_draw = true + + elif _OUT_FOCUS_COLORED: + for x : Mickeytools in _code_editors: + if is_instance_valid(x): + var _gui : Variant = x.get_gui() + if is_instance_valid(gui) and gui is CodeEdit: + _gui.modulate = _UNFOCUS_COLOR + if gui is CodeEdit: + gui.modulate = Color.WHITE + + var vp : Viewport = gui.get_viewport() + if is_instance_valid(vp): + var wm : Window = vp.get_window() + if wm and !wm.has_focus(): + wm.grab_focus() + if is_instance_valid(gui) and !gui.has_focus(): + if gui is VBoxContainer: + gui = gui.get_child(0) + gui.grab_focus.call_deferred() + + var item_list : ItemList = _item_list + if is_instance_valid(item_list): + _update_path() + + if txt.length() > 0: + for x : int in range(item_list.item_count - 1, -1, -1): + var _txt : String = item_list.get_item_text(x) + if _txt.is_empty() or _txt.begins_with("@"): + _txt = item_list.get_item_tooltip(x).get_file() + if !(_txt in items): + item_list.remove_item(x) + item_list.get_parent().get_child(0).set(&"text", txt) + item_list.queue_redraw() + + set_deferred(&"_focus_queue", false) + +func _update_path() -> void: + if _item_list.item_count == _editor.get_child_count(): + for x : Mickeytools in _code_editors: + var ref : Control = x.get_reference() + if is_instance_valid(ref): + var index : int = ref.get_index() + if index > -1 and _item_list.item_count > index: + x.set_src(_item_list.get_item_tooltip(index)) + +func _on_focus(tool : Mickeytools, refresh_history : bool = true) -> void: + if _focus_queue: + return + _focus_queue = true + + var filesearch : Object = _item_list.get_parent().get_child(0) + if filesearch is LineEdit: + var txt : String = filesearch.text + if !txt.is_empty(): + var items : PackedStringArray = [] + for x : int in _item_list.item_count: + items.append(_item_list.get_item_text(x)) + filesearch.set(&"text", "") + _set_focus.call_deferred(tool, txt, items, refresh_history) + return + _set_focus(tool, "", [], refresh_history) + +func _out_it(node : Node, with_signals : bool = false) -> void: + var has_tween : bool = is_instance_valid(_tweener) + if has_tween and _code_editors.size() == 0: + _tweener.clear() + + for x : int in range(_code_editors.size() - 1, -1 , -1): + var tool : Mickeytools = _code_editors[x] + if is_instance_valid(tool): + if tool.is_equal(node): + if has_tween: + _tweener.secure_clear(tool.get_control()) + tool.reset(with_signals) + tool.free() + else: + continue + _code_editors.remove_at(x) + +func _grab_focus_by_tab(tb : int) -> void: + if tb > -1 and tb < _editor.get_child_count(): + var ctrl : Control = _editor.get_child(tb) + for pop : Window in _pop_scripts: + var control : Control = pop.get_base_control() + for m : Mickeytools in _code_editors: + var gui : Control = m.get_gui() + if m.get_reference() == ctrl and (control == gui or gui.get_parent()): + m.focus.emit(m) + +func _on_tab_change(tb : int = 0) -> void: + if !_chaser_enabled: + _grab_focus_by_tab(tb) + + + process_update_queue(tb) + +func _setup(editor : TabContainer, setup : bool) -> void: + const INIT_2 : Array[StringName] = [&"connect", &"disconnect"] + const INIT_3 : Array[Array] = [[&"tab_changed", &"_on_tab_change"],[&"child_entered_tree", &"_on_it"], [&"child_exiting_tree", &"_out_it"]] + var _2 : StringName = INIT_2[int(!setup)] + for _3 : Array in INIT_3: + var _0 : StringName = _3[0] + if editor.has_signal(_0): + var _1 : Callable = Callable.create(self, _3[1]) + if editor.is_connected(_0, _1) != setup: + editor.call(_2, _0, _1) + + if setup: + if !FileAccess.file_exists("res://addons/script_spliter/io/backward_key_button.tres"): + if DirAccess.dir_exists_absolute("res://addons/script_spliter/io"): + var input : InputEventKey = InputEventKey.new() + input.keycode = KEY_LEFT + input.alt_pressed = true + input.pressed = true + ResourceSaver.save(input, "res://addons/script_spliter/io/backward_key_button.tres") + input = null + if !FileAccess.file_exists("res://addons/script_spliter/io/forward_key_button.tres"): + if DirAccess.dir_exists_absolute("res://addons/script_spliter/io"): + var input : InputEventKey = InputEventKey.new() + input.keycode = KEY_RIGHT + input.alt_pressed = true + input.pressed = true + ResourceSaver.save(input, "res://addons/script_spliter/io/forward_key_button.tres") + input = null + if !FileAccess.file_exists("res://addons/script_spliter/io/backward_mouse_button.tres"): + if DirAccess.dir_exists_absolute("res://addons/script_spliter/io"): + var input : InputEventMouseButton = InputEventMouseButton.new() + input.button_index = MOUSE_BUTTON_XBUTTON1 + input.pressed = true + ResourceSaver.save(input, "res://addons/script_spliter/io/backward_mouse_button.tres") + input = null + if !FileAccess.file_exists("res://addons/script_spliter/io/forward_mouse_button.tres"): + if DirAccess.dir_exists_absolute("res://addons/script_spliter/io"): + var input : InputEventMouseButton = InputEventMouseButton.new() + input.button_index = MOUSE_BUTTON_XBUTTON2 + input.pressed = true + ResourceSaver.save(input, "res://addons/script_spliter/io/forward_mouse_button.tres") + input = null + + if !InputMap.has_action(&"ui_script_spliter_forward"): + InputMap.add_action(&"ui_script_spliter_forward") + else: + InputMap.action_erase_events(&"ui_script_spliter_forward") + + if FileAccess.file_exists(_HANDLE_FORWARD_KEY_PATH): + var key_0 : InputEventKey = ResourceLoader.load(_HANDLE_FORWARD_KEY_PATH) + if key_0 is InputEvent: + InputMap.action_add_event(&"ui_script_spliter_forward", key_0) + else: + printerr("Not type InputEvent: ", key_0) + else: + printerr("Not exist file", _HANDLE_FORWARD_KEY_PATH) + + if FileAccess.file_exists(_HANDLE_FORWARD_MOUSE_BUTTON_PATH): + var key_1 : Variant = ResourceLoader.load(_HANDLE_FORWARD_MOUSE_BUTTON_PATH) + if key_1 is InputEvent: + InputMap.action_add_event(&"ui_script_spliter_forward", key_1) + else: + printerr("Not type InputEvent: ", key_1) + else: + printerr("Not exist file", _HANDLE_FORWARD_MOUSE_BUTTON_PATH) + + if !InputMap.has_action(&"ui_script_spliter_backward"): + InputMap.add_action(&"ui_script_spliter_backward") + else: + InputMap.action_erase_events(&"ui_script_spliter_backward") + + if FileAccess.file_exists(_HANDLE_BACKWARD_KEY_PATH): + var key_0 : Variant = ResourceLoader.load(_HANDLE_BACKWARD_KEY_PATH) + if key_0 is InputEvent: + InputMap.action_add_event(&"ui_script_spliter_backward", key_0) + else: + printerr("Not type InputEvent: ", key_0) + else: + printerr("Not exist file", _HANDLE_BACKWARD_KEY_PATH) + + if FileAccess.file_exists(_HANDLE_BACKWARD_MOUSE_BUTTON_PATH): + var key_1 : InputEventMouseButton = ResourceLoader.load(_HANDLE_BACKWARD_MOUSE_BUTTON_PATH) + if key_1 is InputEvent: + InputMap.action_add_event(&"ui_script_spliter_backward", key_1) + else: + printerr("Not type InputEvent: ", key_1) + else: + printerr("Not exist file", _HANDLE_BACKWARD_MOUSE_BUTTON_PATH) + +func _on_sub_change(__ : int, tab : TabContainer) -> void: + if _chaser_enabled: + return + var _tab : int = tab.current_tab + if _tab > -1 and _tab < tab.get_child_count(): + var control : Control = tab.get_child(_tab) + + for x : Mickeytools in _code_editors: + if is_instance_valid(x): + var ctrl : Variant = x.get_control() + if is_instance_valid(ctrl): + if ctrl == control: + x.focus.emit(x) + return + +func _on_tab_rmb(itab : int, tab : TabContainer) -> void: + if tab.get_child_count() > itab and itab > -1: + if is_instance_valid(_item_list): + var ref : Node = tab.get_child(itab) + for x : Mickeytools in _code_editors: + if x.get_control() == ref: + for e : Node in _editor.get_children(): + if e == x.get_reference() and e.get_parent() != null: + var i : int = e.get_index() + if i > -1 and i < _item_list.item_count: + _item_list.item_clicked.emit(i, _item_list.get_local_mouse_position(), MOUSE_BUTTON_RIGHT) + return + break + +func _on_close(itab : int, tab : TabContainer) -> void: + if tab.get_child_count() > itab and itab > -1: + if is_instance_valid(_item_list): + var ref : Node = tab.get_child(itab) + for x : Mickeytools in _code_editors: + if x.get_control() == ref: + for e : Node in _editor.get_children(): + if e == x.get_reference(): + remove_tool(x) + var i : int = e.get_index() + if i > -1 and i < _item_list.item_count: + _item_list.item_clicked.emit(i, _item_list.get_local_mouse_position(), MOUSE_BUTTON_MIDDLE) + return + break + +func _on_enter(n : Node, tab : TabContainer) -> void: + var root : Node = n.get_parent() + for x : Mickeytools in _code_editors: + if x.get_root() == root: + x.update.call_deferred() + break + var _v : bool = tab.get_child_count() > 0 + if tab.visible != _v: + tab.visible = _v + +func _on_exit(n : Node, tab : TabContainer) -> void: + var _v : bool = tab.get_child_count() > 1 or (tab.get_child_count() > 0 and tab.get_child(0) != n) + if tab.visible != _v: + tab.visible = _v + if !is_queued_for_deletion(): + process_update_queue() + +func _get_root() -> Control: + var margin : Root = Root.new(self) + margin.size_flags_horizontal = Control.SIZE_EXPAND_FILL + margin.size_flags_vertical = Control.SIZE_EXPAND_FILL + + var texture : TextureRect = TextureRect.new() + texture.size_flags_horizontal = Control.SIZE_EXPAND_FILL + texture.size_flags_vertical = Control.SIZE_EXPAND_FILL + texture.expand_mode = TextureRect.EXPAND_IGNORE_SIZE + texture.stretch_mode = TextureRect.STRETCH_KEEP_CENTERED + texture.texture = preload("res://addons/script_spliter/assets/github_CodeNameTwister.png") + texture.self_modulate.a = 0.25 + + margin.add_child(texture) + return margin + +func _get_container() -> Control: + var editor : EditorContainer = EditorContainer.new() + editor.separator_line_size = 4.0 + editor.drag_button_size = 12.0 + editor.behaviour_can_expand_focus_same_container = true + return editor + +func _out_drag(e : Control) -> void: + var current : Control = null + + is_dd_handled = false + _last_dd_root = null + if is_instance_valid(_ddo): + _ddo.visible = false + var np : Node = _ddo.get_parent() + if is_instance_valid(np): + current = np + np.remove_child(_ddo) + if is_instance_valid(current): + if current.get_global_rect().has_point(current.get_global_mouse_position()): + if e is TabBar: + var ct : int = e.current_tab + var p : Node = e.get_parent() + if p and ct < p.get_child_count(): + var gui : Node = p.get_child(ct) + + var root : Node = null + for x : Mickeytools in _code_editors: + var __root : Node = x.get_root() + if is_instance_valid(_root) and __root.get_parent() == current: + root = __root + break + + if is_instance_valid(root): + for x : Mickeytools in _code_editors: + if x.get_control() == gui or x.get_gui() == gui: + if root != x.get_root(): + queue_swap(x, root) + return + elif e is ItemList: + var it : PackedInt32Array = e.get_selected_items() + if it.size() > 0: + var src : String = e.get_item_tooltip(it[0]) + var root : Node = null + for x : Mickeytools in _code_editors: + var __root : Node = x.get_root() + if is_instance_valid(_root) and __root.get_parent() == current: + root = __root + break + + if is_instance_valid(root): + for x : Mickeytools in _code_editors: + if x.get_src() == src: + if root != x.get_root(): + queue_swap(x, root) + return + + +func queue_swap(x : Mickeytools, root : Node) -> void: + if is_instance_valid(x): + var ref : Node = x.get_reference() + if is_instance_valid(ref) and is_instance_valid(root): + remove_tool(x) + create_code_editor.call_deferred(root, ref) + _new_tools.call_deferred(_code_editors.duplicate(false)) + + +func _new_tools(tools : Array[Mickeytools]) -> void: + var tool : Mickeytools = null + for x in _code_editors: + if x in tools: + continue + tool = x + break + if tool: + tool.focus.emit.call_deferred(tool) + await Engine.get_main_loop().process_frame + if is_instance_valid(tool): + tool.update() + +func _on_drag(e : Control) -> void: + is_dd_handled = is_instance_valid(e) + if !is_dd_handled: + _last_dd_root = null + if is_instance_valid(_ddo): + _ddo.visible = false + var np : Node = _ddo.get_parent() + if np: + np.remove_child(_ddo) + +func _get_container_edit() -> Control: + var rtab : DD = DD.new() + + rtab.get_tab_bar().tab_close_display_policy = TabBar.CLOSE_BUTTON_SHOW_ALWAYS + + rtab.drag_to_rearrange_enabled = true + + + rtab.child_entered_tree.connect(_on_enter.bind(rtab)) + rtab.child_exiting_tree.connect(_on_exit.bind(rtab)) + + rtab.visible = false + + var rcall : Callable = _on_sub_change.bind(rtab) + + rtab.tab_changed.connect(rcall) + rtab.tab_clicked.connect(rcall) + rtab.get_tab_bar().tab_close_pressed.connect(_on_close.bind(rtab)) + rtab.get_tab_bar().select_with_rmb = true + rtab.get_tab_bar().tab_rmb_clicked.connect(_on_tab_rmb.bind(rtab)) + + rtab.on_dragging.connect(_on_drag) + rtab.out_dragging.connect(_out_drag) + + rtab.size_flags_horizontal = Control.SIZE_EXPAND_FILL + rtab.size_flags_vertical = Control.SIZE_EXPAND_FILL + + return rtab + +func _create_by_last_used() -> void: + if _lifo_src.size() > 0: + var item_list : ItemList = _item_list + if is_instance_valid(item_list): + var unused : Array[Node] = [] + if _item_list.item_count == _editor.get_child_count(): + for x : Node in _main.get_children(): + if is_instance_valid(x): + if x is TabContainer and x.get_child_count() == 0: + unused.append(x) + else: + for y : Node in x.get_children(): + if y is TabContainer and y.get_child_count() == 0: + unused.append(y) + for u : Node in unused: + var sc : String = get_last_script_used() + var dirty : bool = false + if sc.is_empty(): + continue + + for x : int in _item_list.item_count: + if _item_list.get_item_tooltip(x) == sc: + create_code_editor(u, _editor.get_child(x)) + dirty = true + break + if !dirty and sc.begins_with("res://") and FileAccess.file_exists(sc): + if _SHOULD_OPEN_CLOSED_EDITOR_SCRIPT: + var res : Variant = ResourceLoader.load(sc) + if res is Script: + EditorInterface.edit_script.call_deferred(res) + +func update() -> void: + if is_queued_for_deletion() or !_plugin.is_inside_tree(): + return + + _clear() + if _editor.get_child_count() > 0: + var root : Node = _get_editor_root() + if null != root and _editor.current_tab > -1: + create_code_editor(root, _editor.get_current_tab_control()) + + _create_by_last_used() + + for x : Node in _main.get_children(): + if is_instance_valid(x): + if x is TabContainer and x.get_child_count() == 0: + for z : Node in _editor.get_children(): + if null != create_code_editor(x, z): + break + else: + for y : Node in x.get_children(): + if y is TabContainer and y.get_child_count() == 0: + for z : Node in _editor.get_children(): + if null != create_code_editor(y, z): + break + + if !is_instance_valid(_last_tool) or _last_tool.is_queued_for_deletion(): + for i : int in range(_code_editors.size() - 1, -1, -1): + if is_instance_valid(_code_editors[i]): + _last_tool = _code_editors[i] + _last_tool.focus.emit.call_deferred(_last_tool) + break + _code_editors.remove_at(i) + + if _pop_scripts.size() > 0: + for p : Window in _pop_scripts: + if !p.visible: + p.show() + + if _pop_script_placeholder: + for x : Mickeytools in _code_editors: + if !x.is_floating(): + var ref : Node = x.get_reference() + if ref.get_parent() != null: + if get_item_text(x.get_src()).begins_with(_POP_SCRIPT_PLACEHOLDER): + continue + _clear_placeholder() + else: + _clear_placeholder() + +func _clear_placeholder() -> void: + if _pop_script_placeholder: + for x : int in range(_item_list.item_count): + var txt : String = _item_list.get_item_text(x) + if txt.is_empty() or txt.begins_with("@"): + txt = _item_list.get_item_tooltip(x).get_file() + if txt.begins_with(_POP_SCRIPT_PLACEHOLDER): + _item_list.item_clicked.emit(x, _item_list.get_local_mouse_position(), MOUSE_BUTTON_MIDDLE) + break + _pop_script_placeholder = false + + + +func is_visible_minimap_required() -> bool: + return _MINIMAP_4_UNFOCUS_WINDOW + +func get_item_text(src : String) -> String: + var item_list : Control = _item_list + var text : String = "" + if !src.is_empty(): + if is_instance_valid(item_list): + var indx : int = -1 + for x : int in item_list.item_count: + if item_list.get_item_tooltip(x) == src: + indx = x + break + if indx > -1: + text = item_list.get_item_text(indx) + if text.is_empty() or text.begins_with("@"): + text = item_list.get_item_tooltip(indx).get_file() + text = text.trim_suffix("(*)") + return text + +func get_aviable() -> Node: + for x : Node in _main.get_children(): + if x is TabContainer and x.get_child_count() == 0: + return x + for y : Node in x.get_children(): + if y is TabContainer and y.get_child_count() == 0: + return y + return null + +func is_node_valid(root : Node) -> bool: + return is_instance_valid(root) and root.is_inside_tree() + +func is_valid_code_editor(root : Node, editor : Node, fallback : bool = true) -> bool: + if !is_node_valid(root) or !is_node_valid(editor): + return false + + if !editor.is_node_ready(): + return false + + if editor.get_child_count() == 0: + if fallback and editor.is_inside_tree(): + var index : int = editor.get_index() + if index > -1 and _item_list.item_count > index: + _item_list.item_selected.emit(index) + return is_valid_code_editor(root, editor, false) + return false + + return true + + +func is_valid_doc(editor : Control) -> bool: + if !editor is ScriptEditorBase: + for x : Node in editor.get_children(): + if x is RichTextLabel: + return true + return false + +func add_tool(tool : Mickeytools) -> void: + _code_editors.append(tool) + tool_added.emit(tool) + +func remove_tool(x : Mickeytools, with_signals : bool = true) -> void: + x.reset(with_signals) + _code_editors.erase(x) + x.free() + +func create_code_editor(root : Node, editor : Node) -> Mickeytools: + if !is_valid_code_editor(root, editor): + return null + + var tool : Mickeytools = null + + if root.get_child_count() > 0: + var childs : Array[Node] = root.get_children() + for m : Mickeytools in _code_editors: + if m.get_reference() == editor: + var o : Node = m.get_control() + if o in childs or m.get_gui() in childs: + return null + else: + for m : Mickeytools in _code_editors: + if m.get_reference() == editor: + var o : Node = m.get_control() + var __root : Control = m.get_root() + if is_instance_valid(__root) and __root.get_child_count() > 1: + if __root and __root.current_tab != o.get_index(): + tool = m + break + + if is_valid_doc(editor): + if editor.name.begins_with("@"): + return + + if null == tool: + for x : Mickeytools in _code_editors: + if x.is_equal(editor): + return null + tool = Mickeytools.new(self, root, editor) + tool.focus.connect(_on_focus) + add_tool(tool) + + tool.focus.emit(tool) + else: + tool.reset() + tool.set_root(root) + tool.set_reference(editor) + + if _last_tool == null: + _last_tool = tool + tool.focus.emit(tool) + tool.update.call_deferred() + return tool + +func update_queue(__ : int = 0) -> void: + if _plugin: + _plugin.set_process(true) + if _main and _container: + update_rect() + _main.update() + +#region callback +func _on_it(editor : Node) -> void: + if is_valid_doc(editor): + if editor.name.begins_with("@"): + editor.queue_free() + return + update_queue(0) + update() + +func _on_container_entered() -> void: + update_queue() + +func _on_container_exit() -> void: + for x : Mickeytools in _code_editors: + x.reset() + if !is_queued_for_deletion(): + process_update_queue() +#endregion + +func remove_split(node : Node) -> void: + if _code_editors.size() > 1: + if node is CodeEdit: + for it : int in range(_code_editors.size() - 1, -1, -1): + var x : Mickeytools = _code_editors[it] + if x.get_gui() == node: + _remove_split_by_control(x.get_control()) + + remove_tool(x) + + process_update_queue() + break + +func _remove_split_by_control(c : Control) -> void: + for x : Node in _main.get_children(): + if x is TabContainer:continue + if x.get_child_count() > 0: + for y : Node in x.get_children(): + for z : Node in y.get_children(): + if z == c: + _main.remove_child(x) + return + +func _get_unused_editor_control() -> Array[Node]: + var out : Array[Node] = [] + for x : Node in _editor.get_children(): + var exist : bool = false + for m : Mickeytools in _code_editors: + if !is_instance_valid(m): + _code_editors.erase(m) + continue + if m.is_equal(x): + exist = true + break + if !exist: + out.append(x) + return out + +func _free_editor_container(control : Control) -> bool: + if control.get_parent() == _main: + for x : int in range(_code_editors.size() - 1, -1 , -1): + var c : Mickeytools = _code_editors[x] + var cc : Variant = c.get_control() + if is_instance_valid(cc): + var _a : Node = cc.get_parent() + var _b : Node = control + if _a == _b or _a.get_parent() == _b: + remove_tool(c) + else: + remove_tool(c) + _main.remove_child(control) + control.queue_free() + return true + return false + +func build(editor : TabContainer, columns : int = 0, rows : int = 0) -> void: + _setup(editor, true) + + var root : Node = editor.get_parent() + if is_instance_valid(root) and !(root is Root): + _root = root + + if is_instance_valid(_editor) and _editor != editor: + if _editor.tree_entered.is_connected(_on_container_entered): + _editor.tree_entered.disconnect(_on_container_entered) + + if _editor.tree_exiting.is_connected(_on_container_exit): + _editor.tree_exiting.disconnect(_on_container_exit) + + _editor = editor + + if !_editor.tree_entered.is_connected(_on_container_entered): + _editor.tree_entered.connect(_on_container_entered) + + if !_editor.tree_exiting.is_connected(_on_container_exit): + _editor.tree_exiting.connect(_on_container_exit) + + if !is_instance_valid(_container): + _container = _get_root() + + if !is_instance_valid(_main): + _main = _get_container() + + root = _container.get_parent() + + if root != _root: + if is_instance_valid(root): + root.remove_child(_container) + var index : int = _editor.get_index() + _root.add_child(_container) + _root.move_child(_container, index) + + root = _main.get_parent() + if root != _container: + if is_instance_valid(root): + root.remove_child(_main) + _container.add_child(_main) + + _container.size = _container.get_parent().size + _container.anchor_left = 0.0 + _container.anchor_top = 0.0 + _container.anchor_right = 1.0 + _container.anchor_bottom = 1.0 + + _main.behaviour_expand_on_focus = true + _main.behaviour_expand_on_double_click = true + + + _editor.visible = false + _main.visible = true + + update_config() + + update_build(columns, rows) + + if (_root is Control): + if !_root.item_rect_changed.is_connected(update_rect): + _root.item_rect_changed.connect(update_rect) + update_rect.call_deferred() + +func update_rect() -> void: + var _size : Vector2 = _container.size + _size.x = maxf(_container.size.x, 1.0) + _size.y = maxf(_container.size.y, 1.0) + _main.size = _size + for x : Node in _main.get_children(): + if x is Control: + if x is TabContainer: + continue + for y : Node in x.get_children(): + if y is Control: + y.set_deferred(&"size", x.size) + _main.update() + +func find_editor(node : Node) -> Control: + for x : Node in _main.get_children(): + for y : Node in x.get_children(): + if y == node: + return x + return null + +func can_remove_split(node : Node) -> bool: + if !is_instance_valid(_main): + return false + + if node == null: + return _code_editors.size() > 1 + + if _code_editors.size() > 1: + if node is CodeEdit: + var main : bool = false + for x : Mickeytools in _code_editors: + if x.is_floating(): + continue + var item_list : Node = _item_list + if item_list: + var reference : Node = x.get_reference() + if reference.get_parent() != null: + if get_control_item_name(reference.get_index()).begins_with(_POP_SCRIPT_PLACEHOLDER): + continue + if main: + return true + main = true + return false + +func get_control_item_name(index : int) -> String: + var item_list : Node = _item_list + if item_list: + if index > -1 and index < item_list.item_count: + var text : String = item_list.get_item_text(index) + if text.is_empty() or text.begins_with("@"): + text = item_list.get_item_tooltip(index).get_file() + return text + return "" + + +func get_editor_item_text(c : int) -> String: + var item_list : Control = _item_list + var text : String = "" + if c > -1: + if is_instance_valid(item_list): + if null != item_list and c < _editor.get_child_count() and item_list.item_count > c: + text = item_list.get_item_text(c) + if text.is_empty() or text.begins_with("@"): + text = item_list.get_item_tooltip(c).get_file() + text = text.trim_suffix("(*)") + return text + +func can_add_split(_node : Node) -> bool: + if !is_instance_valid(_main): + return false + + if _node == null: + return _code_editors.size() < _editor.get_child_count() + + for o : int in _editor.get_child_count(): + if get_editor_item_text(o).begins_with(_POP_SCRIPT_PLACEHOLDER): + continue + var x : Node = _editor.get_child(o) + var created : bool = false + if x.has_method(&"get_base_editor"): + x = x.call(&"get_base_editor") + for m : Mickeytools in _code_editors: + if m.get_gui() == x: + created = true + break + else: + if x.get_child_count() > 0: + var child : Node = x.get_child(0) + for m : Mickeytools in _code_editors: + var gui : Node = m.get_gui() + if gui == x or child == gui: + created = true + break + else: + for m : Mickeytools in _code_editors: + var gui : Node = m.get_gui() + if gui == x : + created = true + break + if !created: + return true + return false + +func add_split(control : Node) -> void: + var unused : Array[Node] = _get_unused_editor_control() + if unused.size() == 0: + print("[INFO] Not aviable split!") + return + + var current_unused : Node = control + + for x : Mickeytools in _code_editors: + if x.is_equal(control) or x.get_gui() == control: + current_unused = null + break + + var root : Control = get_aviable() + if root == null: + var broot : Node = _main.make_split_container_item() + root = _get_container_edit() + broot.add_child(root) + _main.add_child(broot) + + if null == current_unused: + current_unused = unused[0] + + _create_by_last_used() + if root.get_child_count() == 0: + create_code_editor(root, current_unused) + + process_update_queue() + +func get_current_columns_and_rows() -> Array[int]: + var out : Array[int] = [0, 0] + if is_instance_valid(_main): + var columns : int = _main.max_columns + var container : int = _main.get_child_count() + if container > 0 and columns > 0: + @warning_ignore("integer_division") + container = int(container / columns) + out[0] = columns + out[1] = container + return out + +func update_build(columns : int, rows : int) -> void: + for x : Node in _main.get_children(): + if x is EditorContainer: + for y in x.get_children(): + if y.has_method(&"reset"): + y.call(&"reset") + _out_drag(null) + + current_columns = maxi(columns, 0) + current_rows = maxi(rows, 0) + + var totals : int = maxi(current_columns * current_rows, 1) + _main.max_columns = current_columns + + while _main.get_child_count() > totals: + if !_free_editor_container(_main.get_child(_main.get_child_count() - 1)): + break + + while _main.get_child_count() < totals: + var broot : Node = _main.make_split_container_item() + var root : Node = _get_container_edit() + broot.add_child(root) + _main.add_child(broot) + + var aviable : Node = get_aviable() + if aviable: + if _lifo_src.size() > 0: + _create_by_last_used() + aviable = get_aviable() + while aviable != null: + var unused : Array[Node] = _get_unused_editor_control() + if unused.size() == 0: + break + if null == create_code_editor(aviable, unused[0]): + break + aviable = get_aviable() + + process_update_queue() + + +#region _CHASER_ +func get_current_focus_index() -> int: + var arr : PackedInt32Array = _item_list.get_selected_items() + if arr.size() > 0: + return arr[0] + return 0 + +func focus_by_index(index : int, check_is_visible : bool = true) -> int: + if _code_editors.size() > index: + if check_is_visible: + while _code_editors.size() > index: + var cd : Mickeytools = _code_editors[index] + if cd != _last_tool: + var variant : Variant = cd.get_control() + if is_instance_valid(variant): + if variant is Control: + var parent : Node = variant.get_parent() + if parent is TabContainer: + if parent.get_current_tab_control() == variant: + _on_focus(cd) + return index + index += 1 + else: + var cd : Mickeytools = _code_editors[index] + var variant : Variant = cd.get_control() + if is_instance_valid(variant): + if variant is Control: + var parent : Node = variant.get_parent() + if parent is TabContainer: + if parent.get_current_tab_control() == variant: + _on_focus(cd) + return index + return -1 + +func get_focus_config() -> Dictionary: + return { + "highlight_selected" : _SPLIT_USE_HIGHLIGHT_SELECTED + ,"behaviour_expand_on_focus" : _main.behaviour_expand_on_focus + ,"last_tool" : _last_tool + } + +func set_focus_config(d : Dictionary) -> void: + _chaser_enabled = false + _SPLIT_USE_HIGHLIGHT_SELECTED = d["highlight_selected"] + _main.behaviour_expand_on_focus = d["behaviour_expand_on_focus"] + + var _last : Variant = d["last_tool"] + if is_instance_valid(_last): + if _last != _last_local_tool: + _last.focus.emit(_last) + +func enable_focus_highlight(enable : bool) -> void: + _chaser_enabled = !enable + _SPLIT_USE_HIGHLIGHT_SELECTED = enable + _main.behaviour_expand_on_focus = enable + +func should_grab_focus() -> bool: + return !_chaser_enabled +#endregion + +#region _POP_SCRIPT_ +func _on_pop_input(event : InputEvent) -> void: + (_editor.get_parent() as Control).gui_input.emit(event) + +func is_pop_script(ctrl : Node) -> bool: + for pop : Node in _pop_scripts: + var control : Control = pop.get_base_control() + if ctrl is CodeEdit: + for __ : int in range(2): + ctrl = ctrl.get_parent() + if ctrl == null: + return false + for x : Node in control.get_children(): + if x == ctrl: + return true + return false + +func _on_pop_script_close(pop : Window) -> void: + if !is_instance_valid(pop) or pop.is_queued_for_deletion(): + return + var container : Node = pop.get_base_control() + for x : Mickeytools in _code_editors: + var gui : Node = x.get_gui() + var control : Node = x.get_control() + if control.get_parent() == container or gui.get_parent() == container: + remove_tool(x, true) + + if container.get_child_count() < 1: + _pop_scripts.erase(pop) + if !pop.is_queued_for_deletion(): + pop.queue_free() + update_queue() + return + push_warning("Can not free popscript!") + +func make_pop_script(control : Node) -> Window: + if control is CodeEdit: + for __ : int in range(2): + control = control.get_parent() + if control == null: + return null + var m : Mickeytools = null + for x : Mickeytools in _code_editors: + if x.get_control() == control: + m = x + break + + if m == null: + return null + + var node : Node = FLYING_SCRIPT.instantiate() + node.set_base_control(_get_container_edit()) + + var editor : Control = m.get_reference() + remove_tool(m) + + _plugin.add_child(node) + + var tool : Mickeytools = create_code_editor(node.get_base_control(), editor) + if null == tool: + if !node.is_inside_tree(): + node.free() + else: + node.queue_free() + return null + + node.proxy = editor + node.controller = tool + + node.on_close.connect(_on_pop_script_close) + + _pop_scripts.append(node) + + _check_pop() + return node + +func _check_pop() -> void: + if !_pop_script_placeholder: + var placeholder : bool = true + var total_floatings : int = 0 + for x : Mickeytools in _code_editors: + if !x.is_floating(): + placeholder = false + break + total_floatings += 1 + if placeholder and _editor.get_child_count() <= total_floatings: + _pop_script_placeholder = true + var PLACEHOLDER : String = str("res://addons/script_spliter/context/",_POP_SCRIPT_PLACEHOLDER, ".gd") + if FileAccess.file_exists(PLACEHOLDER): + var script : Script = ResourceLoader.load(PLACEHOLDER) + if null != script: + _editor.child_entered_tree.connect(_on_placeholder, CONNECT_ONE_SHOT) + EditorInterface.edit_script(script) + +func _placeholder_queue() -> void: + for x : int in _editor.get_child_count(): + var txt : String = get_editor_item_text(x) + if txt.begins_with(_POP_SCRIPT_PLACEHOLDER): + var n : Node = _editor.get_child(x) + var c : Control = n.call(&"get_base_editor") + if c != null: + if c is CodeEdit: + c.editable = false + c.minimap_draw = false + +func _on_placeholder(__ : Node) -> void: + _placeholder_queue.call_deferred() +#endregion + +func process_update_queue(__ : int = 0) -> void: + update_queue(__) + update_queue.call_deferred(__) + +func get_selected_item() -> int: + var item_list : ItemList = _item_list + if is_instance_valid(item_list): + for x : int in item_list.item_count: + if item_list.is_selected(x): + return x + return -1 + +func can_expand_same_focus() -> bool: + return _BEHAVIOUR_CAN_EXPAND_SAME_ON_FOCUS + +#region _8_ +func swap(caller : Object) -> void: + if !_SWAP_BY_BUTTON: + return + + if !is_instance_valid(_main) or _main.get_child_count() == 0: + return + + var separators : Array = _main.get_separators() + if separators.size() == 0: + return + + var index : int = 0 + var linesep : Object = null + for x : Object in separators: + if x == caller: + linesep =x + break + index += 1 + + if linesep: + if linesep.is_vertical: + var atotal : int = 1 + var btotal : int = 1 + var nodes : Array[Node] = [] + + for x : int in range(index + 1, separators.size(), 1): + var clinesep : Object = separators[x] + if clinesep.is_vertical: + break + atotal += 1 + for x : int in range(index - 1, -1, -1): + var clinesep : Object = separators[x] + if clinesep.is_vertical: + break + btotal += 1 + + var cindex : int = index + while atotal > 0: + cindex += 1 + atotal -= 1 + if cindex < _main.get_child_count(): + nodes.append(_main.get_child(cindex)) + continue + break + + for x : Node in nodes: + cindex = btotal + while cindex > 0: + cindex -= 1 + _main.move_child(x, x.get_index() - 1) + else: + index += 1 + if _main.get_child_count() > index: + var child : Node = _main.get_child(index - 1) + _main.move_child(child, index) +#endregion +#region _7_ +var _search_symbol : String = "" + +func set_search_symbol(symbol: String) -> void: + _search_symbol = symbol + +func reset_symbol() -> void: + _search_symbol = "" + +func search_by_symbol(reference : Node) -> void: + if _search_symbol.is_empty(): + return + var symbol : String = _search_symbol + var class_nm : StringName = reference.name.strip_edges() + + reset_symbol() + + if symbol == class_nm: + return + + if class_nm.is_empty(): + return + + if class_nm.begins_with("_"): + if class_nm in GLOBALS: + return + + if ClassDB.class_exists(class_nm): + var prefx : String = "" + if class_nm == "GraphNode": + prefx = "class_theme_item" + if symbol.begins_with("@"): + prefx = "class_annotation" + elif ClassDB.class_has_signal(class_nm, symbol): + prefx = "class_signal" + elif ClassDB.class_has_enum(class_nm, symbol, true): + prefx = "class_constant" + else: + var list : Array[Dictionary] = ClassDB.class_get_property_list(class_nm, true) + for x : Dictionary in list: + if x.name == symbol: + prefx = "class_property" + break + if prefx.is_empty(): + list = ClassDB.class_get_method_list(class_nm, true) + for x : Dictionary in list: + if x.name == symbol: + prefx = "class_method" + break + if !prefx.is_empty(): + var path : String = "{0}:{1}:{2}".format([prefx, class_nm, symbol]) + EditorInterface.get_script_editor().goto_help(path) +#endregion + +#region 0.3.6 +var last_hover_tab : TabBar = null + +func get_hover_tab(tabs : Array[TabBar] = []) -> TabBar: + var nodes : Array[TabBar] = tabs + if tabs.size() == 0: + nodes = get_tabs() + for n : TabBar in nodes: + if n.get_global_rect().has_point(n.get_global_mouse_position()): + return n + return null + +func has_other_tabs() -> bool: + var tabs : Array[TabBar] = get_tabs() + var hover : TabBar = get_hover_tab(tabs) + last_hover_tab = hover + if is_instance_valid(hover): + var container : TabContainer = hover.get_parent() + if container.get_tab_count() > 1: + var index :int = container.current_tab + if index > 0 and index < container.get_tab_count() - 1: + return true + return false + +func has_right_tabs() -> bool: + var tabs : Array[TabBar] = get_tabs() + var hover : TabBar = get_hover_tab(tabs) + last_hover_tab = hover + if is_instance_valid(hover): + var container : TabContainer = hover.get_parent() + var index : int = container.current_tab + return index > -1 and index < container.get_tab_count() - 1 + return false + +func has_left_tabs() -> bool: + var tabs : Array[TabBar] = get_tabs() + var hover : TabBar = get_hover_tab(tabs) + last_hover_tab = hover + if is_instance_valid(hover): + var container : TabContainer = hover.get_parent() + var index : int = container.current_tab + return index > 0 + return false + +func get_tabs() -> Array[TabBar]: + var tabs : Array[TabBar] = [] + var nodes : Array[Node] = _plugin.get_tree().get_nodes_in_group(&"__SPLITER_TAB__") + for x : Node in nodes: + if x is TabBar: + tabs.append(x) + return tabs + +func close_right_tabs() -> void: + var hover : TabBar = last_hover_tab + if is_instance_valid(hover): + var container : TabContainer = hover.get_parent() + var index : int = container.current_tab + if index > -1 and container.get_child_count() > index: + var childs : Array[Node] = container.get_children() + var out : Array[Node] = [] + var _tools : Array[Mickeytools] = [] + for c : int in range(index + 1, childs.size(), 1): + out.append(childs[c]) + for x : Mickeytools in _code_editors: + if x.get_control() in out: + _tools.append(x) + for t : Mickeytools in _tools: + t.reset(true) + +func close_left_tabs() -> void: + var hover : TabBar = last_hover_tab + if is_instance_valid(hover): + var container : TabContainer = hover.get_parent() + var index : int = container.current_tab + if index > -1 and container.get_child_count() > index: + var childs : Array[Node] = container.get_children() + var out : Array[Node] = [] + var _tools : Array[Mickeytools] = [] + for c : int in range(index - 1, -1, -1): + out.append(childs[c]) + for x : Mickeytools in _code_editors: + if x.get_control() in out: + _tools.append(x) + for t : Mickeytools in _tools: + t.reset(true) + +func close_other_tabs() -> void: + var hover : TabBar = last_hover_tab + if is_instance_valid(hover): + var container : TabContainer = hover.get_parent() + var index : int = container.current_tab + if index > -1 and container.get_child_count() > index: + var out : Array[Node] = container.get_children() + var _tools : Array[Mickeytools] = [] + out.erase(container.get_child(index)) + for x : Mickeytools in _code_editors: + if x.get_control() in out: + _tools.append(x) + for t : Mickeytools in _tools: + t.reset(true) +#endregion diff --git a/addons/script_spliter/core/builder.gd.uid b/addons/script_spliter/core/builder.gd.uid new file mode 100644 index 0000000..e663f5d --- /dev/null +++ b/addons/script_spliter/core/builder.gd.uid @@ -0,0 +1 @@ +uid://dpje5up34xbux diff --git a/addons/script_spliter/core/ui/dd.gd b/addons/script_spliter/core/ui/dd.gd new file mode 100644 index 0000000..984dc44 --- /dev/null +++ b/addons/script_spliter/core/ui/dd.gd @@ -0,0 +1,40 @@ +@tool +extends Control +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +@export var lbl : Control + +var _0x0001 : float = 0.0 +var _0x0002 : float= 0.5 + +func _ready() -> void: + if !is_inside_tree(): + set_process(false) + +func _process(delta: float) -> void: + if !visible: + return + var p : Control = get_parent() + if !p: + return + _0x0001 += delta * 2.0 + if _0x0001 >= 1.0: + _0x0001 = 0.0 + if _0x0002 == 1.0: + _0x0002 = 0.5 + else: + _0x0002 = 1.0 + modulate.a = lerp(modulate.a, _0x0002, _0x0001) + lbl.pivot_offset = (lbl.size + Vector2.ONE) / 2.0 + lbl.scale = lerp(lbl.scale, Vector2.ONE * _0x0002 , _0x0001 * 0.24) + +func _enter_tree() -> void: + set_process(true) + +func _exit_tree() -> void: + set_process(false) diff --git a/addons/script_spliter/core/ui/dd.gd.uid b/addons/script_spliter/core/ui/dd.gd.uid new file mode 100644 index 0000000..369773c --- /dev/null +++ b/addons/script_spliter/core/ui/dd.gd.uid @@ -0,0 +1 @@ +uid://prv0v0r500g6 diff --git a/addons/script_spliter/core/ui/dd.tscn b/addons/script_spliter/core/ui/dd.tscn new file mode 100644 index 0000000..07174ed --- /dev/null +++ b/addons/script_spliter/core/ui/dd.tscn @@ -0,0 +1,27 @@ +[gd_scene load_steps=3 format=3 uid="uid://bd4fb42jjkgr0"] + +[ext_resource type="Script" uid="uid://prv0v0r500g6" path="res://addons/script_spliter/core/ui/dd.gd" id="1_1ryr1"] +[ext_resource type="Texture2D" uid="uid://cxds5tr6aq5v3" path="res://addons/script_spliter/assets/dd.png" id="2_pid5b"] + +[node name="Dd" type="ColorRect" node_paths=PackedStringArray("lbl")] +modulate = Color(0.8, 0.8, 0.8, 0.501533) +self_modulate = Color(1, 1, 1, 0.4) +size_flags_horizontal = 4 +size_flags_vertical = 4 +tooltip_text = "Drop the current dragged tab for change window!" +color = Color(1.3236e-07, 0.348188, 0.0242278, 1) +script = ExtResource("1_1ryr1") +lbl = NodePath("Label") + +[node name="Label" type="TextureRect" parent="."] +show_behind_parent = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 +texture = ExtResource("2_pid5b") +stretch_mode = 3 diff --git a/addons/script_spliter/core/ui/icon/MultiSpliter.svg b/addons/script_spliter/core/ui/icon/MultiSpliter.svg new file mode 100644 index 0000000..4e3a514 --- /dev/null +++ b/addons/script_spliter/core/ui/icon/MultiSpliter.svg @@ -0,0 +1,43 @@ + + + + + + + + diff --git a/addons/script_spliter/core/ui/icon/MultiSpliter.svg.import b/addons/script_spliter/core/ui/icon/MultiSpliter.svg.import new file mode 100644 index 0000000..15d28b6 --- /dev/null +++ b/addons/script_spliter/core/ui/icon/MultiSpliter.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bslfeut6hh5yo" +path="res://.godot/imported/MultiSpliter.svg-ba196a92a18cd9aeefd856cd4e65a016.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/core/ui/icon/MultiSpliter.svg" +dest_files=["res://.godot/imported/MultiSpliter.svg-ba196a92a18cd9aeefd856cd4e65a016.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=8.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/script_spliter/core/ui/icon/MultiSpliterButton.svg b/addons/script_spliter/core/ui/icon/MultiSpliterButton.svg new file mode 100644 index 0000000..28877b8 --- /dev/null +++ b/addons/script_spliter/core/ui/icon/MultiSpliterButton.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + diff --git a/addons/script_spliter/core/ui/icon/MultiSpliterButton.svg.import b/addons/script_spliter/core/ui/icon/MultiSpliterButton.svg.import new file mode 100644 index 0000000..50eeeb9 --- /dev/null +++ b/addons/script_spliter/core/ui/icon/MultiSpliterButton.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://151hs5hrois7" +path="res://.godot/imported/MultiSpliterButton.svg-f2ca8d7d3b41369a9fe8ce79d9fcb1df.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/core/ui/icon/MultiSpliterButton.svg" +dest_files=["res://.godot/imported/MultiSpliterButton.svg-f2ca8d7d3b41369a9fe8ce79d9fcb1df.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=8.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/script_spliter/core/ui/icon/MultiSpliterItem.svg b/addons/script_spliter/core/ui/icon/MultiSpliterItem.svg new file mode 100644 index 0000000..09251a4 --- /dev/null +++ b/addons/script_spliter/core/ui/icon/MultiSpliterItem.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + diff --git a/addons/script_spliter/core/ui/icon/MultiSpliterItem.svg.import b/addons/script_spliter/core/ui/icon/MultiSpliterItem.svg.import new file mode 100644 index 0000000..d8027f5 --- /dev/null +++ b/addons/script_spliter/core/ui/icon/MultiSpliterItem.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bd3tnqhyiny6o" +path="res://.godot/imported/MultiSpliterItem.svg-73b989ef018da2301c61b6f59ef99931.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/script_spliter/core/ui/icon/MultiSpliterItem.svg" +dest_files=["res://.godot/imported/MultiSpliterItem.svg-73b989ef018da2301c61b6f59ef99931.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=8.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/script_spliter/core/ui/multi_split_container.gd b/addons/script_spliter/core/ui/multi_split_container.gd new file mode 100644 index 0000000..36e567d --- /dev/null +++ b/addons/script_spliter/core/ui/multi_split_container.gd @@ -0,0 +1,999 @@ +@tool +@icon("icon/MultiSpliter.svg") +extends Container +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# https://github.com/CodeNameTwister/Multi-Split-Container +# +# Multi-Split-Container addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +const SplitContainerItem : Script = preload("res://addons/script_spliter/core/ui/split_container_item.gd") +const SplitButton : Texture = preload("res://addons/script_spliter/core/ui/icon/MultiSpliterButton.svg") + +@export_category("Multi-Split Settings") +## Max columns by rows, after added childs this is eparated by row group by columns size! +## [br][br] +## if this value is 0, will not create rows spliters. +@export_range(0.0, 1000.0, 1.0) var max_columns : int = 0: + set(e): + max_columns = maxi(0, e) + + if Engine.is_editor_hint(): + for x : int in range(separators_line_offsets.size()): + separators_line_offsets[x] = 0.0 + for x : LineSep in _separators: + x.queue_free() + + _separators.clear() + _first = true + update() + +@export_group("Line Separator", "separator_line") +## Line separator size. +@export var separator_line_size : float = 4.0: + set(e): + separator_line_size = max(e, 0.0) + update() + +## Separator line color. +@export var separator_line_color : Color = Color.MAGENTA: + set(e): + separator_line_color = e + if separator_line_color == Color.MAGENTA: # That color reminds me of texture not found errors. + var root = EditorInterface.get_base_control() + separator_line_color = root.get_theme_color("base_color", "Editor") + update() + +## Separator line visibility. +@export var separator_line_visible : bool = true: + set(e): + separator_line_visible = e + for l : LineSep in _separators: + l.visible = separator_line_visible + +@export_subgroup("Behaviour", "behaviour_") +## Enable function for auto expand lines container on inside focus. +@export var behaviour_expand_on_focus : bool = true + +## Enable function for auto expand lines container on double click in the line. +@export var behaviour_expand_on_double_click : bool = true: + set(e): + behaviour_expand_on_double_click = e + for l : LineSep in _separators: + l.double_click_handler = behaviour_expand_on_double_click + +## Enable movement by touching line. +@export var behaviour_can_move_by_line : bool = true: + set(e): + behaviour_can_move_by_line = e + for l : LineSep in _separators: + l.draggable = behaviour_can_move_by_line + +## This allow expand you current focused container if you shrunk it. +@export var behaviour_can_expand_focus_same_container : bool = false + +## Enable smooth when expand container. +@export var behaviour_expand_smoothed : bool = true: + set(e): + behaviour_expand_smoothed = e + if !e: + if _tween and _tween.is_running(): + _tween.kill() + _tween = null + +## Time speed duration for reset expand container. +@export_range(0.01, 1000.0, 0.01) var behaviour_expand_smoothed_time : float = 0.24: + set(e): + behaviour_expand_smoothed_time = maxf(0.01, e) + if _tween and _tween.is_running(): + _tween.kill() + _tween = null + +## Custom initial offset for separator lines. (TODO: Still Working here!) +@export var separators_line_offsets : Array[float] : + set(e): + separators_line_offsets = e + + if Engine.is_editor_hint(): + if separators_line_offsets.size() != _separators.size(): + separators_line_offsets.resize(_separators.size()) + update() + +@export_subgroup("Drag Button", "drag_button") + +## Set if drag button always be visible (Useful for test button size) +@export var drag_button_always_visible : bool = false: + set(e): + drag_button_always_visible = e + + var min_visible_drag_button : float = 0.0 + if drag_button_always_visible: + min_visible_drag_button = 0.4 + + for l : LineSep in _separators: + if l.button: + l.button.modulate.a = 0.0 + l.button.min_no_focus_transparense = min_visible_drag_button + +## Min size for drag button visible on split lines. +@export_range(1.0, 200.0, 0.1) var drag_button_size : float = 24.0: + set(e): + drag_button_size = e + update() + +## Modulate color for the drag button. +@export var drag_button_modulate : Color = Color.MAGENTA: + set(e): + drag_button_modulate = e + if drag_button_modulate == Color.MAGENTA: + if Engine.is_editor_hint(): + var root : Control = EditorInterface.get_base_control() + drag_button_modulate = root.get_theme_color("base_color", "Editor").lightened(0.5) + update() + +## Change default drag button icon. +@export var drag_button_icon : Texture = null: + set(e): + drag_button_icon = e + update() + +var _separators : Array[LineSep] = [] +var _last_container_focus : Node = null +var _frame : int = 1 +var _first : bool = true +var _tween : Tween = null + +func get_separators() -> Array[LineSep]: + return _separators + +## Get line begin offset limit. +func get_line_seperator_left_offset_limit(index : int) -> float: + if index < _separators.size(): + var line_sep : LineSep = _separators[index] + if !line_sep.is_vertical: + if index < 1: + return -_separators[index].initial_position.x + var next : LineSep = _separators[index - 1] + return (next.initial_position.x + (next.size.x/2.0)) - _separators[index].initial_position.x + else: + if index < 1: + return -_separators[index].initial_position.y + var next : LineSep = _separators[index - 1] + return (next.initial_position.y + (next.size.y/2.0)) - _separators[index].initial_position.y + push_warning("[PLUGIN] Not valid index for line separator!") + return 0.0 + +## Get line end offset limit. +func get_line_seperator_right_offset_limit(index : int) -> float: + if index < _separators.size(): + var line_sep : LineSep = _separators[index] + if !line_sep.is_vertical: + if index + 1 == _separators.size(): + return (size.x/2.0) -_separators[index].initial_position.x + var current : LineSep = _separators[index] + return (_separators[index + 1].initial_position.x - current.initial_position.x + (current.size.x/2.0)) + else: + if index + 1 == _separators.size(): + return size.x -_separators[index].initial_position.y + var current : LineSep = _separators[index] + return (_separators[index + 1].initial_position.y - current.initial_position.y + (current.size.y/2.0)) + push_warning("[PLUGIN] Not valid index for line separator!") + return 0.0 + +# This is function is util when you want expand or constraint manualy offset. +## Update offset of the line +func update_line_separator_offset(index : int, offset : float) -> void: + var line_sep : LineSep = _separators[index] + line_sep.offset = offset + line_sep.force_update() + +## Get total line count. +func get_line_separator_count() -> int: + return _separators.size() + +## Get Line reference by index, see get_line_separator_count() +func get_line_separator(index : int) -> LineSep: + return _separators[index] + +## Get if line separator is vertical. +func is_vertical_line_separator(index : int) -> bool: + if index < _separators.size(): + return _separators[index].is_vertical + push_warning("[PLUGIN] Not valid index for line separator!") + return false + +## Expand splited container by index container. +func expand_splited_container(node : Node) -> void: + var same : bool = _last_container_focus == node + + if same and !behaviour_can_expand_focus_same_container: + return + + _last_container_focus = node + + if !behaviour_expand_on_focus: + return + + if _tween and _tween.is_running(): + if same: + return + _tween.kill() + _tween = null + + var top_lines : Array[LineSep] = [] + var bottom_lines : Array[LineSep] = [] + + var update_required : bool = false + + for line : LineSep in _separators: + if node in line.top_items: + update_required = update_required or line.offset < 0.0 + top_lines.append(line) + elif node in line.bottom_items: + update_required = update_required or line.offset > 0.0 + bottom_lines.append(line) + + if update_required: + if behaviour_expand_smoothed: + _tween = get_tree().create_tween() + _tween.tween_method(_reset_expanded_lines.bind(top_lines, bottom_lines), 0.0, 1.0, behaviour_expand_smoothed_time) + else: + _reset_expanded_lines(1.0, top_lines, bottom_lines) + +func _reset_expanded_lines(_lerp : float, top_lines : Array[LineSep], bottom_lines : Array[LineSep]) -> void: + for iline : int in range(top_lines.size() - 1, -1, -1): + var line : LineSep = top_lines[iline] + if is_instance_valid(line): + if line.offset < 0.0: + line.offset = lerp(line.offset, 0.0, _lerp) + else: + top_lines.remove_at(iline) + + for iline : int in range(bottom_lines.size() - 1, -1, -1): + var line : LineSep = bottom_lines[iline] + if is_instance_valid(line): + if line.offset > 0.0: + line.offset = lerp(line.offset, 0.0, _lerp) + else: + bottom_lines.remove_at(iline) + + for line : LineSep in top_lines: + line.force_update() + for line : LineSep in bottom_lines: + line.force_update() + +## Get initial position of a separator line. +func get_line_separator_initial_position(index : int) -> Vector2: + if index < _separators.size(): + return _separators[index].initial_position + push_warning("[PLUGIN] Not valid index for line separator!") + return Vector2.ZERO + +class DragButton extends Button: + var _frm : float = 0.0 + var _line_sep : LineSep = null + var _is_pressed : bool = false + + var is_hover : bool = false + + var _hover : Array[bool] = [false, false] + + var min_no_focus_transparense : float = 0.0: + set(e): + min_no_focus_transparense = e + modulate.a = maxf(modulate.a, min_no_focus_transparense) + + static var DEFAULT_STYLE : StyleBox = null + + func set_drag_icon(new_icon : Texture) -> void: + if icon != new_icon: + if new_icon == null: + icon = SplitButton + return + icon = new_icon + + func update_gui() -> void: + if !_line_sep: + return + + if _line_sep.is_vertical: + _line_sep.mouse_default_cursor_shape = Control.CURSOR_VSPLIT + mouse_default_cursor_shape = Control.CURSOR_VSPLIT + else: + _line_sep.mouse_default_cursor_shape = Control.CURSOR_HSPLIT + mouse_default_cursor_shape = Control.CURSOR_HSPLIT + + func set_line(line_sep : LineSep) -> void: + if _line_sep: + if _line_sep.mouse_entered.is_connected(_on_enter): + _line_sep.mouse_entered.disconnect(_on_enter) + if _line_sep.mouse_exited.is_connected(_on_exit): + _line_sep.mouse_exited.disconnect(_on_exit) + if _line_sep.gui_input.is_connected(_on_input): + _line_sep.gui_input.disconnect(_on_input) + + _line_sep = line_sep + + if _line_sep: + if !_line_sep.mouse_entered.is_connected(_on_enter): + _line_sep.mouse_entered.connect(_on_enter.bind(1)) + if !_line_sep.mouse_exited.is_connected(_on_exit): + _line_sep.mouse_exited.connect(_on_exit.bind(1)) + if !_line_sep.gui_input.is_connected(_on_input): + _line_sep.gui_input.connect(_on_input) + + + func _init(line_sep : LineSep = null) -> void: + modulate.a = 0.0 + + set_line(line_sep) + + button_down.connect(_on_press) + button_up.connect(_out_press) + mouse_entered.connect(_on_enter.bind(0)) + mouse_exited.connect(_on_exit.bind(0)) + + gui_input.connect(_custom_input) + + icon = SplitButton + icon_alignment = HORIZONTAL_ALIGNMENT_CENTER + vertical_icon_alignment = VERTICAL_ALIGNMENT_CENTER + expand_icon = true + + if null != icon: + flat = true + + if DEFAULT_STYLE == null: + DEFAULT_STYLE = StyleBoxEmpty.new() + + focus_mode = Control.FOCUS_CLICK + + set(&"theme_override_styles/focus", DEFAULT_STYLE) + set(&"theme_override_styles/disabled_mirrored", DEFAULT_STYLE) + set(&"theme_override_styles/disabled", DEFAULT_STYLE) + set(&"theme_override_styles/hover_pressed_mirrored", DEFAULT_STYLE) + set(&"theme_override_styles/hover_pressed", DEFAULT_STYLE) + set(&"theme_override_styles/hover_mirrored", DEFAULT_STYLE) + set(&"theme_override_styles/hover", DEFAULT_STYLE) + set(&"theme_override_styles/pressed_mirrored", DEFAULT_STYLE) + set(&"theme_override_styles/pressed", DEFAULT_STYLE) + set(&"theme_override_styles/normal_mirrored", DEFAULT_STYLE) + set(&"theme_override_styles/normal", DEFAULT_STYLE) + + z_as_relative = true + z_index = 2000 + + update_gui() + + func _custom_input(e : InputEvent) -> void: + if e is InputEventMouseButton: + if e.pressed and e.double_click: + get_tree().call_group(&"ScriptSpliter", &"swap", get_parent()) + + func _on_input(e : InputEvent) -> void: + if e is InputEventMouseButton: + if e.pressed and e.double_click: + if _line_sep and _line_sep.double_click_handler: + _line_sep.offset = 0.0 + _line_sep.offset_updated.emit() + elif e.pressed and _line_sep.draggable and e.button_index == 1: + button_down.emit() + elif !e.pressed and _line_sep.draggable and e.button_index == 1: + button_up.emit() + + func set_line_sep_reference(ref : LineSep) -> void: + _line_sep = ref + + func _ready() -> void: + set_process(false) + + func _on_enter(x : int = 0) -> void: + _hover[x] = true + + _frm = 0.0 + modulate.a = 1.0 + is_hover = true + set_process(true) + + func _on_exit(x : int = 0) -> void: + _hover[x] = false + + for h : bool in _hover: + if h != false: + return + + _frm = 0.0 + modulate.a = 1.0 + is_hover = false + set_process(true) + + func _on_press() -> void: + _is_pressed = true + _frm = 0.0 + modulate.a = 1.0 + set_process(true) + + func _out_press() -> void: + _is_pressed = false + set_process(true) + + func _process(delta : float) -> void: + if !has_focus() and !is_hover: + _frm += delta * 0.4 + if _frm >= 1.0: + _frm = 1.0 + set_process(false) + modulate.a = lerp(modulate.a, min_no_focus_transparense, _frm) + if _is_pressed: + var mpos : Vector2 = _line_sep.get_parent().get_local_mouse_position() + if mpos != get_rect().get_center(): + _line_sep.update_offset_by_position(mpos) + +class UndoredoSplit extends RefCounted: + var object : SplitContainerItem = null + var c_objects : Array[Node] = [] + +class LineSep extends ColorRect: + signal offset_updated() + + var top_lines : Array[LineSep] = [] + var bottom_lines : Array[LineSep] = [] + + var top_items : Array[Control] = [] + var bottom_items : Array[Control] = [] + + var is_vertical : bool = false: + set(e): + is_vertical = e + + if button: + button.update_gui() + + var row : int = 0 + + var initial_position : Vector2 = Vector2.ZERO + var offset : float = 0.0 + + var min_size_offset : float = 0.0 + + var prev_line : LineSep = null + var next_line : LineSep = null + + var button : DragButton = null + + var double_click_handler : bool = true + var draggable : bool = true + + func set_next_line(next : LineSep = null) -> void: + next_line = next + next.prev_line = self + + func clear() -> void: + top_items.clear() + bottom_items.clear() + top_lines.clear() + bottom_lines.clear() + + func reset() -> void: + position = initial_position + update_items() + + func update_items() -> void: + if is_vertical: + for item : Control in top_items: + item.size.y = position.y - item.position.y + if !prev_line: + item.position.y = 0.0 + + for item : Control in bottom_items: + item.position.y = position.y + size.y + + if next_line: + item.size.y = next_line.position.y - item.position.y + else: + item.size.y = get_parent().size.y - item.position.y + else: + for item : Control in top_items: + item.size.x = position.x - item.position.x + (size.x / 2.0) - 2.0 + if !prev_line: + item.position.x = 0.0 + + for item : Control in bottom_items: + var diff : float = position.x + (size.x / 2.0) + 2.0 + item.position.x = diff + + if next_line: + item.size.x = next_line.position.x - item.position.x + else: + item.size.x = get_parent().size.x - item.position.x + + func force_update() -> void: + update_offset_by_position(initial_position + Vector2(offset * int(!is_vertical), offset * int(is_vertical))) + + func get_current_position() -> Vector2: + return initial_position + Vector2(offset * int(!is_vertical), offset * int(is_vertical)) + + func update_offset_by_position(vpos : Vector2) -> void: + if is_vertical: + min_size_offset = 0.0 + for x : Control in top_items: + min_size_offset = maxf(min_size_offset, x.get_minimum_size().y) + if prev_line: + prev_line.min_size_offset = 0.0 + for x : Control in prev_line.bottom_items: + prev_line.min_size_offset = maxf(prev_line.min_size_offset, x.get_minimum_size().y) + + offset = vpos.y - initial_position.y + offset = minf(offset, get_parent().size.y - (initial_position.y + size.y + min_size_offset)) + offset = maxf(offset, -(initial_position.y - min_size_offset)) + + if next_line: + var val : float = next_line.position.y - (initial_position.y + size.y + min_size_offset) + if offset > val: + offset = val + else: + var val : float = get_parent().size.y - (initial_position.y + (size.y / 2.0) + min_size_offset) + if offset > val: + offset = val + if prev_line: + var val : float = -(initial_position.y - (prev_line.position.y + prev_line.size.y + prev_line.min_size_offset)) + + if offset < val: + offset = val + else: + var top_size_offset : float = 0.0 + for x : Control in top_items: + top_size_offset = maxf(top_size_offset, x.get_minimum_size().y) + offset = maxf(offset, top_size_offset-initial_position.y) + + position.y = initial_position.y + offset + + for line : LineSep in top_lines: + line.size.y = position.y - line.position.y + + for line : LineSep in bottom_lines: + line.position.y = position.y + size.y + + if next_line: + line.size.y = next_line.position.y - line.position.y + else: + line.size.y = get_parent().size.y - line.position.y + else: + min_size_offset = 0.0 + for x : Control in bottom_items: + min_size_offset = maxf(min_size_offset, x.get_minimum_size().x) + + if prev_line: + prev_line.min_size_offset = 0.0 + for x : Control in prev_line.bottom_items: + prev_line.min_size_offset = maxf(prev_line.min_size_offset, x.get_minimum_size().x) + + offset = vpos.x - initial_position.x + offset = minf(offset, get_parent().size.x - (initial_position.x + size.x + min_size_offset)) + offset = maxf(offset, -initial_position.x) + + if next_line: + var val : float = next_line.position.x - (initial_position.x + size.x + min_size_offset) + if offset > val: + offset = val + else: + var val : float = get_parent().size.x - (initial_position.x + (size.x/2.0) + min_size_offset) + if offset > val: + offset = val + if prev_line: + var val : float = -(initial_position.x - (prev_line.position.x + prev_line.size.x + prev_line.min_size_offset)) + + if offset < val: + offset = val + else: + var top_size_offset : float = 0.0 + for x : Control in top_items: + top_size_offset = maxf(top_size_offset, x.get_minimum_size().x) + offset = maxf(offset, top_size_offset-initial_position.x) + + position.x = initial_position.x + offset + update_items() + + func _draw() -> void: + update() + + func update() -> void: + button.rotation_degrees = 90.0 * int(is_vertical) + button.pivot_offset = button.size / 2.0 + button.position = size / 2.0 - button.pivot_offset + + + + func _init() -> void: + color = Color.RED + + func _ready() -> void: + name = "SplitLine" + if button == null: + button = DragButton.new(self) + add_child(button, false, Node.INTERNAL_MODE_BACK) + +func _test() -> void: + queue_redraw() + +func _init() -> void: + child_entered_tree.connect(_on_enter) + child_exiting_tree.connect(_on_exiting) + +func update() -> void: + set_process(true) + +func _create_separator() -> Control: + var line_sep : LineSep = LineSep.new() + line_sep.offset_updated.connect(update) + return line_sep + +func _undoredo_undo(ur : UndoredoSplit) -> void: + if !is_instance_valid(ur): + return + + var split : SplitContainerItem = ur.object + if is_instance_valid(split): + if split.get_parent() == self: + ur.c_objects = split.get_children() + for x : Node in ur.c_objects: + split.remove_child(x) + if x is Control: + x.visible = false + add_child(x) + if is_instance_valid(split) and split.get_parent() == self: + remove_child(split) + +func _update() -> void: + var items : Array[Control] = [] + for x : Node in get_children(): + if is_instance_valid(x) and x is Control: + if x.visible and !x.is_queued_for_deletion(): + if x is SplitContainerItem: + if x.get_child_count() > 0: + var _is_visible : bool = false + for y : Node in x.get_children(): + if y is Control and y.visible: + _is_visible = true + break + if !_is_visible: + continue + else: + x.queue_free() + continue + elif x is DragButton or x is LineSep: + x.queue_free() + continue + else: + var container : SplitContainerItem = SplitContainerItem.new() + + add_child(container, true) + + x.reparent(container) + x = container + + + x.size_flags_horizontal = Control.SIZE_FILL + x.size_flags_vertical = Control.SIZE_FILL + x.clip_contents = true + x.custom_minimum_size = Vector2.ZERO + items.append(x) + + var totals : int = items.size() + var rows : int = 0 + + if max_columns > 0: + var _totals : int = totals + rows = 0 + while _totals > max_columns: + _totals -= max_columns + rows += 1 + totals -= rows + + if totals < 1: + for x : int in range(0, _separators.size(), 1): + _separators[x].queue_free() + _separators[x] = null + _separators.clear() + + for x : Control in items: + x.position = Vector2.ZERO + x.size = get_rect().size + return + else: + if separator_line_size <= 0.0: + for x : int in range(0, _separators.size(), 1): + _separators[x].queue_free() + _separators[x] = null + _separators.clear() + else: + var sep : int = totals - 1 + rows + for x : int in range(sep, _separators.size(), 1): + _separators[x].queue_free() + _separators[x] = null + _separators.resize(sep) + for x : int in range(0, _separators.size(), 1): + if _separators[x] == null: + _separators[x] = _create_separator() + + rows += 1 + if max_columns > 1: + if totals > max_columns: + totals = max_columns + + var rect_size : Vector2 = get_rect().size + var start_position : Vector2 = Vector2.ZERO + + var size_split : Vector2 = (rect_size / Vector2(totals, rows)) + + var size_sep : Vector2 = Vector2.ONE * separator_line_size + + if totals > 1: + size_sep = (size_sep / (totals - 1)) + + var item_size : Vector2 = Vector2(size_split.x, size_split.y) + var line_size : Vector2 = Vector2(separator_line_size, item_size.y) + + var total_items : int = items.size() + + var vpos : Vector2 = Vector2.ZERO + var current_row : int = 0 + + var item_index : int = 0 + + var last_vline : LineSep = null + var last_hline : LineSep = null + + for x : Control in items: + x.position = Vector2.ZERO + x.size = x.get_minimum_size() + + for z : int in range(_separators.size()): + var x : LineSep = _separators[z] + + x.clear() + + start_position.x += 1 + + if 0 < max_columns and start_position.x + 1 > max_columns: + total_items -= max_columns + start_position.x = 0.0 + start_position.y += 1.0 + current_row += 1 + if total_items <= max_columns and total_items > 0: + size_split = (rect_size / Vector2(total_items, rows)) + if total_items == 1: + size_sep = Vector2.ONE * separator_line_size + else: + size_sep = ((Vector2.ONE * separator_line_size) / (total_items - 1)) + item_size = Vector2(size_split.x, size_split.y) + line_size = Vector2(separator_line_size, rect_size.y - x.position.y) + + vpos = Vector2(0.0, start_position.y) * item_size + x.is_vertical = true + + if x.get_parent() == null: + add_child(x, false, Node.INTERNAL_MODE_BACK) + + + x.row = current_row + + if items.size() > 0: + var it : int = mini(item_index, items.size() - 1) + var min_size : float = 0.0 + + var _has : bool = false + + for y : int in range(z - 1, -1, -1): + if it > -1: + var item : Control = items[it] + x.top_items.append(item) + min_size = maxf(item.get_minimum_size().y, min_size) + it -= 1 + + var ln : LineSep = _separators[y] + if ln.is_vertical: + _has = true + break + x.top_lines.append(ln) + if !_has: + for _it : int in range(it, -1, -1): + var item : Control = items[it] + x.top_items.append(item) + + if item_index + 1 < items.size(): + it = item_index + 1 + _has = false + for y : int in range(z + 1, _separators.size(), 1): + if it < items.size(): + var item : Control = items[it] + x.bottom_items.append(item) + it += 1 + + var ln : LineSep = _separators[y] + if ln.is_vertical: + _has = true + break + x.bottom_lines.append(ln) + if !_has: + for _it : int in range(it, items.size(), 1): + var item : Control = items[_it] + x.bottom_items.append(item) + + var vline_size : Vector2 = Vector2(rect_size.x, separator_line_size) + + x.initial_position = vpos + x.initial_position.y -= (vline_size.y) / 2.0 + x.position = x.initial_position + + x.button.size = Vector2(drag_button_size, drag_button_size) + + x.set(&"size", vline_size) + x.update() + + if last_vline: + last_vline.set_next_line(x) + + last_vline = x + last_hline = null + item_index += 1 + continue + + vpos = start_position * item_size + + if x.get_parent() == null: + add_child(x, false, Node.INTERNAL_MODE_BACK) + + + if item_index < items.size(): + var item : Control = items[item_index] + x.top_items.append(item) + item_index += 1 + if item_index < items.size(): + if z + 1 < _separators.size(): + if !_separators[z].is_vertical: + x.bottom_items.append(items[item_index]) + else: + x.bottom_items.append(items[item_index]) + + x.initial_position = vpos + x.initial_position.x -= (line_size.x) / 2.0 + + x.button.size = Vector2(drag_button_size, drag_button_size) + + x.row = current_row + x.position = x.initial_position + + x.set(&"size", line_size) + x.update() + + if last_hline: + last_hline.set_next_line(x) + last_hline = x + + for x : Control in items: + x.size = size + + var min_visible_drag_button : float = 0.0 + if drag_button_always_visible: + min_visible_drag_button = 0.4 + + if _first: + for l : LineSep in _separators: + l.visible = separator_line_visible + l.color = separator_line_color + l.double_click_handler = behaviour_expand_on_double_click + l.button.self_modulate = drag_button_modulate + l.button.min_no_focus_transparense = min_visible_drag_button + l.button.set_drag_icon(drag_button_icon) + l.draggable = behaviour_can_move_by_line + + l.reset() + + else: + if separators_line_offsets.size() > 0: + for l : int in range(0, _separators.size(), 1): + if l < separators_line_offsets.size(): + _separators[l].offset = separators_line_offsets[l] + continue + break + + for l : LineSep in _separators: + l.visible = separator_line_visible + l.color = separator_line_color + l.double_click_handler = behaviour_expand_on_double_click + l.button.self_modulate = drag_button_modulate + l.button.min_no_focus_transparense = min_visible_drag_button + l.button.set_drag_icon(drag_button_icon) + l.draggable = behaviour_can_move_by_line + + l.force_update() + + if !Engine.is_editor_hint(): + separators_line_offsets.clear() + else: + for l : int in range(0, _separators.size(), 1): + if l < separators_line_offsets.size(): + separators_line_offsets[l] = _separators[l].offset + continue + break + +func _on_enter(n : Node) -> void: + n.is_inside_tree() + if n is SplitContainerItem or (n is Control and !Engine.is_editor_hint()): + if !n.visibility_changed.is_connected(_on_visible): + n.visibility_changed.connect(_on_visible) + if is_node_ready(): + for x : int in range(separators_line_offsets.size()): + separators_line_offsets[x] = 0.0 + update() + +func _on_visible() -> void: + update() + +func _on_exiting(n : Node) -> void: + if n is SplitContainerItem or (n is Control and !Engine.is_editor_hint()): + if is_node_ready(): + for x : int in range(separators_line_offsets.size()): + separators_line_offsets[x] = 0.0 + for x : LineSep in _separators: + x.offset = 0.0 + if n.visibility_changed.is_connected(_on_visible): + n.visibility_changed.disconnect(_on_visible) + update() + +func _process(__ : float) -> void: + if is_node_ready(): + if _frame > 0: + _frame -= 1 + return + _update() + if _first: + _first = false + else: + set_process(false) + +func _on_exiting_tree() -> void: + var vp : Viewport = get_viewport() + if vp and vp.size_changed.is_connected(update): + vp.size_changed.disconnect(update) + + var parent : Node = get_parent() + if parent is Control: + if parent.item_rect_changed.is_connected(update): + parent.item_rect_changed.disconnect(update) + +func _enter_tree() -> void: + var vp : Viewport = get_viewport() + if vp and !vp.size_changed.is_connected(update): + vp.size_changed.connect(update) + + var parent : Node = get_parent() + if parent is Control: + if !parent.item_rect_changed.is_connected(update): + parent.item_rect_changed.connect(update) + + if !tree_exiting.is_connected(_on_exiting_tree): + tree_exiting.connect(_on_exiting_tree) + +func _on_draw() -> void: + update() + +func _ready() -> void: + separator_line_color = separator_line_color + drag_button_modulate = drag_button_modulate + + size_flags_horizontal = Control.SIZE_EXPAND_FILL + size_flags_vertical =Control.SIZE_EXPAND_FILL + + set_deferred(&"anchor_left", 0.0) + set_deferred(&"anchor_top", 0.0) + set_deferred(&"anchor_bottom", 1.0) + set_deferred(&"anchor_right", 1.0) + + if Engine.is_editor_hint(): + draw.connect(_on_draw) + + if _first: + update() diff --git a/addons/script_spliter/core/ui/multi_split_container.gd.uid b/addons/script_spliter/core/ui/multi_split_container.gd.uid new file mode 100644 index 0000000..4d714ab --- /dev/null +++ b/addons/script_spliter/core/ui/multi_split_container.gd.uid @@ -0,0 +1 @@ +uid://cbd7egxjurkl4 diff --git a/addons/script_spliter/core/ui/split_container_item.gd b/addons/script_spliter/core/ui/split_container_item.gd new file mode 100644 index 0000000..223b613 --- /dev/null +++ b/addons/script_spliter/core/ui/split_container_item.gd @@ -0,0 +1,69 @@ +@tool +@icon("icon/MultiSpliterItem.svg") +extends Control +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# https://github.com/CodeNameTwister/Multi-Split-Container +# +# Multi-Split-Container addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +var focus_handler : bool = false + +## Expand if tight by spliter +func show_splited_container() -> void: + var parent : Node = get_parent() + if parent.has_method(&"expand_splited_container"): + parent.call(&"expand_splited_container", self) + + +func _ready() -> void: + set_process(false) + + size_flags_horizontal = Control.SIZE_FILL + size_flags_vertical = Control.SIZE_FILL + + set_deferred(&"anchor_left", 0.0) + set_deferred(&"anchor_top", 0.0) + set_deferred(&"anchor_bottom", 1.0) + set_deferred(&"anchor_right", 1.0) + +func _init() -> void: + name = "SplitContainerItem" + + child_exiting_tree.connect(_on_child_exiting_tree) + child_entered_tree.connect(_on_child_entered_tree) + +func _on_visible() -> void: + var _visible : bool = false + for x : Node in get_children(): + if x is Control: + if x.visible: + _visible = true + break + visible = _visible + +func _on_child_entered_tree(n : Node) -> void: + if n is Control: + n.size = size + n.set_anchor(SIDE_LEFT, 0.0) + n.set_anchor(SIDE_RIGHT, 1.0) + n.set_anchor(SIDE_TOP, 0.0) + n.set_anchor(SIDE_BOTTOM, 1.0) + if !n.visibility_changed.is_connected(_on_visible): + n.visibility_changed.connect(_on_visible) + +func _disconnect(n : Node) -> void: + if n is Control: + if n.visibility_changed.is_connected(_on_visible): + n.visibility_changed.disconnect(_on_visible) + for x : Node in n.get_children(): + _disconnect(x) + +func _on_child_exiting_tree(n : Node) -> void: + _disconnect(n) + +func _enter_tree() -> void: + var c : Node = get_parent() + if c is Control: + size = c.size diff --git a/addons/script_spliter/core/ui/split_container_item.gd.uid b/addons/script_spliter/core/ui/split_container_item.gd.uid new file mode 100644 index 0000000..50508dc --- /dev/null +++ b/addons/script_spliter/core/ui/split_container_item.gd.uid @@ -0,0 +1 @@ +uid://buerhchaby30c diff --git a/addons/script_spliter/io/backward_key_button.tres b/addons/script_spliter/io/backward_key_button.tres new file mode 100644 index 0000000..b3fcda1 --- /dev/null +++ b/addons/script_spliter/io/backward_key_button.tres @@ -0,0 +1,5 @@ +[gd_resource type="InputEventKey" format=3 uid="uid://p4o5dw6yauu"] + +[resource] +alt_pressed = true +key_label = 4194319 diff --git a/addons/script_spliter/io/backward_mouse_button.tres b/addons/script_spliter/io/backward_mouse_button.tres new file mode 100644 index 0000000..394ee5a --- /dev/null +++ b/addons/script_spliter/io/backward_mouse_button.tres @@ -0,0 +1,5 @@ +[gd_resource type="InputEventMouseButton" format=3 uid="uid://bwpahdvr80ivr"] + +[resource] +device = -1 +button_index = 8 diff --git a/addons/script_spliter/io/forward_key_button.tres b/addons/script_spliter/io/forward_key_button.tres new file mode 100644 index 0000000..03c1d61 --- /dev/null +++ b/addons/script_spliter/io/forward_key_button.tres @@ -0,0 +1,5 @@ +[gd_resource type="InputEventKey" format=3 uid="uid://b43ac78k4ox2a"] + +[resource] +alt_pressed = true +physical_keycode = 4194321 diff --git a/addons/script_spliter/io/forward_mouse_button.tres b/addons/script_spliter/io/forward_mouse_button.tres new file mode 100644 index 0000000..eab54ba --- /dev/null +++ b/addons/script_spliter/io/forward_mouse_button.tres @@ -0,0 +1,4 @@ +[gd_resource type="InputEventMouseButton" format=3 uid="uid://bs1lk5ids0s01"] + +[resource] +button_index = 9 diff --git a/addons/script_spliter/plugin.cfg b/addons/script_spliter/plugin.cfg new file mode 100644 index 0000000..94d35ed --- /dev/null +++ b/addons/script_spliter/plugin.cfg @@ -0,0 +1,9 @@ +[plugin] + +name="Script Spliter" +description="Tool Addon for godot 4 +Allow split script window." +author="Twister" +version="0.3.6" +github="https://github.com/CodeNameTwister/Script-Spliter" +script="plugin.gd" diff --git a/addons/script_spliter/plugin.gd b/addons/script_spliter/plugin.gd new file mode 100644 index 0000000..4b1ac33 --- /dev/null +++ b/addons/script_spliter/plugin.gd @@ -0,0 +1,458 @@ +@tool +extends EditorPlugin +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Script Spliter +# https://github.com/CodeNameTwister/Script-Spliter +# +# Script Spliter addon for godot 4 +# author: "Twister" +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +const BUILDER : Script = preload("res://addons/script_spliter/core/builder.gd") +const CONTEXT : Script = preload("res://addons/script_spliter/context/context_window.gd") + +const CMD_MENU_TOOL : String = "Script Spliter" + +#CONTEXT +const ICON_ADD_COLUMN : Texture = preload("res://addons/script_spliter/context/icons/split_cplus.svg") +const ICON_REMOVE_COLUMN : Texture = preload("res://addons/script_spliter/context/icons/split_cminus.svg") +const ICON_ADD_ROW : Texture = preload("res://addons/script_spliter/context/icons/split_rplus.svg") +const ICON_REMOVE_ROW : Texture = preload("res://addons/script_spliter/context/icons/split_rminus.svg") +const ICON_FLOATING : Texture = preload("res://addons/script_spliter/context/icons/atop.png") +const ICON_TAB : Texture = preload("res://addons/script_spliter/assets/tab_icon.svg") + +var _rmb_editor_add_split : EditorContextMenuPlugin = null +var _rmb_editor_remove_split: EditorContextMenuPlugin = null +var _rmb_editor_code_add_split : EditorContextMenuPlugin = null +var _rmb_editor_code_remove_split : EditorContextMenuPlugin = null +var _rmb_editor_pop_script : EditorContextMenuPlugin = null +var _rmb_editor_code_pop_script : EditorContextMenuPlugin = null + +var _rmb_close_all_tab_in_split : EditorContextMenuPlugin = null +var _rmb_close_all_tab_in_split_right : EditorContextMenuPlugin = null +var _rmb_close_all_tab_in_split_left : EditorContextMenuPlugin = null + +var _menu_split_selector : Window = null +var _builder : Object = null + +var _daemon_chaser : Node = null + +#region _REF_ +var _tab_container : Node = null: + get: + if !is_instance_valid(_tab_container): + var script_editor: ScriptEditor = EditorInterface.get_script_editor() + _tab_container = find(script_editor, "*", "TabContainer") + return _tab_container + +var _item_list : Node = null: + get: + if !is_instance_valid(_item_list): + var script_editor: ScriptEditor = EditorInterface.get_script_editor() + _item_list = find(script_editor, "*", "ItemList") + return _item_list +#endregion + +#region _USER_BUFFER_ +var _rows : int = 0: + set(e): + _rows = maxi(e, 0) +var _columns : int = 0: + set(e): + _columns = maxi(e, 0) +var _refresh_warnings_on_save : bool = true +#endregion + +var _frm : int = 0 +var _d_chase : bool = false + +func get_builder() -> Object: + return _builder + +func find(root : Node, pattern : String, type : String) -> Node: + var e : Array[Node] = root.find_children(pattern, type, true, false) + if e.size() > 0: + return e[0] + return null + +func get_split_rows() -> int: + return _rows + +func get_split_columns() -> int: + return _columns + +func _on_save(res : Resource) -> void: + if res is Script: + _save_external_data() + +func _save_external_data() -> void: + if _d_chase == true: + return + _d_chase = true + if _refresh_warnings_on_save and is_instance_valid(_builder): + if _daemon_chaser == null: + _daemon_chaser = ResourceLoader.load("res://addons/script_spliter/core/DaemonChaser.gd").new() + add_child(_daemon_chaser) + _daemon_chaser.set_current_index(_builder.get_current_focus_index()) + _daemon_chaser.buffer = _builder.get_focus_config() + _builder.enable_focus_highlight(false) + _daemon_chaser.run(_builder.focus_by_index, _builder.set_focus_config) + set_deferred(&"_d_chase", false) + +func _process(__: float) -> void: + if _frm < 2: + _frm += 1 + return + _frm = 0 + set_process(false) + if is_instance_valid(_builder): + _builder.update() + +func _on_change_settings() -> void: + if is_instance_valid(_builder): + _builder.update_config() + var settings : EditorSettings = EditorInterface.get_editor_settings() + var changes : PackedStringArray = settings.get_changed_settings() + + if &"plugin/script_spliter/behaviour/refresh_warnings_on_save" in changes: + _refresh_warnings_on_save = settings.get_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save") + +func _init() -> void: + var o : Object = _tab_container + if o == null: + #push_warning("[Script-Spliter] 0x000A") + return + o = _item_list + if o == null: + #push_warning("[Script-Spliter] 0x000B") + return + +func _run() -> void: + if is_instance_valid(_builder): + var settings : EditorSettings = EditorInterface.get_editor_settings() + var scripts_tab_container : Node = _tab_container + + if !scripts_tab_container: + push_warning("[Script-Spliter] 0x000A Error can not find editor reference!") + return + + var il : Node = _item_list + if null != il: + _builder.set_item_list(il) + else: + push_warning("[Script-Spliter] 0x000B Error can not find editor reference!") + return + + if !scripts_tab_container.is_node_ready(): + await scripts_tab_container.ready + if !is_instance_valid(scripts_tab_container): + push_error("Unspected error reference be replace or free it, can not run plugin!") + return + + settings.settings_changed.connect(_on_change_settings) + + _builder.init_1() + _builder.build(scripts_tab_container, _columns, _rows) + set_process_input(true) + +func set_type_split(columns : int, rows : int) -> void: + _columns = columns + _rows = rows + + var str_columns : String = str(maxi(_columns, 1)) + var str_rows : String = str(maxi(rows, 1)) + + print("[{0}] {1} {2}: > {3} {5} - {4} {6}".format( + [ + _get_translated_text("INFO"), + _get_translated_text("Setting"), + _get_translated_text("To"), + _get_translated_text("Columns"), + _get_translated_text("Rows"), + str_columns, + str_rows + ]) ) + + if is_instance_valid(_builder): + _builder.update_build(columns, rows) + +func _exit_tree() -> void: + remove_tool_menu_item(CMD_MENU_TOOL) + _setup(0) + + if is_instance_valid(_builder): + _builder.init_0() + _builder.free.call_deferred() + + var settings : EditorSettings = EditorInterface.get_editor_settings() + if settings.settings_changed.is_connected(_on_change_settings): + settings.settings_changed.disconnect(_on_change_settings) + + if is_instance_valid(_daemon_chaser) and !_daemon_chaser.is_queued_for_deletion(): + _daemon_chaser.queue_free() + +func _get_translated_text(text : String) -> String: + # TODO: Translation + return text + +func swap(caller : Object) -> void: + if is_instance_valid(_builder): + _builder.swap(caller) + +func _setup(input : int) -> void: + var settings : EditorSettings = EditorInterface.get_editor_settings() + + if input != 0: + add_to_group(&"ScriptSpliter") + + main_screen_changed.connect(_on_change) + resource_saved.connect(_on_save) + + var ctx_add_column : String = _get_translated_text("ADD_SPLIT").capitalize() + var ctx_remove_split : String = _get_translated_text("REMOVE_SPLIT").capitalize() + var ctx_pop_script : String = _get_translated_text("MAKE_FLOATING_SCRIPT").capitalize() + var ctx_close_tabs : String = _get_translated_text("CLOSE_OTHERS_TABS_IN_SPLIT").capitalize() + var ctx_close_tabs_right : String = _get_translated_text("CLOSE_RIGHT_TABS_IN_SPLIT").capitalize() + var ctx_close_tabs_left : String = _get_translated_text("CLOSE_LEFT_TABS_IN_SPLIT").capitalize() + + #SETUP + _rmb_editor_add_split = CONTEXT.new(ctx_add_column, _add_window_split, _can_add_split, ICON_ADD_COLUMN) + _rmb_editor_remove_split = CONTEXT.new(ctx_remove_split, _remove_window_split, _can_remove_split, ICON_REMOVE_COLUMN) + + _rmb_editor_code_add_split = CONTEXT.new(ctx_add_column, _add_window_split, _can_add_split, ICON_ADD_COLUMN) + _rmb_editor_code_remove_split = CONTEXT.new(ctx_remove_split, _remove_window_split, _can_remove_split, ICON_REMOVE_COLUMN) + + _rmb_editor_pop_script = CONTEXT.new(ctx_pop_script, _make_pop_script, _can_make_pop_script, ICON_FLOATING) + _rmb_editor_code_pop_script = CONTEXT.new(ctx_pop_script, _make_pop_script, _can_make_pop_script, ICON_FLOATING) + + _rmb_close_all_tab_in_split = CONTEXT.new(ctx_close_tabs, _close_all_tabs_in_split, _can_close_tab_in_split, ICON_TAB) + _rmb_close_all_tab_in_split_left = CONTEXT.new(ctx_close_tabs_left, _close_all_tabs_in_split_left, _can_close_left_tab_in_split, ICON_TAB) + _rmb_close_all_tab_in_split_right = CONTEXT.new(ctx_close_tabs_right, _close_all_tabs_in_split_right, _can_close_right_tab_in_split, ICON_TAB) + + add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_close_all_tab_in_split) + add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_close_all_tab_in_split_left) + add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_close_all_tab_in_split_right) + + + add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_editor_add_split) + add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_editor_remove_split) + + add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, _rmb_editor_code_add_split) + add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, _rmb_editor_code_remove_split) + + add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_editor_pop_script) + add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, _rmb_editor_code_pop_script) + + if !settings.has_setting(&"plugin/script_spliter/rows"): + settings.set_setting(&"plugin/script_spliter/rows", _rows) + else: + _rows = settings.get_setting(&"plugin/script_spliter/rows") + if !settings.has_setting(&"plugin/script_spliter/columns"): + settings.set_setting(&"plugin/script_spliter/columns", _columns) + else: + _columns = settings.get_setting(&"plugin/script_spliter/columns") + if !settings.has_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit"): + settings.set_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit", false) + if !settings.has_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save"): + settings.set_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save", _refresh_warnings_on_save) + else: + _refresh_warnings_on_save = settings.get_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save") + else: + if is_in_group(&"ScriptSpliter"): + remove_from_group(&"ScriptSpliter") + + main_screen_changed.disconnect(_on_change) + resource_saved.disconnect(_on_save) + + if is_instance_valid(_rmb_close_all_tab_in_split): + remove_context_menu_plugin(_rmb_close_all_tab_in_split) + if is_instance_valid(_rmb_close_all_tab_in_split_right): + remove_context_menu_plugin(_rmb_close_all_tab_in_split_right) + if is_instance_valid(_rmb_close_all_tab_in_split_left): + remove_context_menu_plugin(_rmb_close_all_tab_in_split_left) + + if is_instance_valid(_rmb_editor_add_split): + remove_context_menu_plugin(_rmb_editor_add_split) + if is_instance_valid(_rmb_editor_remove_split): + remove_context_menu_plugin(_rmb_editor_remove_split) + if is_instance_valid(_rmb_editor_code_add_split): + remove_context_menu_plugin(_rmb_editor_code_add_split) + if is_instance_valid(_rmb_editor_code_remove_split): + remove_context_menu_plugin(_rmb_editor_code_remove_split) + if is_instance_valid(_rmb_editor_pop_script): + remove_context_menu_plugin(_rmb_editor_pop_script) + if is_instance_valid(_rmb_editor_code_pop_script): + remove_context_menu_plugin(_rmb_editor_code_pop_script) + + + if settings.has_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit"): + if settings.get_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit") == true: + settings.set_setting(&"plugin/script_spliter/rows", _rows) + settings.set_setting(&"plugin/script_spliter/columns", _columns) + +func _can_close_tab_in_split(path : PackedStringArray) -> bool: + return _builder.has_other_tabs() + +func _can_close_right_tab_in_split(path : PackedStringArray) -> bool: + return _builder.has_right_tabs() + +func _can_close_left_tab_in_split(path : PackedStringArray) -> bool: + return _builder.has_left_tabs() + +func _close_all_tabs_in_split(__ : Variant) -> void: + _builder.close_other_tabs() + +func _close_all_tabs_in_split_right(__ : Variant) -> void: + _builder.close_right_tabs() + +func _close_all_tabs_in_split_left(__ : Variant) -> void: + _builder.close_left_tabs() + +func _can_add_split(path : PackedStringArray) -> bool: + if !is_instance_valid(_builder): + return false + if path.size() == 0: + return _builder.can_add_split(null) + else: + for x : String in path: + if x.begins_with("res://"): + var sc : ScriptEditor = EditorInterface.get_script_editor() + return _builder.can_add_split(sc.get_current_editor().get_base_editor()) + else: + var node : Node = get_node_or_null(x) + if node: + return _builder.can_add_split(node) + else: + var sc : ScriptEditor = EditorInterface.get_script_editor() + return _builder.can_add_split(sc.get_current_editor().get_base_editor()) + return false + +func _can_remove_split(path : PackedStringArray) -> bool: + if !is_instance_valid(_builder): + return false + if path.size() == 0: + return _builder.can_remove_split(null) + else: + for x : String in path: + if x.begins_with("res://"): + var sc : ScriptEditor = EditorInterface.get_script_editor() + return _builder.can_remove_split(sc.get_current_editor().get_base_editor()) + else: + var node : Node = get_node_or_null(x) + if node: + return _builder.can_remove_split(node) + else: + var sc : ScriptEditor = EditorInterface.get_script_editor() + return _builder.can_remove_split(sc.get_current_editor().get_base_editor()) + return false + +func _add_window_split(variant : Variant) -> void: + var control : Control = null + if variant is Script: + var sc : ScriptEditor = EditorInterface.get_script_editor() + if variant == sc.get_current_script(): + control = sc.get_current_editor().get_base_editor() + else: + var c : ScriptEditorBase = sc.get_current_editor() + if c: + control = c.get_base_editor() + elif variant is CodeEdit: + control = variant + if is_instance_valid(control): + _builder.add_split(control) + +func _remove_window_split(variant : Variant) -> void: + var control : Control = null + if variant is Script: + var sc : ScriptEditor = EditorInterface.get_script_editor() + if variant == sc.get_current_script(): + control = sc.get_current_editor().get_base_editor() + else: + var c : ScriptEditorBase = sc.get_current_editor() + if c: + control = c.get_base_editor() + elif variant is CodeEdit: + control = variant + if is_instance_valid(control): + _builder.remove_split(control) + +func _make_pop_script(variant : Variant) -> void: + var control : Control = null + if variant is Script: + var sc : ScriptEditor = EditorInterface.get_script_editor() + var arr : Array[ScriptEditorBase] = sc.get_open_script_editors() + var scs : Array[Script] = sc.get_open_scripts() + if arr.size() == scs.size(): + for y : int in range(0, scs.size(), 1): + if scs[y] == variant: + control = arr[y].get_base_editor() + break + if variant is CodeEdit: + control = variant + if is_instance_valid(control): + _builder.make_pop_script(control) + +func _can_make_pop_script(path : PackedStringArray) -> bool: + if !is_instance_valid(_builder): + return false + for x : String in path: + var node : Node = get_node_or_null(x) + if node: + return !_builder.is_pop_script(node) + return false + +func _on_change(screen_name : String) -> void: + if screen_name == "Script": + if is_instance_valid(_builder): + _builder.update_rect.call_deferred() + + +func _enter_tree() -> void: + _setup(1) + if !is_instance_valid(_builder): + _builder = BUILDER.new(self) + add_tool_menu_item(CMD_MENU_TOOL, _on_tool_command) + +func _on_tool_command() -> void: + if is_instance_valid(_builder): + var data : Array[int] = _builder.get_current_columns_and_rows() + _columns = data[0] + _rows = data[1] + + if !is_instance_valid(_menu_split_selector): + _menu_split_selector = (ResourceLoader.load("res://addons/script_spliter/context/menu_tool.tscn") as PackedScene).instantiate() + _menu_split_selector.set_plugin(self) + _menu_split_selector.visible = false + add_child(_menu_split_selector) + _menu_split_selector.popup_centered.call_deferred() + +func _ready() -> void: + set_process(false) + set_process_input(false) + if !get_tree().root.is_node_ready(): + await get_tree().root.ready + for __ : int in range(2): + await get_tree().process_frame + _run() + +func _notification(what: int) -> void: + if what == NOTIFICATION_PREDELETE: + if is_instance_valid(_builder) and !_builder.is_queued_for_deletion(): + _builder.init_0() + _builder.free() + +func _input(event: InputEvent) -> void: + if event is InputEventKey: + if event.pressed and event.ctrl_pressed: + if event.keycode == 49: + set_type_split(0, 0) + elif event.keycode == 50: + set_type_split(2, 1) + elif event.keycode == 51: + set_type_split(1, 2) + elif event.keycode == 52: + set_type_split(3, 1) + elif event.keycode == 53: + set_type_split(1, 3) + elif event.keycode == 54: + set_type_split(2, 2) diff --git a/addons/script_spliter/plugin.gd.uid b/addons/script_spliter/plugin.gd.uid new file mode 100644 index 0000000..00567bf --- /dev/null +++ b/addons/script_spliter/plugin.gd.uid @@ -0,0 +1 @@ +uid://dwmaoslxt1uop diff --git a/characters/samus/samus-texture-128-corrected.png b/characters/samus/samus-texture-128-corrected.png new file mode 100755 index 0000000..279bf27 Binary files /dev/null and b/characters/samus/samus-texture-128-corrected.png differ diff --git a/characters/samus/samus-texture-128-corrected.png.import b/characters/samus/samus-texture-128-corrected.png.import new file mode 100644 index 0000000..b57e341 --- /dev/null +++ b/characters/samus/samus-texture-128-corrected.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ge73q5qik686" +path.s3tc="res://.godot/imported/samus-texture-128-corrected.png-ff9d6e4a0c1ecde120b84e2b801c0cf2.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://characters/samus/samus-texture-128-corrected.png" +dest_files=["res://.godot/imported/samus-texture-128-corrected.png-ff9d6e4a0c1ecde120b84e2b801c0cf2.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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/characters/samus/samus-texture-mat.tres b/characters/samus/samus-texture-mat.tres new file mode 100644 index 0000000..61bf687 --- /dev/null +++ b/characters/samus/samus-texture-mat.tres @@ -0,0 +1,7 @@ +[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://dfacvvhew44xp"] + +[ext_resource type="Texture2D" uid="uid://ge73q5qik686" path="res://characters/samus/samus-texture-128-corrected.png" id="1_awcuv"] + +[resource] +albedo_texture = ExtResource("1_awcuv") +texture_filter = 0 diff --git a/characters/samus/samus.bin b/characters/samus/samus.bin new file mode 100644 index 0000000..0ed273f --- /dev/null +++ b/characters/samus/samus.bin @@ -0,0 +1,524 @@ +]P=?)]P=?)]P=?)^Z ?$- ^Z ?$- ^Z ?$- ^Z ?$- %P=?3=%P=?3=%P=?3=t<7?Ot<7?Ot<7?Ot<7?Ot??O=t??O=t??O=t??O=;? ;? ;? ;? ?qo?qo?qo?qo]+1?]+1?]+1?]+1?t><7?Ot><7?Ot><7?Ot><7?O]>P=?7]>P=?7]>P=?7t>??O=t>??O=t>??O=t>??O=>;? >;? >;? >;? >? =>? =>? =>? =O/>9?ѽO/>9?ѽO/>9?ѽO/>9?ѽH>c?;;H>c?;;H>c?;;H>c?;; w9?d w9?d w9?d w9?d>Y?K=>Y?K=>Y?K=>Y?K=ɮ>!?,=ɮ>!?,=ɮ>!?,=ɮ>!?,='3Y?\M>'3Y?\M>'3Y?\M>'3Y?\M>]3B?>]3B?>]3B?>]3B?>3s?O>3s?O>3s?O>3s?O>Y?K=Y?K=Y?K=Y?K=? =? =? =? =Ǯ!? -=Ǯ!? -=Ǯ!? -=Ǯ!? -=O/9?ѽO/9?ѽO/9?ѽO/9?ѽHc?;;Hc?;;Hc?;;Hc?;;Qiq?Qiq?Qiq?sc? sc? sc? sc? ͗2$?p͗2$?p͗2$?p͗2$?p潛L3%?r2>L3%?r2>L3%?r2>L3%?r2>M>iq?M>iq?M>iq?Q>?=Q>?=Q>?=M?=M?=M?=B3Ԕ?Vr>B3Ԕ?Vr>B3Ԕ?Vr>B3Ԕ?Vr>^Z3 ?$- >^Z3 ?$- >^Z3 ?$- >^Z3 ?$- >%=P=?-=%=P=?-=%=P=?-=XB>|jXB>|jXB>|jXB>|jL{k=0HļL{k=0HļL{k=0HļL{k=0HļaFL>%aFL>%aFL>%aFL>%XBl!ѯ|jXBl!ѯ|jXBl!ѯ|j >KI= >KI= >KI= >KI= >KI=ma|=ma|=ma|=ma|=Ƭը=z=Ƭը=z=Ƭը=z=Ƭը=z= ]=vY> ]=vY> ]=vY> ]=vY>+UO=bJ=+UO=bJ=+UO=bJ=+UO=bJ=S1Ŀ=B=S1Ŀ=B=S1Ŀ=B=S1Ŀ=B="b>=(>"b>=(>"b>=(>l!ѯP=l!ѯP=l!ѯP=Ll!ѯ0HļLl!ѯ0HļLl!ѯ0HļQQl!ѯllm=QQl!ѯllm=QQl!ѯllm=),Oy>),Oy>),Oy>`(>`(>`(>s&vY>s&vY>s&vY>X6=z>X6=z>X6=z>mal!ѯ mal!ѯ mal!ѯ aFl!ѯ%aFl!ѯ%aFl!ѯ%HB=>jHB=>jHB=>jHB=>jJ={k=JHļJ={k=JHļJ={k=JHļJ={k=JHļ`F>L>%`F>L>%`F>L>%`F>L>%HB=l!ѯjHB=l!ѯjHB=l!ѯj> >KI=> >KI=> >KI=> >KI=> >KI=ka>|=:ka>|=:ka>|=:ka>|=:ͬ>ը=n=ͬ>ը=n=ͬ>ը=n=ͬ>ը=n=,>]=vY>,>]=vY>,>]=vY>,>]=vY>+U>=8J=+U>=8J=+U>=8J=+U>=8J=Z1=}'=~B=Z1=}'=~B=Z1=}'=~B=Z1=}'=~B=="b>=(>="b>=(>="b>=(>=l!ѯP==l!ѯP==l!ѯP=.,O>o>.,O>o>.,O>o>J=l!ѯJHļJ=l!ѯJHļJ=l!ѯJHļ+`=(>+`=(>+`=(>SQ>l!ѯ@lm=SQ>l!ѯ@lm=SQ>l!ѯ@lm=ka>l!ѯ9ka>l!ѯ9ka>l!ѯ9`F>l!ѯ%`F>l!ѯ%`F>l!ѯ%&>vY>&>vY>&>vY>X>6=n>X>6=n>X>6=n>%y?2??~%y?2??~%y?2??~%y?2??~%y?2??~?$ ? ?$ ? ?$ ? ?$ ? 㽅?F?%<㽅?F?%<㽅?F?%<㽅?F?%<ԅ?6?$0ԅ?6?$0ԅ?6?$0ԅ?6?$0(??((??((??((??(?a??a??a??a???iv??iv??iv??iv??iv ?? ?? ?? ????t?7 >t?7 >t?7 >t?7 R=? R=? R=? =4?ͼ=4?ͼ=4?ͼ=4?ͼf%>H?@f%>H?@f%>H?@f%>H?@V]=?oԼV]=?oԼV]=?oԼV]=?oԼ-=?<=-=?<=-=?<=-=?<=-=?<==Z?==Z?==Z?==Z?=4b=?%\>4b=?%\>4b=?%\>4b=?%\>Ή3a?1>Ή3a?1>Ή3a?1>Ή3a?1>f3? $>f3? $>f3? $>f3? $>QN|3?ǀ">QN|3?ǀ">QN|3?ǀ">QN|3?ǀ">-?D=-?D=-?D=-?D=-?D=ĽZ?=ĽZ?=ĽZ?=ĽZ?=b?'\>b?'\>b?'\>b?'\>CȮr?_#p=CȮr?_#p=CȮr?_#p=h%H?@h%H?@h%H?@h%H?@8བྷ}?)Ƽ8བྷ}?)Ƽ8བྷ}?)Ƽ8བྷ}?)Ƽ1L߽A6?k'ٽ1L߽A6?k'ٽ1L߽A6?k'ٽY%@?BY%@?BY%@?BY%@?BiS3?}>iS3?}>iS3?}>iS3?}>~8=}?UƼ~8=}?UƼ~8=}?UƼ~8=}?UƼh?h?h?h?%L=A6?w'ٽ%L=A6?w'ٽ%L=A6?w'ٽIȮ=r?O#p=IȮ=r?O#p=IȮ=r?O#p=<"L;?YԼ<"L;?YԼ<"L;?YԼ<"L;?YԼZ?Z?Z?Z?Z?6{$?fɚ<6{$?fɚ<6{$?fɚ<6{$?fɚN@JǗ?*=>N@JǗ?*=>N@JǗ?*=>N@JǗ?*=>cS?a=cS?a=cS?a=cS?a=MީsK{?>=MީsK{?>=MީsK{?>=MީsK{?>=)ӽ? M)ӽ? M)ӽ? M)ӽ? M)ӽ? Mֽs0?1ֽs0?1ֽs0?1ֽs0?1C?C?C?C?C?}ȼ?i߼}ȼ?i߼}ȼ?i߼}ȼ?i߼䭽?䭽?䭽?䭽?QH(8?,O>QH(8?,O>QH(8?,O>QH(8?,O>QH(8?,O>QH(8?,O>-?&^O-?&^O-?&^O-?&^O7G?7G?7G?7G?N(Oy>ςN(Oy>ςN(Oy>ςN(Oy>ςJĈik>7JĈik>7JĈik>7JĈik>7JĈik>7>L +>L +>L +>L +k>k>k>k>b,V>>\b,V>>\b,V>>\b,V>>\~뽫>ɚ~뽫>ɚ~뽫>ɚ~뽫>ɚY+>ۇY+>ۇY+>ۇY+>ۇ=MEL=EFɽ=MEL=EFɽ=MEL=EFɽUS>?J=US>?J=US>?J=US>?J=y>P'=y>P'=y>P'=y>P'=tj=H!ڟj>H!ڟj>H!ڟj>H > > > > >.0=aW.0=aW.0=aW1@ڽz>-1@ڽz>-1@ڽz>-1@ڽz>-ˇ?`?鑽ˇ?`?鑽ˇ?`?鑽ˇ?`?鑽ˇ?`?鑽?q?`zۼ?q?`zۼ?q?`zۼ?q?`zۼ6??6??6??6????l%4??l%4??l%4??l%4h? ?˽h? ?˽h? ?˽h? ?˽5$?Rs?25$?Rs?25$?Rs?25$?Rs?2セ+??.+??.+??.+??.f?1?f?1?f?1?f?1?f?1?΂,?'?u ΂,?'?u ΂,?'?u ΂,?'?u +??B+??B+??B+??B4,?[%?i;4,?[%?i;4,?[%?i;4,?[%?i;K,?0 ?hؼK,?0 ?hؼK,?0 ?hؼK,?0 ?hؼk>Q?.k>Q?.k>Q?.k>Q?.k>Q?.k>Q?.>n?fd<>n?fd<>n?fd<>n?fd<>n?fd<>n?fd<>4?1<>4?1<>4?1<>4?1<>4?1<>4?1<ò>i?0=ò>i?0=ò>i?0=ò>i?0=ò>i?0=4>)?YJx4>)?YJx4>)?YJx4>)?YJx4>)?YJx>=?)G>=?)G>=?)G>=?)G>=?)G2?I?92?I?92?I?9P[0??SE$P[0??SE$P[0??SE$$1??1 +$1??1 +$1??1 +{>e?1{>e?1{>e?1{>e?1{>e?1[>+?h=[>+?h=[>+?h=[>+?h=[>+?h=x>p?7=x>p?7=x>p?7=x>p?7=x>p?7=o>H?.o>H?.o>H?.o>H?.o>H?.\ҫ>"?\ҫ>"?\ҫ>"?\ҫ>"?\ҫ>"?^>0?F|^>0?F|^>0?F|^>0?F|^>0?F|X>?@X>?@X>?@X>?@X>?@6={$?Hɚ<6={$?Hɚ<6={$?Hɚ<6={$?Hɚ{$?=3>{$?=3>{$?=3>{$?=J>{$?z;J>{$?z;J>{$?z;J>{$?z;&.>{$?ڽ&.>{$?ڽ&.>{$?ڽ&.>{$?ڽgn>s S?gn>s S?gn>s S?gn>s S?J>? APJ>? APJ>? APJ>? APٍ=A?=ٍ=A?=ٍ=A?=ٍ=A?=K>e?m=K>e?m=K>e?m=K>e?m=s>T?T?T?T?j?(>Dv->j?(>Dv->j?(>Dv->j?(>N@>JǗ? =>N@>JǗ? =>N@>JǗ? =>N@>JǗ? =>=wީ=wީ=wީ=)=?o M)=?o M)=?o M)=?o M)=?o M=s0?1=s0?1=s0?1=s0?1>C?B>C?B>C?B>C?B>C?B}<?s߼}<?s߼}<?s߼}<?s߼=?=?=?=?[H>(8?&O>[H>(8?&O>[H>(8?&O>[H>(8?&O>[H>(8?&O>[H>(8?&O>->?X^O->?X^O->?X^O->?X^O7>G?7>G?7>G?7>G?H(>Oy>ׂH(>Oy>ׂH(>Oy>ׂH(>Oy>ׂJĈ>ik>7JĈ>ik>7JĈ>ik>7JĈ>ik>7JĈ>ik>7=> L +=> L +=> L +=> L +k>>k>>k>>k>>b,>V>>db,>V>>db,>V>>db,>V>>dp=>Ϛp=>Ϛp=>Ϛp=>ϚY>+>Y>+>Y>+>Y>+>9M>EL=YFɽ9M>EL=YFɽ9M>EL=YFɽW>S>!J=W>S>!J=W>S>!J=W>S>!J=z>>B'=z>>B'=z>>B'=z>>B'=t>j=j=j=j=j=<ڟ=j>Hڟ=j>Hڟ=j>Hڟ=j>H<><><><><>*=0=oW*=0=oW*=0=oW!@=z>1!@=z>1!@=z>1!@=z>16b=N?*>6b=N?*>6b=N?*> =d?c> =d?c> =d?c>3"?1)D>3"?1)D>3"?1)D>3"?1)D>F3T??5>F3T??5>F3T??5>F3T??5> +d?c> +d?c> +d?c>bN?*>bN?*>bN?*>kI<>:Ѿ>ZʪS>Szl8 :Ѿ>Z̪SSzH8 ʪS>Szl8 (> >ZkI<>v;?ʪS>Szl8 g>n6H:Ѿ>Zv;?vܾ(>cmK?9|Jm=n6Hp羰|ݾG g>n6H:Ѿ>Z(> >Z~>g>r6H g>n6Hp羰|ݾG^>|ݾG~>g>r6H(> >Z~>g>r6HmI?<> >ZmI?<>>(>_mK?>v;?mI?<>|ݾG~>g>r6H(>_mK?y?<J?|ݾG2v>÷=?\?]o9|?J=^>a?sA׾2v>÷=?g"?0";? +>\?]oDvŷ8?p羰|ݾG^>|ݾG2v>÷=?? d?y?<J?\?]o9|?J==t>,~ +?dG?? d?g"?0";? +>\?]oyBJ? j?? d?y?<J?yBJ?vܾ(>cmK?>(>_mK?y?<J? j?+t,~ +?dG?=t>,~ +?dG?? d?9|Jm=\]oyBJ? j?9|Jm=cmK?\]o}g"0";?> j?+t,~ +?dG?9|Jm=\]oDvŷ8?p羰|ݾG\]o}g"0";?>Dvŷ8?^a?oA׾}g"0";?>^a?oA׾-=(l?v>Dvŷ8?^a?oA׾^>a?sA׾2v>÷=?^a?oA׾-(l?v>-=(l?v>^>a?sA׾+t,~ +?dG?-(l?v>-=(l?v>=t>,~ +?dG?-(l?v>^>a?sA׾g"?0";? +>-(l?v>=t>,~ +?dG?g"?0";? +>}g"0";?>+t,~ +?dG?-=(l?v>v;?vܾ(>cmK?>(>_mK?>v;?v;?̪SSzH8 ʪS>Szl8 >v;?̪SSzH8 >v;?mI?<>߼?'==I#v>e? +(>}?Q`v>e? +(>;>N{?;;>}?Q`9z GX⾍b?þ>߼?'==I#=I#}?Q``6?>⾍b?þ>߼?'=v>e? +(>;>z|W:g$$>9z GX`6?>⾍b?þ>`6?> i?>-w>@k?>;>5'"dURA? i?>-w>@k?>a?]G?~3|!z|W:g$$>`6?> i?>-w>@k?>;>N{?;;>?/fk7:-w>@k?>a?]G??/fk7:N{?;;>?/fk7:N{?;;>}?Q`~3|!z|W:g$$>~3|!5'"dURA?a?]G??/fk7:5'"dURA?a?]G?~3|!5'"dURA? i?>z|W:g$$>9z GX9z GX=I#}%`rԾe?' +(>-H#<?'=}%`2{;;>!??k?rԾe?' +(>-H#<?'=>b?>9z?7GX}%`-H#!??k?rԾe?' +(><?'=>b?>X+??u>>b?>X+??u>9z?7GX9|?:s[$>!??k?DWk?Z>7>Fi? J>X+??u>a]G?DWk?Z>7>Fi? J>5'?"dORA?7>Fi? J>X+??u>9|?:s[$>`~?V~~ɽ*<2{;;>!??k?DWk?Z>~~ɽ*~~ɽ*<2{;;>5'?"dORA?`~?V}%`2{;;>~~ɽ*`~?V9z?7GX9|?:s[$>-H#9z?7GXa]G?5'?"dORA?7>Fi? J>5'?"dORA?`~?VWM>6>PVj>щU}+K* 2Do-C ?F%WM>6>C ?F%FY1T?I?vf>{?5WM>6>PVj>FY1T?I?Vq +H.OP;?щU}+K* C ?F%BWS{vf>{?5щU}+K* 2Do-BWS{ғC>zdɽPVj>2Do-Vq +H.OP;?ғC>zdɽ.|yVq +H.OP;?=&I#~?ғC>zdɽnG4?0;=5a5?BWS{.|yd>OU^}ғC>zdɽFY1T?I?Vq +H.OP;?nG4?0;=5a5?[<.|y=&I#~?ȃ>]n#^?FY1T?I?=&I#~?vf>{?53>Po?nG4?0;=5a5?BWS{d>OU^}vf>{?53>Po?=&I#~?3>Po?ȃ>]n#^?V?AXI?b˽d>OU^}a>V"hi3>Po?V?AXI?b˽ȃ>]n#^?V?AXI?b˽_?oǖža>V"hiV?AXI?b˽_?oǖž[<ȃ>]n#^?_?oǖž[V"hi_?oǖž[<.|yd>OU^}a>V"hiRA?RA?{w>!v? T]?RA?<UHB T]?RA?dr_<?={w>!v?RA?VQ>odr_<?=RA?VQ>o<UHBVQ>o<UHB)&I?{c>BDK?E)&I?{c>B2I?$)?q<K?1>h?DK?EoM?5>VQ>odr_<?=)&I?{c>B2I?$)?q<<UHB T]?DK?EoM?5>{w>!v? T]?K?1>h?oM?5>dr_<?={w>!v?2I?$)?q<K?1>h?9Cp ?\=Ta޵ZY[uW>Jx`ԭc28㾷ed?q +f]\=Ta;Z-?} [{=Yq;?'i>?iq +f]9Cp ?;Z-?} h">Jl?U=D?8 ?c28㾷ed?i>?i9Cp ?޵ZY[uW>h">Jl?>;'?[>{ٽYq?\=TaJx`ԭ[{=YqU>=D8 h>"Jl޵ZY[uW>Jx`ԭ>;'?U>=D8 ;?Z-} =?iq +f]?iU>=D8 h>"Jl;?Z-} =9C?>p ?\嬭<>;'?[>{ٽYq?;?Z-} =\=?T>a??\嬭Jl?U=D?8 ?[>{ٽYq?G> z`?ѭ>\=?T>a?G> z`?ѭ>޵>ZY[?uW\=?T>a?9C?>p ?\嬭<;Z-?} U=D?8 ?;?'G> z`?ѭ>޵>ZY[?uW[{=Yq;?'h>"Jl޵>ZY[?uW9C?>p 5{3>bʡ=N]9蝾W[KN]9蝾W[K>W[K{N>]95{3>bʡ=sp9> Ҿ,WY>N]95{3>bʡ=XfnBܾK蝾W[Kp4pXfnBܾK^Z> M_Q!>[p4p5{3>bʡ=sp9>XfnBܾKdH[>蝾W[Kp4p>p4p>W[KM_Q!>[p4p>p4p:_>P!>[>p4p>W[KXf?nBܾ>L5{?3> ʡ=>p4p:_>P!>[^?Z>) Xf?nBܾ>L>W[K{N>]95{?3> ʡ=d?H[u>Xf?nBܾ>Ls?p%>5{?3> ʡ=(N?s>q>^?Z>) d?H[u>Xf?nBܾ>L{N>]9>,WY>s?p%>5{?3> ʡ=YQZ=Op?>fY?>ZV?b?HVپ=>d?H[u>s?p%>fY?>ZV? ?>\>?(N?s>q>d?H[u>V=>D\>>,WY>b?HVپ=>s?p%>\Y>ZV?QZOp?>YQZ=Op?>fY?>ZV?>b>?\Y>ZV?fY?>ZV? ?>\>? Ҿ,WY>N=D\>V=>D\>>,WY>sp9>dH[>bHVپͽ=>\Y>ZV?QZOp?>dH[>(Ns>>>b>?\Y>ZV?sp9>bHVپͽ=> Ҿ,WY>N=D\>(Ns>>>b>?ⳢvZ?e>XfnBܾKdH[>^Z> (Ns>>^Z> (Ns>>ⳢvZ?e>@Arp?b^Z> M_Q!>[@Arp?bⳢvZ?e>@Arp?b@>Arp?b쳢>vZ?_>>b>?ⳢvZ?e>쳢>vZ?_> ?>\>?@>Arp?b쳢>vZ?_>(N?s>q>^?Z>) M_Q!>[@Arp?b@>Arp?b:_>P!>[@>Arp?b:_>P!>[^?Z>) 쳢>vZ?_> ?>\>?(N?s>q> Ҿ,WY>N]9{N>]9>,WY>+]&*#Tjf>qo<؍tbՖXr_>tG>>"mXr_>tG>>"m}L?"mx?.*9oK٦S^?#Tjf>Xr_>tG>}L? w4*\+]&*qo<؍tbՖ=|q}O.) w4*\ Ȗ $h=|q}O.) Ȗ $h{>ҕh?X?8?ɾ Ȗ $h=|x?.*xy?Iҕh?X?>c? $>'VA< +?9oK٦S^?>g?}L?g??>c? $>>g?}L?g?/q?>?(xy?Iҕh?X?>c? $>?8?ɾ/q?>?( Ȗ $h?8?ɾ/q?>?(xy?IVn??>oB?Ԓ6o?翽fڝ/N? +b"? =ZD5^? +F>6o?翽޼~?==M w?K}?fڝ/N? +>oB?ԒmVH?{{s?5^? +F>DmmI=>t!8WӼ1P>Vn??>oB?Ԓt!8WӼ1޼~?==MVn??<=>h +t!8WӼ1^e>}MRԗe:? w?K}?<=>h +t!8WӼ1^e>}M}~=DSrT?N{$:6n?e(=QRAeýG>Rԗe:?LyZ1="<=>h +AeýG>LyZ1="笜=l̿AeýG>Rԗe:?Z=? G,?vO?I?Rԗe:? w?K}?mVH?{{s?vO?I?AeýG>;Mn笜=l̿r>4vk73Z=? G,?Z=? G,?vO?I?rT?N{$:6n?e(=QRb"? =ZDmVH?{{s?vO?I?rT?N{$:5^? +F>r>4vk73Z=? G,?6n?e(=QR;Mn~=DSr>4vk736n?e(=QRkV?T=X?ѾM3 [?Oؾ>E[?>>Ma?>$5=wF ; ?=>ku?3 [?Oؾ>E[?>>=wF ; ?=6SC#X?ѾM3 [?Oؾ>=>ku?=_}?u{PE[?>>Ma?>$5=_}?u{P>逕>rkV?T=Ma?>$50=6SC#>逕>rkV?T=X?ѾMa n?g>D=6SC#>逕>r4$v6>a nm>-B?ݒK?b?g>DݒK?b?g>D=_}?u{P>逕>r4$v6>a n=wF ; ?=6SC#4$v6>m>-B?=wF ; ?=>ku?m>-B?ݒK?b=>ku?=_}?u{P-=m]ı=gd?">E^)ҭa>Y`>>?2`-D?>d ?-=m]G^\=?L>%E=?K>=rq8?0?| >?2`G^\=?ı=gd?\>HE? ?g>2(>:Il?8?0?| -D?>d ?Krq?L%E=?g>2(>:Il?a>Y`>-D?>d ?g2(:Il\HE K>=rq">E^)ҭ>?2`80| =\HE L%E=?">E^)ҭa>Y`>-=m]ı=gd??Mf=8-=m]G^\=??Mf=8G^\=?ı=gd??Mf=8Mf8<-D>d> 80| =g2(:Il\HE Mf8<>2>`?80| =Krq?L%E=?>2>`?"E^?)ҭ>Krq?\>HE? ?g>2(>:Il?Mf8<-D>d> >2>`?cY?U"E^?)ҭ>cY?U"E^?)ҭ>L>%E=?\>HE? ?8?0?| -D>d> cY?Ug2(:IlL>%E=?K>=rq"mPr_t G>oμ؍tbՖ'T>jf>+>]P*x.d*vLx.d*"mL|oμ؍tbՖvL'T>jf>>oK?ئSU?'T>jf>+>]P*>oK?ئSU?w?5*\L|oμ؍tbՖ+>]P*w?5*\L|ǖ> 'hw?5*\}q}?O)8?ɾ {ҕh?Xǖ> 'h}q}?O)zyI 'h>oK?ئSU?-V?A< +?w?5*\}q}?O);۾c? $> {ҕh?X-V?A< +?}q}?O)vLoK?ئSU?-V?A< +?;۾c? $>oѾg?-V?A< +?zyI?(oѾg?/q>?(8?ɾ;۾c? $> {ҕh?XzyI?(8?ɾǖ> 'h%־oB?ʒPVn??<~?;=Zڝ>/N?>6o?8翽/^ +Z>j" =ZDZڝ>/N?>6o?8翽j" =ZDeNd*<~?;=>6o?8翽/^ +Z>gVH{{s?%־oB?ʒZڝ>/N?&w??K}?Hmm?I=>%־oB?ʒPVn??l!8?WӼ%1Hmm?I=>PVn??eNd*<~?;=l!8?WӼ%1eNd*^;e>}l!8?WӼ%1 <=?>h+l!8?WӼ%1 <=?>h+&w??K}?R?ԗe:?Hmm?I=>rTN{:j" =ZDeNd*^;e>}DR^;e>} <=?>h+L?yZ1="DRl̿ۻMnL?yZ1="6ne(==RrTN{:DR^;e>} <=?>h+L?yZ1="R?ԗe:?Ae?ý3>l̿L?yZ1="Ae?ý3>pOQ?Z= G,?R?ԗe:?Ae?ý3>pOQ?gVH{{s?&w??K}?R?ԗe:?Z= G,?r4vk13l̿ۻMnAe?ý3>6ne(==RrTN{:pOQ?Z= G,?/^ +Z>rTN{:pOQ?gVH{{s?j" =ZD6ne(==RZ= G,?r4vk136ne(==Rr4vk13DRۻMnV=>D\>L>R=f?b?HVپ=>YQZ=Op?>L>R=f?b?HVپ=>8ؾR=f?QZOp?>YQZ=Op?>L>R=f?8ؾR=f?N=D\>V=>D\>L>R=f?bHVپͽ=>8ؾR=f?QZOp?>bHVپͽ=>8ؾR=f?N=D\>=$?=$?=$?$?=B?=B?$?0>$?0>$?0>$?=?=?=?=?0>?0>?0>?0>?=>=>=>=>????>>>>=?=?=?=?=$?=$?=$?0>?0>?0>?0>?=>=>=>=>0>>0>>0>>0>>=>=>=>=>=p>=p>=p>=p>>>>>0>>0>>0>>0>>0>p>0>p>0>p>0>p>>>>>>>>>>>>>>>>>>>>>>>>>0>>0>>0>>0>>0>>0>>0>>0>>0>p>0>p>0>p>0>p>=>=>=>=>=p>=p>=p>=p>======p>p>p>p>====>>@>@>>>======0>=0>=0>=0>=0>=0>=>?>?>?>?>$?0>B?0>B?>$?0>$?0>$?0>$?=`?0>p?=`?0>p?=P?=p?=p?=p?h>p?>`?>`?h>p??0>~?0>~?>b?=H?=H?=H?=f?>p?>p?>p?>P?>b?>b?=f?=f?>p?>b?=f?<p?>p?>p?>p?>p?=p?=p?=p?=p?=p?=p?=p??=~?=~??=~?=~?>~?>~??>~?>~???=~?=~?>~??<~?>p?>p?>p?>~?>~??h>~??h>~?0>p?=`?0>p?=`?=p?=p?=p?=P?h>p?>`?>`?h>p?0>~?0>~??=f?=H?=H?=H?>b?>P?>p?>p?>p?=f?=f?>b?>b?<p?=f?>b?>p?>p?>p?>p?>p?=p?=p?=p?=p?=p?=p?=p?=~?=~???>~?>~?=~?=~??=~?=~???>~?>~??>~?>~?h>~??h>~?<~??>~?>p?>p?>p?>>>>>h>>@>>>>>>>>>>>>>>>>>>>>x>>x>>x>>x>>`>>`>>`>>`>> >> >> >> >> >> >>>> >>`>>`>>`>>`>>`>>>>>>`>> >> >>>>>>>>>>>>>>x>>x>>x>>x>>x>>>>>>>>>>x>>x>>x>>x>>>>>> >>x>>x>>`>> >>>> >>`>>`>>`>>`>>`>>`>>`>>V??R?J?^?>R?l?>l?>>X?>X?P>\?P>\?P>\?P>\?P>\?l?>l?>0>l?0>l?l?>l?&?P>N?P>N?l??l??>X?>X?l??l??>l?>l?H?>>>,?>?>>0>>@>p?@>>@>p?@>>>V?@>V?@>V?@>V?@>>>?@>?@>?@>?@>?@> ?@> ?@> ?@> ?@> ?@>b?>>=0>=p?@>>=>=V?@>>=>=?=?=?=?=?=,?=,?=,?=,?=,?=H?=H?=H?=H?=H?=V?p?=~?=>=~?=>=>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>?>?>?>?>>>>>>>>>>>>>>>>>?>?>?>?>>>>>>>>>?>?>?>?>>>>>>>>>>>>>>>?>?>?>?>>>>>>>>>>>>>>>>>>>?>?>?>?>>>>>>>>>>?>?>?>?????????>>>>>>>>>>>>>>>>>>?>?>?>?>>>>>>>>> +?> +?> +?>?>?>?>?> +?> +?> +?> +?> +?> +?> +?>?>?>?>?> +???>?> +?? +?> +?> +?> +?> +?>?>?> +?> +?> +?> +?> +?> +?> +?>>>>>>>>>>?>?>?>?>?>>>>"?J?"?J?>>>J?>>:?J? +?J?> +?> +? +?J?>J?>J?> +?> +?>J?>?>?>J?>*?>*?>*?>*?> ?> ??N??N?>*?>*?:?*?:?*?>*?>*?>*?>*?> ?> ?>d?>d? +?*? +?*? +?*? +?*? +? ? +? ? ?? ??"?*?"?*?"?*?"?*?"? ?4?~?4?~?"? ??h??h??h??h??h?> ?:?`?:?`?:? ?>p?>p?>p?>p?>p?>l?>l?~?>~?Z?>Z?@?(?@?(?l?>l?~?~?T?Z?T?Z?T?Z?T?Z?H?j?H?j?H?j?H?j?H?j?T?P?T?P?T?P?T?P?d?Z?d?Z?d?Z?d?Z?x?Z?>V?>V?x?Z?d?P?d?P?d?P?d?P?d?j?d?j?d?j?d?j?x?j?x?j?>`?d?~?d?~?d?(?d?(?T?~?T?~?T?(?T?(?x?~?>^?>^?>^?x?(?d?N?x?N?x?P?>N?x?P?X>.?X>.?X>.?X>.?X>.??>?>x>,?x>,?? +??>X>&?X>&??>?>h>6?h>6??>?>H>6?H>6??>?>8>,?8>,?>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>0>>?>,?>>>H?>>>p?@>>@>p?@>>@>>>V?@>V?@>V?@>V?@>?@>?@>?@>?@>?@> ?@> ?@> ?@> ?@> ?@>0>=>=b?>>=>=p?@>>=>=V?@>?=?=?=?=?=,?=,?=,?=,?=,?=H?=H?=H?=H?=H?= ??=~?=>=~?=>=>?>?>?>?>?"?J?"?J?>>>>:?J?>>>J?>> +?J?> +?> +? +?J?> +?> +?>J?>J?>J?>?>?>J?>*?>*?>*?>*??N??N?> ?> ?:?*?:?*?>*?>*?>*?>*?>*?>*?>d?>d?> ?> ? +?*? +?*? +?*? +?*? ?? ?? +? ? +? ?"?*?"?*?"?*?"?*?"? ?4?~?4?~?"? ??h??h??h??h??h?:? ?:?`?:?`?> ?>p?>p?>p?>p?>p?l?>l?~?>~?@?(?@?(?>Z?>Z?@?~?@?~?>l?>l?~?~?V?>V?x?Z?d?P?d?P?d?P?d?P?d?j?d?j?d?j?d?j?>`?x?j?x?j?d?(?d?(?d?~?d?~?T?(?T?(?T?~?T?~?x?(?>^?>^?>^?x?~?d?N?x?P?>N?x?P?>N?>>>>>>>>>>>>>?>?>?>?>?>>>>>?>>>>>>>>>>>>                     + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +_?R==_?R==_?R==>Y?==>Y?==>Y?==>Y?==C?'F>4,=C?'F>4,=C?'F>4,=u>!?w>=˾6=u>!?w>=˾6=u>!?w>=˾6=u>!?w>=˾6=Yi?N:='=Yi?N:='=Yi?N:='=Yi?N:='=֠$?c><=͹=֠$?c><=͹=֠$?c><=͹=֠$?c><=͹=97H?(><<97H?(><<97H?(><<97H?(><< yO?=a= yO?=a= yO?=a= yO?=a=s>!?w>=ɾ6=s>!?w>=ɾ6=s>!?w>=ɾ6=s>!?w>=ɾ6=_?R==_?R==_?R==Yi?N:='=Yi?N:='=Yi?N:='=Yi?N:='=٠$?[><=͹=٠$?[><=͹=٠$?[><=͹=٠$?[><=͹=+<*?=Y=-=+<*?=Y=-=+<*?=Y=-=+<*?=Y=-=,6?">z>,6?">z>,6?">z>,6?">z>Fj?e=Fj?e=Fj?e=Fj?e==TE?O\(>%g=^<=TE?O\(>%g=^<=TE?O\(>%g=^<=TE?O\(>%g=^'=&=vQ.?[-&>'=&=vQ.?[-&>'=&=vQ.?[-&>'=&=I?@$>Y=N߃Y=N߃Y=N߃Y=N߃C>l=l=xA>C>l=l=xA>C>l=l=xA>C>l=l=????e>hR>4,'>4,'>e>hR>4,'>4,'>e>hR>4,'>4,'>e>hR>4,'>4,'>qQ.?a-&>'=;=qQ.?a-&>'=;=qQ.?a-&>'=;=qQ.?a-&>'=;='<*?.=Y=-='<*?.=Y=-='<*?.=Y=-='<*?.=Y=-=I?@$>h=V߃h=V߃h=V߃h=V߃<,6?">z>,6?">z>,6?">z>,6?">z>Fj?e=Fj?e=Fj?e=Fj?e=f?p=f?p=f?p=>?>}=}=>?>}=}=>?>}=}=>?>}=}=MJ?==MJ?==MJ?==MJ?==z>z>Dl=?[=z>z>Dl=?[=z>z>Dl=?[=z>z>Dl=?[=f?s=f?s=f?s=i?=<i?=<i?=<i?=<i?=<i?=<>>3>>>3>>>3>>>3>i>h>$K;i>h>$K;i>h>$K;i>h>$K;C?'F>+,=C?'F>+,=C?'F>+,=[?1>[?1>[?1>[?1>vb?RT=vb?RT=vb?RT=vb?RT=[?>[?>[?>[?>Fi?L˵=Fi?L˵=Fi?L˵=tge?Y=tge?Y=tge?Y=tge?Y=tge?Y=k\?E +>8C*;k\?E +>8C*;k\?E +>8C*;k\?E +>8C*;bW?w!>bW?w!>bW?w!>bW?w!>????b[?{>b[?{>b[?{>b[?{>%ZL?K>2;%ZL?K>2;%ZL?K>2;%ZL?K>2;Bb?=Bb?=Bb?=\?' >\?' >\?' >Y?><Y?><Y?><`?@k>`?@k>`?@k>k?=k?=k?=Ud?Um=Ud?Um=Ud?Um=???vh?zK=vh?zK=vh?zK=@?(">=@?(">=@?(">=i?=i?=i?=;\?>;\?>;\?>;\?>7b?H6=7b?H6=7b?H6=7b?H6=P[?j>P[?j>P[?j>P[?j>Ni?=Ni?=Ni?=+*e?=+*e?=+*e?=+*e?=+*e?=]?{ >]?{ >]?{ >]?{ >X?S>X?S>X?S>X?S>????hIS?`2>hIS?`2>hIS?`2>hIS?`2>\W?#>\W?#>\W?#>\W?#>r`?9o=r`?9o=r`?9o=98\?>98\?>98\?>+k?-=+k?-=+k?-=a`X?> ><a`X?> ><a`X?> ><?wd? F=?wd? F=?wd? F= ?> ?> ?>OA?!>D(=OA?!>D(=OA?!>D(=i?Z=i?Z=i?Z=???kj?=kj?=kj?=Yr?tV=Yr?tV=Yr?tV=Yr?tV=Yr?tV=^?>^?>^?>^?>TBb?w=;TBb?w=;TBb?w=;TBb?w=;a?4=<a?4=<a?4=<a?4=<e?}=L<e?}=L<e?}=L<e?}=L<`?"=#;`?"=#;`?"=#;`?"=#;U?G)>U?G)>U?G)>U?G)>U?G)>=?>=?>=?>=?>Zc?a=f=Zc?a=f=Zc?a=f=xS?x2>xS?x2>xS?x2>xS?x2> `?= `?= `?= `?= `?=:K?S>:K?S>:K?S>:K?S>OZ?>OZ?>OZ?>OZ?>J9?!j>J9?!j>J9?!j>J9?!j>Ib?M=Ib?M=Ib?M=.gi?ƴ=.gi?ƴ=.gi?ƴ=)8f?>=)8f?>=)8f?>=Yf?2=Yf?2=Yf?2=v3?>v3?>v3?>v3?>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????     V +  ##*$ '(!+(+/0,404@););12<k2k6?38?8DL.>L>HG=BGBPIESISWFM[F[TUQ]U]RYaRa^_ch_h9`::ZzeZebdfldli5jo5ourngrg|qwtqtmC7vCvyAxsAsO\Np\p{~JX~X%--K&&}"  +    ")!%&*(50(0,+.7+7 3[:3:-A81/;F/F>6==@GL@LE?DD$IORIRM<UN<NHPVYPYSZWTZT9KQXKX]CJ\C\4#B2#2'^_e^b_^kb^eh^hkiwninlmo{m{cu}qrpyv~d|dat``gszfxfxjP..     + !!&  ##/')O)O%=%=,1$+1+30226>94>4-:F8:85?LB?B<;AI;IGHJJ77EKDDCNN  M@ @RRQVXbW^YUj\TagSfidymdmhkouku]nqntx|pxpl`{`{e}}zZZc_v_[wwsr~     + !! "'>.)GD)D#49($EK$K0&8C%B=FIL/JH/H*@Q;6VA?TO5YUR\MW^Sb`Xg_aN]f<j,:Ph+ic-e31dZ2[7krulysmwn|zo}v{~{qxqtpt +  + ( " **)?)?֞3lO?Dt5Z$94۶t?bX>۶tj|fo¾?i>_>4>X?v\>KE?< F)h\o?'2P4=/3M44?c > ??-3b}g4nk|3$"4u3$|?c >?=?lZo!55]?4]?>c >D=?@޳6T6%?׽4? =xc >%i{=?v2ќ4iP*V [64 V?c >B߁=u>?iо3 _3>X?d\KE?< ~F>'h_o?P3 43c2v45?c +?8?䛳5nk3|3$ʻ4_3$|?c ?=?f<5,]?è4]?>c Q=?gY5JTN?4?=xc !i=?b4kP*4V =4 V?c E߁=|>?p H]>?Um*4Um4^ܡ@=?-K9+.|?e~ H4e|*T46-H>?Y+(4/^dO9? 0?|4 0?9ؔt3a%?VTF?"!=O4"!=E Rv4?9?'?ET<>>JMu?x/?2I>X|Ϳ?hY>=~?Ó=y;=<;sN0???]=?9/P?tA)4Sx8LA=K?n?) $>?$4?=wN??ht5iv=|xn?M4!l?;q>1q¾l??, m=ʈɾ?9?'ET>>>HMu?/2I>g=V|Ϳ?YY>=~l?v;=<mN0??ݿ]=?SK2nA=?YR4`Z4A=n?n῵* >?ar3?W)41p35q늿R?@@5O?l5O?l5"e"e5?5"e"e5???????<=L=====>>*>;>L>]>n>>>>>"">>33>>DD>>UU>>ff>>ww>?DD?? ??UU???"""?ff&?*?.?333?ww7?;?@?DDD?H?L?Q?UUU?Y?]?""b?fff?j?n?33s?www?{??""?DD?ff???̌???33?UU?ww???ݝ??""?DD?ff???̬???33?UU?ww???ݽ??""?DD?ff??????33?UU?ww?????""?DD?ff??????33?UU?ww????@@""@33@DD@UU@ff@ww@@ @ +@ @ @ @@@@""@33@DD@UU@ff@ww@@@@@@@@ @!@"""@33#@DD$@UU%@ff&@ww'@(@)@*@+@,@-@.@0@1@""2@333@DD4@UU5@ff6@ww7@8@9@:@;@<@=@>@@@go什^Egl什Egm什3Ggq什yIgl什Lgo什Pgk什_Ugp什Zgp什Ragp什fhgp什2pgp什xgp什فgm什go什 go什 gn什go什gr什VŌgp什sҌgo什go什gn什lgo什< gl什ggq什)go什9gq什Ign什?Zgk什jgn什{gn什gp什睍gq什6gm什gn什)ҍgm什㍾gp什^go什gm什gr什2*gn什;gn什%Mgo什t^gq什ogr什go什|gm什gn什xgq什Žgo什mҎgn什Ꮎgl什񎾙gq什gp什Ugl什Wgo什)gm什7gp什Cgm什Ogp什M[gp什Nfgn什pgo什zgo什gn什%gp什gp什 go什`gl什gp什go什go什ⲏgm什#gn什gm什gp什¶gp什gn什ഏgp什Bgl什/gq什gp什gl什hgp什go什gm什gn什go什̑gn什%go什)gp什go什&ygo什#rgn什jgk什7cgp什M[gm什Sgn什Jgq什Agp什8gn什/gm什&gl什Wgo什cgm什4gp什gk什;󎾚gq什y莾gq什ݎgo什mҎgo什%ǎgp什gq什*gr什vgo什go什gr什gn什tgn什Khgm什[gm什Ogm什0Cgn什6gr什2*go什go什gn什xgq什gl什H덾gp什ލgn什)ҍgm什ōgo什*gn什gs什^gm什 gq什ևgn什{go什ogp什cgn什Wgo什1Lgp什@gp什55gq什)go什gn什go什 go什gn什#􌾙gm什錾go什gn什F֌gr什̌go什~Ìgo什|gq什gn什Bgo什 go什 gr什gl什4gl什5go什|gp什1vgp什2pgp什jgq什Fegn什[`gl什[gp什Wgr什Sgo什Pgo什Mgo什(Kgp什Igq什zGgo什MFgp什Ego什^E>?y=,3&KX?>?y=,3&KX???????O0׽kO4׽lO/׽}mO/׽oO,׽rO1׽vO,׽{O.׽=O-׽O/׽O/׽xO0׽O-׽ O-׽O/׽UO-׽UNjO,׽ҋO-׽ދO.׽닾O/׽O/׽IO-׽IO,׽"O/׽1O/׽@O2׽4PO*׽ `O2׽$pO.׽O/׽$O/׽O.׽O0׽,ČO+׽|ՌO/׽挾O,׽qO,׽ +O-׽O0׽E-O1׽>O-׽yPO.׽aO2׽lsO-׽O/׽앍O.׽񦍾O.׽ķO/׽aȍO2׽؍O2׽荾O,׽O+׽5O.׽eO2׽0&O,׽4O.׽BO.׽1PO.׽L]O,׽iO1׽vO1׽O-׽O,׽O0׽ȠO.׽祈O0׽lO.׽;O1׽PO+׽ǎO1׽A͎O,׽ ҎO0׽֎O/׽*َO-׽kێO1׽܎O,׽EݎO.׽ݎO.׽T܎O.׽)ێO.׽َO0׽x׎O-׽ԎO,׽ ҎO2׽ΎO/׽ʎO+׽ƎO2׽EŽO.׽\O.׽O0׽lO,׽qO1׽O1׽lO-׽mO-׽O/׽O0׽O.׽`yO2׽pO2׽%hO/׽!_O.׽UO.׽\LO.׽BO0׽8O1׽}.O2׽$O0׽O,׽O-׽O,׽O0׽m퍾O-׽⍾O1׽p֍O0׽ʍO0׽꾍O0׽O.׽񦍾O+׽̚O-׽O2׽DO,׽uO-׽yiO.׽\O-׽yPO.׽CO.׽Y7O.׽*O/׽(O/׽O/׽O,׽qO/׽댾O0׽pߌO2׽ӌO1׽ƌO/׽TO1׽O/׽O+׽핌O3׽O3׽,~O+׽xrO0׽fO3׽|[O2׽4PO/׽EO3׽$:O.׽`/O2׽$O1׽mO-׽@O/׽IO.׽O.׽ 󋾩O+׽鋾O2׽O+׽؋O/׽ϋO-׽UNjO/׽iO0׽̷O0׽|O+׽|O,׽ТO-׽yO/׽xO/׽ՐO/׽O1׽O1׽O.׽}O,׽4zO1׽vO/׽sO,׽pqO.׽`oO/׽mO.׽lO/׽kO0׽kt1Y>GA;6>u?t1Y>GA;6>u???????ּ|> -ּ|> -qU=ab)/?T|SoM>G?XyS֣pM>L?tS锡sM>8T?mSFxM>^?meSf}M>l?g[SHM>{?OS$eM>?BSM>?~4SѠM>J?$Sp֦M>?&SJnM>/?`S8M>?RM>%?R?ßYM>BD?R+XM>0d?REM>#?֜R4M>?R N>?oRzN>?XR4(N>?'ARr흽7N>5?V)RmFN>jZ?ER\UN>?QeN>?QʜptN>?QFރN>d?Qh6BN>?Qv웽N>;?h~QN>ua?eQ6YoN>?uMQN>?? 5QǚN>V?Q~N>&?Q6N> ?P O>> ?P{`O>b ?'Pc)O>ׅ ?P")8O> ?GP:ۘFFO> ?yPt.TO> ?cPVaO>7 +?MPPoO>. +?n8Pb֗|O>O +?a#P{O>n +?PZ.O>x +?OO> +?O䖽ŮO>' +?wOO> +?Os5O> ?FO=pO>8 ?rOE ^O>7 ?O'֕O>bQ ?`zO٤-O>/j ?)jO'uO>. ?ZOGP>T ?uKO P> ?=Om𔽮P> ?2/OǔP>: ?!O,'P> ?wOY|.P> ? OY 6P> ?mN8

?N0:CP>X0 ?5N,IP>> ?6N[㓽NP>K ?N7˓SP>W ?NnJXP>b ?NV\P>l ?Nא_P>3u ?N?cP>| ?λN%veP> ?NlgP>g ?,NeiP>ي ?NaiP> ?CNE`WjP> ?Na=jP>I ?;N4ciP>6 ?sNfiP>l ?!Nk!hP> ?JNrfP>̈́ ?NyQeP> ?NzcP>| ?rN􌓽^aP>ew ?[Nx +_P>q ?N5h\P>Jk ?uN+YP>Td ?NU“{VP>\ ?3NғSP>T ?*N5䓽OP>K ?NKP>B ?>N +GP>8 ?[N{\CP>0. ?Nd5>P>7# ?O`L:P> ? Owd"5P> ?fO}/P> ?HO*P> ?'OIJ%P>j ? 1OΔ8P>[ ?:O딽<P> ?EO P>Ǹ ?OO( P>B ?lZOHP>I ?eOKiTO>ֈ ?pO׊gO>w ?|ONAO>f ?OЕO>T ?O}O>B ?eOO>)0 ?/Ot?O>, ?=OfO> ?OQO> +?OZO> +?O!ޖ0O>C +?OO>S +?.P1ҠO> + +?P\O>m +?YP?O>qw +?=,P\…O>(a +?\;P/ᗽn|O>J +?JPsO>3 +?,ZPE +?iP7k_O> +?yPSUO> ?PɘLO> ?PBO>Z ?AP*7O> ?P[-O>ʊ ?^Pnm#O>q ?$PoO>FX ?PO>> ?Pz$O>$ ?QWMN> + ?K QN>?1QN>?BQN>?RTQ&N>?eQ[$N>?LwQ1N>$l?ԈQě.N>OQ?_Q-N>o6?Q- N>v?|QIbN>?QN>?Q˜ vN>?QL kN>ï?[R4`N>?Rh&UN>_?6R6Н?N>HE?GRD4N>+?XR6*N>?&iR*hN>M?yRٙ2N>?Rʞ +N>?RN>?5RK*M>?RXM>{?R`oM>(d?7RM>5M?tR9ޟM>6?NRZM>6!?R1M>8 ? SmXAM>?S$~CM>u?$SVM>?0SĠlM>?:S堽M>S?DS$M>?NSM>?VS:M>f?l^SQM>w?feS)g~M>l?kS'zzM>Cb?pSVvM>Y?KuSsM>R?xSD~qM>tM?J{SoM>tI?|SnM>G?J}SxnM>KF???????t 2c?fDS2d? 2uc283?DuSY@393׉?hvdg3\3&?Fw}C3LV3?]Xyg13"3u?^{7JC3D 3y?Z}$M3"3?tGf3+3Q?>ف@>2%3%|?ב +273x?pN23t?su33p?r,33k? ԋT333g?,#<3%3a?P53v3j\?"T^303V?ɸ+2z(3P?6a3>,3YJ?/3p>3C?םs43A(3=?Xp3:3 $036?Eviay3wQ3.?Pb3VA=3'?o0I3?3?03dW3D?uL3NR3b?ޱy6c3J3]?ŴnJ 32/X33?'53TG3~?B3dX3~?k2]3~?^G#3H3~?ýIH3^3~?Ž/ 3 2\38~?3Ƚ 3vIb3~?Xy˽H3W3~?4νh2"!y3~?н3g33~?ӽO3m3k~?=+ֽݙ3S?l3~?ؽg.39g3~?G۽3;j3D~?ݽZ3w2f3~~?5ཹm2@!w3v~?%[43-3m~? C3n3>e~?9=Ͻ23\~?tR0 +3A3T~?뽻3Sn3L~?w+[3y3D~?;$2Cf31=~?񽐘@3+L35~?9313C.~?ch\1oR3'~?,d3r3 ~?@^23X~?'BE13~?\23 ~?.(2t3~?O3o3~?U!P3w3H}?mf"$3J3}?G2 3:}?d!>B3/3}?Fm33p}?s63ȉ3}?DS3z3}?,3/H3}?AM53k3}?NJTf3 3}? 3Ջ3}?Tb2;3'}?Ɗ3+3}?.=33W}?523}?2$2ê3:}?d' 3)3}?D +Y393)}?0n3ϛ3}?x2Χ23}?3Q3=}?NJ5333}?W|33^}?v.3:3;}?"2ˎ3L}?cr$F3=3}?M1{3: 3}?Nse3,3}?F33p}?HKP23<3l}?\\3~3}?g}393}?U 3C3b}?1v΃2b73}? %k 3V[3}?O-3楕3~?Jo2zi3~?Y< o3N3 ~?C$h2ص3l ~??P,3ώ3~?3n>3~?y3.n3A~?,dc2}3 ~?23%~?tH3(z3!*~?tШ_3!r3L/~?l!D3u>~34~? Q{3`y39~?8カ2P3a?~?w:A3A +3D~?=23J~?Ŵ>2,936P~?$齜23U~?罰2т3[~?z彭2J)3a~?FN e33g~?)2y3m~?-X3>p3s~?A+߽z3Ly3y~?"jݽOV3)e3~?p۽;g3t3~?ٽT2^r39~?7ؽ[]3is3p~?@+ֽ3U3~? NԽTw3^3~?kҽG3Yg3.~?Yнak2y3r~?νp^3,:N3~?ե̽:U2q3~?Iʽ "3jF3A~?2Ƚ1A3]3~?WƽTU3\3~?Ľ2SL3~?۵½=3$_3$~?E3.Z3K~?p_2&Mg3l~?^m:2 R3~?/B3u]3~?~} 2Uu3~? mhB3O3}~?[}3X3_?IoL3-H34?V7n3>3 ?$m3 I3?\2fG3D?'l]<3 G3?2SE3@#?祽Q1)3%H3(?<ޣE+'3DF3-?Iء Ӹ2=3 3?E֟=b3=638?nםVy3 ,3=?ޛO213A?7뙽Q;3L%3F?q35X13EK?03z13O?2&?3UX?Pi$34 3j\?h܎E23\`?|(ܶ2ګ+3&d?/33Y3g?剽N3x 3Ek?Y03HF*3n?)݆<2E!3q?p)9373t?(x?323w?ςZ+33.z?aE2 03|? x)3m$3~?~>33? }"r33Ђ?^{>R3R3y?(y1V3%3?x92H;13.?wԤu3Om135?ve;3B$3?vzd3D3?u+-3Z3?uV2O#3???????N 2>[> Zf?þY> =?k?8ίl;S?^?&K j;S?g?e;| S?u?a3_;mS?g?-JX;R?? FO;R??GD;R??hl 8;R?c? +;R?!?) +j; R?7?=5 ;UR?!U?,0:tR? t? :R?P?ֳ:kR?ܵ?(:UR??w@:~?R??(2 9](R? ?ӣp?8R?E?輁rBQ?k?LN'~Q??)ܼ܃SQ?ȸ?ּ ƬQ??$ZмNQ?Q?ɼ) xQ?.?9ü0'^Q?V?~3ADQ?2~?[)Q??Ů>vQ?i?ΧAP???ʠDP??%bP?B?F԰nP?i?E?P??w ˻oP?ŵ?\zyػUP?=?.l滔;P?G?<^%!P?$?P5WP?H?CxeO?&l?zj5n -O??(O?/?<IO?? fO??6<Q$uO??%%*^O?63?ѻ2/#HO?Q?]41O?o?~ˣt9=O?? 8>O?Q?arxCYN??\JeGOiN??$zMN??2JN?)?5H1RHN??^zEN??$u\VC%N?d?j@+.N?U?В>7N??J-X;[@N??ϫ͍8JN?݁?u5TN?s?6ŻY2y^N?d?)9ӻo/8iN?U?K,VtN?E?h%)N?5?Dő&N?$?xb#N??= ' )N??JN??`N?W?G"0YN?M?a*N?׶?I1jVN??)9P 'N??#gAhWO?y?1I1hO?d?QD7i!O?/O?SXg70O?=9?`K5@O?"?hOO?C ?$ppE_O?9?x$ݻpO??hmֻO??mPλ&O??NttǻO??{O?|?&b1O?c?ҰO?J?̎@O?1?6 O?@? +P?%?[P??.P?7?_AP?n?oNwnSP?q?qYheP?@w?I= +YxP?[?J.P?^@?;P?$?ü},P??WǼ=P??u<˼zP??bμP??ҼgyP?˘?r.ּȺqQ?|?ټyr"Q?u`?%@ݼa5Q?DD?q༻iSHQ?(?637[Q? ?jvr~nQ? ?€Q?/?fmIcQ?u?& +68Q???`9@Q??dHI:qQ?tf?0?S5:Q?K?-#d:VQ?1?:Q??X:ZR??:k"R??2N:13R??:6uD:CR?s?{jS:SR??5";cR?j?p;rR?l? 6';R?W? +; R?A?K 0(;R?-?( 0;7R?f? 7;R? ?[>;R??RE;qR?W?vK;%R?&?{n4Q;R??kV;SR?X?Ş%[;R??I]_;-R?Ǧ?& c;S??`7f; S??,:h;:S?;?qh,j;S??\_]l;S??gCm;ES?щ?,*m;S???????0I('>RR1G('>F^>(gy?F^>(gy???????p~>;2a>|8:վxa?bUQ?.z?Uj/z?U߼K 1z?xUݼV5z?g8U ۼ5࿼9z?THټ=z?ϓT@ּ,nS雼hz?H``RIz?4HuRǝlz?yGP D瓼{?Fi5)%{?F!%'bY{?LEn'{?iD mĈa1{?9C3h.;{?t'C]XٻSD{?DsB6@GN{?A;@zW{?Av*u`{?a@KJoi{?9?iJr{?x ?ʷlgdz{?3d>#f^{?=݅98Y({?=:9T{? <,:O{?r;f+;$I{?K;"P\;DD{?":܅;h@>{?$:Ĝ;m;{?ܖ9Ѳ;46{? 9;F2{?8 +!;e.{?8H;o*{?7(<&U{?s 7H) <)#{?6r <0{?l'6;R' |?2;t) +|? 3U;,%|?P3Le;wP.|?3G";0|?>3F;3|?3;h5 {?,4{;!8l{?;j4;:{?4A;c={?Z4Q<;@{?25 u;B{?lz5=Z;E`{?5vX?;%H{?-6XZ#;eKu{?1`6;SN{?d6A):9KQ{?7:LT{?Z7r<:rUW{?t79fZ{? 8OQ~]{?h8/`C{?8pFc{?&9Ӻ f{?Ĉ9v j[{?95)Qm}{?]R:,Ip{?:[i;sf{?#;܄w.{?;>Az٢{?h;u7}k{?i<ܵbޗ{? 䆼{?><z{?E ? !it{??O9)n{?@Xg{?@yV%_a{? A-Z{?цA5>T{?B=򬓼M{?(B(F!;F{?C HNŖ?{?C\V2M 9{?Dd^Й2{?D_feP+{? EJn˜#{?ߎEt%v_B{?F}r{?Fkӂ!R{?G񤆼 +{?Gk 주z?O$H5'H_z?èH֑z?\-IRy𧼟z?I;9z?~5J?z?Jzpz?;Kxz?ݽKѦ#z?>LLez?LWQ mz?1>MvRz?̻M—z?8NɈ0z?Nsz?*+OAJz?O< ҋz?<Psz?PYJļS~z?lPƼ)xz?cQ+ɼ6qz?Qxv˼򹺼kz?2Riͼtez?ʔRϼS%`z?RѼ̼Zz?cMSӼjJUz?SaռJPz?S׼!Kz??TؼGz?Tټ{Bz?THۼ濼?z?Utܼ0F;z?8UUݼ8z?gUi޼5z?gU1߼%X3z?ڱU߼Y`1z?@UrX/z?U༅.z?U~.z?UἋ-z???????޽&޽,޽޽8ñ޽޽*ñ޽޽P4ı޽޽:±޽#޽ ,@ı޽45޽?޽gI޽hT4ñ޽_޽l޽x4±޽ͅ޽[޽\$ñ޽ȯ ޽޽͑ +޽Hݑ±޽푾޽9޽ ޽7꽨޽ /޽@޽AQ&±޽b޽s޽ı޽޽޽X޽˒޽ݒ"޽ ޽"ı޽޽#޽44޽D&޽tU2޽e(޽u4ñ޽ȅ0±޽H޽x޽D&ı޽8޽ϓ޽DݓB޽a꓾޽޽޽2޽޽$ +޽-,޽7޽?4޽QG޽eN(ı޽T ޽UZFñ޽_޽c4޽ı޽޽꒾޽ݒ޽В޽kĒ޽ӷ޽<޽޽޽޽y ޽l޽`±޽S0ñ޽iG ޽1;޽ /0޽# ޽*޽@ ñ޽޽4޽葾޽Hݑ޽+ґ ޽8Ǒ>޽u޽᱑޽6ı޽T޽[޽޽8±޽v.޽m2±޽e޽\޽hT ޽|L޽D ޽=(ñ޽6@±޽/޽)B޽#*޽޽0±޽޽0B޽ 8ñ޽G ޽ +޽.ı޽޽s.±޽$޽޽޽ E> ƶ=Vj4s? E> ƶ=Vj4s?????????E9]V=%?j93em=0$?i9ep=-$?vh9es=$?zf9e9y=$?c9fe=$?`9e=0$?o]9e~=!$?mY9eC=$?T9 e>=$?P9Ren=$?J9We=%?D9(eI=%?>9e=^%?M89eW=%?j19Le=Z%?-*9IeR=o&%?"9e/=.%?9eD=7%?90eZ=@%? +9eq=3J%?h9e=S%?s8e=]%?D8e=h%?8he=r%?J8e=:}%?8e=%?8-eQ!=%?8eU<=R%?O8{eW=%?87veKs=%?8ope;=%? 8jeT=Q%?y8de= +%?8^e =%?,u8Xe=%?{j8 Se=s%?_8Me9=H&?U80Ge5V=&?mJ8GAer=&??8e;e +=*&?<585e7=F6&?*8/e9=A&?N 8)e=YM&?8<$e=X&? 8e=c&?8e4=o&?7|eN=z&?7eh=Ƅ&?U7e=Y&?7e=&?7jd*=٣&?7id"=&?ڿ7d~=g&?K7d2=&?77d<=&?7d%=&?77{d:=-&?ė7\dM=U&?7id`=&&?Ή7dr=&?T7d=&?3}7dK=f'?ow7d='?r7dѱ= '?m7d='?}h7;d3='?Wd7d;='?`7d='?X]7d=1#'?Z7d;=@&'?4X7Fds=('?`V7BdU=*'? U7d=@,'?=T7d= -'?S7d=l-'?T7 d=F-'?T7Fdt=,'?3U7d=,'?&V75d/=+'?[W7d=)'?X7d/=('?Z7d=<&'?\7d~=$'?^7d=!'?a7RdV='?c7dU=%'?f7dd='?i7d='?m7dտ='?p7d=&'?Nt7d= +'?;x7'dX='?Y|7qd|=I'?7d$=&?!7RdI=&?̉7ds=&?7d*g=I&?7]dY=&?Θ7:dBL=%&? 7/d1>=Q&?77d/=V&?97Wd =*&?7d=&?7d=_&?7(d=&?7d=&?^7 d=&?7d=&?F77e=&?7e=&?7eF=H&?l7e e*y=ʊ&?T76ef=3&?T7e?T={&?f7enA=s&?8el.=k&? 8eB=c&? 8#e=[&?b8'eR=S&?!8++e=K&?9)8I/e=tC&?08q3eڸ=2;&?>887eΤ=2&??8;e=*&?aG8@el|=."&?N87De h=&?V8qHeS=Z&?@^8Leb?=&?e8Pe*=v&?m8#Ue=%?*u8]Ye0=%?|8]e=#%?d8aey=%?8ee'=N%?8/je=%?8Xneʜ=%?8zreLj=L%?8vet= %?]8zea=۬%?8~epM=%?8ǂe9=%?'8Æe&=%?G8e=%?Q8e=%?H8te=,}%?$8Ae=u%?8eQ=n%?8em=f%?$8Peʥ=I_%?8ew=X%?9cer=Q%? +9ѫer='J%?,9)enb=eC%?9seyR=<%?9eB=X6%?!9øe3=0%?&9ɻe%=)%?E,9e= $%?i19e=P%?]69Je=%?#;9e=s%??9zeI=S%?D9em=j %?NH98e%=%?JL9ke_=G%?P9e-=$?S9we=$?V9Le=a$?Z9e?=$?\9e=$?_9ep=$?a9Se='$?c9eV=$?e9eP{=$?dg9_ew=$?h9es=$?i9ep=]$?uj9en=$?j9Keum= +$?k9`e +m=$???????Yʲe?u2Sfa?613Ky~Xsw?75̔$sw?v:K߰ rw?BI)z; qw?Nx7} pw?]ꛅ߲#nw?om kw?ʄhw?~8 ew?CyF3L?bw?ԃPT{H [^w?YE6Zw?T Uw?C;D+UPw?bӪqrKw?%]hEw?7nhC-@w?9ㄾ\Wc +!:w? 3w?BmhY +F-w?t>S &w?c8 w?݅`Nw?yc w?@LI1qW w?-. +w?oMiv? v?5#F+ +}v?9r@ߛ 4v?`{ +v?퇾qH Qv?M+H[g v?i$;= v?è6 +gv?爾N v?&n j +v?fHݱ* v?/[ Pv?&䉾I7 +v?"Y, v?#aS8 Q yv? Npv?q܊Ƃ3 +gv?E _v?^U/Vv?k 4Nv?'ˋnıOEv? =v?7=DケF@5v?tYC -v?ͪve &v?ߌwB~v?` ؁Xv?Emquv?;vRBEv?KoN%v?ҍ?Zu?WF}[Pu?,(#ԱFu?PM u?uAlu?ڙ"lu?W"u?ێ>>J\u?'V  u?;29u?7+:u?@M/u?TZFhu?rdpqjZu?rb\u?|(M̽u?퉈u?B$ +ptu?ފ[oTu?0/dݻu? _^7u?>P;I̼u?~_xu?wʩM u?n4v(du?rd)αZu?YOтOu?:Lu?>{hu?y.^-8u?8u? DZMu?'+DZZ0u?㎾ Z`N u?͎ȭyGu?ݶҋ>u?˞AU7Vu?]nu?fk +RpKu?P@hu?32u?v bu?9*;2u? ٍXтu?x褰Nu?v?:vk+7v?S;Z v??07]ͫv? o +M&v?<猾=|nv?l "v?x8h@B(v?t -v?'M(Pmn3v?% "9v?^`?] >v?jӋjNJDv?֩?h +Jv?K05 Pv?^UfE1Vv?}*Y \v?G4b;bv?ӊY hv?ݧt/ ov?{LU!a Euv?aO_Zϸ {v?" v? + P +v?6ɉ Hv?4Ql v?"oP© ښv?AgM #v?eZ iv?爾>F2' v?úfΝ7 +v?ƍal +$v?`,L +Yv?84nhR v?G2 v?jۇǚd v?`g v?s)R< v?=XbLr v?&-P +v?x_#S@v?:؆WژS Fv?yMS; v?)qA w?n\oFQ $w?84 +` w? Cr/8w?兾g~Bw?gAW pw?љs !w?t˕1r &w?P +]+w?-!ֱܱ0w?G RNӣ 4w?鄾>9w?JɄV4 =w?󍐱 Aw?%+ Ew?mT%l Iw?1QiaT~Mw?5)H7o\Qw?Tw?ޡ0Xw?ꃾV0\[w?ԃh4 [^w?VbW&,aw?z}X9cw?C 4 Cfw?oplhw?uxpㆱFjw?[jcQ; ylw?]ܼd#nw?R3ow?\Igpw?A`6qw?t;+rw?7}dLHsw?i4/xsw?3OLsw???????>4=y>O?5vb=6K??Uۻ:TK? ?'[<ݬK??,/t<'K?o?_;I?f?ul=;I?e?+}m=LԈ;I???z8B= <+J??U?=(<0J?n?{b<=7<6J?͂?_9=<=J?~?N6=d<[CJ?y?#.3=!"=;6?";o<xK?/?\;<|K?)?0; +s?mUu1I('>F^>x55y?F^>x55y???????"ұ> H >OY^}$ e1.|?UP$<ּ<|?C$TԼ<|?=4$v=Ѽ<|?\"$ͼ<8|? $ɼ6c<|?K#ļHc<*|?U#喐<Ԗ|?#݁/<|?#۟<}|?c#UT6=|?#=f5=|?)=5=c|?{=z4=3|?<; =3= |?%h =3=|?8y +=bG2=ֳ|?=*=|?K<0b)=|?K<_='|? #ɢռCD<ȏ|?OL$ּ/<#|?T$Oؼ<|?P[$yټj< |?`$Cdڼ<Í|?{d$i ۼ<|?f$sۼ6 zӦN zԦN<# zԦN< zΦN&8?H1?c1<'R8??1?T9(:8?V71?f6}*I8?.1?e3'+z8?&1?S00D,8?%1?0-'f->8?$1?T).8? 1?&/z8?1?ei#.0:8?0? &28?#0?SW38?0?y49?%0?z59?0?K79?0?mNyb8?"9??0? +߭9i+9?0?<r:49?٫0?M<=9?*0?`|̡=F9?x0?e2>P9?Ɏ0?P@?Y9?(0?红AWb9?{0? +ߺNCfk9?r0?ֺfDct9?h0?κwEP}9?-_0?>ƺ'G'9?U0?ÀՉH9?L0?:I9?C0?u筺PK9?:0? Lr9?10? N9?M)0?4~Oʸ9? 0?4P9?0??GRt9?0?VvS9?0?0?ua9`Ei$9?fG0?G9xg{9?P0?'ɗ86f9?=Z0?gɝdӈ9?c0?ˣob9?rm0?-#jOav9?.w0?!vК_m9?0?Х]d9?Š0?йZ\L[9?0?/MZR9?t0?u|XH9?U0?*V?9?50?oAT669? 0?7XR,9?0?%o@Q#9?0?O{9?d0?ig7MM9?0?@7MK-9?0?yۥ(bI8?40?s wG8?0?XE48?1?=ȺCa8?41?Ժ̺A8?R1??|ߺ`?8?O$1?=8?(-1?<%8?51?+::8?f>1?e8ϱ8?F1? 6٩8?O1?48?W1?'| +3o8?^1?RBP18?f1?e 0/8?m1?c[%.-8?7u1?\4*U,}8?<|1?<.*w8?1?36)p8?1?97/'aj8?1?iH;=;3N-=?;=h +;/,=?s;=xP;+=J??3<=;*+=?m<=Ϧ;k*=?<= ;)=M? <=>;(=?)#==*q;((=?`==<;K'=[?==f̢;z&=?==;I%=?>=;-$=p?[>=A;#=̓?:>=%d;Y"#=,?>=;DG"=??=;j!=?)Y?=œ;Ȍ =H?7?=ߛ;=??=;=?M@=;{=d?,S@=2; =?@=M;+=?2@=Bi;J=}?/ A=;i=ڇ?YDA=ޠ;=6?~A=;'=?A=zۓ;u=?qA=;=G?'B=;=?]B==;7=?B=`;^=S?B=솏;=? +B=2;B=?(C=ٍ;=U?WC=J;=?!C=7;B=?C=j;9x=O?C=;=?D=ۉ;: =?^)D=k;, =>?MD= [;Pp =?oD=Ϡ; =ٍ?8D=; =%?LD=G9;R +=n?#D=G;̦ =?D=8;=?D=)A;8]=E?E=H;ۿ=?!E= +;'=͏?1E=w;۔=?>E=;=Q?IE=Bc;=?PE=;O=А?1VE=kf; = ?7ZE=;; +=I?\E=~;=?]E=q"~;q*=?\]E=TS};=?[E=|;^='?_XE={;r=Z?SE=%{;=?ME=z;T=?FE=y;==?.>E=Yy;ڽ=?V4E=}x;0{=>?<)E=`x;7>=e?E=w;4=?E=w;*<?(E=Cw;V<Г?D=v; <?D=v;< ?D=֕v;<'?`D=Buv;y?t?=;=ڎ?B?=؍;[=u??=sЎ;ˆ= ?>=2ˏ;%=?>=Ȑ;z=3?Kx>=3ȑ;Gw=Ì?E>=ɒ;Pv=P?g>=̓; +w=܋?)==Wє;y=e?==֕;4|=?a}==ݖ;=t?K==;=?==P;F={?6<=;A=?<=p;=}?b<=F; =?=[<=;J =|?,<=;!=?;=;"=y?;=;#=?G;=;$=v?y;=;{%=?N;=;m&=t?%;=ף;\'=?:=Ĥ;G(=u?,:=;.)=??:=;*={?{:=p;*=?b:=1J;w+=?!?:=;f,=?:=r;Fc-=?9=r;(.=0?9=r;..=?9=^+;/=Y?t9=ܬ;xN0=~?҄9=;k0=~?j9=&; 1=4~?Q9=K;J-2=}?;9=bN;H2=}?%9=(ԯ; @3=8}?9=CP;43=|?8= °;3,4=|?8=);ؒ4=m|?}8=;4=6|?8=hױ;n?5=|?8=/;5={?8=W;5={?8=;b5={?U8=; 6={?>8=;6=}{?/8=^;&6=y{???????jE>f=jE>f=}=;7<J?;.;2U?\ V;9;qlU? iU;;tU? ZT;t;U? PS;-;~U?` MR;);kV?X( QQ;;o7V? e]P;;ZV? >pO;v;{V?t ŊN;d;V?d GM;];iV?; L;b;V?w 2 L;t;hV? +GGK;;UW? +:J;;VW? +fI;;&W? +)I;,;7W? +H;s;HGW?o +G;Ľ;BUW?\ +MG;;aW?K +F;Ȅ;lW?< + +8F;J;vW?0 +E;m;~W?& +sBE;u;SW? +D;j;2W? +_nD;N;W?- +%D;;LW? +޼C;o;zW? +gqC;*;)W?z +/C;;EW?d$ +B;¸;؅W?- + B;;W?9 +B;*;>xW?G +B;};,oW?|X +bpB;~;ldW?k +gB;; XW?* +hB;;EJW? +VtB;{ʸ;:W? +cB;;)W?i + B;;;3W?A +B;d;W?} C;z;V?: +hC;d;V?c +C;4;V?t 5D;F;V? + D;4;{V?o ?E;;ZV?' nE;I;8V?m_ }F;Ξ;V? 7G;;OU?G G;;dU?  H;;U? V I;ı;pU? YJ;;DU? }K;;U?w${L;S;T?l M;L;JT?N;;̅T? O;?f;"ST?PNP;M;T?R;QU;S??S;l;GS?:AT;m;~S?U;;GS?W;e;S?\/lX;7T;Q?}c;;;QQ?R!-ee;n;P?tf;N;uP?oh;0;QP?i;f;P?mHk;;O?m;r;O?.n;;eO?_kp;Ȩ;m+O?Σq;T;N?)*s; n;N?sJ9t;M;N?'3v;);-HN?Ww;;N?M+/y;;M?sߨz;T;٤M?Ϻ|;5<pM?c;};<2J?x;2a<.J?V8;< J?"c;^;6[?]?<;n[?Z?F<;[?? NϷ <<]?=><ç<0^?a>XU<*<<ɼ<π^?M>Eu<u<<^?Ӳ>'<"@|<<^^?#>Je<-<_?v9>'<2<@ _?">)_<+<'_?w>3׽<=2_?><,=6_?J><w=7_?]>A!<=7_?->z6E!N< ( =._?>yP4L<' = _?/>A< =_? U>@0<+q= _?W><={_?ݱ>5<=o^?\>s<1=^?(>< ='^?lp>Sr<=1^?>J3< =^?_>=< =^?/z>M< =s^?W>G<=8^?>j#< =L]?T>I<$<]?><=<<]?i=?d<3?3 <;X?5\?xTW? +?pww>wwssTH?[w>:>ssTH?[w>:>??????{=O>绻{=O>绻K!ǽG?lE\ @>ȓ,?)E}@>wȓJ,?E?>Ɠ+?ES?>*?Ee?>޹G)?EL?>['?E ?>%?)E?>͕#?E\?>!? E?>r?zE?>^)?=E~?>H?VE{f?>}0?EL?>G?sE0?>$?xE?># +?E>>:’G?dE>>[?EF>>1?k Fߍ>>_O?Fh>>.<>?FA>> ?tF>><{?$FH=>ˑ?,Fy=>?3Fl=>!|?;F/l=>/S?CF==>})!?LF*=>"?TFy<>;Ԑ?9]F˫<>󨐽?"fFy<>?}?7oFE<>QJ?xF<>%џ?Ft;>P1?F=;>̏e?XF-n;>𠏽t?DFi6;>t]?UF:>I"x?F:>3o?F3:>9g?]FP:>Ɏ^?F!:>TU?F9>wL?vF9>PC?`Fb9>*:?bF&9>\1?} G8>⍽'?G8>n?GHo8>?>+G18>d ?6G7>kf0?BGG7>fL<?MGix7>&5.?YGo:7> ?dG6> ?KpG6>r?{Gŀ6>C?G C6>茽?;G6>A⌽?G5>?7?G5>ጽw?"猽?GV5>v?G 4>x?G4>_m?G]4>+)b?;G"4>@ErW?G3>f8L?,Hխ3>@?HHt3>5?H_;3>썽6*?")H3>$?M4H`2>&cM?e?Hz2>槎?cJHD^2>u@?GUH(2>D?_H`1> d?jH1>Q?tHF1>S?H\1>? +HB,1>?ϒH0>ҭ?ZH0>L ?H0>qs?ǮHu0>蒽?HK0>)aǃ??HM"0>vܓy?H/>ZZo?H(/>ٔ>f?{H=/>S[\?H͋/>\ޕS?7Hi/>^bJ?$HI/>疽'B?H*/>&n9?H />1?I.>z| *?I.>"? I%.>p?I=.>p?KI$.>h?pI.> j?3It.> +? Ig.>)?h#IT[.>̫?%IQ.>,?'IJ.>.?g)IE.>)?|*IIC.>(?+I C.>??+I1E.>X?*I"K.>?(I>V.>qO?*&IHf.>Ѡ"?w"I-{.>$)?I.>w?HI.>??I.>? +I.>)1w?I#&/>^& ?HT/>?H/>A?HҼ/>'%?H4/>|Ǣ 0?H20>Ϣ;?Hr0>PТG?H0>ʢT?HU0>-Yb? HC1>ɪop?H1>ʑ?~|Hm1>r0?mHN,2>Mȝ?!]HI~2>(#ɭ?LH>2>5??㽡?N+H3>̃?H3>Eu?H<34>?G4>?G4>Xn'?GI5>H39?Gl5>%̟K?6G6>u]?ɛGg6>@ap?PG6>vۂ?vG(7>aQ?QdG7>?QG7>!?{?GH8>49X?3-G{8>Ҝs?G9>kc? Ge9>?AFR9>f?F:>0$?UFz:>9Ț5?GF:>^F?F,;>V? F;>f?FT;>'3v?qF+<>˜H?8sF{<>^?vdF<>i?-VF=>=?jHF^=>A?5;Fۤ=>疽,?.F!=>,?"F5(>>>P?F e>>i?a FQ>>?UF>>\ +?E?>~?oE3?>\ޔ4?Eo]?>?E?>s4?}Eգ?>6Gn ?;E&?>`!$?E?>?(?fEA?>1蓽*?E?>N֓O,?nE?>˓,?E@>??????a30(>1Г3->°2?^;z2C??];E2C?F?_;2|C?D?M`;s2aC?ʔ?_;Ϸ2C??a;ǵ2E!C??9c;>2A#C??c;I2%C??"g;2<(C??h;2A+C?ۃ?,k;ؤ2.C??yn;(2I2C?!{? q;2L6C?0v?=u;2:C?p??x;2I?C?Ek?'|;L2CDC?>e?~;2IC?^?;v{2$OC?0X?i;s2UC?#Q?; l2B[C?I?;c2aC?B?ƕ;[2hC?9?q;R2oC?1?c;H2vC?(?;>2~C??H;42C??ٰ;q*2C? ?ʶ;2(C??;2ݟC?? ; 2֨C?>?;G1 C?k?$;)1C?J?;1DC??F;1@C?0?;1xC?5?;i1C??;1C?c?;1C??;G1D??;10D?'u?;u1D?{g?D!;\f1'D?Y?);V13D?iK?1;F1+@D?<?<;61LD?A.?E;E&1YD?A?O;r1fD??Y;[1sD?p?b;0HD??l;A0D??v;?0D?*?I;0D??ҋ;>0D??;I0 D?e?=;0D??;rp0D?z?;\0lD?h?F;DH0E?U?;30E?B?q;0$E? +0?; 015E??V;/EE?) ?;/VE?D? +;/gE? ?;/xE??#; /E??~1;/kE?s?>;k/E??GL;R/E?w?-Y;\:/E?`?f;w!/E?;J?nu;0/E?J3?;}.K F??;d.!F?Q?;.45F?K?;.IF? ?s;ԃ.#^F?ٻ?;h.rF??;M.F??V;2.xF?s?;.F?[?;-F?C?;K-F?-,?&;-F??<3;-F??rA;-G?? Q;y-Q&G??t^;p`-_9G?q?k;[G-"LG?U?x;.-^G??;;@-pG?6x?;H,G?=c?;,+G?N?;,JG?:?;M, G?'?l;^,XG??;,8G?c?;8y,G?k?;e,G? ?;Q,H?O?;>,H?;?+;,,.H?׭?;,*H?:? ;J ,7H?e?;+vBH?]?';6+=MH?.x?n.;+MWH?l?E5;+`H?sb?;;9+?iH?X?A;+qH?iP?F;+!xH?I?LJ;N+}H?E?N;>+H?B?N;+^H?B?kO;+^H?D?L;5+H?DI?lK;+~H?O?G;!+xH?W?A;t+qH?2b?"=;+uiH?Jn?3;z+x_H?/|?,+; +SH?֋?";+GH??;,8H?? ;,&)H?a?T;4,BH???h;aM,!H?y?;gg,G? +?;,mG?#?%;џ,G?>?; ,G?Z?֥;, G?+x?;?,G?F?7;-iG?R? +n;B-OG?=?Z;tf-4G??G; -uG?I?!2;l-jF?L9?;-F?[?;@-F?~?f;$.F?q?;KL.F?O?;wt.iF?s?h;.&KF??q;.G,F?_3?;.: F?W?m;/E?|?U;@/E?D?i>;i/E??';/VE??-;:/:qE?,?I;/GRE?1?; 03E?RU?%;P30E?Kx?ٸ;~Z0D??;0ID??;0D??w;90?D?g?c;0 D?$?lO;:1gD?=?;;61LD?%[?F(;X1z2D?>x?; y1#D?O?;1D?G?;1C??;1C??p;B1C??p;m 2C??[;"2BC?#?;.92&C?6?ܜ;N2ZrC?|H?Ӑ;Rb2bC?X?[;Lt2TC?f?3~;t2HC?s?u;2fq2H>r4oJv t=,>:Xx_=|>M:Xx^=~>{:#Yx^=~>t:YxƝ^=h}>ll:[Zx^^=|{>a:?[x^=sx>U:C\xѵ]=u>`G:r]xM]=q>7:^x\=6l>S%:K`xU\=g>:ax[=la>e9cxn+[=7[>U9exZ=lT>9gxNY=M>9ixuY=F>9lxHX=>>z9pnxKtW=6>-\9pxBV=D.><9sx U=%>97vxT=7>[8yxS=]>8{x,R= >_8~xQ=c>8܁xCP=F>%e8x_O=Z>f=8xo2N=1>8XxSL=?>M7x>K=F>7xF{J=x>Ε7Yx.I=>i7ŘxxG=h>q=7:x~F=(>P7xUE=J>67xC=>x6xCB=g>6Nx@=T>V6٭x)R?=>`'6hx!==ۈ>5xcJ<=d>5xJ:=A~>5x,9=y>+h5x}7=v>+85x5=r>65}x\^4==p>4xл2=n>4Fx1=m>y4xj/=m>%K4xŽ-=`n>4xw ,=p>34x5Z*=r>3Fx(=Mv>K3Ax&={>i3'x)1%=>>3xt#=>3xv!=>2Jxx=J>I2x5=K>2"xXs=Q>x2axU=׽>T2x=>22wx.)=e>2Nxd=V>1x= >_1x=8> 1x=Z/>1 xV=0H>p1 x =c>,t1x8 +=>:a1y =>P1yV=>B1$y= >.71$y=>M.1y(=,>(1}yar=U>$1x~_$1x["<3>k&1xZ< +>P*1ux<#>01xh81Ex;LVC1ixA(P1XxcI< >^1xd<>o1xѕ<8X>W1#xK<>t1ux5<>1x< > 1x-1x1xǃ<>_2>x@U1.2x@'L2ex!H<>ok2xj<+>ދ2.x< >M2vx<A >2x< >2x< >33Ҿx< >j=3ٺx<=!>c3ʶx3xe<$!> 3xe;*3Px Ǿ<3">4xa+4xn<">U4`x?<">4x,Ծ<##>4xN< ^#>a4&x<3#>5x.5Oxw<$>[5xf<^/$>5x k5J{x<=z$>5wx5 <ؗ$>: 68tx]<$>?36px<$>\6mx<$>l6jx<$>67hx<$> 6ex<$>69cxg!7`x&<$>[G7^x<$>k7\x<6$>ӏ7[xk7SYx;7Wxe<z$>7TVxQ8Ux^<;$>78Sx=$> V8Rx =#>t8Qxz=#>g8Px=#>­8Pxs =k#>t8iOx =9#>8Nx=#>8WNx*"=">|9MxX=">.9Mx +[= ^">E9KMx=r"">[9MxB=U!>p9LxjA =ަ!>9Lx"=Cg!>9Lx +%=&!>9Lx$(= >9Lx*=8 >p9MxW-=^ >9BMxU/=L >9wMxt2=K>q9Mx4=L> :MxLr7=N>:NNx9= +>":NxeJ<=c>-:NxL>=>8:_Ox@=A>rB:Ox4C=>K:+PxzeE=:>S:PxfG=>{[: +QxI=BA>b:{QxK=>h:QxM=>n:bRx\O=M>s:RxzQ=Y>>x:LSxR=#>Y|:SxcT=g>:0TxU=:>s:TxGW=>:UxX=h>:UxY=0A>":UxZ=>:QVx[=~>M:Vx\=>3:Wxb]=.>ֈ:bWxA]=M>:Wxv^=s>:XxZ^=>:BXx_=->:{Xxe_=b>??????Z==N3U==2 вin|?2 вin|???????=>w=>wssRHYw:>ssRHYw:>??????~O>껻~O>껻+ ZU?V=&X< 5/V??o=@G<<-V?|=<*V?=f<<'V?=Q<"V?J=.=?< qw<˓ +T?>@< +T? +>:< +T?cJ>u< + T?Ɖ>s<<6 +OT?>< +sT?>&< +T?F> < +T?>~<<¬ +T?l>< +$T?*>V< +ۆT?@>B< +T?">= +T?> =ԍ +T?> =e +T??H>=~ +T?>=Rv +T?>==m +1T?>X =d +T?T>d%=/[ +~T?[>]*=^Q +u~T?>p'0=.G +~T?>j5=< +}T?a>1;=1 +T}T?>!@=Y& +}T?>-F= +|T?")>K= +|T?k>]Q=[ +|T?>V= |T?R>\= |T?- >9b=u |T?l >Xg= }T?z >qm= i}T? >s= }T?% +>x= 9~T?` +>~= ~T? +>7ˁ=Q ^T? +>=aw T? + >/=Qh T?C@ >7ى=Y T?t >}=I T?4 >=;: T? >}=* T? >dF= T?; >Ж= T?mj >~R=DT? >.ʛ=e"T? >?:=xlT?Z >=ϋT?- >%=@T?> >A=ԫɎT?Xd >I=dT?g >=jT? >Ϋ=|T? >=km֕T?8 >Nޯ=4^ܗT?n>˱="OT?>T=K@KT?7>{m=1T?M> =T#=T?Ha>=BT?sr>HC=ϦT?>b=թT?@> =T?>uF=fhT?֝>dg=-T?ɡ>1o=XǷT? >Y=ĻT?w>'=T?>f=cT?p>_k=םT?>M=yT?y}>5=T?l>W=Ѓ[T?GW>{5=A}3T?/;>:=xrT?>(=sT? >C="q!T?o >#=eoT?F >ɿ=n/U?S >8=%o$ U? >u=xpYU?j >{=rU? >d=uY"U?x= >=y+U?n >e= ~3U? >'=*Ba=EU? +>I=NU?b +>y=WU?O- +>0=͜`U? >τ=)tiU?6i >V=0rU?p >=̳zU?z>ј=FU?z7>|=+U?>U =U?f>\=U?>vV=bqU?>#=U?+>p=@OU?>O=mU?Z>o{=KU?>t= U?j>m=SU?0%>[g=zU?>p`=fU?[>nPZ=R&U?>S=-U?>9M=4U?7>qG=;U?>\A=BpU?j}>!j;=UIU?#>і5=OAU?a>/=UWV?s>X*=[5V?>$=aV?j==gW V?==JlV?_=M=XqV?==*vV?77=M2 =zSV?=Ҿ=4V?!#=u=mCV?=%3 :1'>fo ?^L>@?{ ?\#L> @? ?]jL>޼@? ?]L>@?s ?]iL>&@? ?\1L>@?І ?['L>@? ?ZZGL>@?ʈ ?ZL>@? ?X6L>@?d ?XL>@? ?VL>E@? ?V*L>@? ?-TL>@? ?RLL>@? + ?,RFL>׭@? ?NlL>@?= ?yML>@?+ ?JL>`@?V ?IL>x@? ?FL>\@?W ?yCL>@?8 ?AM>w@?R ?#>M>@? ?:r M>@?\ ?~7[M>b@?P ?3M>Ԉ@? ?V0MM> @? ?J,X%M>~@? ?b(,M>y@? ?#4M>s@?n ?~n@?. ?kEM>g@?N ?NM>@a@? ?U +XM>cZ@? ?ZaM>9S@? ?\lM>K@?0!? 6wM>C@?!?M>;@?S!?VM>3@?#!?jM>=*@?-!?LSM>!@?N8!?M>g@?C!?6XM>o @?5N!?[M>#@?Y!?KM>q??e!?~M>h??q!?^M>6??}!?צ? N>??!?}N>??!?D+N>??X!?4:N>??!?vIN>>??o!?{XN>??!?tfN>??!?ktN>??!?VcN>??o!?~\8N>w??!?NTN>m??!?MN>rd??"?DN>9[??~ "?U>WN>LR??"?6&N>I??"?%1N>TA??;'"??*oN>U9??b/"?8$N>1??&7"?N>u*??|>"?O>#??fE"?1 O>!??K"?%O>"??Q"? O>??5W"?f"O>v ??"\"?(O>??`"?f.O>??_d"?7v3O>"??g"?7O>>?mj"?1;O>w>?l"?!Y>O>%>?o"?"AO>>?p"?nCO>Y>?r"?{EO>>?s"?GO>>?t"?MHO>>?Qu"?IO>A>?u"?@IO>>?u"? IO>>?u"?WIO>>?t"?HO>>?/t"?GO>Q>? s"?NFO>O>?q"?DO>>? p"?UwBO>>?-n"??O>>?l"?0=O>>?i"?:O>E>?f"?6O>>?c"? 2O>??`"?-.O>??9]"?]*O>??Y"?%O>M +??U"?  O>??]Q"? +3O>??L"?2O>??1H"?;O>??.C"?: O>5??="?qO>$??o8"?bN>A)??2"?!N>.??,"?"'~N>,4??&"?p,N>9??4 "?E0yN>???"?"5N>F??"?9zN>WL?? "? >N>R??"?pCN>`Y??!?HuN>`??^!?ON>f??!?TN>m??H!?jZN>t??!?_N>"|??!?kdN>e??!?kvN>??!?okN>?? !?vaN>??!?{WN>??!? 7MN>??ȧ!?BN>??!?Fq8N>??w!?N .N>:??J!?#N>??&!?\,N>`??~!?N>??v!?EgN>{??n!?+M>??f!?kM>~??^!?wM>??V!?]QM>S??N!?3M>@?F!?8M> @??!?JM>@?g7!??sM>=@?/!?ȩM>D@?E(!?M>:&@? !?WM>-@?!?}TM>3@?U!?'M>|:@?= !?{M>A@?I!?9rM>sG@?p ?~iM>M@? ? +`M>S@?= ?XM>Y@? ?tPM>_@? ?}tHM>e@?r ?@M>Ak@? ? 9M>p@? ?&1M> v@? ?](*M>4{@? ?9.#M>3@?l ? 1M> @?[ ?k4xM>@?| ?8:M>1@?β ?;E +M>~@?O ??M>@? + ?BL>@? ?DL>S@? ?2HL>@?j ?J?L><@? ?ML>h@?ė ?OL>V@?Ȕ ?}PL>@? ?SuL>@? ?#T9L>@?= ?VYL>@?5 ?XL>޶@?v ?YL>v@? ?XZL>߹@? ?\L>@? ?[L>@? ?\L>@? ? ^AL>@?o ?]L>@???????2S>/w3Dr1S>w^1v==pn->Ed==Q"qR>Yd=#=!qNV> d=>0= qy]>d=>=q h>-e=O=qu>Ue=_a=zqa>%f=cu=wq>>f==qb>ag=ӡ= +qNǣ>h=깶=q">fh=Ҷ=p>i==p>xj=L=p7>Uk=#==pV>7l=?=p\v>m=y\=po>wn=y=8p>:n=ǖ=p֤>o=p=p;>p=з=Gp;>q==p|3>rr= =pGP>Ds=)%=ֱpk> t=N@=Ip>t=Z=p>vu=!t=apU>v=Ҍ='pxƥ>Ȥv==wp֥> w=o=ip>>w=rϸ=p:>w=r=cp>Sx==~p>,x==upq>,x=f=[p,>zx= #=3p6>ww=/=pԥ>qw=8=pȾ>v=A= p>{@v=H=ppv>ku="M=pZ>lt=QP=p,>>s=Q=0p>4q=Q=p'>Op=zn=L=p*>l=H=qpգ>Sj=KK=G qNy>"g=V=qA>ae=se=1q1>c=iw=Dq3P>`=܌=8Xq4>%^==kqs>zh[==q>X=7=q>V==q\<>hDS=+=vP=V=q\>ĞM==Qq>XJ==qw>G==r>_D='=#rĎ>A=uf=a8r>>=A=)Mr>;= +=ar*>8=08=vr޲>F5==Sr:>Ɣ2=\׼=r-š>y/=$,=HrI>[,=/=rUљ>=)=H=r7Y>Z&=nA=}rL>3"=#=%si>= =sI>=u=*s}>==X=s>$=)P=Os>=[=as">=2=ss> ==s?>ʈ +=X= sϔ>K=w=+s`>=q =s> =T=s>Y<=s><$}=s>o<=s I>&z<=t~>I<@o=6%tz><,=3t>np(G(C<[=Yt>]'<#K=Uqt><=K|tⵎ>RSL<=t!>7P<~=t(>ۚ<=t_><`N=%t@&>!ɢǦ<~=yt>R<=:tn>T<@=HtuL>R<}=t.>:Q<==Jt)><M=8t>[M>ٴ<=it>Z<=to>ؖ<=Ut6>c<=gt_>< =;t>ٞ<؟=t͌>Ɵ<=t\><,=t>V<^\=t>>|<x=nt͎><q=OtӦ>̯<=?td><=t) >kc<= +t +>D<.y=?s +>C<=9s>]<#0=s +><= s><=s$>}=P:=ŕsš>q=˒=Qs(>v={=ls>Z =G=Xs46>==?Cs=>ރ==v.sqA> =uc=sŗ>=/=sH>=K.=[rɘ>Ic!=ߘ=rI>$==rǙ>h(=x=er@C>_;+=k={r輚>rc.=|g=΋ri4>yw1=I=qxrC>?y4=g=`er>Zg7==RrQ>@:=x=K@r)>===L.rRb>R?=o=rSɝ>PB=?3= rj->D=Ϻ=q?> @G=p=q>vI==qYF>K==qN>M=il=*q> P== qQA>R=Ӹ=q>S==q)נ>(U=yK=/q>H\W= =q|q^>X=Oҷ=Tqq>oZ=5=fq֡>[=h=]qE >]=x8=Tq?>L^=P =KqGn>c_==CqØ>:^`===q>>a==6q>sb=d~=u1q>9b=c=,qP>:c=L=)q?->cc=7='&q=>c='=$qI>0d=l="qP>?? ????5O?l5"e"e5????mN3L"F#?^354xM????VXȽyWƋ>n M>ljp????ּz>'3j[5;>ͽ)>???pc?Ɵ)-id3* 3+????Q1> 7y?#&R????֙XF('>eAB^>y????&}1>yR;3z????X=ȽwTƋ>&n=r Mmjp????j[5;=)>???R2b?J%WI+????2>U21y?'&44R????X1J('>2@^>55y????2>oe1R3;z????ۦ g@0:?/v3.[/????(=Vc1|7C=U|2&1????7(>(j;3e:x2[3e????H(ܞ="!>]:x%o????>wssTH?[w>:>???=~O>껻*>I?`骾"1????ِ'4">=h:;~ ????\rH>+2K6k4<4???? +Nc==>:21|????=>wssRHYw:>???zO>軻*>I]>#1????B5%>&M=I>< @????8̳S>=c2~5? 4?????5O?l5O?l5"e"e5?5"e"e5???????mN3L"mN3L"F#?^354xM?F#?^354xM???????VXȽyVXȽyWƋ>n M>ljp?WƋ>n M>ljp???????<=L=====>>*>;>L>]>n>>>>>"">>33>>DD>>UU>>ff>>ww>?DD?? ??UU???"""?ff&?*?.?333?ww7?;?@?DDD?H?L?Q?UUU?Y?]?""b?fff?j?n?33s?www?{??""?DD?ff???̌???33?UU?ww???ݝ??""?DD?ff???ּ>͂44(>f)q>R>2+TZ >oc +>=iu>⧼0m>ܨ6>kڼ?>%$g=)r(՛=),5=:H0=.!a3J =( 6=%/8t=g54:/=9tV<=^=7==q?Ä==&@Q=^=>;^=: Y9=3X6_=6W+2=_ z.=k))=$8m> @^>E׼2f>&>;bxp +>˦ + >@Im)>`~EI>xӻ=0>\ > RR#>Rۼ>ieּ>͂4NRӼú>4PѼi>4)2мp>p{'Ѽi>-׻ٸҼ=l>Hm3ռ8>(!SIsؼ*>kTܼJ>bSP >Ǽl2F >/[7 >0/]0>cNH<>$ +e>\3snN>|@ ?>KN =;jU 2=r\}_H=aH=b=aL`=Fh_-O=Un[F"=V-[*=;OŧQ>.G>=S>ʖ3a#>n8(4>Vx>=&>&l +>u)h0 > ƼU>2\>\SMn>J޼~>9lڼ>(ּ>͂46Y>=) *?6Lk>a *?4?>~!6,?s3>("-?1u>#e/?e0>S %|"1?f.~>%2?,>Ѳ&g4?s+J>'=5?d*>'6?ٺ)?>&au7?)>Ɲ%7?)w>M.$h7?7*>?"6?,>@N5?f->s4?0½>B1?Ū2Y>U1}/?.A5 +C>C,?d7>Y*?EP8$>4 )?8> )?8> +})?*9W>>(?q:b>B(?.;r>#&?<:G>%?2>#>$??G>#"?A!>?dC?Y>?E A>U0X?.H` >U?Jڱ">ܽ)?m2M ,%>AKֽ? O'>ßϽ ?[wRt*>Ƚ ?Uu*-> ½? W/>ɞ[?9Y_2>o>[4>[>0]6>e+ >DO^a8>">;_9>6L>`h;>ߧX`>`p<>y>$a>>/>Qb_?>Nc> c @>">cA>m>qdB>k>eC>PZ>eLD>DU>oIf`E>I>f9F>/>o&e>g4.G>y>|gG>@*>^h\G>Ҥ >P6hn!H>᥽V>>hGH>R1>gH>p4#>[fG>Ȱ>%d}E>dSl>Y`b~C>Hý>S_&#A>ν>˄\~>>_ٽu>+Y;>佡>U8>?JQt5>6-ۼ?3)NA2>|V ?hJ />?*F+> ?9C)>  ?*?F&>T?=#>JDD#?:Q!>n &?8 >C<%(?d7>)?6\>|3*?N6b>y*???????͵id?dY2b?B;3Ecq2n49'T?F2"48S?Oo2Œ4R?M24R?n?2~04AS?%2N4y?GAEq2?3$i{?C!(3ɲ3:|?h(2[:3L}?z 293hK}?2 3G}?zH 2&3@}?Oh2396}?f2Z3C*}?vb#2ѯ3'}?2D03s}?2`243}?V(2R3}?e23.}?Mc\C23AL}?R2y 3u}?9 r23 }?wt 23}?!h=D2/3}/~?߽K2 v3Jw~?r˽?2`3ջ~?<3iK3H~?2g93?2I3 63+?ͬF2>3M?I˾(2Q3~?2ֽ2k3~?9B23G=~?^23}?B2X3@i}?2s3F|?7''293|?123|?:293{?Bd62D73U{?ҳI2!3 z?7OU2ͧ3z?B|UX2PY3_z?EZ|2"3z?m\^Ih2a35y?UaӔ2 3y?\d<2-3y? fM253ty?f2)#3jy?Zm02]4x?Ί2) 4w?2n4 u?Н+2Z,47s?'eN2^>4 p?徾r2cS4rm? ξ42rc44j?ݾ#2't4f?24ic?& 2a>=F}?_t;A]??eJL\?D?Ôe:&Y\??6&dgG\?K?`q[?֒?O[ K9[?ת?AS$:[?]?Hg:[?5?6<]:C[?.?,:?'\??T;\?b?;^]?H >${$;A^?.9>,;W_?5>7x,;Ӡ`?>r %;b?V>{ݹg;c?a>a::we?9>[DE;k: %g?pW>Y; :{h?>X;S;:i?Z><<{?8&h?>x2.CIV<zf?^>g<We? >v<ҭ?wd?>T<avc?>Q<*2b?>o<%P`?(l><<_?B>B<:'^?{?0L<Ļ\??L?z ?W;2$8M?;?:)\N?L?֯9-tͺO?lM?G]_Q?M?DddR?~\?)zV? ?YF W?0?MbcX?|?];TFY??YfMZ?@?^zr[??dan\?b?cTx A]???????[1F('>\1F('>ח}y?F^>~y?D^>|y?F^>}y?F^>}y?F^>}y?F^>}y?D^>|y?D^>|y?H^>|y?F^>|y?F^>zy?F^>|y?F^>}y?H^>{y?F^>|y?F^>{y?F^>{y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?F^>|y?a>Iby?g>s'"y[y?Pr>z(x?0">Hy?0w?> 9v?0>/NSDWu?œ>27?Ps?a>%?\$q?Z>bniZo?Fy>yvlm?0)> +ܵ1j?z>׵ꇵth?1>ӵD΍e?>Uϵ-;lc?T>[̵Y&a?Ґ>L'ɵB^? ?wƵ-]?[=?jĵ9[?v?õԣZ?V8?µb Z?v?õԣZ?[=?jĵ9[? ?wƵ-]?ϐ>N'ɵB^?S>[̵V&a?>Vϵ.;lc?1>ӵD΍e?z>׵ꇵth?0)> +ܵ4j?Fy>yvlm?Z>bniZo?c>"@\$q?œ>67CPs?0>0NSDWu?>9v?0">H}?0w?Pr>z(x?g>s+"y[y?a>Iby?D^>}y???????a>g 3>3}),Ju?rΆ.u? \Ro,5v?(bJ)xev? QT#)v? "C%v?눾yv?n,(;v?,􉾎Y򻺃v?HQ^ o)ԻvTv?< v?㏾ɌR~Ju?G~ֻT=,u?}it?et4s? |?%XPP9r?B(Ms:q?;cYoy;Sp?ᓷᛀ:S;%n?vS#;/;m?!鿾;ʠ;Tm?{ː;;im?4; #;˪m?8lZ<=;n?r*<< <p?(vL<u<@x?&n=r Mmjp?TƋ>&n=r Mmjp???????9+1x<>NjJ4S\<>杦) ƼHpu<>n<2>u~<#>8(3=ښ>,=ק=J>H.G;=B*=;OF==!V=#O=n[L=`=zh_ ==aV==b_=5=a=2=\N= =jjU =?>Kn<@>|@ +\3N<<<>$]<0>c\<7 >_/l<)F >/鼸ǼTBs<*>lz3<,>i"S¸<9l>I\'.׻K<^>{ P +IR<>49+1<>FfLR<">hR <>O !<0>]~<:I>ӻm=)>=} >AIx=p +>&=>b8=f>1M^=>׼$=.m>)=)=Jzz.==2== X6=_=JW+Y9==3;= ^= :O==N=>ф===('@7===r?~V<==^=E:=!=:8=t=%h56==L/l3=: =(H0==J!!,=(=:r(=Û=$=g=)?=>6=>lڼ;=`>-i=u>⧼ = +>=X=Y >Aci<>+ <~q>p84<>Tf9+1[@=>]0YC1F =R>npW[0=*?JV/S=?CU/=t?҂UKZ0u=0?!U16=?RyV62i=?qWx3=7?X#45Lͭ=>^gZK6n;=\Y>o%\8 +5=>]9:=t>d_<=Hl>ƻa>sR= >;|c`~@=,>eBc=>qjf}CF=>JugD憆=q> hmE= >[hEk=g>ThQE=0>0FgEߓ=>0 f4DW=>YtdC=>bmB=>j`@e=n> ^>=>z[X:/=>U>8I==?R5h=݌?O 3+1=E ?jL=R0k>9? I/-ָ >a`?eE*T`>?BT(>?Y?Z%> ?N<-"$>$?z9 1>E'?6Sm'>!*?4!>Tl,?2#>.?$0C#%>0?.E&>H2?p-'>3?YN,.'>4?{~+ '>5?+'>p6?*q'>96?@ +<@&> 6?ծ+p{2%>5?,ٸ#>4?-OH">e3?8/w >I2?0r>0?2*UH>.?4u5>-?hC6'>J+?n7E +5>)?8/D$>)?"7>K)?m7^>I*?6><*?6J>z"+?l6w,>B+?x7 >*?F}8f>)?o9p >3 (?; }>l&?#>Tz> +#?@",>] ?VC.!O=(?XFmf#=Pm?6I%=f?LN( =&?OB_*y\=. ?R,>Q=:?U.=ߤ?X'0 =>[2=>?????? sFd?Xpf2d? 2V'CĞ+?'Sϱ(uj}?5%=ϱm|?Cı?G{?]qӳy?tٱnx?!GK%qw?rpv? 9 u?< 6 u?iO9 et?7sgy: t?ߓlر +0u?ېX\бWu?픱A!&v?p* v? If߱'w?c/y' Mx?oIH6sx?)iPƱ+a߳|Fy?fq۱۳jy?k4?޳ y?4]yKx?Ȇʊñcv?# +mM +F7u?둠os?R%p?ռaH2m?ʾJݱ:$?k? ؾ[Kh?j\Xwe?-VBc b?1@.m #_?9t$g\?oX04}sY?Y \;Y׽W?K hűS΄oU?L4uT?ıXS?uSXֱ͇3S?E%8'T?6 RDU? bM*hV?] *ɏCX?I㆙M}Y?űxg&\?m ͱ˷o^?\ոjf;a?辟Z d?ܾ}XzPf?sоסCi?T¾ɱ69l?1ẕra,o?7=xyr?5&|x " +u?ٱ"+Zw?ʚgFDZ ޳]y? I֐Ko{?.-@~=EA|? }?(hfL}?ߪT͑}?l'=б|?:H;od{?N˝³Zz?b׳y?>OuZZڱ糱x?~Nw?5ӱb?`v?(܌-;v?/ M[u?G )\u?Gpv?{uͱUv?<DZwlw?^Js#Mpx?#]zGpӳy?8Dpı2OA{?z%J?ɱ8|?"Luy}?VCW+???????F퉯>԰T1>{u?ۼDgK?T?O;:M?P?v6;,O?,?7Lvz;c'Q?(?,e;AS???Qw;T? + ?8< ;FV?\ +?.$ۥ;^W?| ?F ;W?0 ?ờ)u;W?' +?٫=J;KW?)6 ?{k\";?V?z ?+i:V?Q ?YB:$U?u ?<:E:MT?&?q>;;J:S??ؑ;.:1R?(?nl;* 9ZR?N?#;29RR??9 <ܧ9^R?d?Jb<ʴ9R??0Ti<4p:{_?)>dhUe<(:b?F>hal[<7Vd?ތ>T< e? +>K<^\-ke?'5>s"B<;e?>r7,<-(e?W>h !<9 e? +><5e?y>yɕ;UQf?u>;`If?>K;e+g?zw>;gTg?>e;c[h?>p;[ +h?>?;OK i?>;@Eh?@>´:/ lg?6>:n`Je?D>دwc?O>(ƺ"㺇`?O>-/tH^??7}Bg{[?{X?9yX?P ?YPջj9U?y?ZBJi:SS??6:YP?U?~.!;N?6?u0DU\;{UM?a?ƘX;.L?0?U7kS;.K?=?W{4|;K?x?tLB;L?I?NƉqx 11I('>qx 1F^>x55y?a>+5R5by?g>WM55y[y?Pr>5E5x?/">5h&5w?>5%/5v?0>5:5Wu?œ>٨5 bF5s?c>25*R5$q?Z>F5_5Zo?Fy> 85 m5lm?0)>z5 z5j?z>5GM5th?1>5=5e?>5U5lc?P>5i5&a?А>5՗5^? ?q5G5-]?Z=?5kܝ5[?v?x5m{5Z?V8?5 5 +Z?x?x5m{5Z?Z=?5kܝ5[? ?m5G5-]?А>5՗5^?U>5h5&a?>5V5lc?1>5=5e?z>5GM5th?0)>v5 z5j?Fy> 85 m5lm?Z>F5_5Zo?c>25+R5$q?œ>٨5 bF5s?0>5:5Wu?>5!/5v?.">5!h&5w?Pr>5C5x?g>WM55y[y?a>+5Q5cy?D^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?D^>x55y?F^>x55y?D^>x55y?D^>x55y?F^>x55y?F^>x55y?F^>x55y?D^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y?F^>x55y???????6<>2a0>\1RY<;z?i;j`Ż{?V)֝lj̻,e|?mӻy|?qٻU}?] U߻}?O|E}?/G.껃}?NĜo}?dћ'p}?:K$9}?%+t}?MIK"$}?!3 Y滝|?B- ݻs>|?:zһ{?6Ha}PŻ{?Ulh3\z?9a:YI]y?kDxy?_s-'yx?hwavLMgx?i`w!3&+hx?]tۺOx?zokx?EiZ3o?y?scdP:ɚy?>]3 9j:y?]X(s:M-;8z?*TAU.;Rk;9qz?DQC&w;c;z?Oh; l;ϩz?H3P;ى;z?kR;6;Jz?tV;|W񂻗x?/h|?&H3}ػ]|?"2a4ܻ5|?y"j{t?o-qr4wqn?ojdP.e<%]hSJUeGcKFwٽ)M@%н+43ˤǽ&[zp ~?-ԺbXI𨓽#Ə4u+X$&̇<ƺ_G&ۦ g@똑9?&|;:ƺX:#&̇ŏ:4u+X:I𨓽:bŒ:~?[ ;~;q&;[64;)ˤǽAM@;u%нmcK;FwٽJU;eJ];^齐.e;2%j;u?o;!q;|mr;4wq;]@o;-!j;{ +0e;>uC];gLU;f_TfK;FM轄P@;%⽽"4;4(eܽ3&;ս$;oν ;ƽ8:~;:bxH]:IܭKɏ:4X:$u>:SҒ9GXۦ g@0:?/v3.[/?-0:?L;%nA;/?.:?Pz;,;/?,:?</?:?(u/?K:?.¼=u/?:?4.׼ ˼/? :?)ݼX/?m:?eJ9/?b9?.]x/?9?+b~/? 9?#| 1y/? 9?I6hxt/?9? S!;Zp/?9?ti%l/?d9?$i(kj/?9?A*~ h/?!9?*A!Jh/?9?A* h/?d9?bi(jj/?9?i%l/?9?S!m<Xp/? +9?o7ivt/? 9?$ /y/?9?,F_~/?b9?7_|/?k:?%N7/? :?Y +뼍ݼU/?:?2׼J˼/?K:?Q3¼Ar/?:?,x/?!:??֌=/? &:? {l\/?):?kJ?۫/?,:?/?.:?Rx̻Y/?-0:?LxnA/?0:?/v3.[/???????(=Vc1(=Vc1|7C=U|2&1?`7C=" ;m`?7C=ɋ;q/?v6C=;D&1/?5C=c +(j;37(>(j;3e:x2[3e?e:x2[3e???????H(ܞ="H(ܞ="!>]:x%o? >g»0$ޠo?>LB}ǣo?(>C[ϖo?>W ";o? +>qIo?> ovo?Z> #≼ho?>18Xo?ݳ>pLSHo?г>G_ 46o?ó>pR ˼%o?>_ؼo?Щ>@弮o?ٝ>ۙZfn?>\dKn?x>5\$n?>hEn?{>퟽-zn?%x>Gn?v>Fn?&x>Gn?{>q퟽{n?>`GhFn?z>4#n?>q[Mn?ܝ>ncn?Щ>F=弲o?>lؼo?ó>p ˼%o?г>B_S06o?ݳ>(lL_OHo?>{8Xo?\>M#߉ho? >@ + +ovo? +>%Io?>S";o?)>-Жo?>\JB_ţo? >»/$ޠo?!>]:x%o? >;-$;ޠo?>IJB<3;Жo?>S<5"<;o? +><I9 = oH#=B߉{8=ǀ"lL= O<Ho?г>B_=0<6o?ó>p= <%o?>h=K<o?Щ>C=\=<o?ܝ>l=cn[=R4=#=n?>_=*h=Fn?{>q==|n?$x>=G=n?v>}F=~=n?%x>=G=n?{>==zn?>=h=En?x>5=?$=n?>\=(ԙ=f=E@<o?>[=<o?ó>p= <%o?г>G_=3<6o?ݳ>pL=R<Ho?>)8=S#={ =;ob<(IW<} "<;o?'>5LB<ƣ;o? >8;.$;ޠo?!>]:x%o???????>w>wssTH?[w>:>ssTH?[w>:>??????=~O>껻=~O>껻Sih?He>Sih?He>??????n2'>81n2'>81p ?L9=1=`R?p ?L9=1=`R???????nH>lnH>l{ (\b9?{ (\b9??????? [==y33 [==y33 }`>c1u? }`>c1u???????=>w=>wssRHYw:>ssRHYw:>??????zO>軻zO>軻~ż6JO]?/z=~ż6JO]?/z=??????"> "> ?n6`B>P? ?n6`B>P???????[S>G4[S>G4~5? 4?~5? 4??????? \ No newline at end of file diff --git a/characters/samus/samus.gd b/characters/samus/samus.gd new file mode 100644 index 0000000..5548c4d --- /dev/null +++ b/characters/samus/samus.gd @@ -0,0 +1,49 @@ +extends CharacterBody3D + +@export var state_machine: LimboHSM +@onready var idle_state: LimboState = $LimboHSM/Idle + +@export var move_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: + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + + _initialize_state_machine() + + +func _initialize_state_machine() -> void: + state_machine.initial_state = idle_state + state_machine.initialize(self) + state_machine.set_active(true) + +func _unhandled_input(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 = move_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 + move_pcam.set_third_person_rotation_degrees(pcam_rotation_degrees) diff --git a/characters/samus/samus.gd.uid b/characters/samus/samus.gd.uid new file mode 100644 index 0000000..ad1ff0f --- /dev/null +++ b/characters/samus/samus.gd.uid @@ -0,0 +1 @@ +uid://byrirmtjstdx6 diff --git a/characters/samus/samus.glb b/characters/samus/samus.glb new file mode 100644 index 0000000..0536a89 Binary files /dev/null and b/characters/samus/samus.glb differ diff --git a/characters/samus/samus.glb.import b/characters/samus/samus.glb.import new file mode 100644 index 0000000..f7ee2ec --- /dev/null +++ b/characters/samus/samus.glb.import @@ -0,0 +1,44 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://cene38uaq3y64" +path="res://.godot/imported/samus.glb-042d9a5e196885bb34364cad04e22af3.scn" + +[deps] + +source_file="res://characters/samus/samus.glb" +dest_files=["res://.godot/imported/samus.glb-042d9a5e196885bb34364cad04e22af3.scn"] + +[params] + +nodes/root_type="CharacterBody3D" +nodes/root_name="Samus" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +_subresources={ +"materials": { +"Material": { +"use_external/enabled": true, +"use_external/path": "uid://dfacvvhew44xp" +} +} +} +gltf/naming_version=1 +gltf/embedded_image_handling=1 diff --git a/characters/samus/samus.gltf b/characters/samus/samus.gltf new file mode 100644 index 0000000..3b1ccce --- /dev/null +++ b/characters/samus/samus.gltf @@ -0,0 +1,6456 @@ +{ + "asset":{ + "generator":"Khronos glTF Blender I/O v4.0.44", + "version":"2.0" + }, + "scene":0, + "scenes":[ + { + "name":"Scene", + "nodes":[ + 28 + ] + } + ], + "nodes":[ + { + "name":"DEF_pelvis", + "rotation":[ + 0.5942882299423218, + 9.682182167125575e-08, + 3.8525621448570746e-07, + 0.8042521476745605 + ], + "translation":[ + 1.1097006336058257e-07, + -0.07379588484764099, + -0.27284228801727295 + ] + }, + { + "name":"DEF_toes_l", + "rotation":[ + 0.2175150215625763, + -1.840470076786005e-06, + -5.684929078597634e-07, + 0.9760569930076599 + ], + "scale":[ + 1, + 0.9999998807907104, + 0.9999998807907104 + ], + "translation":[ + -1.3135229792737846e-08, + 0.16323956847190857, + -6.957080245229008e-09 + ] + }, + { + "children":[ + 1 + ], + "name":"DEF_foot_l", + "rotation":[ + 0.5682543516159058, + -1.5461463931387698e-07, + -2.713864830639068e-07, + 0.8228530287742615 + ], + "translation":[ + 2.135379872925114e-09, + 0.49902787804603577, + -5.832992755472333e-09 + ] + }, + { + "name":"DEF_heel_l", + "rotation":[ + -0.20516124367713928, + -3.088917210902764e-08, + 4.3720017828263735e-08, + 0.978728175163269 + ], + "scale":[ + 1, + 0.9999999403953552, + 1 + ], + "translation":[ + 2.135379872925114e-09, + 0.49902787804603577, + -5.832992755472333e-09 + ] + }, + { + "children":[ + 2, + 3 + ], + "name":"DEF_lowerleg_l", + "rotation":[ + -0.08043701201677322, + 5.318103646345662e-08, + 3.050914898494739e-08, + 0.9967597126960754 + ], + "scale":[ + 1, + 0.9999999403953552, + 1 + ], + "translation":[ + 1.613355116170112e-09, + 0.5004483461380005, + -5.846612083360014e-10 + ] + }, + { + "children":[ + 4 + ], + "name":"DEF_upperleg_l", + "rotation":[ + -0.8570992350578308, + 0.18282298743724823, + -0.10047125071287155, + 0.47102251648902893 + ], + "scale":[ + 1, + 0.9999998211860657, + 0.9999998211860657 + ], + "translation":[ + -0.0262211374938488, + 0.14807692170143127, + -1.7800971363612916e-08 + ] + }, + { + "children":[ + 5 + ], + "name":"DEF_pelvis_l", + "rotation":[ + 0.27299758791923523, + -0.05823143199086189, + 0.20031945407390594, + 0.9391238689422607 + ], + "scale":[ + 0.9999999403953552, + 0.9999999403953552, + 0.9999999403953552 + ], + "translation":[ + -0.05273757129907608, + -0.09807388484477997, + -0.2803380489349365 + ] + }, + { + "name":"DEF_toes_r", + "rotation":[ + 0.2175149917602539, + 1.8404699630991672e-06, + 5.684929647031822e-07, + 0.9760569930076599 + ], + "scale":[ + 1, + 0.9999999403953552, + 1 + ], + "translation":[ + -1.6202763575279278e-08, + 0.16323962807655334, + 6.796831542033033e-09 + ] + }, + { + "children":[ + 7 + ], + "name":"DEF_foot_r", + "rotation":[ + 0.5682542324066162, + 1.546146535247317e-07, + 2.7138645464219735e-07, + 0.8228530883789062 + ], + "scale":[ + 1, + 1.0000001192092896, + 1 + ], + "translation":[ + -4.419824950474549e-09, + 0.49902790784835815, + -3.9062300061232236e-09 + ] + }, + { + "name":"DEF_heel_r", + "rotation":[ + -0.20516133308410645, + 3.088914724003189e-08, + -4.372003203911845e-08, + 0.978728175163269 + ], + "scale":[ + 1, + 1.0000001192092896, + 1 + ], + "translation":[ + -4.419824950474549e-09, + 0.49902790784835815, + -3.9062300061232236e-09 + ] + }, + { + "children":[ + 8, + 9 + ], + "name":"DEF_lowerleg_r", + "rotation":[ + -0.08043698221445084, + -1.71463963027918e-08, + -2.2246478437182304e-08, + 0.9967597126960754 + ], + "scale":[ + 1, + 1.0000001192092896, + 0.9999999403953552 + ], + "translation":[ + 1.068835953077496e-08, + 0.5004483461380005, + 2.2406254629459e-10 + ] + }, + { + "children":[ + 10 + ], + "name":"DEF_upperleg_r", + "rotation":[ + -0.8570992350578308, + -0.18282295763492584, + 0.10047133266925812, + 0.4710225462913513 + ], + "scale":[ + 1, + 0.9999998211860657, + 0.9999998211860657 + ], + "translation":[ + 0.026221174746751785, + 0.14807693660259247, + -9.059375116748924e-08 + ] + }, + { + "children":[ + 11 + ], + "name":"DEF_pelvis_r", + "rotation":[ + 0.27299749851226807, + 0.05823148787021637, + -0.2003190815448761, + 0.9391239285469055 + ], + "scale":[ + 0.9999999403953552, + 1, + 0.9999998807907104 + ], + "translation":[ + 0.052737779915332794, + -0.09807385504245758, + -0.2803380489349365 + ] + }, + { + "name":"DEF_head", + "rotation":[ + 0.3518194258213043, + -1.0868997257773572e-08, + -5.796993463036415e-08, + 0.9360678791999817 + ], + "translation":[ + -2.4424906541753444e-15, + 0.07756800949573517, + -1.1827796697616577e-07 + ] + }, + { + "children":[ + 13 + ], + "name":"DEF_neck", + "rotation":[ + -0.4402303695678711, + 1.4448794161125988e-08, + 7.451009764736227e-08, + 0.8978849053382874 + ], + "scale":[ + 1, + 0.9999999403953552, + 1 + ], + "translation":[ + 1.3322676295501878e-14, + 0.3298793137073517, + 1.4988010832439613e-15 + ] + }, + { + "name":"DEF_fingers_l", + "rotation":[ + -0.1744685173034668, + 5.811677361577949e-09, + -3.6803406544549944e-08, + 0.9846627712249756 + ], + "scale":[ + 1, + 0.9999999403953552, + 0.9999999403953552 + ], + "translation":[ + 4.433688971516858e-09, + 0.10607405751943588, + -1.0173598852247778e-08 + ] + }, + { + "children":[ + 15 + ], + "name":"DEF_hand_l", + "rotation":[ + -0.04450597986578941, + -0.7069002985954285, + 0.017086952924728394, + 0.7057047486305237 + ], + "translation":[ + -1.1594596571740112e-07, + 0.3677442669868469, + -1.2383168268570444e-08 + ] + }, + { + "children":[ + 16 + ], + "name":"DEF_lowerarm_l", + "rotation":[ + 0.0830555111169815, + 0.002839589025825262, + -0.023253832012414932, + 0.9962695240974426 + ], + "scale":[ + 1.0000001192092896, + 0.9999999403953552, + 0.9999998807907104 + ], + "translation":[ + 3.6903657019138336e-08, + 0.40388593077659607, + -1.862645149230957e-09 + ] + }, + { + "children":[ + 17 + ], + "name":"DEF_upperarm_l", + "rotation":[ + 0.16693860292434692, + 0.61440509557724, + -0.3338117003440857, + 0.6951314210891724 + ], + "scale":[ + 1, + 0.9999996423721313, + 0.9999999403953552 + ], + "translation":[ + 0.08433244377374649, + 0.2027110457420349, + -0.005734667181968689 + ] + }, + { + "children":[ + 18 + ], + "name":"DEF_shoulder_l", + "rotation":[ + -0.23774707317352295, + 0.7836201190948486, + 0.49895748496055603, + 0.28365010023117065 + ], + "scale":[ + 1.0000001192092896, + 0.9999998211860657, + 0.9999999403953552 + ], + "translation":[ + -0.07696466147899628, + 0.3025479018688202, + -0.0768880546092987 + ] + }, + { + "name":"DEF_gunpoint_r", + "rotation":[ + -0.037245504558086395, + 0.7070387601852417, + -0.009815593250095844, + 0.7061251401901245 + ], + "scale":[ + 0.9999999403953552, + 0.9999999403953552, + 1 + ], + "translation":[ + -4.402753717158703e-08, + 0.4811078906059265, + 1.1496695151436143e-08 + ] + }, + { + "children":[ + 20 + ], + "name":"DEF_lowerarm_r", + "rotation":[ + 0.07280454784631729, + -0.0030787393916398287, + 0.02322336658835411, + 0.9970710873603821 + ], + "scale":[ + 1, + 1.0000001192092896, + 1.0000001192092896 + ], + "translation":[ + 1.1315569281578064e-07, + 0.4038860499858856, + -1.862645149230957e-09 + ] + }, + { + "children":[ + 21 + ], + "name":"DEF_upperarm_r", + "rotation":[ + 0.16693861782550812, + -0.6144050359725952, + 0.3338116705417633, + 0.6951314806938171 + ], + "scale":[ + 1, + 0.9999997615814209, + 0.9999998211860657 + ], + "translation":[ + -0.08433247357606888, + 0.20271113514900208, + -0.005734523758292198 + ] + }, + { + "children":[ + 22 + ], + "name":"DEF_shoulder_r", + "rotation":[ + -0.23774713277816772, + -0.7836199998855591, + -0.49895748496055603, + 0.28365030884742737 + ], + "scale":[ + 1, + 0.9999998211860657, + 1 + ], + "translation":[ + 0.07696466147899628, + 0.3025479316711426, + -0.0768880769610405 + ] + }, + { + "children":[ + 14, + 19, + 23 + ], + "name":"DEF_chest", + "rotation":[ + 0.04766033589839935, + 1.4687819849257266e-08, + 5.866708008284149e-09, + 0.9988636374473572 + ], + "translation":[ + -2.1538326677728037e-14, + 0.11220654845237732, + -7.840950111415168e-15 + ] + }, + { + "children":[ + 24 + ], + "name":"DEF_stomach", + "rotation":[ + 0.7273042798042297, + 1.1849294168086999e-07, + -1.0164863617490028e-08, + 0.6863152384757996 + ], + "scale":[ + 1, + 0.9999999403953552, + 0.9999999403953552 + ], + "translation":[ + -1.4683621072514308e-14, + -0.009219586849212646, + -0.06262290477752686 + ] + }, + { + "children":[ + 0, + 6, + 12, + 25 + ], + "name":"CTRL_COG", + "rotation":[ + -0.7071067690849304, + -1.1520229747929989e-07, + -1.1520229747929989e-07, + 0.7071067690849304 + ], + "translation":[ + -7.367092536014752e-08, + 1.3288058042526245, + -0.0009025931358337402 + ] + }, + { + "mesh":0, + "name":"Samus_Mesh", + "skin":0 + }, + { + "children":[ + 27, + 26 + ], + "name":"Samus_Armature", + "rotation":[ + 0, + -1, + 0, + 1.6292068494294654e-07 + ] + } + ], + "animations":[ + { + "channels":[ + { + "sampler":0, + "target":{ + "node":26, + "path":"translation" + } + }, + { + "sampler":1, + "target":{ + "node":26, + "path":"rotation" + } + }, + { + "sampler":2, + "target":{ + "node":26, + "path":"scale" + } + }, + { + "sampler":3, + "target":{ + "node":0, + "path":"translation" + } + }, + { + "sampler":4, + "target":{ + "node":0, + "path":"rotation" + } + }, + { + "sampler":5, + "target":{ + "node":0, + "path":"scale" + } + }, + { + "sampler":6, + "target":{ + "node":6, + "path":"translation" + } + }, + { + "sampler":7, + "target":{ + "node":6, + "path":"rotation" + } + }, + { + "sampler":8, + "target":{ + "node":6, + "path":"scale" + } + }, + { + "sampler":9, + "target":{ + "node":5, + "path":"translation" + } + }, + { + "sampler":10, + "target":{ + "node":5, + "path":"rotation" + } + }, + { + "sampler":11, + "target":{ + "node":5, + "path":"scale" + } + }, + { + "sampler":12, + "target":{ + "node":4, + "path":"translation" + } + }, + { + "sampler":13, + "target":{ + "node":4, + "path":"rotation" + } + }, + { + "sampler":14, + "target":{ + "node":4, + "path":"scale" + } + }, + { + "sampler":15, + "target":{ + "node":2, + "path":"translation" + } + }, + { + "sampler":16, + "target":{ + "node":2, + "path":"rotation" + } + }, + { + "sampler":17, + "target":{ + "node":2, + "path":"scale" + } + }, + { + "sampler":18, + "target":{ + "node":1, + "path":"translation" + } + }, + { + "sampler":19, + "target":{ + "node":1, + "path":"rotation" + } + }, + { + "sampler":20, + "target":{ + "node":1, + "path":"scale" + } + }, + { + "sampler":21, + "target":{ + "node":3, + "path":"translation" + } + }, + { + "sampler":22, + "target":{ + "node":3, + "path":"rotation" + } + }, + { + "sampler":23, + "target":{ + "node":3, + "path":"scale" + } + }, + { + "sampler":24, + "target":{ + "node":12, + "path":"translation" + } + }, + { + "sampler":25, + "target":{ + "node":12, + "path":"rotation" + } + }, + { + "sampler":26, + "target":{ + "node":12, + "path":"scale" + } + }, + { + "sampler":27, + "target":{ + "node":11, + "path":"translation" + } + }, + { + "sampler":28, + "target":{ + "node":11, + "path":"rotation" + } + }, + { + "sampler":29, + "target":{ + "node":11, + "path":"scale" + } + }, + { + "sampler":30, + "target":{ + "node":10, + "path":"translation" + } + }, + { + "sampler":31, + "target":{ + "node":10, + "path":"rotation" + } + }, + { + "sampler":32, + "target":{ + "node":10, + "path":"scale" + } + }, + { + "sampler":33, + "target":{ + "node":8, + "path":"translation" + } + }, + { + "sampler":34, + "target":{ + "node":8, + "path":"rotation" + } + }, + { + "sampler":35, + "target":{ + "node":8, + "path":"scale" + } + }, + { + "sampler":36, + "target":{ + "node":7, + "path":"translation" + } + }, + { + "sampler":37, + "target":{ + "node":7, + "path":"rotation" + } + }, + { + "sampler":38, + "target":{ + "node":7, + "path":"scale" + } + }, + { + "sampler":39, + "target":{ + "node":9, + "path":"translation" + } + }, + { + "sampler":40, + "target":{ + "node":9, + "path":"rotation" + } + }, + { + "sampler":41, + "target":{ + "node":9, + "path":"scale" + } + }, + { + "sampler":42, + "target":{ + "node":25, + "path":"translation" + } + }, + { + "sampler":43, + "target":{ + "node":25, + "path":"rotation" + } + }, + { + "sampler":44, + "target":{ + "node":25, + "path":"scale" + } + }, + { + "sampler":45, + "target":{ + "node":24, + "path":"translation" + } + }, + { + "sampler":46, + "target":{ + "node":24, + "path":"rotation" + } + }, + { + "sampler":47, + "target":{ + "node":24, + "path":"scale" + } + }, + { + "sampler":48, + "target":{ + "node":14, + "path":"translation" + } + }, + { + "sampler":49, + "target":{ + "node":14, + "path":"rotation" + } + }, + { + "sampler":50, + "target":{ + "node":14, + "path":"scale" + } + }, + { + "sampler":51, + "target":{ + "node":13, + "path":"translation" + } + }, + { + "sampler":52, + "target":{ + "node":13, + "path":"rotation" + } + }, + { + "sampler":53, + "target":{ + "node":13, + "path":"scale" + } + }, + { + "sampler":54, + "target":{ + "node":19, + "path":"translation" + } + }, + { + "sampler":55, + "target":{ + "node":19, + "path":"rotation" + } + }, + { + "sampler":56, + "target":{ + "node":19, + "path":"scale" + } + }, + { + "sampler":57, + "target":{ + "node":18, + "path":"translation" + } + }, + { + "sampler":58, + "target":{ + "node":18, + "path":"rotation" + } + }, + { + "sampler":59, + "target":{ + "node":18, + "path":"scale" + } + }, + { + "sampler":60, + "target":{ + "node":17, + "path":"translation" + } + }, + { + "sampler":61, + "target":{ + "node":17, + "path":"rotation" + } + }, + { + "sampler":62, + "target":{ + "node":17, + "path":"scale" + } + }, + { + "sampler":63, + "target":{ + "node":16, + "path":"translation" + } + }, + { + "sampler":64, + "target":{ + "node":16, + "path":"rotation" + } + }, + { + "sampler":65, + "target":{ + "node":16, + "path":"scale" + } + }, + { + "sampler":66, + "target":{ + "node":15, + "path":"translation" + } + }, + { + "sampler":67, + "target":{ + "node":15, + "path":"rotation" + } + }, + { + "sampler":68, + "target":{ + "node":15, + "path":"scale" + } + }, + { + "sampler":69, + "target":{ + "node":23, + "path":"translation" + } + }, + { + "sampler":70, + "target":{ + "node":23, + "path":"rotation" + } + }, + { + "sampler":71, + "target":{ + "node":23, + "path":"scale" + } + }, + { + "sampler":72, + "target":{ + "node":22, + "path":"translation" + } + }, + { + "sampler":73, + "target":{ + "node":22, + "path":"rotation" + } + }, + { + "sampler":74, + "target":{ + "node":22, + "path":"scale" + } + }, + { + "sampler":75, + "target":{ + "node":21, + "path":"translation" + } + }, + { + "sampler":76, + "target":{ + "node":21, + "path":"rotation" + } + }, + { + "sampler":77, + "target":{ + "node":21, + "path":"scale" + } + }, + { + "sampler":78, + "target":{ + "node":20, + "path":"translation" + } + }, + { + "sampler":79, + "target":{ + "node":20, + "path":"rotation" + } + }, + { + "sampler":80, + "target":{ + "node":20, + "path":"scale" + } + } + ], + "name":"standing_idle -loop", + "samplers":[ + { + "input":8, + "interpolation":"STEP", + "output":9 + }, + { + "input":8, + "interpolation":"STEP", + "output":10 + }, + { + "input":8, + "interpolation":"STEP", + "output":11 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":13 + }, + { + "input":8, + "interpolation":"STEP", + "output":14 + }, + { + "input":8, + "interpolation":"STEP", + "output":15 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":16 + }, + { + "input":8, + "interpolation":"STEP", + "output":17 + }, + { + "input":8, + "interpolation":"STEP", + "output":18 + }, + { + "input":8, + "interpolation":"STEP", + "output":19 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":20 + }, + { + "input":8, + "interpolation":"STEP", + "output":21 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":22 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":23 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":24 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":25 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":26 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":27 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":28 + }, + { + "input":8, + "interpolation":"STEP", + "output":29 + }, + { + "input":8, + "interpolation":"STEP", + "output":30 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":31 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":32 + }, + { + "input":8, + "interpolation":"STEP", + "output":33 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":34 + }, + { + "input":8, + "interpolation":"STEP", + "output":35 + }, + { + "input":8, + "interpolation":"STEP", + "output":36 + }, + { + "input":8, + "interpolation":"STEP", + "output":37 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":38 + }, + { + "input":8, + "interpolation":"STEP", + "output":39 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":40 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":41 + }, + { + "input":8, + "interpolation":"STEP", + "output":42 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":43 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":44 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":45 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":46 + }, + { + "input":8, + "interpolation":"STEP", + "output":47 + }, + { + "input":8, + "interpolation":"STEP", + "output":48 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":49 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":50 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":51 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":52 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":53 + }, + { + "input":8, + "interpolation":"STEP", + "output":54 + }, + { + "input":8, + "interpolation":"STEP", + "output":55 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":56 + }, + { + "input":8, + "interpolation":"STEP", + "output":57 + }, + { + "input":8, + "interpolation":"STEP", + "output":58 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":59 + }, + { + "input":8, + "interpolation":"STEP", + "output":60 + }, + { + "input":8, + "interpolation":"STEP", + "output":61 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":62 + }, + { + "input":8, + "interpolation":"STEP", + "output":63 + }, + { + "input":8, + "interpolation":"STEP", + "output":64 + }, + { + "input":8, + "interpolation":"STEP", + "output":65 + }, + { + "input":8, + "interpolation":"STEP", + "output":66 + }, + { + "input":8, + "interpolation":"STEP", + "output":67 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":68 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":69 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":70 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":71 + }, + { + "input":8, + "interpolation":"STEP", + "output":72 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":73 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":74 + }, + { + "input":8, + "interpolation":"STEP", + "output":75 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":76 + }, + { + "input":8, + "interpolation":"STEP", + "output":77 + }, + { + "input":8, + "interpolation":"STEP", + "output":78 + }, + { + "input":8, + "interpolation":"STEP", + "output":79 + }, + { + "input":8, + "interpolation":"STEP", + "output":80 + }, + { + "input":8, + "interpolation":"STEP", + "output":81 + }, + { + "input":8, + "interpolation":"STEP", + "output":82 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":83 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":84 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":85 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":86 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":87 + }, + { + "input":8, + "interpolation":"LINEAR", + "output":88 + }, + { + "input":12, + "interpolation":"LINEAR", + "output":89 + }, + { + "input":8, + "interpolation":"STEP", + "output":90 + } + ] + }, + { + "channels":[ + { + "sampler":0, + "target":{ + "node":26, + "path":"translation" + } + }, + { + "sampler":1, + "target":{ + "node":26, + "path":"rotation" + } + }, + { + "sampler":2, + "target":{ + "node":26, + "path":"scale" + } + }, + { + "sampler":3, + "target":{ + "node":0, + "path":"translation" + } + }, + { + "sampler":4, + "target":{ + "node":0, + "path":"rotation" + } + }, + { + "sampler":5, + "target":{ + "node":0, + "path":"scale" + } + }, + { + "sampler":6, + "target":{ + "node":6, + "path":"translation" + } + }, + { + "sampler":7, + "target":{ + "node":6, + "path":"rotation" + } + }, + { + "sampler":8, + "target":{ + "node":6, + "path":"scale" + } + }, + { + "sampler":9, + "target":{ + "node":5, + "path":"translation" + } + }, + { + "sampler":10, + "target":{ + "node":5, + "path":"rotation" + } + }, + { + "sampler":11, + "target":{ + "node":5, + "path":"scale" + } + }, + { + "sampler":12, + "target":{ + "node":4, + "path":"translation" + } + }, + { + "sampler":13, + "target":{ + "node":4, + "path":"rotation" + } + }, + { + "sampler":14, + "target":{ + "node":4, + "path":"scale" + } + }, + { + "sampler":15, + "target":{ + "node":2, + "path":"translation" + } + }, + { + "sampler":16, + "target":{ + "node":2, + "path":"rotation" + } + }, + { + "sampler":17, + "target":{ + "node":2, + "path":"scale" + } + }, + { + "sampler":18, + "target":{ + "node":1, + "path":"translation" + } + }, + { + "sampler":19, + "target":{ + "node":1, + "path":"rotation" + } + }, + { + "sampler":20, + "target":{ + "node":1, + "path":"scale" + } + }, + { + "sampler":21, + "target":{ + "node":3, + "path":"translation" + } + }, + { + "sampler":22, + "target":{ + "node":3, + "path":"rotation" + } + }, + { + "sampler":23, + "target":{ + "node":3, + "path":"scale" + } + }, + { + "sampler":24, + "target":{ + "node":12, + "path":"translation" + } + }, + { + "sampler":25, + "target":{ + "node":12, + "path":"rotation" + } + }, + { + "sampler":26, + "target":{ + "node":12, + "path":"scale" + } + }, + { + "sampler":27, + "target":{ + "node":11, + "path":"translation" + } + }, + { + "sampler":28, + "target":{ + "node":11, + "path":"rotation" + } + }, + { + "sampler":29, + "target":{ + "node":11, + "path":"scale" + } + }, + { + "sampler":30, + "target":{ + "node":10, + "path":"translation" + } + }, + { + "sampler":31, + "target":{ + "node":10, + "path":"rotation" + } + }, + { + "sampler":32, + "target":{ + "node":10, + "path":"scale" + } + }, + { + "sampler":33, + "target":{ + "node":8, + "path":"translation" + } + }, + { + "sampler":34, + "target":{ + "node":8, + "path":"rotation" + } + }, + { + "sampler":35, + "target":{ + "node":8, + "path":"scale" + } + }, + { + "sampler":36, + "target":{ + "node":7, + "path":"translation" + } + }, + { + "sampler":37, + "target":{ + "node":7, + "path":"rotation" + } + }, + { + "sampler":38, + "target":{ + "node":7, + "path":"scale" + } + }, + { + "sampler":39, + "target":{ + "node":9, + "path":"translation" + } + }, + { + "sampler":40, + "target":{ + "node":9, + "path":"rotation" + } + }, + { + "sampler":41, + "target":{ + "node":9, + "path":"scale" + } + }, + { + "sampler":42, + "target":{ + "node":25, + "path":"translation" + } + }, + { + "sampler":43, + "target":{ + "node":25, + "path":"rotation" + } + }, + { + "sampler":44, + "target":{ + "node":25, + "path":"scale" + } + }, + { + "sampler":45, + "target":{ + "node":24, + "path":"translation" + } + }, + { + "sampler":46, + "target":{ + "node":24, + "path":"rotation" + } + }, + { + "sampler":47, + "target":{ + "node":24, + "path":"scale" + } + }, + { + "sampler":48, + "target":{ + "node":14, + "path":"translation" + } + }, + { + "sampler":49, + "target":{ + "node":14, + "path":"rotation" + } + }, + { + "sampler":50, + "target":{ + "node":14, + "path":"scale" + } + }, + { + "sampler":51, + "target":{ + "node":13, + "path":"translation" + } + }, + { + "sampler":52, + "target":{ + "node":13, + "path":"rotation" + } + }, + { + "sampler":53, + "target":{ + "node":13, + "path":"scale" + } + }, + { + "sampler":54, + "target":{ + "node":19, + "path":"translation" + } + }, + { + "sampler":55, + "target":{ + "node":19, + "path":"rotation" + } + }, + { + "sampler":56, + "target":{ + "node":19, + "path":"scale" + } + }, + { + "sampler":57, + "target":{ + "node":18, + "path":"translation" + } + }, + { + "sampler":58, + "target":{ + "node":18, + "path":"rotation" + } + }, + { + "sampler":59, + "target":{ + "node":18, + "path":"scale" + } + }, + { + "sampler":60, + "target":{ + "node":17, + "path":"translation" + } + }, + { + "sampler":61, + "target":{ + "node":17, + "path":"rotation" + } + }, + { + "sampler":62, + "target":{ + "node":17, + "path":"scale" + } + }, + { + "sampler":63, + "target":{ + "node":16, + "path":"translation" + } + }, + { + "sampler":64, + "target":{ + "node":16, + "path":"rotation" + } + }, + { + "sampler":65, + "target":{ + "node":16, + "path":"scale" + } + }, + { + "sampler":66, + "target":{ + "node":15, + "path":"translation" + } + }, + { + "sampler":67, + "target":{ + "node":15, + "path":"rotation" + } + }, + { + "sampler":68, + "target":{ + "node":15, + "path":"scale" + } + }, + { + "sampler":69, + "target":{ + "node":23, + "path":"translation" + } + }, + { + "sampler":70, + "target":{ + "node":23, + "path":"rotation" + } + }, + { + "sampler":71, + "target":{ + "node":23, + "path":"scale" + } + }, + { + "sampler":72, + "target":{ + "node":22, + "path":"translation" + } + }, + { + "sampler":73, + "target":{ + "node":22, + "path":"rotation" + } + }, + { + "sampler":74, + "target":{ + "node":22, + "path":"scale" + } + }, + { + "sampler":75, + "target":{ + "node":21, + "path":"translation" + } + }, + { + "sampler":76, + "target":{ + "node":21, + "path":"rotation" + } + }, + { + "sampler":77, + "target":{ + "node":21, + "path":"scale" + } + }, + { + "sampler":78, + "target":{ + "node":20, + "path":"translation" + } + }, + { + "sampler":79, + "target":{ + "node":20, + "path":"rotation" + } + }, + { + "sampler":80, + "target":{ + "node":20, + "path":"scale" + } + } + ], + "name":"T-Pose", + "samplers":[ + { + "input":91, + "interpolation":"LINEAR", + "output":92 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":93 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":94 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":95 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":96 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":97 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":98 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":99 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":100 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":101 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":102 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":103 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":104 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":105 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":106 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":107 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":108 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":109 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":110 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":111 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":112 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":113 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":114 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":115 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":116 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":117 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":118 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":119 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":120 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":121 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":122 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":123 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":124 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":125 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":126 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":127 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":128 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":129 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":130 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":131 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":132 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":133 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":134 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":135 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":136 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":137 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":138 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":139 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":140 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":141 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":142 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":143 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":144 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":145 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":146 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":147 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":148 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":149 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":150 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":151 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":152 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":153 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":154 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":155 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":156 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":157 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":158 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":159 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":160 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":161 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":162 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":163 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":164 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":165 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":166 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":167 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":168 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":169 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":170 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":171 + }, + { + "input":91, + "interpolation":"LINEAR", + "output":172 + } + ] + }, + { + "channels":[ + { + "sampler":0, + "target":{ + "node":26, + "path":"translation" + } + }, + { + "sampler":1, + "target":{ + "node":26, + "path":"rotation" + } + }, + { + "sampler":2, + "target":{ + "node":26, + "path":"scale" + } + }, + { + "sampler":3, + "target":{ + "node":0, + "path":"translation" + } + }, + { + "sampler":4, + "target":{ + "node":0, + "path":"rotation" + } + }, + { + "sampler":5, + "target":{ + "node":0, + "path":"scale" + } + }, + { + "sampler":6, + "target":{ + "node":6, + "path":"translation" + } + }, + { + "sampler":7, + "target":{ + "node":6, + "path":"rotation" + } + }, + { + "sampler":8, + "target":{ + "node":6, + "path":"scale" + } + }, + { + "sampler":9, + "target":{ + "node":5, + "path":"translation" + } + }, + { + "sampler":10, + "target":{ + "node":5, + "path":"rotation" + } + }, + { + "sampler":11, + "target":{ + "node":5, + "path":"scale" + } + }, + { + "sampler":12, + "target":{ + "node":4, + "path":"translation" + } + }, + { + "sampler":13, + "target":{ + "node":4, + "path":"rotation" + } + }, + { + "sampler":14, + "target":{ + "node":4, + "path":"scale" + } + }, + { + "sampler":15, + "target":{ + "node":2, + "path":"translation" + } + }, + { + "sampler":16, + "target":{ + "node":2, + "path":"rotation" + } + }, + { + "sampler":17, + "target":{ + "node":2, + "path":"scale" + } + }, + { + "sampler":18, + "target":{ + "node":1, + "path":"translation" + } + }, + { + "sampler":19, + "target":{ + "node":1, + "path":"rotation" + } + }, + { + "sampler":20, + "target":{ + "node":1, + "path":"scale" + } + }, + { + "sampler":21, + "target":{ + "node":3, + "path":"translation" + } + }, + { + "sampler":22, + "target":{ + "node":3, + "path":"rotation" + } + }, + { + "sampler":23, + "target":{ + "node":3, + "path":"scale" + } + }, + { + "sampler":24, + "target":{ + "node":12, + "path":"translation" + } + }, + { + "sampler":25, + "target":{ + "node":12, + "path":"rotation" + } + }, + { + "sampler":26, + "target":{ + "node":12, + "path":"scale" + } + }, + { + "sampler":27, + "target":{ + "node":11, + "path":"translation" + } + }, + { + "sampler":28, + "target":{ + "node":11, + "path":"rotation" + } + }, + { + "sampler":29, + "target":{ + "node":11, + "path":"scale" + } + }, + { + "sampler":30, + "target":{ + "node":10, + "path":"translation" + } + }, + { + "sampler":31, + "target":{ + "node":10, + "path":"rotation" + } + }, + { + "sampler":32, + "target":{ + "node":10, + "path":"scale" + } + }, + { + "sampler":33, + "target":{ + "node":8, + "path":"translation" + } + }, + { + "sampler":34, + "target":{ + "node":8, + "path":"rotation" + } + }, + { + "sampler":35, + "target":{ + "node":8, + "path":"scale" + } + }, + { + "sampler":36, + "target":{ + "node":7, + "path":"translation" + } + }, + { + "sampler":37, + "target":{ + "node":7, + "path":"rotation" + } + }, + { + "sampler":38, + "target":{ + "node":7, + "path":"scale" + } + }, + { + "sampler":39, + "target":{ + "node":9, + "path":"translation" + } + }, + { + "sampler":40, + "target":{ + "node":9, + "path":"rotation" + } + }, + { + "sampler":41, + "target":{ + "node":9, + "path":"scale" + } + }, + { + "sampler":42, + "target":{ + "node":25, + "path":"translation" + } + }, + { + "sampler":43, + "target":{ + "node":25, + "path":"rotation" + } + }, + { + "sampler":44, + "target":{ + "node":25, + "path":"scale" + } + }, + { + "sampler":45, + "target":{ + "node":24, + "path":"translation" + } + }, + { + "sampler":46, + "target":{ + "node":24, + "path":"rotation" + } + }, + { + "sampler":47, + "target":{ + "node":24, + "path":"scale" + } + }, + { + "sampler":48, + "target":{ + "node":14, + "path":"translation" + } + }, + { + "sampler":49, + "target":{ + "node":14, + "path":"rotation" + } + }, + { + "sampler":50, + "target":{ + "node":14, + "path":"scale" + } + }, + { + "sampler":51, + "target":{ + "node":13, + "path":"translation" + } + }, + { + "sampler":52, + "target":{ + "node":13, + "path":"rotation" + } + }, + { + "sampler":53, + "target":{ + "node":13, + "path":"scale" + } + }, + { + "sampler":54, + "target":{ + "node":19, + "path":"translation" + } + }, + { + "sampler":55, + "target":{ + "node":19, + "path":"rotation" + } + }, + { + "sampler":56, + "target":{ + "node":19, + "path":"scale" + } + }, + { + "sampler":57, + "target":{ + "node":18, + "path":"translation" + } + }, + { + "sampler":58, + "target":{ + "node":18, + "path":"rotation" + } + }, + { + "sampler":59, + "target":{ + "node":18, + "path":"scale" + } + }, + { + "sampler":60, + "target":{ + "node":17, + "path":"translation" + } + }, + { + "sampler":61, + "target":{ + "node":17, + "path":"rotation" + } + }, + { + "sampler":62, + "target":{ + "node":17, + "path":"scale" + } + }, + { + "sampler":63, + "target":{ + "node":16, + "path":"translation" + } + }, + { + "sampler":64, + "target":{ + "node":16, + "path":"rotation" + } + }, + { + "sampler":65, + "target":{ + "node":16, + "path":"scale" + } + }, + { + "sampler":66, + "target":{ + "node":15, + "path":"translation" + } + }, + { + "sampler":67, + "target":{ + "node":15, + "path":"rotation" + } + }, + { + "sampler":68, + "target":{ + "node":15, + "path":"scale" + } + }, + { + "sampler":69, + "target":{ + "node":23, + "path":"translation" + } + }, + { + "sampler":70, + "target":{ + "node":23, + "path":"rotation" + } + }, + { + "sampler":71, + "target":{ + "node":23, + "path":"scale" + } + }, + { + "sampler":72, + "target":{ + "node":22, + "path":"translation" + } + }, + { + "sampler":73, + "target":{ + "node":22, + "path":"rotation" + } + }, + { + "sampler":74, + "target":{ + "node":22, + "path":"scale" + } + }, + { + "sampler":75, + "target":{ + "node":21, + "path":"translation" + } + }, + { + "sampler":76, + "target":{ + "node":21, + "path":"rotation" + } + }, + { + "sampler":77, + "target":{ + "node":21, + "path":"scale" + } + }, + { + "sampler":78, + "target":{ + "node":20, + "path":"translation" + } + }, + { + "sampler":79, + "target":{ + "node":20, + "path":"rotation" + } + }, + { + "sampler":80, + "target":{ + "node":20, + "path":"scale" + } + } + ], + "name":"walking -cycle", + "samplers":[ + { + "input":173, + "interpolation":"STEP", + "output":174 + }, + { + "input":173, + "interpolation":"STEP", + "output":175 + }, + { + "input":173, + "interpolation":"STEP", + "output":176 + }, + { + "input":173, + "interpolation":"STEP", + "output":177 + }, + { + "input":173, + "interpolation":"STEP", + "output":178 + }, + { + "input":173, + "interpolation":"STEP", + "output":179 + }, + { + "input":173, + "interpolation":"STEP", + "output":180 + }, + { + "input":173, + "interpolation":"STEP", + "output":181 + }, + { + "input":173, + "interpolation":"STEP", + "output":182 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":184 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":185 + }, + { + "input":173, + "interpolation":"STEP", + "output":186 + }, + { + "input":173, + "interpolation":"LINEAR", + "output":187 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":188 + }, + { + "input":173, + "interpolation":"STEP", + "output":189 + }, + { + "input":173, + "interpolation":"LINEAR", + "output":190 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":191 + }, + { + "input":173, + "interpolation":"LINEAR", + "output":192 + }, + { + "input":173, + "interpolation":"LINEAR", + "output":193 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":194 + }, + { + "input":173, + "interpolation":"STEP", + "output":195 + }, + { + "input":173, + "interpolation":"LINEAR", + "output":196 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":197 + }, + { + "input":173, + "interpolation":"LINEAR", + "output":198 + }, + { + "input":173, + "interpolation":"STEP", + "output":199 + }, + { + "input":173, + "interpolation":"STEP", + "output":200 + }, + { + "input":173, + "interpolation":"STEP", + "output":201 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":202 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":203 + }, + { + "input":173, + "interpolation":"STEP", + "output":204 + }, + { + "input":173, + "interpolation":"LINEAR", + "output":205 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":206 + }, + { + "input":173, + "interpolation":"LINEAR", + "output":207 + }, + { + "input":173, + "interpolation":"LINEAR", + "output":208 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":209 + }, + { + "input":173, + "interpolation":"STEP", + "output":210 + }, + { + "input":173, + "interpolation":"STEP", + "output":211 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":212 + }, + { + "input":173, + "interpolation":"STEP", + "output":213 + }, + { + "input":173, + "interpolation":"LINEAR", + "output":214 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":215 + }, + { + "input":173, + "interpolation":"STEP", + "output":216 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":217 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":218 + }, + { + "input":173, + "interpolation":"STEP", + "output":219 + }, + { + "input":173, + "interpolation":"STEP", + "output":220 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":221 + }, + { + "input":173, + "interpolation":"STEP", + "output":222 + }, + { + "input":173, + "interpolation":"STEP", + "output":223 + }, + { + "input":173, + "interpolation":"STEP", + "output":224 + }, + { + "input":173, + "interpolation":"STEP", + "output":225 + }, + { + "input":173, + "interpolation":"STEP", + "output":226 + }, + { + "input":183, + "interpolation":"LINEAR", + "output":227 + }, + { + "input":173, + "interpolation":"STEP", + "output":228 + }, + { + "input":173, + "interpolation":"STEP", + "output":229 + }, + { + "input":173, + "interpolation":"STEP", + "output":230 + }, + { + "input":173, + "interpolation":"STEP", + "output":231 + }, + { + "input":173, + "interpolation":"STEP", + "output":232 + }, + { + "input":173, + "interpolation":"STEP", + "output":233 + }, + { + "input":173, + "interpolation":"STEP", + "output":234 + }, + { + "input":173, + "interpolation":"STEP", + "output":235 + }, + { + "input":173, + "interpolation":"STEP", + "output":236 + }, + { + "input":173, + "interpolation":"STEP", + "output":237 + }, + { + "input":173, + "interpolation":"STEP", + "output":238 + }, + { + "input":173, + "interpolation":"STEP", + "output":239 + }, + { + "input":173, + "interpolation":"STEP", + "output":240 + }, + { + "input":173, + "interpolation":"STEP", + "output":241 + }, + { + "input":173, + "interpolation":"STEP", + "output":242 + }, + { + "input":173, + "interpolation":"STEP", + "output":243 + }, + { + "input":173, + "interpolation":"STEP", + "output":244 + }, + { + "input":173, + "interpolation":"STEP", + "output":245 + }, + { + "input":173, + "interpolation":"STEP", + "output":246 + }, + { + "input":173, + "interpolation":"STEP", + "output":247 + }, + { + "input":173, + "interpolation":"STEP", + "output":248 + }, + { + "input":173, + "interpolation":"STEP", + "output":249 + }, + { + "input":173, + "interpolation":"STEP", + "output":250 + }, + { + "input":173, + "interpolation":"STEP", + "output":251 + }, + { + "input":173, + "interpolation":"STEP", + "output":252 + }, + { + "input":173, + "interpolation":"STEP", + "output":253 + }, + { + "input":173, + "interpolation":"STEP", + "output":254 + }, + { + "input":173, + "interpolation":"STEP", + "output":255 + } + ] + } + ], + "materials":[ + { + "doubleSided":true, + "name":"Material", + "pbrMetallicRoughness":{} + } + ], + "meshes":[ + { + "name":"Cube.012", + "primitives":[ + { + "attributes":{ + "COLOR_0":0, + "POSITION":1, + "NORMAL":2, + "TEXCOORD_0":3, + "JOINTS_0":4, + "WEIGHTS_0":5 + }, + "indices":6, + "material":0 + } + ] + } + ], + "skins":[ + { + "inverseBindMatrices":7, + "joints":[ + 26, + 0, + 6, + 5, + 4, + 2, + 1, + 3, + 12, + 11, + 10, + 8, + 7, + 9, + 25, + 24, + 14, + 13, + 19, + 18, + 17, + 16, + 15, + 23, + 22, + 21, + 20 + ], + "name":"Samus_Armature" + } + ], + "accessors":[ + { + "bufferView":0, + "componentType":5123, + "count":1053, + "normalized":true, + "type":"VEC4" + }, + { + "bufferView":1, + "componentType":5126, + "count":1053, + "max":[ + 1.2608606815338135, + 1.9941614866256714, + 0.2904457747936249 + ], + "min":[ + -1.154639482498169, + -3.804062620460513e-10, + -0.34189608693122864 + ], + "type":"VEC3" + }, + { + "bufferView":2, + "componentType":5126, + "count":1053, + "type":"VEC3" + }, + { + "bufferView":3, + "componentType":5126, + "count":1053, + "type":"VEC2" + }, + { + "bufferView":4, + "componentType":5121, + "count":1053, + "type":"VEC4" + }, + { + "bufferView":5, + "componentType":5126, + "count":1053, + "type":"VEC4" + }, + { + "bufferView":6, + "componentType":5123, + "count":1434, + "type":"SCALAR" + }, + { + "bufferView":7, + "componentType":5126, + "count":27, + "type":"MAT4" + }, + { + "bufferView":8, + "componentType":5126, + "count":2, + "max":[ + 3 + ], + "min":[ + 0 + ], + "type":"SCALAR" + }, + { + "bufferView":9, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":10, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":11, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":12, + "componentType":5126, + "count":181, + "max":[ + 3 + ], + "min":[ + 0 + ], + "type":"SCALAR" + }, + { + "bufferView":13, + "componentType":5126, + "count":181, + "type":"VEC3" + }, + { + "bufferView":14, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":15, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":16, + "componentType":5126, + "count":181, + "type":"VEC3" + }, + { + "bufferView":17, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":18, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":19, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":20, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":21, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":22, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":23, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":24, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":25, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":26, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":27, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":28, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":29, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":30, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":31, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":32, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":33, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":34, + "componentType":5126, + "count":181, + "type":"VEC3" + }, + { + "bufferView":35, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":36, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":37, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":38, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":39, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":40, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":41, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":42, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":43, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":44, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":45, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":46, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":47, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":48, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":49, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":50, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":51, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":52, + "componentType":5126, + "count":181, + "type":"VEC3" + }, + { + "bufferView":53, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":54, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":55, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":56, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":57, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":58, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":59, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":60, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":61, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":62, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":63, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":64, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":65, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":66, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":67, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":68, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":69, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":70, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":71, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":72, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":73, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":74, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":75, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":76, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":77, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":78, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":79, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":80, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":81, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":82, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":83, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":84, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":85, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":86, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":87, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":88, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":89, + "componentType":5126, + "count":181, + "type":"VEC4" + }, + { + "bufferView":90, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":91, + "componentType":5126, + "count":1, + "max":[ + 0 + ], + "min":[ + 0 + ], + "type":"SCALAR" + }, + { + "bufferView":92, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":93, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":94, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":95, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":96, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":97, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":98, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":99, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":100, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":101, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":102, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":103, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":104, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":105, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":106, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":107, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":108, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":109, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":110, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":111, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":112, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":113, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":114, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":115, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":116, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":117, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":118, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":119, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":120, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":121, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":122, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":123, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":124, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":125, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":126, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":127, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":128, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":129, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":130, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":131, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":132, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":133, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":134, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":135, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":136, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":137, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":138, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":139, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":140, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":141, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":142, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":143, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":144, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":145, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":146, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":147, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":148, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":149, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":150, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":151, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":152, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":153, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":154, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":155, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":156, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":157, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":158, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":159, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":160, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":161, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":162, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":163, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":164, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":165, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":166, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":167, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":168, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":169, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":170, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":171, + "componentType":5126, + "count":1, + "type":"VEC4" + }, + { + "bufferView":172, + "componentType":5126, + "count":1, + "type":"VEC3" + }, + { + "bufferView":173, + "componentType":5126, + "count":2, + "max":[ + 1.3333333333333333 + ], + "min":[ + 0 + ], + "type":"SCALAR" + }, + { + "bufferView":174, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":175, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":176, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":177, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":178, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":179, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":180, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":181, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":182, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":183, + "componentType":5126, + "count":81, + "max":[ + 1.3333333333333333 + ], + "min":[ + 0 + ], + "type":"SCALAR" + }, + { + "bufferView":184, + "componentType":5126, + "count":81, + "type":"VEC3" + }, + { + "bufferView":185, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":186, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":187, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":188, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":189, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":190, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":191, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":192, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":193, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":194, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":195, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":196, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":197, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":198, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":199, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":200, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":201, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":202, + "componentType":5126, + "count":81, + "type":"VEC3" + }, + { + "bufferView":203, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":204, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":205, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":206, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":207, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":208, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":209, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":210, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":211, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":212, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":213, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":214, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":215, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":216, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":217, + "componentType":5126, + "count":81, + "type":"VEC3" + }, + { + "bufferView":218, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":219, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":220, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":221, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":222, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":223, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":224, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":225, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":226, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":227, + "componentType":5126, + "count":81, + "type":"VEC4" + }, + { + "bufferView":228, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":229, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":230, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":231, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":232, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":233, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":234, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":235, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":236, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":237, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":238, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":239, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":240, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":241, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":242, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":243, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":244, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":245, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":246, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":247, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":248, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":249, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":250, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":251, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":252, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":253, + "componentType":5126, + "count":2, + "type":"VEC3" + }, + { + "bufferView":254, + "componentType":5126, + "count":2, + "type":"VEC4" + }, + { + "bufferView":255, + "componentType":5126, + "count":2, + "type":"VEC3" + } + ], + "bufferViews":[ + { + "buffer":0, + "byteLength":8424, + "byteOffset":0, + "target":34962 + }, + { + "buffer":0, + "byteLength":12636, + "byteOffset":8424, + "target":34962 + }, + { + "buffer":0, + "byteLength":12636, + "byteOffset":21060, + "target":34962 + }, + { + "buffer":0, + "byteLength":8424, + "byteOffset":33696, + "target":34962 + }, + { + "buffer":0, + "byteLength":4212, + "byteOffset":42120, + "target":34962 + }, + { + "buffer":0, + "byteLength":16848, + "byteOffset":46332, + "target":34962 + }, + { + "buffer":0, + "byteLength":2868, + "byteOffset":63180, + "target":34963 + }, + { + "buffer":0, + "byteLength":1728, + "byteOffset":66048 + }, + { + "buffer":0, + "byteLength":8, + "byteOffset":67776 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":67784 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":67808 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":67840 + }, + { + "buffer":0, + "byteLength":724, + "byteOffset":67864 + }, + { + "buffer":0, + "byteLength":2172, + "byteOffset":68588 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":70760 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":70792 + }, + { + "buffer":0, + "byteLength":2172, + "byteOffset":70816 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":72988 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":73020 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":73044 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":73068 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":75964 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":75988 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":76012 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":78908 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":78932 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":78956 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":81852 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":81876 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":81900 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":81932 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":81956 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":81980 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":84876 + }, + { + "buffer":0, + "byteLength":2172, + "byteOffset":84900 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":87072 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":87104 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":87128 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":87152 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":90048 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":90072 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":90096 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":92992 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":93016 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":93040 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":95936 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":95960 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":95984 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":96016 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":96040 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":96064 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":98960 + }, + { + "buffer":0, + "byteLength":2172, + "byteOffset":98984 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":101156 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":104052 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":104076 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":104100 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":106996 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":107020 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":107044 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":109940 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":109964 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":109988 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":112884 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":112908 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":112932 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":112964 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":112988 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":113012 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":115908 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":115932 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":115956 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":118852 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":118876 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":118900 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":121796 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":121820 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":121844 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":121876 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":121900 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":121924 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":121956 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":121980 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":122004 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":124900 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":124924 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":124948 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":127844 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":127868 + }, + { + "buffer":0, + "byteLength":2896, + "byteOffset":127892 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":130788 + }, + { + "buffer":0, + "byteLength":4, + "byteOffset":130812 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":130816 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":130828 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":130844 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":130856 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":130868 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":130884 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":130896 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":130908 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":130924 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":130936 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":130948 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":130964 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":130976 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":130988 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131004 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131016 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131028 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131044 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131056 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131068 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131084 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131096 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131108 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131124 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131136 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131148 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131164 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131176 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131188 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131204 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131216 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131228 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131244 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131256 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131268 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131284 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131296 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131308 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131324 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131336 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131348 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131364 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131376 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131388 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131404 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131416 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131428 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131444 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131456 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131468 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131484 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131496 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131508 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131524 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131536 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131548 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131564 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131576 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131588 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131604 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131616 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131628 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131644 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131656 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131668 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131684 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131696 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131708 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131724 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131736 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131748 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131764 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131776 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131788 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131804 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131816 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131828 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131844 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131856 + }, + { + "buffer":0, + "byteLength":16, + "byteOffset":131868 + }, + { + "buffer":0, + "byteLength":12, + "byteOffset":131884 + }, + { + "buffer":0, + "byteLength":8, + "byteOffset":131896 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":131904 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":131928 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":131960 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":131984 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":132008 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":132040 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":132064 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":132088 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":132120 + }, + { + "buffer":0, + "byteLength":324, + "byteOffset":132144 + }, + { + "buffer":0, + "byteLength":972, + "byteOffset":132468 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":133440 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":134736 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":134760 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":134784 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":136080 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":136104 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":136128 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":137424 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":137448 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":137472 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":138768 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":138792 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":138816 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":140112 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":140136 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":140160 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":140192 + }, + { + "buffer":0, + "byteLength":972, + "byteOffset":140216 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":141188 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":142484 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":142508 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":142532 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":143828 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":143852 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":143876 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":145172 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":145196 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":145220 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":146516 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":146540 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":146564 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":147860 + }, + { + "buffer":0, + "byteLength":972, + "byteOffset":147884 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":148856 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":150152 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":150176 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":150200 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":151496 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":151520 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":151544 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":151576 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":151600 + }, + { + "buffer":0, + "byteLength":1296, + "byteOffset":151624 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":152920 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":152944 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":152968 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153000 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153024 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":153048 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153080 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153104 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":153128 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153160 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153184 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":153208 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153240 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153264 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":153288 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153320 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153344 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":153368 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153400 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153424 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":153448 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153480 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153504 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":153528 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153560 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153584 + }, + { + "buffer":0, + "byteLength":32, + "byteOffset":153608 + }, + { + "buffer":0, + "byteLength":24, + "byteOffset":153640 + } + ], + "buffers":[ + { + "byteLength":153664, + "uri":"samus.bin" + } + ] +} diff --git a/characters/samus/samus.gltf.import b/characters/samus/samus.gltf.import new file mode 100644 index 0000000..a95630d --- /dev/null +++ b/characters/samus/samus.gltf.import @@ -0,0 +1,37 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://16ya8p8urk4b" +path="res://.godot/imported/samus.gltf-5c9da60a8f798efe4d198ea1c6739ad9.scn" + +[deps] + +source_file="res://characters/samus/samus.gltf" +dest_files=["res://.godot/imported/samus.gltf-5c9da60a8f798efe4d198ea1c6739ad9.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +_subresources={} +gltf/naming_version=1 +gltf/embedded_image_handling=1 diff --git a/characters/samus/samus.tscn b/characters/samus/samus.tscn new file mode 100644 index 0000000..922ffb7 --- /dev/null +++ b/characters/samus/samus.tscn @@ -0,0 +1,132 @@ +[gd_scene load_steps=15 format=3 uid="uid://b6cat7mj1lmpb"] + +[ext_resource type="PackedScene" uid="uid://cene38uaq3y64" path="res://characters/samus/samus.glb" id="1_3tb66"] +[ext_resource type="Script" uid="uid://byrirmtjstdx6" path="res://characters/samus/samus.gd" id="2_1vd4e"] +[ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="2_gqrom"] +[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="3_3tb1x"] +[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="4_1vd4e"] +[ext_resource type="Script" uid="uid://b8hhnqsugykly" path="res://addons/phantom_camera/scripts/resources/camera_3d_resource.gd" id="5_3tb1x"] +[ext_resource type="Script" uid="uid://dohyq145fqsdy" path="res://scripts/characters/samus/idle.gd" id="7_6gxik"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_wkxnt"] +radius = 0.410222 + +[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_3u6of"] + +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_gqrom"] +animation = &"standing_idle " + +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_3tb1x"] +animation = &"walking " + +[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_1vd4e"] +graph_offset = Vector2(-420.994, -37.8418) +nodes/Blend2/node = SubResource("AnimationNodeBlend2_3u6of") +nodes/Blend2/position = Vector2(100, 100) +nodes/idle/node = SubResource("AnimationNodeAnimation_gqrom") +nodes/idle/position = Vector2(-140, 40) +nodes/walk/node = SubResource("AnimationNodeAnimation_3tb1x") +nodes/walk/position = Vector2(-140, 220) +node_connections = [&"Blend2", 0, &"idle", &"Blend2", 1, &"walk", &"output", 0, &"Blend2"] + +[sub_resource type="Resource" id="Resource_6gxik"] +script = ExtResource("4_1vd4e") +duration = 1.0 +transition = 0 +ease = 2 + +[sub_resource type="Resource" id="Resource_1vd4e"] +script = ExtResource("5_3tb1x") +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 +metadata/_custom_type_script = "uid://b8hhnqsugykly" + +[node name="Samus" node_paths=PackedStringArray("state_machine", "move_pcam") instance=ExtResource("1_3tb66")] +script = ExtResource("2_1vd4e") +state_machine = NodePath("LimboHSM") +move_pcam = NodePath("PhantomCamera3D") + +[node name="Skeleton3D" parent="Samus_Armature" index="0"] +bones/1/position = Vector3(-0.0564104, -0.0819997, -0.275536) +bones/1/rotation = Quaternion(0.532204, 0.0352717, -0.0405761, 0.844907) +bones/2/position = Vector3(-0.110015, -0.105465, -0.273875) +bones/2/rotation = Quaternion(0.212103, 0.00295528, 0.178504, 0.960802) +bones/3/position = Vector3(-0.0262212, 0.148077, -6.29464e-08) +bones/3/rotation = Quaternion(0.820532, 0.0768203, -0.201506, -0.52936) +bones/4/rotation = Quaternion(-0.0813801, 5.54073e-08, 4.85456e-08, 0.996683) +bones/5/rotation = Quaternion(0.573798, -0.0253381, -0.00181086, 0.818603) +bones/6/rotation = Quaternion(0.217515, -1.84893e-06, -5.86377e-07, 0.976057) +bones/7/rotation = Quaternion(-0.198261, -0.0161392, -0.0196166, 0.97982) +bones/8/position = Vector3(-0.00514961, -0.108737, -0.284717) +bones/8/rotation = Quaternion(0.192436, 0.0892449, -0.229082, 0.950013) +bones/9/position = Vector3(0.0262211, 0.148077, -6.624e-08) +bones/9/rotation = Quaternion(0.722371, 0.224226, -0.101927, -0.646153) +bones/10/rotation = Quaternion(-0.261936, -2.69341e-09, -1.27318e-07, 0.965085) +bones/11/rotation = Quaternion(0.60672, 0.00900321, 0.0239919, 0.794502) +bones/12/rotation = Quaternion(0.217515, 1.83635e-06, 5.50013e-07, 0.976057) +bones/13/rotation = Quaternion(-0.158114, -0.0111925, 0.0230516, 0.987088) +bones/14/position = Vector3(-0.0330754, 0.012613, -0.078391) +bones/14/rotation = Quaternion(0.693184, -0.00310139, -0.00991227, 0.720686) +bones/15/rotation = Quaternion(0.0457954, 0.0051759, 0.0422762, 0.998043) +bones/16/rotation = Quaternion(-0.601214, 0.00402665, 0.00826362, 0.799035) +bones/17/rotation = Quaternion(0.561584, 0.0233951, -0.028791, 0.826587) +bones/19/rotation = Quaternion(-0.0712464, 0.60118, -0.774026, 0.185447) +bones/20/rotation = Quaternion(0.62182, 0.00217642, -0.174097, 0.763561) +bones/21/rotation = Quaternion(-0.180338, -0.970693, 0.051125, 0.150395) +bones/22/rotation = Quaternion(-0.174469, -3.25258e-10, -1.38881e-08, 0.984663) +bones/23/rotation = Quaternion(0.237747, 0.78362, 0.498957, -0.28365) +bones/24/rotation = Quaternion(0.0187276, -0.538211, 0.833539, 0.123248) +bones/25/rotation = Quaternion(0.627716, -0.00232292, 0.20023, 0.752247) +bones/26/rotation = Quaternion(0.0594015, 0.0899191, -0.94021, 0.323095) + +[node name="CollisionShape3D" type="CollisionShape3D" parent="." index="2"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("CapsuleShape3D_wkxnt") + +[node name="AnimationTree" type="AnimationTree" parent="." index="3"] +tree_root = SubResource("AnimationNodeBlendTree_1vd4e") +anim_player = NodePath("../AnimationPlayer") +parameters/Blend2/blend_amount = 0.0 + +[node name="Camera3D" type="Camera3D" parent="." index="4"] +physics_interpolation_mode = 1 +transform = Transform3D(-1, -4.50261e-08, 7.49359e-08, -1.77636e-15, 0.857167, 0.515038, -8.74228e-08, 0.515038, -0.857167, 2.84382e-07, 3.39957, -3.25295) + +[node name="PhantomCameraHost" type="Node" parent="Camera3D" index="0"] +process_priority = 300 +process_physics_priority = 300 +script = ExtResource("2_gqrom") + +[node name="PhantomCamera3D" type="Node3D" parent="." index="5" node_paths=PackedStringArray("follow_target")] +transform = Transform3D(-1, -4.50261e-08, 7.49359e-08, -1.77636e-15, 0.857167, 0.515038, -8.74228e-08, 0.515038, -0.857167, 2.84382e-07, 3.39957, -3.25295) +script = ExtResource("3_3tb1x") +follow_mode = 6 +follow_target = NodePath("..") +tween_resource = SubResource("Resource_6gxik") +camera_3d_resource = SubResource("Resource_1vd4e") +follow_offset = Vector3(0, 1.445, 0) +follow_distance = 3.795 +vertical_rotation_offset = 0.541052 +horizontal_rotation_offset = 3.14159 +spring_length = 3.795 + +[node name="LimboHSM" type="LimboHSM" parent="." index="6"] + +[node name="Idle" type="LimboState" parent="LimboHSM" index="0" node_paths=PackedStringArray("animation_player")] +script = ExtResource("7_6gxik") +animation_player = NodePath("../../AnimationPlayer") +animation = &"standing_idle" + +[node name="Walk" type="LimboState" parent="LimboHSM" index="1"] + +[node name="Aim" type="LimboState" parent="LimboHSM" index="2"] + +[node name="Shoot" type="LimboState" parent="LimboHSM" index="3"] diff --git a/demo/LICENSE_ASSETS.md b/demo/LICENSE_ASSETS.md new file mode 100644 index 0000000..f2760dc --- /dev/null +++ b/demo/LICENSE_ASSETS.md @@ -0,0 +1,5 @@ +LimboAI Demo project graphical assets (PNG & SVG files in the "assets/" folder) +Copyright (c) 2024 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/ diff --git a/demo/agents/01_agent_melee_simple.tscn b/demo/agents/01_agent_melee_simple.tscn new file mode 100644 index 0000000..228640a --- /dev/null +++ b/demo/agents/01_agent_melee_simple.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=5 format=3 uid="uid://1dnm7tuik8xo"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_l180o"] +[ext_resource type="Texture2D" uid="uid://cw8s50856x8ct" path="res://demo/assets/agent_melee_simple.png" id="2_bvbes"] +[ext_resource type="BehaviorTree" uid="uid://bpdm5jnegi38" path="res://demo/ai/trees/01_agent_melee_simple.tres" id="3_tb7cx"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_s08ac"] + +[node name="AgentMeleeSimple" instance=ExtResource("1_l180o")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_bvbes") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_bvbes") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_bvbes") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_bvbes") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_bvbes") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_bvbes") + +[node name="Health" parent="." index="3"] +max_health = 3.0 + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_tb7cx") +blackboard_plan = SubResource("BlackboardPlan_s08ac") diff --git a/demo/agents/02_agent_charger.tscn b/demo/agents/02_agent_charger.tscn new file mode 100644 index 0000000..5a5b780 --- /dev/null +++ b/demo/agents/02_agent_charger.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=5 format=3 uid="uid://g1pnvanyxcpa"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_n83hi"] +[ext_resource type="Texture2D" uid="uid://ce16nc0wy2s8" path="res://demo/assets/agent_charger.png" id="2_y7pic"] +[ext_resource type="BehaviorTree" uid="uid://ylife72ym5et" path="res://demo/ai/trees/02_agent_charger.tres" id="3_nacc3"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_pmyhf"] + +[node name="AgentCharger" instance=ExtResource("1_n83hi")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_y7pic") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_y7pic") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_y7pic") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_y7pic") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_y7pic") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_y7pic") + +[node name="Hitbox" parent="Root" index="1"] +damage = 2.0 + +[node name="Health" parent="." index="3"] +max_health = 8.0 + +[node name="BTPlayer" type="BTPlayer" parent="." index="4"] +behavior_tree = ExtResource("3_nacc3") +blackboard_plan = SubResource("BlackboardPlan_pmyhf") diff --git a/demo/agents/03_agent_imp.tscn b/demo/agents/03_agent_imp.tscn new file mode 100644 index 0000000..e3533c9 --- /dev/null +++ b/demo/agents/03_agent_imp.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=5 format=3 uid="uid://730bthc0ywhd"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_13xup"] +[ext_resource type="Texture2D" uid="uid://h70okn6hmxum" path="res://demo/assets/agent_imp.png" id="2_xd5s8"] +[ext_resource type="BehaviorTree" uid="uid://c2bxoo68ywb27" path="res://demo/ai/trees/03_agent_imp.tres" id="3_furh3"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_aog23"] + +[node name="AgentImp" instance=ExtResource("1_13xup")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_xd5s8") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_xd5s8") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_xd5s8") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_xd5s8") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_xd5s8") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_xd5s8") + +[node name="Health" parent="." index="3"] +max_health = 4.0 + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_furh3") +blackboard_plan = SubResource("BlackboardPlan_aog23") diff --git a/demo/agents/04_agent_skirmisher.tscn b/demo/agents/04_agent_skirmisher.tscn new file mode 100644 index 0000000..2a71d9f --- /dev/null +++ b/demo/agents/04_agent_skirmisher.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=5 format=3 uid="uid://co6yeafaljbq0"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_2ir76"] +[ext_resource type="Texture2D" uid="uid://l042ovqqsy3l" path="res://demo/assets/agent_skirmisher.png" id="2_w8tqw"] +[ext_resource type="BehaviorTree" uid="uid://qqmjvbeibatn" path="res://demo/ai/trees/04_agent_skirmisher.tres" id="3_bhfkv"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_vjbry"] + +[node name="AgentSkirmisher" instance=ExtResource("1_2ir76")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_w8tqw") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_w8tqw") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_w8tqw") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_w8tqw") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_w8tqw") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_w8tqw") + +[node name="Health" parent="." index="3"] +max_health = 7.0 + +[node name="BTPlayer" type="BTPlayer" parent="." index="4"] +behavior_tree = ExtResource("3_bhfkv") +blackboard_plan = SubResource("BlackboardPlan_vjbry") diff --git a/demo/agents/05_agent_ranged.tscn b/demo/agents/05_agent_ranged.tscn new file mode 100644 index 0000000..04e4eb8 --- /dev/null +++ b/demo/agents/05_agent_ranged.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=5 format=3 uid="uid://ci3x5esepbu5v"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_oa4xm"] +[ext_resource type="Texture2D" uid="uid://cjts4ennjtepg" path="res://demo/assets/agent_ranged.png" id="2_37lvn"] +[ext_resource type="BehaviorTree" uid="uid://cqluon1y1hnn5" path="res://demo/ai/trees/05_agent_ranged.tres" id="3_f7r5w"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_2kwy7"] + +[node name="AgentRanged" instance=ExtResource("1_oa4xm")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_37lvn") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_37lvn") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_37lvn") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_37lvn") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_37lvn") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_37lvn") + +[node name="Health" parent="." index="3"] +max_health = 6.0 + +[node name="BTPlayer" type="BTPlayer" parent="." index="4"] +behavior_tree = ExtResource("3_f7r5w") +blackboard_plan = SubResource("BlackboardPlan_2kwy7") diff --git a/demo/agents/06_agent_melee_combo.tscn b/demo/agents/06_agent_melee_combo.tscn new file mode 100644 index 0000000..242845b --- /dev/null +++ b/demo/agents/06_agent_melee_combo.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=5 format=3 uid="uid://blxmw2w1h2s0s"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_dny3b"] +[ext_resource type="Texture2D" uid="uid://bo0ibp7tvjbba" path="res://demo/assets/agent_combo.png" id="2_4rqld"] +[ext_resource type="BehaviorTree" uid="uid://cpncl1db8j12f" path="res://demo/ai/trees/06_agent_melee_combo.tres" id="3_l805q"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_67ric"] + +[node name="AgentMeleeCombo" instance=ExtResource("1_dny3b")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_4rqld") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_4rqld") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_4rqld") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_4rqld") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_4rqld") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_4rqld") + +[node name="Health" parent="." index="3"] +max_health = 6.0 + +[node name="BTPlayer" type="BTPlayer" parent="." index="4"] +behavior_tree = ExtResource("3_l805q") +blackboard_plan = SubResource("BlackboardPlan_67ric") diff --git a/demo/agents/07_agent_melee_nuanced.tscn b/demo/agents/07_agent_melee_nuanced.tscn new file mode 100644 index 0000000..57f9bfa --- /dev/null +++ b/demo/agents/07_agent_melee_nuanced.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=5 format=3 uid="uid://2e4ohaqjaawb"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_afx5l"] +[ext_resource type="Texture2D" uid="uid://usu3j55d6dgc" path="res://demo/assets/agent_melee_nuanced.png" id="2_e51r0"] +[ext_resource type="BehaviorTree" uid="uid://c2u6sljqkim0n" path="res://demo/ai/trees/07_agent_melee_nuanced.tres" id="3_b8kcf"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_tnf02"] + +[node name="AgentMeleeNuanced" instance=ExtResource("1_afx5l")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_e51r0") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_e51r0") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_e51r0") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_e51r0") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_e51r0") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_e51r0") + +[node name="Health" parent="." index="3"] +max_health = 6.0 + +[node name="BTPlayer" type="BTPlayer" parent="." index="4"] +behavior_tree = ExtResource("3_b8kcf") +blackboard_plan = SubResource("BlackboardPlan_tnf02") diff --git a/demo/agents/08_agent_demon.tscn b/demo/agents/08_agent_demon.tscn new file mode 100644 index 0000000..5bbd3cb --- /dev/null +++ b/demo/agents/08_agent_demon.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=5 format=3 uid="uid://dbmcufef0cc4b"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_115kp"] +[ext_resource type="Texture2D" uid="uid://d1tx7u8ho0r4v" path="res://demo/assets/agent_demon.png" id="2_cb5f2"] +[ext_resource type="BehaviorTree" uid="uid://cpcnbi81jqge4" path="res://demo/ai/trees/08_agent_demon.tres" id="3_ebd57"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_5sr4g"] + +[node name="AgentDemon" instance=ExtResource("1_115kp")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_cb5f2") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_cb5f2") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_cb5f2") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_cb5f2") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_cb5f2") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_cb5f2") + +[node name="Health" parent="." index="3"] +max_health = 8.0 + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_ebd57") +blackboard_plan = SubResource("BlackboardPlan_5sr4g") diff --git a/demo/agents/09_agent_summoner.tscn b/demo/agents/09_agent_summoner.tscn new file mode 100644 index 0000000..c8362d3 --- /dev/null +++ b/demo/agents/09_agent_summoner.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=5 format=3 uid="uid://bycvi2fb0f7ue"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_neifu"] +[ext_resource type="Texture2D" uid="uid://ombnpn2edldt" path="res://demo/assets/agent_summoner.png" id="2_fcti4"] +[ext_resource type="BehaviorTree" uid="uid://cpxk7jnqpwwlc" path="res://demo/ai/trees/09_agent_summoner.tres" id="3_bunpq"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_bqv3d"] + +[node name="AgentSummoner" instance=ExtResource("1_neifu")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_fcti4") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_fcti4") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_fcti4") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_fcti4") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_fcti4") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_fcti4") + +[node name="Health" parent="." index="3"] +max_health = 8.0 + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_bunpq") +blackboard_plan = SubResource("BlackboardPlan_bqv3d") diff --git a/demo/agents/agent_base.tscn b/demo/agents/agent_base.tscn new file mode 100644 index 0000000..44ab253 --- /dev/null +++ b/demo/agents/agent_base.tscn @@ -0,0 +1,4529 @@ +[gd_scene load_steps=36 format=3 uid="uid://ooigbfhfy4wa"] + +[ext_resource type="Texture2D" uid="uid://dlo1ine6p5di4" path="res://demo/assets/agent_bobby.png" id="1_1u51b"] +[ext_resource type="Script" uid="uid://68wbhtvlbkqm" path="res://demo/agents/scripts/agent_base.gd" id="1_n8vy2"] +[ext_resource type="Texture2D" uid="uid://dj4oayt5ttvh8" path="res://demo/assets/fx.png" id="2_lv102"] +[ext_resource type="Texture2D" uid="uid://dwhhxj5557qrb" path="res://demo/assets/shadow.png" id="2_vr0jo"] +[ext_resource type="Texture2D" uid="uid://2uyxh7sy8qny" path="res://demo/assets/weapon_ninja_star.png" id="4_1c5xq"] +[ext_resource type="Texture2D" uid="uid://bdusy0qqtw0th" path="res://demo/assets/smoke.png" id="4_mnb6v"] +[ext_resource type="Script" uid="uid://5byn62y1oa76" path="res://demo/agents/scripts/health.gd" id="4_qwtrf"] +[ext_resource type="Script" uid="uid://dntc3c582m5w8" path="res://demo/agents/scripts/hitbox.gd" id="5_taq6b"] +[ext_resource type="Script" uid="uid://dq5h6yydckjc1" path="res://demo/agents/scripts/hurtbox.gd" id="6_jnvxm"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_2k81i"] +size = Vector2(140, 40) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_26abe"] +size = Vector2(88, 40) + +[sub_resource type="Curve" id="Curve_noh01"] +_data = [Vector2(0, 0.010989), 0.0, 0.0, 0, 0, Vector2(0.151111, 1), 1.3559, 1.3559, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_sb0wp"] +curve = SubResource("Curve_noh01") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_f5i1x"] +lifetime_randomness = 0.5 +particle_flag_disable_z = true +emission_shape = 3 +emission_box_extents = Vector3(40, 1, 1) +direction = Vector3(0, -1, 0) +spread = 90.0 +initial_velocity_min = 150.0 +initial_velocity_max = 250.0 +angular_velocity_min = -90.0 +angular_velocity_max = 90.0 +gravity = Vector3(0, 0, 0) +radial_accel_min = -90.0 +radial_accel_max = 90.0 +damping_min = 200.0 +damping_max = 200.0 +scale_min = 0.8 +scale_max = 1.2 +scale_curve = SubResource("CurveTexture_sb0wp") + +[sub_resource type="Curve" id="Curve_e33mb"] +_data = [Vector2(0, 0.010989), 0.0, 0.0, 0, 0, Vector2(0.151111, 1), 1.3559, 1.3559, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_qti8k"] +curve = SubResource("Curve_e33mb") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_gmal1"] +lifetime_randomness = 0.5 +particle_flag_disable_z = true +emission_shape = 3 +emission_box_extents = Vector3(40, 1, 1) +direction = Vector3(0, -1, 0) +spread = 90.0 +initial_velocity_min = 150.0 +initial_velocity_max = 250.0 +angular_velocity_min = -90.0 +angular_velocity_max = 90.0 +gravity = Vector3(0, 0, 0) +radial_accel_min = -90.0 +radial_accel_max = 90.0 +damping_min = 200.0 +damping_max = 200.0 +scale_min = 0.8 +scale_max = 1.2 +scale_curve = SubResource("CurveTexture_qti8k") +color = Color(0.913725, 0.8, 0.898039, 1) + +[sub_resource type="CircleShape2D" id="CircleShape2D_0c228"] + +[sub_resource type="Animation" id="Animation_nvm4d"] +resource_name = "RESET" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig/LegR:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(31, 65)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig/LegR:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/LegR:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/Body:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(5, 53)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/Body:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/Body:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body/Hat:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(2, -91)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body/HandL:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-60, -53)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/HandR:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(51, -51)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/LegL:position") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-29, 65)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/LegL:rotation") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/LegL:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("FX/Cloud:visible") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Hitbox/HitboxCollisionShape2D:disabled") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig:modulate") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(1, 1, 1, 1)] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Root/Rig:position") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, -76)] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("Root/Rig:rotation") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/23/type = "value" +tracks/23/imported = false +tracks/23/enabled = true +tracks/23/path = NodePath("Root/Rig:scale") +tracks/23/interp = 1 +tracks/23/loop_wrap = true +tracks/23/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/24/type = "value" +tracks/24/imported = false +tracks/24/enabled = true +tracks/24/path = NodePath("FX/Death:emitting") +tracks/24/interp = 1 +tracks/24/loop_wrap = true +tracks/24/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/25/type = "value" +tracks/25/imported = false +tracks/25/enabled = true +tracks/25/path = NodePath("Root/Rig/Body/HandL/WeaponNinjaStar:visible") +tracks/25/interp = 1 +tracks/25/loop_wrap = true +tracks/25/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/26/type = "value" +tracks/26/imported = false +tracks/26/enabled = true +tracks/26/path = NodePath("Root/Hitbox:knockback_enabled") +tracks/26/interp = 1 +tracks/26/loop_wrap = true +tracks/26/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/27/type = "value" +tracks/27/imported = false +tracks/27/enabled = true +tracks/27/path = NodePath("Root/Hurtbox/HurtboxCollisionShape2D:disabled") +tracks/27/interp = 1 +tracks/27/loop_wrap = true +tracks/27/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} + +[sub_resource type="Animation" id="Animation_8wj70"] +resource_name = "attack_1" +length = 0.28 +step = 0.01 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(0, -76), Vector2(0, -76)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/LegL:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-48, 48), Vector2(-55, 35), Vector2(-55, 35), Vector2(-29, 65)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/LegL:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.918872, 1.36873, 1.36873, 0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/LegL:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/LegR:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(35, 68), Vector2(31, 65)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/LegR:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [-0.125403, 0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/LegR:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 53), Vector2(5, 53), Vector2(5, 53)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.204683, 0.274184, 0.274184, 0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1.1, 0.9), Vector2(1.1, 0.9), Vector2(1.1, 0.9), Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/Hat:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(2, -91), Vector2(2, -91)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/Body/HandL:position") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-77.4704, -36.9794), Vector2(71.4321, -75.3422), Vector2(71.4321, -75.3422), Vector2(-60, -53)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.8, 1.8), Vector2(1.8, 1.8), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("Root/Rig/Body/HandR:position") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(71.4504, -76.2001), Vector2(-47.4494, -37.9368), Vector2(-47.4494, -37.9368), Vector2(51, -51)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1.6, 1.6), Vector2(1.6, 1.6), Vector2(1.6, 1.6), Vector2(1, 1)] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Root/Hitbox/HitboxCollisionShape2D:disabled") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.3), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [true, false, true, true] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("Root/Hitbox:knockback_enabled") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [false, false, false] +} + +[sub_resource type="Animation" id="Animation_s1dey"] +resource_name = "attack_2" +length = 0.3 +step = 0.01 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, -76)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/LegL:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-29, 65), Vector2(-29, 65), Vector2(-48, 48)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/LegL:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.397498, 0.918872] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/LegL:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/LegR:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(50, 51), Vector2(35, 68)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/LegR:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, -0.401688, -0.125403] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/LegR:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 53), Vector2(5, 53)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, -0.278326, 0.204683] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.9, 1.1), Vector2(1.1, 0.9)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/Hat:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(2, -91)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/Body/HandL:position") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-60, -53), Vector2(-1.7771, -44.1117), Vector2(-77.4704, -36.9794)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("Root/Rig/Body/HandR:position") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(51, -51), Vector2(-70.2132, -64.2738), Vector2(71.4504, -76.2001)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 0.15, 0.25), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1.6, 1.6)] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Root/Hitbox/HitboxCollisionShape2D:disabled") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0, 0.25, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("Root/Hitbox:knockback_enabled") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [false, false, false] +} + +[sub_resource type="Animation" id="Animation_g7a0r"] +resource_name = "attack_3" +length = 0.35 +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig/Body:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(-5, 40), Vector2(-5, 40)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig/Body:rotation") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, -0.349066, 0.436332] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/Body:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.9, 1.1), Vector2(1.1, 0.9)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/Body/Hat:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(2, -91)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body/HandL:position") +tracks/6/interp = 2 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.2, 0.25, 0.3), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-60, -53), Vector2(-93.4894, -42.3521), Vector2(6.40698, 1.6281), Vector2(68.5276, -75.9627)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/7/interp = 2 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.2, 0.25, 0.3), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, 1.70101, 0.0, 0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(2, 2), Vector2(3, 3)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body/HandR:position") +tracks/9/interp = 2 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(51, -51), Vector2(-1.40495, -52.6598), Vector2(-66.8689, -27.8787)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/10/interp = 2 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/LegL:position") +tracks/12/interp = 2 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-29, 65), Vector2(-57, 59), Vector2(37, 63)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/LegL:rotation") +tracks/13/interp = 2 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.706805, -0.742333] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/LegL:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/LegR:position") +tracks/15/interp = 2 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(31, 65), Vector2(-45, 39)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/LegR:rotation") +tracks/16/interp = 2 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, -0.477383, 1.06217] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/LegR:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("FX/Cloud:visible") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Hitbox/HitboxCollisionShape2D:disabled") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.25, 0.35), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Hitbox:knockback_enabled") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0.2, 0.35), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, false] +} + +[sub_resource type="Animation" id="Animation_jcwlt"] +resource_name = "charge" +length = 0.2 +loop_mode = 1 +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, -76)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/LegL:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(-16, 67), Vector2(-43, 30), Vector2(17, 26), Vector2(51, 50), Vector2(-16, 67)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/LegL:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [0.518326, 0.991314, 0.518326, -1.96385, 0.518326] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/LegL:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/LegR:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(23, 69), Vector2(74, 43), Vector2(6, 23), Vector2(-35, 47), Vector2(23, 69)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/LegR:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [0.811128, -0.351373, 0.811128, 1.40327, 0.811128] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/LegR:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 53), Vector2(5, 53), Vector2(5, 53), Vector2(5, 53)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [0.553472, 0.61588, 0.553472, 0.61588, 0.553472] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/Hat:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(2, -91)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1.1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/Body/HandL:position") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(8.86381, -27.008), Vector2(17.3173, -25.7316), Vector2(8.86381, -27.008), Vector2(17.3173, -25.7316), Vector2(8.86381, -27.008)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("Root/Rig/Body/HandR:position") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(22.4758, -47.2741)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Root/Hitbox/HitboxCollisionShape2D:disabled") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [false, false] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("Root/Hitbox:knockback_enabled") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, true] +} + +[sub_resource type="Animation" id="Animation_sva81"] +resource_name = "charge_prepare" +length = 0.3 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, -76)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/LegL:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-29, 65), Vector2(-46, 66), Vector2(-16, 67)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/LegL:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.518326, 0.518326] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/LegL:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/LegR:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(55, 35), Vector2(23, 69)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/LegR:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, -1.03322, 0.811128] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/LegR:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 53), Vector2(5, 53)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, -0.455647, 0.553472] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.1, 0.9), Vector2(0.9, 1.1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/Hat:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(2, -91), Vector2(2, -91), Vector2(2, -91)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0872665] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/Body/HandL:position") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-60, -53), Vector2(-77.6176, -56.3868), Vector2(36.6639, -43.1139)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("Root/Rig/Body/HandR:position") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(51, -51), Vector2(-42.71, -65.1758), Vector2(48.1987, -60.7003)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} + +[sub_resource type="Animation" id="Animation_5k1rd"] +resource_name = "dance" +length = 1.8 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig/Body/Hat:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 1.8), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(2, -91), Vector2(2, -91), Vector2(2, -91)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.1, 1.8), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1, 1.8), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/Body/HandR:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(47.3684, -50.4762), Vector2(36, -51), Vector2(66, -51), Vector2(36, -51), Vector2(66, -51), Vector2(66, -21), Vector2(66, -81), Vector2(66, -21), Vector2(66, -81), Vector2(66, -21), Vector2(47.3684, -50.4762)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.1, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 53), Vector2(5, 53), Vector2(5, 56), Vector2(5, 53), Vector2(5, 56), Vector2(5, 53), Vector2(5, 56), Vector2(5, 53)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.1, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(0.95, 1.05), Vector2(0.95, 1.05), Vector2(1.05, 0.95), Vector2(0.95, 1.05), Vector2(1.05, 0.95), Vector2(0.95, 1.05), Vector2(1.05, 0.95), Vector2(0.95, 1.05), Vector2(1.05, 0.95), Vector2(0.95, 1.05), Vector2(0.95, 1.05)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/LegR:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(46, 65), Vector2(16, 65), Vector2(46, 65), Vector2(16, 65), Vector2(31, 65), Vector2(31, 65), Vector2(31, 65)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/LegR:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/LegR:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/LegL:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(-29, 65), Vector2(-14, 65), Vector2(-44, 65), Vector2(-14, 65), Vector2(-44, 65), Vector2(-29, 65), Vector2(-29, 65), Vector2(-29, 65)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/LegL:rotation") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/LegL:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig:position") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.1, 1.8), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(0, -76), Vector2(0, -76), Vector2(0, -76)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig:rotation") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.1, 1.8), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.1, 1.8), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("Root/Rig/Body/HandL:position") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(-31.5789, -50.4762), Vector2(-75, -53), Vector2(-15, -53), Vector2(-75, -53), Vector2(-15, -53), Vector2(-15, -83), Vector2(-15, -23), Vector2(-15, -83), Vector2(-15, -23), Vector2(-15, -83), Vector2(-31.5789, -50.4762)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} + +[sub_resource type="Animation" id="Animation_wei72"] +resource_name = "death" +length = 0.5 +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig/LegL:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-29, 65), Vector2(-29, 65), Vector2(-29, 65)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig/LegL:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, -1.0566] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/LegL:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/LegR:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(31, 65), Vector2(-12.2578, 72.9572)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/LegR:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, -0.693514] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/LegR:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(5, 53)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body/Hat:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(2, -91)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/HandL:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-60, -53), Vector2(-60, -53), Vector2(-34.0705, -33.1026)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/Body/HandR:position") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(51, -51), Vector2(51, -51), Vector2(27.9362, -34.8835)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = false +tracks/18/path = NodePath("FX/Cloud:visible") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Rig:position") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(0, -76), Vector2(-5, -120), Vector2(0, -40)] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig:rotation") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, -0.801138, -1.60228] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Root/Rig:scale") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("Root/Rig:modulate") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3, 0.4, 0.5), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0.321569), Color(1, 1, 1, 0.588235), Color(1, 1, 1, 0)] +} +tracks/23/type = "value" +tracks/23/imported = false +tracks/23/enabled = true +tracks/23/path = NodePath("FX/Death:emitting") +tracks/23/interp = 1 +tracks/23/loop_wrap = true +tracks/23/keys = { +"times": PackedFloat32Array(0, 0.3, 0.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [false, true, false] +} +tracks/24/type = "value" +tracks/24/imported = false +tracks/24/enabled = true +tracks/24/path = NodePath("Root/Rig/Body/HandL/WeaponNinjaStar:visible") +tracks/24/interp = 1 +tracks/24/loop_wrap = true +tracks/24/keys = { +"times": PackedFloat32Array(0, 0.5), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [false, false] +} + +[sub_resource type="Animation" id="Animation_msfb2"] +resource_name = "dodge" +length = 0.4 +capture_included = true +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(0, -76), Vector2(0, -38), Vector2(0, -76)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig:rotation") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 2, +"values": [0.0, 2.35619, 6.28319, 12.5664] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 0.5), Vector2(1, 0.5), Vector2(1, 0.5), Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/LegL:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-29, 65), Vector2(-24.8287, 40.1066), Vector2(-24.8287, 40.1066), Vector2(-29, 65)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/LegL:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/LegL:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/LegR:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(26.1794, 41.8884), Vector2(26.1794, 41.8884), Vector2(31, 65)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/LegR:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/LegR:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 53), Vector2(5, 53), Vector2(5, 53)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/Hat:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(2, -91), Vector2(2, -91), Vector2(2, -91), Vector2(2, -91)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/Body/HandL:position") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-60, -53), Vector2(-19.9999, -52.9358), Vector2(-19.9999, -52.9358), Vector2(-60, -53)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("Root/Rig/Body/HandR:position") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(51, -51), Vector2(21.9955, -54.1155), Vector2(21.9955, -54.1155), Vector2(51, -51)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0, 0.0] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 0.1, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Root/Hitbox/HitboxCollisionShape2D:disabled") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0, 0.0001, 0.1, 0.2, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 1, +"values": [true, true, true, true, true, true] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("Root/Hurtbox/HurtboxCollisionShape2D:disabled") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0, 0.4), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, false] +} + +[sub_resource type="Animation" id="Animation_gowr5"] +resource_name = "hurt" +length = 0.25 +step = 0.01 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig/Body:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(-9, 29)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig/Body:rotation") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 2), +"update": 0, +"values": [0.0, -0.459832] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/Body:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.9, 1.1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = false +tracks/3/path = NodePath("Root/Rig/Body/Hat:position") +tracks/3/interp = 2 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(2, -91), Vector2(-23.375, -110.918)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/4/interp = 2 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, -0.169267] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body/HandL:position") +tracks/6/interp = 2 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(-60, -53), Vector2(-86.123, -33.8822)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/7/interp = 2 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body/HandR:position") +tracks/9/interp = 2 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(51, -51), Vector2(-4.62756, -33.3235)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/10/interp = 2 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/LegL:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-29, 65)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/LegL:rotation") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/LegL:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/LegR:position") +tracks/15/interp = 2 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(37, 14)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/LegR:rotation") +tracks/16/interp = 2 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, -0.896359] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/LegR:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("FX/Cloud:visible") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Hitbox/HitboxCollisionShape2D:disabled") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.25), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, true] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig:modulate") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 0.11, 0.22), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Color(1, 1, 1, 1), Color(0.721569, 0, 0.0352941, 1), Color(1, 1, 1, 1)] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Root/Rig/Body/HandL/WeaponNinjaStar:visible") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0, 0.25), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [false, false] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("Root/Hitbox:knockback_enabled") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0, 0.25), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [false, false] +} + +[sub_resource type="Animation" id="Animation_gnqgt"] +resource_name = "idle" +length = 0.4 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig/LegR:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(31, 65), Vector2(31, 65)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig/LegR:rotation") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/LegR:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.9, 1.1), Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/Body:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 49), Vector2(5, 53)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/Body:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/Body:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.95, 1.05), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body/Hat:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(2, -91)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body/HandL:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-60, -53), Vector2(-62, -55), Vector2(-60, -53)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/10/interp = 2 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/HandR:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(51, -51), Vector2(49, -53), Vector2(51, -51)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/13/interp = 2 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/LegL:position") +tracks/15/interp = 2 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-29, 65), Vector2(-29, 65), Vector2(-29, 65)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/LegL:rotation") +tracks/16/interp = 2 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/LegL:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.9, 1.1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("FX/Cloud:visible") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Hitbox/HitboxCollisionShape2D:disabled") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.4), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, true] +} + +[sub_resource type="Animation" id="Animation_uow76"] +resource_name = "spit" +length = 0.3 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig/LegL:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.3), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(-29, 65), Vector2(-57, 44)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig/LegL:rotation") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.3), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 0.730707] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/LegL:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.3), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/LegR:position") +tracks/3/interp = 2 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(46, 48), Vector2(31, 65)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/LegR:rotation") +tracks/4/interp = 2 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, -0.718681, 0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/LegR:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body:position") +tracks/6/interp = 2 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(4, 46), Vector2(4, 46)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body:rotation") +tracks/7/interp = 2 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, -0.330061, 0.363712] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.8, 1.2), Vector2(1.1, 0.9)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body/Hat:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(2, -91)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/HandL:position") +tracks/12/interp = 2 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-60, -53), Vector2(-53.8926, -21.1176), Vector2(-19.8796, -43.7927)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/13/interp = 2 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/Body/HandR:position") +tracks/15/interp = 2 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(51, -51), Vector2(47.6296, -15.5481), Vector2(47.0064, -56.4127)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/16/interp = 2 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} + +[sub_resource type="Animation" id="Animation_5mxvi"] +resource_name = "summon" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig/LegL:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(-29, 65), Vector2(-29, 65)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig/LegL:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/LegL:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/LegR:position") +tracks/3/interp = 2 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(47, 54), Vector2(43, 56.75), Vector2(47, 54), Vector2(43, 56.75), Vector2(31, 65)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/LegR:rotation") +tracks/4/interp = 2 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [0.0, -0.40126, -0.768424, -0.40126, -0.768424, 0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/LegR:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body:position") +tracks/6/interp = 2 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.2, 0.6, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 53), Vector2(5, 53), Vector2(5, 53)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body:rotation") +tracks/7/interp = 2 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.2, 0.6, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, -0.179614, -0.179614, 0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(0.9, 1.1), Vector2(1, 1), Vector2(0.9, 1.1), Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body/Hat:position") +tracks/9/interp = 2 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(2, -91), Vector2(2, -91)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/10/interp = 2 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/HandL:position") +tracks/12/interp = 2 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(-60, -53), Vector2(-71.1271, -84.0591), Vector2(-76.1533, -94.4691), Vector2(-71.1271, -84.0591), Vector2(-76.1533, -94.4691), Vector2(-60, -53)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/13/interp = 2 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, -0.836345, 0.0, -0.836345, 0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/Body/HandR:position") +tracks/15/interp = 2 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(51, -51), Vector2(61.8744, -83.286), Vector2(62.8802, -95.0655), Vector2(61.8744, -83.286), Vector2(62.8802, -95.0655), Vector2(51, -51)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/16/interp = 2 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [0.0, 0.0, -0.887813, 0.0, -0.887813, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} + +[sub_resource type="Animation" id="Animation_yn0t6"] +resource_name = "throw" +length = 0.1 +step = 0.01 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, -76)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/LegL:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(-48, 64), Vector2(45, 67)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/LegL:rotation") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.862915, -0.786391] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/LegR:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(-27, 64)] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/LegR:rotation") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 0.899266] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 53)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [-0.250268, 0.250549] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body/Hat:position") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(2, -91)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body/HandR:position") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(37.6892, -51.6964), Vector2(-36.284, -25.5073)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 0.0] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig:scale") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/LegL:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/LegR:scale") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/Body:scale") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(0.9, 1.1), Vector2(1.1, 0.9)] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("Root/Rig/Body/HandL:position") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-70.3036, -52.0327), Vector2(-5.01252, -88.9993), Vector2(66.2323, -78.0635)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1.5, 1.5)] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Root/Rig/Body/HandL/WeaponNinjaStar:visible") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0, 0.09, 0.1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, true, false] +} + +[sub_resource type="Animation" id="Animation_kb56n"] +resource_name = "throw_prepare" +length = 0.2 +loop_mode = 1 +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, -76)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/LegL:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-48, 64), Vector2(-48, 64), Vector2(-48, 64)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/LegL:rotation") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.644548, 0.862915, 0.644548] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/LegR:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(31, 65)] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/LegR:rotation") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 53), Vector2(5, 53)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [-0.194275, -0.250268, -0.194275] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body/Hat:position") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(2, -91)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body/HandL:position") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-27.2463, -58.3579), Vector2(-70.3036, -52.0327), Vector2(-27.2463, -58.3579)] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/Body/HandR:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(37.6892, -51.6964)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/LegL:scale") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/LegR:scale") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/Body:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Root/Rig/Body/HandL/WeaponNinjaStar:visible") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, true] +} + +[sub_resource type="Animation" id="Animation_fh06e"] +resource_name = "walk" +length = 0.6 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig/Body:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(5, 53), Vector2(5, 47), Vector2(5, 53)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig/Body:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig/Body:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.92, 1.08), Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/Body/Hat:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.6), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(2, -91), Vector2(2, -91)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/Body/Hat:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.6), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/Body/Hat:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.6), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Body/HandL:position") +tracks/6/interp = 2 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-60, -53), Vector2(17, -22), Vector2(-60, -53)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Body/HandL:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Body/HandL:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Root/Rig/Body/HandR:position") +tracks/9/interp = 2 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(51, -51), Vector2(-26, -29), Vector2(51, -51)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Root/Rig/Body/HandR:rotation") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 0.0, 0.0] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Root/Rig/Body/HandR:scale") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Root/Rig/LegL:position") +tracks/12/interp = 2 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-29, 65), Vector2(33, 65), Vector2(-29, 65)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Root/Rig/LegL:rotation") +tracks/13/interp = 2 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, -0.991068, 0.0] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Root/Rig/LegL:scale") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1.1, 1.1), Vector2(1, 1), Vector2(1.1, 1.1)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Root/Rig/LegR:position") +tracks/15/interp = 2 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(31, 65), Vector2(-30, 65), Vector2(31, 65)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Root/Rig/LegR:rotation") +tracks/16/interp = 2 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 1.13756, 0.0] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Root/Rig/LegR:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.1, 1.1), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("FX/Cloud:visible") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Root/Hitbox/HitboxCollisionShape2D:disabled") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.6), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, true] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Root/Hurtbox/HurtboxCollisionShape2D:disabled") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 0.6), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [false, false] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_ws2ti"] +_data = { +&"RESET": SubResource("Animation_nvm4d"), +&"attack_1": SubResource("Animation_8wj70"), +&"attack_2": SubResource("Animation_s1dey"), +&"attack_3": SubResource("Animation_g7a0r"), +&"charge": SubResource("Animation_jcwlt"), +&"charge_prepare": SubResource("Animation_sva81"), +&"dance": SubResource("Animation_5k1rd"), +&"death": SubResource("Animation_wei72"), +&"dodge": SubResource("Animation_msfb2"), +&"hurt": SubResource("Animation_gowr5"), +&"idle": SubResource("Animation_gnqgt"), +&"spit": SubResource("Animation_uow76"), +&"summon": SubResource("Animation_5mxvi"), +&"throw": SubResource("Animation_yn0t6"), +&"throw_prepare": SubResource("Animation_kb56n"), +&"walk": SubResource("Animation_fh06e") +} + +[node name="AgentBase" type="CharacterBody2D"] +collision_layer = 2 +collision_mask = 3 +motion_mode = 1 +wall_min_slide_angle = 0.0174533 +safe_margin = 0.001 +script = ExtResource("1_n8vy2") + +[node name="Root" type="Node2D" parent="."] +metadata/_edit_lock_ = true + +[node name="Rig" type="Node2D" parent="Root"] +position = Vector2(0, -76) + +[node name="Shadow" type="Sprite2D" parent="Root/Rig"] +modulate = Color(1, 1, 1, 0.258824) +position = Vector2(0, 76) +texture = ExtResource("2_vr0jo") + +[node name="LegL" type="Sprite2D" parent="Root/Rig"] +position = Vector2(-29, 65) +texture = ExtResource("1_1u51b") +region_enabled = true +region_rect = Rect2(104, 67, 35, 28) + +[node name="LegR" type="Sprite2D" parent="Root/Rig"] +position = Vector2(31, 65) +texture = ExtResource("1_1u51b") +region_enabled = true +region_rect = Rect2(105, 97, 34, 27) + +[node name="Body" type="Sprite2D" parent="Root/Rig"] +position = Vector2(5, 53) +texture = ExtResource("1_1u51b") +offset = Vector2(-5, -53) +region_enabled = true +region_rect = Rect2(4.03712, 4.21556, 94.9839, 121.271) + +[node name="Hat" type="Sprite2D" parent="Root/Rig/Body"] +position = Vector2(2, -91) +texture = ExtResource("1_1u51b") +offset = Vector2(-1, -20) +region_enabled = true +region_rect = Rect2(163, 20, 170, 102) + +[node name="HandL" type="Sprite2D" parent="Root/Rig/Body"] +position = Vector2(-60, -53) +texture = ExtResource("1_1u51b") +region_enabled = true +region_rect = Rect2(111.022, 6.27016, 27.6329, 27.1423) + +[node name="WeaponNinjaStar" type="Sprite2D" parent="Root/Rig/Body/HandL"] +visible = false +texture = ExtResource("4_1c5xq") + +[node name="HandR" type="Sprite2D" parent="Root/Rig/Body"] +show_behind_parent = true +position = Vector2(51, -51) +texture = ExtResource("1_1u51b") +region_enabled = true +region_rect = Rect2(111, 34, 26.9272, 26.6298) + +[node name="Hitbox" type="Area2D" parent="Root"] +position = Vector2(50, 0) +collision_layer = 0 +collision_mask = 4 +script = ExtResource("5_taq6b") +knockback_strength = 1000.0 + +[node name="HitboxCollisionShape2D" type="CollisionShape2D" parent="Root/Hitbox"] +shape = SubResource("RectangleShape2D_2k81i") +disabled = true +debug_color = Color(0.933131, 0.0801983, 0.605982, 0.42) +metadata/_edit_lock_ = true + +[node name="Hurtbox" type="Area2D" parent="Root" node_paths=PackedStringArray("health")] +collision_layer = 8 +collision_mask = 0 +script = ExtResource("6_jnvxm") +health = NodePath("../../Health") + +[node name="HurtboxCollisionShape2D" type="CollisionShape2D" parent="Root/Hurtbox"] +shape = SubResource("RectangleShape2D_26abe") +debug_color = Color(0.466325, 0.590206, 0.107862, 0.42) +metadata/_edit_lock_ = true + +[node name="FX" type="Node2D" parent="."] +position = Vector2(0, -68) +metadata/_edit_lock_ = true + +[node name="Cloud" type="Sprite2D" parent="FX"] +visible = false +scale = Vector2(0.5, 0.5) +texture = ExtResource("2_lv102") +region_enabled = true +region_rect = Rect2(300, 0, 100, 70) + +[node name="Death" type="GPUParticles2D" parent="FX"] +position = Vector2(0, 52) +emitting = false +amount = 16 +texture = ExtResource("4_mnb6v") +lifetime = 0.7 +one_shot = true +explosiveness = 0.7 +fixed_fps = 60 +process_material = SubResource("ParticleProcessMaterial_f5i1x") + +[node name="Summoned" type="GPUParticles2D" parent="FX"] +position = Vector2(0, 83) +emitting = false +amount = 16 +texture = ExtResource("4_mnb6v") +lifetime = 1.4 +one_shot = true +explosiveness = 0.5 +fixed_fps = 60 +process_material = SubResource("ParticleProcessMaterial_gmal1") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +visible = false +position = Vector2(-1, -7) +rotation = 1.5708 +shape = SubResource("CircleShape2D_0c228") + +[node name="Health" type="Node" parent="."] +script = ExtResource("4_qwtrf") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +callback_mode_method = 1 +libraries = { +&"": SubResource("AnimationLibrary_ws2ti") +} +autoplay = "idle" diff --git a/demo/agents/fireball/fireball.gd b/demo/agents/fireball/fireball.gd new file mode 100644 index 0000000..513a722 --- /dev/null +++ b/demo/agents/fireball/fireball.gd @@ -0,0 +1,56 @@ +#* +#* fireball.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +extends Node2D +## Fireball + +const SPEED := 800.0 +const DEAD_SPEED := 400.0 + +@export var dir: float = 1.0 + +var _is_dead: bool = false + +@onready var fireball_sprite: Sprite2D = $Root/Fireball +@onready var death: GPUParticles2D = $FX/Death +@onready var collision_shape_2d: CollisionShape2D = $Hitbox/CollisionShape2D +@onready var root: Node2D = $Root +@onready var trail: GPUParticles2D = $FX/Trail + + +func _ready() -> void: + var tween := create_tween().set_loops() + tween.tween_property(fireball_sprite, ^"rotation", PI * signf(dir), 1.0).as_relative() + + var tween2 := create_tween().set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN) + tween2.tween_property(fireball_sprite, "position:y", -10.0, 0.5).as_relative().set_ease(Tween.EASE_OUT) + tween2.tween_property(fireball_sprite, "position:y", 0.0, 1.0) + tween2.tween_callback(_die) + + +func _physics_process(delta: float) -> void: + var speed: float = SPEED if not _is_dead else DEAD_SPEED + position += Vector2.RIGHT * speed * dir * delta + + +func _die() -> void: + if _is_dead: + return + _is_dead = true + trail.emitting = false + root.hide() + collision_shape_2d.set_deferred(&"disabled", true) + death.emitting = true + await death.finished + queue_free() + + +func _on_hitbox_area_entered(_area: Area2D) -> void: + _die() diff --git a/demo/agents/fireball/fireball.gd.uid b/demo/agents/fireball/fireball.gd.uid new file mode 100644 index 0000000..8e6a542 --- /dev/null +++ b/demo/agents/fireball/fireball.gd.uid @@ -0,0 +1 @@ +uid://cw0jj6rj3e4dp diff --git a/demo/agents/fireball/fireball.tscn b/demo/agents/fireball/fireball.tscn new file mode 100644 index 0000000..646e1b7 --- /dev/null +++ b/demo/agents/fireball/fireball.tscn @@ -0,0 +1,169 @@ +[gd_scene load_steps=18 format=3 uid="uid://wdauoepicegb"] + +[ext_resource type="Script" uid="uid://cw0jj6rj3e4dp" path="res://demo/agents/fireball/fireball.gd" id="1_ituf4"] +[ext_resource type="Texture2D" uid="uid://dwhhxj5557qrb" path="res://demo/assets/shadow.png" id="2_6n8mx"] +[ext_resource type="Texture2D" uid="uid://235liwnxn1n5" path="res://demo/assets/fireball.png" id="3_1an0e"] +[ext_resource type="Script" uid="uid://dntc3c582m5w8" path="res://demo/agents/scripts/hitbox.gd" id="4_rjhgc"] +[ext_resource type="Texture2D" uid="uid://bdusy0qqtw0th" path="res://demo/assets/smoke.png" id="5_dcbp6"] + +[sub_resource type="Curve" id="Curve_mukra"] +_data = [Vector2(0, 0), 0.0, 4.81319, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="CurveTexture" id="CurveTexture_56342"] +curve = SubResource("Curve_mukra") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_gbya7"] +lifetime_randomness = 0.5 +particle_flag_disable_z = true +direction = Vector3(0, -1, 0) +spread = 90.0 +initial_velocity_min = 150.0 +initial_velocity_max = 250.0 +angular_velocity_min = -90.0 +angular_velocity_max = 90.0 +gravity = Vector3(0, 0, 0) +radial_accel_min = -90.0 +radial_accel_max = 90.0 +damping_min = 200.0 +damping_max = 200.0 +scale_min = 0.8 +scale_max = 1.2 +scale_curve = SubResource("CurveTexture_56342") +color = Color(0.552941, 0.552941, 0.552941, 1) + +[sub_resource type="Gradient" id="Gradient_c08h3"] +offsets = PackedFloat32Array(0, 0.549738, 1) +colors = PackedColorArray(0.980453, 0.717632, 0.282353, 1, 0.960906, 0.211521, 0.0390784, 1, 0.201527, 0.201527, 0.201527, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_fhxvw"] +gradient = SubResource("Gradient_c08h3") + +[sub_resource type="Curve" id="Curve_ugmtv"] +_data = [Vector2(0, 0.010989), 0.0, 0.0, 0, 0, Vector2(0.151111, 1), 1.3559, 1.3559, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_1f5jp"] +curve = SubResource("Curve_ugmtv") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_gilhy"] +lifetime_randomness = 0.5 +particle_flag_disable_z = true +emission_shape = 3 +emission_box_extents = Vector3(40, 1, 1) +direction = Vector3(0, -1, 0) +spread = 90.0 +initial_velocity_min = 150.0 +initial_velocity_max = 250.0 +angular_velocity_min = -90.0 +angular_velocity_max = 90.0 +gravity = Vector3(0, 0, 0) +radial_accel_min = -90.0 +radial_accel_max = 90.0 +damping_min = 200.0 +damping_max = 200.0 +scale_min = 0.8 +scale_max = 1.2 +scale_curve = SubResource("CurveTexture_1f5jp") +color_ramp = SubResource("GradientTexture1D_fhxvw") + +[sub_resource type="CircleShape2D" id="CircleShape2D_7uc1b"] +radius = 25.13 + +[sub_resource type="Animation" id="Animation_wr7y0"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Fireball: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_ey8it"] +resource_name = "default" +length = 0.3 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Fireball:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [0, 1, 2, 0] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_cphpk"] +_data = { +&"RESET": SubResource("Animation_wr7y0"), +&"default": SubResource("Animation_ey8it") +} + +[node name="Fireball" type="Node2D"] +script = ExtResource("1_ituf4") + +[node name="FX" type="Node2D" parent="."] +position = Vector2(0, -92) + +[node name="Trail" type="GPUParticles2D" parent="FX"] +show_behind_parent = true +amount = 6 +process_material = SubResource("ParticleProcessMaterial_gbya7") +texture = ExtResource("5_dcbp6") +lifetime = 0.4 +fixed_fps = 60 + +[node name="Death" type="GPUParticles2D" parent="FX"] +emitting = false +amount = 6 +process_material = SubResource("ParticleProcessMaterial_gilhy") +texture = ExtResource("5_dcbp6") +lifetime = 0.7 +one_shot = true +explosiveness = 0.7 +fixed_fps = 60 +local_coords = true + +[node name="Root" type="Node2D" parent="."] + +[node name="Shadow" type="Sprite2D" parent="Root"] +modulate = Color(1, 1, 1, 0.686275) +position = Vector2(0, -1) +scale = Vector2(0.382, 0.297) +texture = ExtResource("2_6n8mx") + +[node name="Fireball" type="Sprite2D" parent="Root"] +position = Vector2(0, -92) +texture = ExtResource("3_1an0e") +hframes = 3 + +[node name="RemoteTransform2D" type="RemoteTransform2D" parent="Root/Fireball"] +remote_path = NodePath("../../../FX") +update_rotation = false +update_scale = false + +[node name="Hitbox" type="Area2D" parent="."] +collision_layer = 0 +collision_mask = 4 +script = ExtResource("4_rjhgc") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] +shape = SubResource("CircleShape2D_7uc1b") +debug_color = Color(0.839216, 0.192157, 0.815686, 0.419608) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_cphpk") +} +autoplay = "default" + +[connection signal="area_entered" from="Hitbox" to="." method="_on_hitbox_area_entered"] diff --git a/demo/agents/ninja_star/ninja_star.gd b/demo/agents/ninja_star/ninja_star.gd new file mode 100644 index 0000000..0a1713e --- /dev/null +++ b/demo/agents/ninja_star/ninja_star.gd @@ -0,0 +1,53 @@ +#* +#* ninja_star.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +extends Node2D + +const SPEED := 800.0 +const DEAD_SPEED := 400.0 + +@export var dir: float = 1.0 + +var _is_dead: bool = false + +@onready var ninja_star: Sprite2D = $Root/NinjaStar +@onready var death: GPUParticles2D = $Death +@onready var collision_shape_2d: CollisionShape2D = $Hitbox/CollisionShape2D +@onready var root: Node2D = $Root + + +func _ready() -> void: + var tween := create_tween().set_loops() + tween.tween_property(ninja_star, ^"rotation", TAU * signf(dir), 1.0).as_relative() + + var tween2 := create_tween().set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN) + tween2.tween_property(ninja_star, "position:y", -10.0, 0.5).as_relative().set_ease(Tween.EASE_OUT) + tween2.tween_property(ninja_star, "position:y", 0.0, 1.0) + tween2.tween_callback(_die) + + +func _physics_process(delta: float) -> void: + var speed: float = SPEED if not _is_dead else DEAD_SPEED + position += Vector2.RIGHT * speed * dir * delta + + +func _die() -> void: + if _is_dead: + return + _is_dead = true + root.hide() + collision_shape_2d.set_deferred(&"disabled", true) + death.emitting = true + await death.finished + queue_free() + + +func _on_hitbox_area_entered(_area: Area2D) -> void: + _die() diff --git a/demo/agents/ninja_star/ninja_star.gd.uid b/demo/agents/ninja_star/ninja_star.gd.uid new file mode 100644 index 0000000..87a2801 --- /dev/null +++ b/demo/agents/ninja_star/ninja_star.gd.uid @@ -0,0 +1 @@ +uid://ea3wq7unbfaw diff --git a/demo/agents/ninja_star/ninja_star.tscn b/demo/agents/ninja_star/ninja_star.tscn new file mode 100644 index 0000000..b4b2289 --- /dev/null +++ b/demo/agents/ninja_star/ninja_star.tscn @@ -0,0 +1,80 @@ +[gd_scene load_steps=10 format=3 uid="uid://bj5n72nomeaci"] + +[ext_resource type="Script" uid="uid://ea3wq7unbfaw" path="res://demo/agents/ninja_star/ninja_star.gd" id="1_pja57"] +[ext_resource type="Texture2D" uid="uid://2uyxh7sy8qny" path="res://demo/assets/weapon_ninja_star.png" id="1_ptof7"] +[ext_resource type="Texture2D" uid="uid://dwhhxj5557qrb" path="res://demo/assets/shadow.png" id="2_2rj5a"] +[ext_resource type="Script" uid="uid://dntc3c582m5w8" path="res://demo/agents/scripts/hitbox.gd" id="2_iem02"] +[ext_resource type="Texture2D" uid="uid://bdusy0qqtw0th" path="res://demo/assets/smoke.png" id="5_t37aw"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_7uc1b"] +radius = 28.0 + +[sub_resource type="Curve" id="Curve_ugmtv"] +_data = [Vector2(0, 0.010989), 0.0, 0.0, 0, 0, Vector2(0.151111, 1), 1.3559, 1.3559, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_1f5jp"] +curve = SubResource("Curve_ugmtv") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_gilhy"] +lifetime_randomness = 0.5 +particle_flag_disable_z = true +emission_shape = 3 +emission_box_extents = Vector3(40, 1, 1) +direction = Vector3(0, -1, 0) +spread = 90.0 +initial_velocity_min = 150.0 +initial_velocity_max = 250.0 +angular_velocity_min = -90.0 +angular_velocity_max = 90.0 +gravity = Vector3(0, 0, 0) +radial_accel_min = -90.0 +radial_accel_max = 90.0 +damping_min = 200.0 +damping_max = 200.0 +scale_min = 0.8 +scale_max = 1.2 +scale_curve = SubResource("CurveTexture_1f5jp") + +[node name="NinjaStar" type="Node2D"] +script = ExtResource("1_pja57") + +[node name="Root" type="Node2D" parent="."] + +[node name="Shadow" type="Sprite2D" parent="Root"] +modulate = Color(1, 1, 1, 0.686275) +position = Vector2(0, -1) +scale = Vector2(0.382, 0.297) +texture = ExtResource("2_2rj5a") + +[node name="NinjaStar" type="Sprite2D" parent="Root"] +position = Vector2(0, -93) +texture = ExtResource("1_ptof7") + +[node name="RemoteTransform2D" type="RemoteTransform2D" parent="Root/NinjaStar"] +remote_path = NodePath("../../../Death") +update_rotation = false +update_scale = false + +[node name="Hitbox" type="Area2D" parent="."] +collision_layer = 0 +collision_mask = 4 +script = ExtResource("2_iem02") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] +shape = SubResource("CircleShape2D_7uc1b") +debug_color = Color(0.839216, 0.192157, 0.815686, 0.419608) + +[node name="Death" type="GPUParticles2D" parent="."] +position = Vector2(0, -93) +emitting = false +amount = 1 +process_material = SubResource("ParticleProcessMaterial_gilhy") +texture = ExtResource("5_t37aw") +lifetime = 0.7 +one_shot = true +explosiveness = 0.7 +fixed_fps = 60 +local_coords = true + +[connection signal="area_entered" from="Hitbox" to="." method="_on_hitbox_area_entered"] diff --git a/demo/agents/player/player.gd b/demo/agents/player/player.gd new file mode 100644 index 0000000..7c5b19a --- /dev/null +++ b/demo/agents/player/player.gd @@ -0,0 +1,103 @@ +#* +#* player.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +extends "res://demo/agents/scripts/agent_base.gd" + +## Player. + +@export var dodge_cooldown: float = 0.4 + +@onready var hsm: LimboHSM = $LimboHSM +@onready var idle_state: LimboState = $LimboHSM/IdleState +@onready var move_state: LimboState = $LimboHSM/MoveState +@onready var attack_state: LimboState = $LimboHSM/AttackState +@onready var dodge_state: LimboState = $LimboHSM/DodgeState + +var can_dodge: bool = true +var attack_pressed: bool = false + + +func _ready() -> void: + super._ready() + can_dodge = true + _init_input_events() + _init_state_machine() + death.connect(func(): remove_from_group(&"player")) + + +func _unhandled_input(event: InputEvent) -> void: + if event.is_echo(): + return + if event.is_action_pressed("attack"): + attack_pressed = true + _process_attack_input() + if event.is_action_pressed("dodge"): + hsm.dispatch("dodge!") + + +func _process_attack_input() -> void: + if not attack_pressed or hsm.get_active_state() == attack_state: + return + hsm.dispatch("attack!") + attack_pressed = false + + +func _init_state_machine() -> void: + hsm.add_transition(idle_state, move_state, idle_state.EVENT_FINISHED) + hsm.add_transition(move_state, idle_state, move_state.EVENT_FINISHED) + hsm.add_transition(idle_state, attack_state, "attack!") + hsm.add_transition(move_state, attack_state, "attack!") + hsm.add_transition(attack_state, move_state, attack_state.EVENT_FINISHED) + hsm.add_transition(hsm.ANYSTATE, dodge_state, "dodge!") + hsm.add_transition(dodge_state, move_state, dodge_state.EVENT_FINISHED) + + dodge_state.set_guard(_can_dodge) + attack_state.set_guard(attack_state.can_enter) + + # Process attack input buffer when move_state is entered. + # This way we can buffer the attack button presses and chain the attacks. + move_state.call_on_enter(_process_attack_input) + + hsm.initialize(self) + hsm.set_active(true) + + +func _init_input_events() -> void: + # Note: Ensures that input events are present even if project.godot wasn't imported. + _add_action(&"move_left", KEY_A) + _add_action(&"move_right", KEY_D) + _add_action(&"move_up", KEY_W) + _add_action(&"move_down", KEY_S) + _add_action(&"dodge", KEY_SPACE) + _add_action(&"attack", KEY_ENTER, KEY_F) + + +func _add_action(p_action: StringName, p_key: Key, p_alt: Key = KEY_NONE) -> void: + if not InputMap.has_action(p_action): + InputMap.add_action(p_action) + var event := InputEventKey.new() + event.keycode = p_key + InputMap.action_add_event(p_action, event) + if p_alt != KEY_NONE: + var alt := InputEventKey.new() + alt.keycode = p_alt + InputMap.action_add_event(p_action, alt) + + +func set_victorious() -> void: + idle_state.idle_animation = &"dance" + + +func _can_dodge() -> bool: + if can_dodge: + can_dodge = false + get_tree().create_timer(dodge_cooldown).timeout.connect(func(): can_dodge = true) + return true + return false diff --git a/demo/agents/player/player.gd.uid b/demo/agents/player/player.gd.uid new file mode 100644 index 0000000..33e8d11 --- /dev/null +++ b/demo/agents/player/player.gd.uid @@ -0,0 +1 @@ +uid://cgqdrwywolo6a diff --git a/demo/agents/player/player.tscn b/demo/agents/player/player.tscn new file mode 100644 index 0000000..f911559 --- /dev/null +++ b/demo/agents/player/player.tscn @@ -0,0 +1,53 @@ +[gd_scene load_steps=8 format=3 uid="uid://d07ag5dcje13i"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_mswd4"] +[ext_resource type="Script" uid="uid://cgqdrwywolo6a" path="res://demo/agents/player/player.gd" id="2_24nyi"] +[ext_resource type="Script" uid="uid://cig7kaq6hm5nd" path="res://demo/agents/player/states/idle_state.gd" id="3_ekb12"] +[ext_resource type="Script" uid="uid://bu4henvxerree" path="res://demo/agents/player/states/move_state.gd" id="4_paikn"] +[ext_resource type="Script" uid="uid://csbtng53jffek" path="res://demo/agents/player/states/attack_state.gd" id="5_mpgu6"] +[ext_resource type="Script" uid="uid://di111ridlwuy5" path="res://demo/agents/player/states/dodge_state.gd" id="6_7o4a6"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_8pofm"] +size = Vector2(150, 50) + +[node name="Player" groups=["player"] instance=ExtResource("1_mswd4")] +collision_layer = 0 +collision_mask = 1 +script = ExtResource("2_24nyi") +dodge_cooldown = null + +[node name="Hitbox" parent="Root" index="1"] +collision_mask = 8 + +[node name="HitboxCollisionShape2D" parent="Root/Hitbox" index="0"] +shape = SubResource("RectangleShape2D_8pofm") + +[node name="Hurtbox" parent="Root" index="2"] +collision_layer = 4 + +[node name="Health" parent="." index="3"] +max_health = 30.0 + +[node name="LimboHSM" type="LimboHSM" parent="." index="4"] + +[node name="IdleState" type="LimboState" parent="LimboHSM" index="0" node_paths=PackedStringArray("animation_player")] +script = ExtResource("3_ekb12") +animation_player = NodePath("../../AnimationPlayer") +idle_animation = &"idle" + +[node name="MoveState" type="LimboState" parent="LimboHSM" index="1" node_paths=PackedStringArray("animation_player")] +script = ExtResource("4_paikn") +animation_player = NodePath("../../AnimationPlayer") +animation = &"walk" + +[node name="AttackState" type="LimboState" parent="LimboHSM" index="2" node_paths=PackedStringArray("animation_player", "hitbox")] +script = ExtResource("5_mpgu6") +animation_player = NodePath("../../AnimationPlayer") +animations = Array[StringName]([&"attack_1", &"attack_2", &"attack_3"]) +hitbox = NodePath("../../Root/Hitbox") + +[node name="DodgeState" type="LimboState" parent="LimboHSM" index="3" node_paths=PackedStringArray("animation_player", "hurtbox_collision")] +script = ExtResource("6_7o4a6") +animation_player = NodePath("../../AnimationPlayer") +animation = &"dodge" +hurtbox_collision = NodePath("../../Root/Hurtbox/HurtboxCollisionShape2D") diff --git a/demo/agents/player/states/attack_state.gd b/demo/agents/player/states/attack_state.gd new file mode 100644 index 0000000..3af48a5 --- /dev/null +++ b/demo/agents/player/states/attack_state.gd @@ -0,0 +1,60 @@ +#* +#* attack_state.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +extends LimboState + +## Attack state: Perform 3-part combo attack for as long as player hits attack button. + +@export var animation_player: AnimationPlayer +@export var animations: Array[StringName] +@export var hitbox: Hitbox + +## Cooldown duration after third attack in the combo is complete. +@export var combo_cooldown: float = 0.1 + +var anim_index: int = 0 +var last_attack_msec: int = -10000 +var _can_enter: bool = true + + +## This func is used to prevent entering this state using LimboState.set_guard(). +## Entry is denied for a short duration after the third attack in the combo is complete. +func can_enter() -> bool: + return _can_enter + + +func _enter() -> void: + if (Time.get_ticks_msec() - last_attack_msec) < 200: + # Perform next attack animation in the 3-part combo, if an attack was recently performed. + anim_index = (anim_index + 1) % 3 + else: + anim_index = 0 + + var horizontal_move: float = Input.get_axis(&"move_left", &"move_right") + if not is_zero_approx(horizontal_move): + agent.face_dir(horizontal_move) + + hitbox.damage = 2 if anim_index == 2 else 1 # deal 2 damage on a third attack in the combo + animation_player.play(animations[anim_index]) + + await animation_player.animation_finished + if is_active(): + get_root().dispatch(EVENT_FINISHED) + + +func _exit() -> void: + hitbox.damage = 1 + last_attack_msec = Time.get_ticks_msec() + if anim_index == 2 and _can_enter: + # Prevent entering this state for a short duration after the third attack + # in the combo sequence is complete. + _can_enter = false + await get_tree().create_timer(combo_cooldown).timeout + _can_enter = true diff --git a/demo/agents/player/states/attack_state.gd.uid b/demo/agents/player/states/attack_state.gd.uid new file mode 100644 index 0000000..bb9edef --- /dev/null +++ b/demo/agents/player/states/attack_state.gd.uid @@ -0,0 +1 @@ +uid://csbtng53jffek diff --git a/demo/agents/player/states/dodge_state.gd b/demo/agents/player/states/dodge_state.gd new file mode 100644 index 0000000..50b3446 --- /dev/null +++ b/demo/agents/player/states/dodge_state.gd @@ -0,0 +1,48 @@ +#* +#* dodge_state.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +extends LimboState +## Dodge state. + + +@export var animation_player: AnimationPlayer +@export var animation: StringName +@export var duration: float = 0.4 +@export var dodge_speed: float = 1000.0 +@export var hurtbox_collision: CollisionShape2D + +var move_dir: Vector2 +var elapsed_time: float + + +func _enter() -> void: + elapsed_time = 0.0 + hurtbox_collision.disabled = true + + var horizontal_move: float = Input.get_axis(&"move_left", &"move_right") + if is_zero_approx(horizontal_move): + move_dir = Vector2.RIGHT * agent.get_facing() + else: + move_dir = Vector2.RIGHT * signf(horizontal_move) + agent.face_dir(move_dir.x) + + animation_player.play(animation, 0.1) + + +func _exit() -> void: + hurtbox_collision.set_deferred(&"disabled", false) + + +func _update(p_delta: float) -> void: + elapsed_time += p_delta + var desired_velocity: Vector2 = move_dir * dodge_speed + agent.move(desired_velocity) + if elapsed_time > duration: + get_root().dispatch(EVENT_FINISHED) diff --git a/demo/agents/player/states/dodge_state.gd.uid b/demo/agents/player/states/dodge_state.gd.uid new file mode 100644 index 0000000..fc958fc --- /dev/null +++ b/demo/agents/player/states/dodge_state.gd.uid @@ -0,0 +1 @@ +uid://di111ridlwuy5 diff --git a/demo/agents/player/states/idle_state.gd b/demo/agents/player/states/idle_state.gd new file mode 100644 index 0000000..61e7ec2 --- /dev/null +++ b/demo/agents/player/states/idle_state.gd @@ -0,0 +1,27 @@ +#* +#* idle_state.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +extends LimboState +## Idle state. + + +@export var animation_player: AnimationPlayer +@export var idle_animation: StringName + + +func _enter() -> void: + animation_player.play(idle_animation, 0.1) + + +func _update(_delta: float) -> void: + var horizontal_move: float = Input.get_axis(&"move_left", &"move_right") + var vertical_move: float = Input.get_axis(&"move_up", &"move_down") + if horizontal_move != 0.0 or vertical_move != 0.0: + get_root().dispatch(EVENT_FINISHED) diff --git a/demo/agents/player/states/idle_state.gd.uid b/demo/agents/player/states/idle_state.gd.uid new file mode 100644 index 0000000..02047fd --- /dev/null +++ b/demo/agents/player/states/idle_state.gd.uid @@ -0,0 +1 @@ +uid://cig7kaq6hm5nd diff --git a/demo/agents/player/states/move_state.gd b/demo/agents/player/states/move_state.gd new file mode 100644 index 0000000..332732a --- /dev/null +++ b/demo/agents/player/states/move_state.gd @@ -0,0 +1,37 @@ +#* +#* move_state.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +extends LimboState +## Move state. + + +const VERTICAL_FACTOR := 0.8 + +@export var animation_player: AnimationPlayer +@export var animation: StringName +@export var speed: float = 500.0 + + +func _enter() -> void: + animation_player.play(animation, 0.1) + + +func _update(_delta: float) -> void: + var horizontal_move: float = Input.get_axis(&"move_left", &"move_right") + var vertical_move: float = Input.get_axis(&"move_up", &"move_down") + + if not is_zero_approx(horizontal_move): + agent.face_dir(horizontal_move) + + var desired_velocity := Vector2(horizontal_move, vertical_move * VERTICAL_FACTOR) * speed + agent.move(desired_velocity) + + if horizontal_move == 0.0 and vertical_move == 0.0: + get_root().dispatch(EVENT_FINISHED) diff --git a/demo/agents/player/states/move_state.gd.uid b/demo/agents/player/states/move_state.gd.uid new file mode 100644 index 0000000..0739566 --- /dev/null +++ b/demo/agents/player/states/move_state.gd.uid @@ -0,0 +1 @@ +uid://bu4henvxerree diff --git a/demo/agents/scripts/agent_base.gd b/demo/agents/scripts/agent_base.gd new file mode 100644 index 0000000..e17a0e2 --- /dev/null +++ b/demo/agents/scripts/agent_base.gd @@ -0,0 +1,161 @@ +#* +#* agent_base.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +extends CharacterBody2D +## Base agent script that is shared by all agents. + +signal death + +# Resource file to use in summon_minion() method. +const MINION_RESOURCE := "res://demo/agents/03_agent_imp.tscn" + +# Projectile resource. +const NinjaStar := preload("res://demo/agents/ninja_star/ninja_star.tscn") +const Fireball := preload("res://demo/agents/fireball/fireball.tscn") + +var summon_count: int = 0 + +var _frames_since_facing_update: int = 0 +var _is_dead: bool = false +var _moved_this_frame: bool = false + +@onready var animation_player: AnimationPlayer = $AnimationPlayer +@onready var health: Health = $Health +@onready var root: Node2D = $Root +@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D +@onready var summoning_effect: GPUParticles2D = $FX/Summoned + + +func _ready() -> void: + health.damaged.connect(_damaged) + health.death.connect(die) + + +func _physics_process(_delta: float) -> void: + _post_physics_process.call_deferred() + + +func _post_physics_process() -> void: + if not _moved_this_frame: + velocity = lerp(velocity, Vector2.ZERO, 0.5) + _moved_this_frame = false + + +func move(p_velocity: Vector2) -> void: + velocity = lerp(velocity, p_velocity, 0.2) + move_and_slide() + _moved_this_frame = true + + +## Update agent's facing in the velocity direction. +func update_facing() -> void: + _frames_since_facing_update += 1 + if _frames_since_facing_update > 3: + face_dir(velocity.x) + +## Face specified direction. +func face_dir(dir: float) -> void: + if dir > 0.0 and root.scale.x < 0.0: + root.scale.x = 1.0; + _frames_since_facing_update = 0 + if dir < 0.0 and root.scale.x > 0.0: + root.scale.x = -1.0; + _frames_since_facing_update = 0 + +## Returns 1.0 when agent is facing right. +## Returns -1.0 when agent is facing left. +func get_facing() -> float: + return signf(root.scale.x) + + +func throw_ninja_star() -> void: + var ninja_star := NinjaStar.instantiate() + ninja_star.dir = get_facing() + get_parent().add_child(ninja_star) + ninja_star.global_position = global_position + Vector2.RIGHT * 100.0 * get_facing() + + +func spit_fire() -> void: + var fireball := Fireball.instantiate() + fireball.dir = get_facing() + get_parent().add_child(fireball) + fireball.global_position = global_position + Vector2.RIGHT * 100.0 * get_facing() + + +func summon_minion(p_position: Vector2) -> void: + var minion: CharacterBody2D = load(MINION_RESOURCE).instantiate() + get_parent().add_child(minion) + minion.position = p_position + minion.play_summoning_effect() + summon_count += 1 + minion.death.connect(func(): summon_count -= 1) + + +## Method is used when this agent is summoned from the dungeons of the castle AaaAaaAAAAAaaAAaaaaaa +func play_summoning_effect() -> void: + summoning_effect.emitting = true + + +## Is specified position inside the arena (not inside an obstacle)? +func is_good_position(p_position: Vector2) -> bool: + var space_state := get_world_2d().direct_space_state + var params := PhysicsPointQueryParameters2D.new() + params.position = p_position + params.collision_mask = 1 # Obstacle layer has value 1 + var collision := space_state.intersect_point(params) + return collision.is_empty() + + +## When agent is damaged... +func _damaged(_amount: float, knockback: Vector2) -> void: + apply_knockback(knockback) + animation_player.play(&"hurt") + var btplayer := get_node_or_null(^"BTPlayer") as BTPlayer + if btplayer: + btplayer.set_active(false) + var hsm := get_node_or_null(^"LimboHSM") + if hsm: + hsm.set_active(false) + await animation_player.animation_finished + if btplayer and not _is_dead: + btplayer.restart() + if hsm and not _is_dead: + hsm.set_active(true) + + +## Push agent in the knockback direction for the specified number of physics frames. +func apply_knockback(knockback: Vector2, frames: int = 10) -> void: + if knockback.is_zero_approx(): + return + for i in range(frames): + move(knockback) + await get_tree().physics_frame + + +func die() -> void: + if _is_dead: + return + death.emit() + _is_dead = true + root.process_mode = Node.PROCESS_MODE_DISABLED + animation_player.play(&"death") + collision_shape_2d.set_deferred(&"disabled", true) + + for child in get_children(): + if child is BTPlayer or child is LimboHSM: + child.set_active(false) + + if get_tree(): + await get_tree().create_timer(10.0).timeout + queue_free() + + +func get_health() -> Health: + return health diff --git a/demo/agents/scripts/agent_base.gd.uid b/demo/agents/scripts/agent_base.gd.uid new file mode 100644 index 0000000..de3be76 --- /dev/null +++ b/demo/agents/scripts/agent_base.gd.uid @@ -0,0 +1 @@ +uid://68wbhtvlbkqm diff --git a/demo/agents/scripts/health.gd b/demo/agents/scripts/health.gd new file mode 100644 index 0000000..181c36c --- /dev/null +++ b/demo/agents/scripts/health.gd @@ -0,0 +1,46 @@ +#* +#* health.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +class_name Health +extends Node +## Tracks health and emits signal when damaged or dead. + +## Emitted when health is reduced to 0. +signal death + +## Emitted when health is damaged. +signal damaged(amount: float, knockback: Vector2) + +## Initial health value. +@export var max_health: float = 10.0 + +var _current: float + + +func _ready() -> void: + _current = max_health + + +func take_damage(amount: float, knockback: Vector2) -> void: + if _current <= 0.0: + return + + _current -= amount + _current = max(_current, 0.0) + + if _current <= 0.0: + death.emit() + else: + damaged.emit(amount, knockback) + + +## Returns current health. +func get_current() -> float: + return _current diff --git a/demo/agents/scripts/health.gd.uid b/demo/agents/scripts/health.gd.uid new file mode 100644 index 0000000..f0f4973 --- /dev/null +++ b/demo/agents/scripts/health.gd.uid @@ -0,0 +1 @@ +uid://5byn62y1oa76 diff --git a/demo/agents/scripts/hitbox.gd b/demo/agents/scripts/hitbox.gd new file mode 100644 index 0000000..57cb327 --- /dev/null +++ b/demo/agents/scripts/hitbox.gd @@ -0,0 +1,39 @@ +#* +#* hitbox.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +class_name Hitbox +extends Area2D +## Area that deals damage. + +## Damage value to apply. +@export var damage: float = 1.0 + +## Push back the victim. +@export var knockback_enabled: bool = false + +## Desired pushback speed. +@export var knockback_strength: float = 500.0 + + +func _ready() -> void: + area_entered.connect(_area_entered) + + +func _area_entered(hurtbox: Hurtbox) -> void: + if hurtbox.owner == owner: + return + hurtbox.take_damage(damage, get_knockback(), self) + + +func get_knockback() -> Vector2: + var knockback: Vector2 + if knockback_enabled: + knockback = Vector2.RIGHT.rotated(global_rotation) * knockback_strength + return knockback diff --git a/demo/agents/scripts/hitbox.gd.uid b/demo/agents/scripts/hitbox.gd.uid new file mode 100644 index 0000000..b2caad4 --- /dev/null +++ b/demo/agents/scripts/hitbox.gd.uid @@ -0,0 +1 @@ +uid://dntc3c582m5w8 diff --git a/demo/agents/scripts/hurtbox.gd b/demo/agents/scripts/hurtbox.gd new file mode 100644 index 0000000..333497f --- /dev/null +++ b/demo/agents/scripts/hurtbox.gd @@ -0,0 +1,22 @@ +#* +#* hurtbox.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +class_name Hurtbox +extends Area2D +## Area that registers damage. + +@export var health: Health + +var last_attack_vector: Vector2 + + +func take_damage(amount: float, knockback: Vector2, source: Hitbox) -> void: + last_attack_vector = owner.global_position - source.owner.global_position + health.take_damage(amount, knockback) diff --git a/demo/agents/scripts/hurtbox.gd.uid b/demo/agents/scripts/hurtbox.gd.uid new file mode 100644 index 0000000..aef7b56 --- /dev/null +++ b/demo/agents/scripts/hurtbox.gd.uid @@ -0,0 +1 @@ +uid://dq5h6yydckjc1 diff --git a/demo/agents/tutorial/tutorial_01_welcome.tscn b/demo/agents/tutorial/tutorial_01_welcome.tscn new file mode 100644 index 0000000..d9114c2 --- /dev/null +++ b/demo/agents/tutorial/tutorial_01_welcome.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=5 format=3 uid="uid://dk67yawiu33jv"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_2vrmp"] +[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_3h4dj"] +[ext_resource type="BehaviorTree" uid="uid://b1mfh8yad7rmw" path="res://demo/ai/trees/tutorial/tutorial_01_welcome.tres" id="3_ilmgw"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"] + +[node name="TutorialWelcome" instance=ExtResource("1_2vrmp")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_3h4dj") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_3h4dj") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_3h4dj") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_3h4dj") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_3h4dj") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_3h4dj") + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_ilmgw") +blackboard_plan = SubResource("BlackboardPlan_52mdk") diff --git a/demo/agents/tutorial/tutorial_02_introduction.tscn b/demo/agents/tutorial/tutorial_02_introduction.tscn new file mode 100644 index 0000000..f14b0d5 --- /dev/null +++ b/demo/agents/tutorial/tutorial_02_introduction.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=5 format=3 uid="uid://cw3yth564nhrw"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_lia2k"] +[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_4x2l4"] +[ext_resource type="BehaviorTree" uid="uid://b1i0xo0o676va" path="res://demo/ai/trees/tutorial/tutorial_02_introduction.tres" id="3_3esuy"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"] + +[node name="TutorialIntro" instance=ExtResource("1_lia2k")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_4x2l4") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_4x2l4") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_4x2l4") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_4x2l4") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_4x2l4") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_4x2l4") + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_3esuy") +blackboard_plan = SubResource("BlackboardPlan_52mdk") diff --git a/demo/agents/tutorial/tutorial_03_types.tscn b/demo/agents/tutorial/tutorial_03_types.tscn new file mode 100644 index 0000000..3ae6493 --- /dev/null +++ b/demo/agents/tutorial/tutorial_03_types.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=5 format=3 uid="uid://bx4iabilsv3rs"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_p8nwq"] +[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_hnwhw"] +[ext_resource type="BehaviorTree" uid="uid://cb0ybf24ahnc3" path="res://demo/ai/trees/tutorial/tutorial_03_types.tres" id="3_a31ka"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"] + +[node name="TutorialTypes" instance=ExtResource("1_p8nwq")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_hnwhw") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_hnwhw") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_hnwhw") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_hnwhw") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_hnwhw") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_hnwhw") + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_a31ka") +blackboard_plan = SubResource("BlackboardPlan_52mdk") diff --git a/demo/agents/tutorial/tutorial_04_sequence.tscn b/demo/agents/tutorial/tutorial_04_sequence.tscn new file mode 100644 index 0000000..0a7202b --- /dev/null +++ b/demo/agents/tutorial/tutorial_04_sequence.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=5 format=3 uid="uid://bhtm8gnk5hsus"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_oibr1"] +[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_j52yc"] +[ext_resource type="BehaviorTree" uid="uid://dln8ywvtqedt7" path="res://demo/ai/trees/tutorial/tutorial_04_sequence.tres" id="3_feewj"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"] + +[node name="TutorialSequence" instance=ExtResource("1_oibr1")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_j52yc") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_j52yc") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_j52yc") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_j52yc") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_j52yc") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_j52yc") + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_feewj") +blackboard_plan = SubResource("BlackboardPlan_52mdk") diff --git a/demo/agents/tutorial/tutorial_05_selector.tscn b/demo/agents/tutorial/tutorial_05_selector.tscn new file mode 100644 index 0000000..699ab50 --- /dev/null +++ b/demo/agents/tutorial/tutorial_05_selector.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=5 format=3 uid="uid://5nqbasyipupf"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_62fs7"] +[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_gdg2c"] +[ext_resource type="BehaviorTree" uid="uid://bf4r652fv5kwi" path="res://demo/ai/trees/tutorial/tutorial_05_selector.tres" id="3_pm5ep"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"] + +[node name="TutorialSelector" instance=ExtResource("1_62fs7")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_gdg2c") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_gdg2c") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_gdg2c") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_gdg2c") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_gdg2c") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_gdg2c") + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_pm5ep") +blackboard_plan = SubResource("BlackboardPlan_52mdk") diff --git a/demo/agents/tutorial/tutorial_06_decorators.tscn b/demo/agents/tutorial/tutorial_06_decorators.tscn new file mode 100644 index 0000000..c053f21 --- /dev/null +++ b/demo/agents/tutorial/tutorial_06_decorators.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=5 format=3 uid="uid://ehc00upu3co"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_mbrnd"] +[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_ttkri"] +[ext_resource type="BehaviorTree" uid="uid://beiki511huxb8" path="res://demo/ai/trees/tutorial/tutorial_06_decorators.tres" id="3_tpgll"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"] + +[node name="TutorialDecorators" instance=ExtResource("1_mbrnd")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_ttkri") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_ttkri") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_ttkri") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_ttkri") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_ttkri") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_ttkri") + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_tpgll") +blackboard_plan = SubResource("BlackboardPlan_52mdk") diff --git a/demo/agents/tutorial/tutorial_07_more_decorators.tscn b/demo/agents/tutorial/tutorial_07_more_decorators.tscn new file mode 100644 index 0000000..c386580 --- /dev/null +++ b/demo/agents/tutorial/tutorial_07_more_decorators.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=5 format=3 uid="uid://brq6c843j1eeo"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_k4qfc"] +[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_q4r1n"] +[ext_resource type="BehaviorTree" uid="uid://tep50j4d6kgp" path="res://demo/ai/trees/tutorial/tutorial_07_more_decorators.tres" id="3_ta3g6"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"] + +[node name="TutorialMoreDecorators" instance=ExtResource("1_k4qfc")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_q4r1n") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_q4r1n") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_q4r1n") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_q4r1n") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_q4r1n") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_q4r1n") + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_ta3g6") +blackboard_plan = SubResource("BlackboardPlan_52mdk") diff --git a/demo/agents/tutorial/tutorial_08_final_touch.tscn b/demo/agents/tutorial/tutorial_08_final_touch.tscn new file mode 100644 index 0000000..0d2d8a7 --- /dev/null +++ b/demo/agents/tutorial/tutorial_08_final_touch.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=5 format=3 uid="uid://b8yj40s43bw8h"] + +[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_bjdsc"] +[ext_resource type="Texture2D" uid="uid://b0oeqsc0xksto" path="res://demo/assets/agent_junior_pieces.png" id="2_onjfd"] +[ext_resource type="BehaviorTree" uid="uid://dp0cglcytwcj5" path="res://demo/ai/trees/tutorial/tutorial_08_final_touch.tres" id="3_c5qx4"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_52mdk"] + +[node name="TutorialFinalTouch" instance=ExtResource("1_bjdsc")] + +[node name="LegL" parent="Root/Rig" index="1"] +texture = ExtResource("2_onjfd") + +[node name="LegR" parent="Root/Rig" index="2"] +texture = ExtResource("2_onjfd") + +[node name="Body" parent="Root/Rig" index="3"] +texture = ExtResource("2_onjfd") + +[node name="Hat" parent="Root/Rig/Body" index="0"] +texture = ExtResource("2_onjfd") + +[node name="HandL" parent="Root/Rig/Body" index="1"] +texture = ExtResource("2_onjfd") + +[node name="HandR" parent="Root/Rig/Body" index="2"] +texture = ExtResource("2_onjfd") + +[node name="BTPlayer" type="BTPlayer" parent="." index="5"] +behavior_tree = ExtResource("3_c5qx4") +blackboard_plan = SubResource("BlackboardPlan_52mdk") diff --git a/demo/ai/tasks/arrive_pos.gd b/demo/ai/tasks/arrive_pos.gd new file mode 100644 index 0000000..edb53fb --- /dev/null +++ b/demo/ai/tasks/arrive_pos.gd @@ -0,0 +1,69 @@ +#* +#* arrive_pos.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +@tool +extends BTAction +## Moves the agent to the specified position, favoring horizontal movement. [br] +## Returns [code]SUCCESS[/code] when close to the target position (see [member tolerance]); +## otherwise returns [code]RUNNING[/code]. + +## Blackboard variable that stores the target position (Vector2) +@export var target_position_var := &"pos" + +## Variable that stores desired speed (float) +@export var speed_var := &"speed" + +## How close should the agent be to the target position to return SUCCESS. +@export var tolerance := 50.0 + +## Specifies the node to avoid (valid Node2D is expected). +## If not empty, agent will circle around the node while moving into position. +@export var avoid_var: StringName + + +func _generate_name() -> String: + return "Arrive pos: %s%s" % [ + LimboUtility.decorate_var(target_position_var), + "" if avoid_var.is_empty() else " avoid: " + LimboUtility.decorate_var(avoid_var) + ] + + +func _tick(_delta: float) -> Status: + var target_pos: Vector2 = blackboard.get_var(target_position_var, Vector2.ZERO) + if target_pos.distance_to(agent.global_position) < tolerance: + return SUCCESS + + var speed: float = blackboard.get_var(speed_var, 10.0) + var dist: float = absf(agent.global_position.x - target_pos.x) + var dir: Vector2 = agent.global_position.direction_to(target_pos) + + # Prefer horizontal movement: + var vertical_factor: float = remap(dist, 200.0, 500.0, 1.0, 0.0) + vertical_factor = clampf(vertical_factor, 0.0, 1.0) + dir.y *= vertical_factor + + # Avoid the node specified by `avoid_var`. + # I.e., if `avoid_var` is set, agent will circle around that node while moving into position. + if not avoid_var.is_empty(): + var avoid_node: Node2D = blackboard.get_var(avoid_var) + if is_instance_valid(avoid_node): + var distance_vector: Vector2 = avoid_node.global_position - agent.global_position + if dir.dot(distance_vector) > 0.0: + var side := dir.rotated(PI * 0.5).normalized() + # The closer we are to the avoid target, the stronger is the avoidance. + var strength: float = remap(distance_vector.length(), 200.0, 400.0, 1.0, 0.0) + strength = clampf(strength, 0.0, 1.0) + var avoidance := side * signf(-side.dot(distance_vector)) * strength + dir += avoidance + + var desired_velocity: Vector2 = dir.normalized() * speed + agent.move(desired_velocity) + agent.update_facing() + return RUNNING diff --git a/demo/ai/tasks/arrive_pos.gd.uid b/demo/ai/tasks/arrive_pos.gd.uid new file mode 100644 index 0000000..617c159 --- /dev/null +++ b/demo/ai/tasks/arrive_pos.gd.uid @@ -0,0 +1 @@ +uid://df82exuqnfdb2 diff --git a/demo/ai/tasks/back_away.gd b/demo/ai/tasks/back_away.gd new file mode 100644 index 0000000..3b00388 --- /dev/null +++ b/demo/ai/tasks/back_away.gd @@ -0,0 +1,39 @@ +#* +#* back_away.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +@tool +extends BTAction +## Moves the agent in the opposite direction of its current facing. [br] +## Returns [code]RUNNING[/code] always. + +## Blackboard variable that stores desired speed. +@export var speed_var: StringName = &"speed" + +## How much can we deviate from the "away" direction (in radians). +@export var max_angle_deviation: float = 0.7 + +var _dir: Vector2 +var _desired_velocity: Vector2 + + +# Called each time this task is entered. +func _enter() -> void: + # Determine "away" direction and desired velocity + _dir = Vector2.LEFT * agent.get_facing() + var speed: float = blackboard.get_var(speed_var, 200.0) + var rand_angle = randf_range(-max_angle_deviation, max_angle_deviation) + _desired_velocity = _dir.rotated(rand_angle) * speed + + +# Called each time this task is ticked (aka executed). +func _tick(_delta: float) -> Status: + agent.move(_desired_velocity) + agent.face_dir(-signf(_dir.x)) + return RUNNING diff --git a/demo/ai/tasks/back_away.gd.uid b/demo/ai/tasks/back_away.gd.uid new file mode 100644 index 0000000..b456046 --- /dev/null +++ b/demo/ai/tasks/back_away.gd.uid @@ -0,0 +1 @@ +uid://bi5e8366xi5s5 diff --git a/demo/ai/tasks/face_target.gd b/demo/ai/tasks/face_target.gd new file mode 100644 index 0000000..bf07d64 --- /dev/null +++ b/demo/ai/tasks/face_target.gd @@ -0,0 +1,32 @@ +#* +#* face_target.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +@tool +extends BTAction +## Flips the agent to face the target, returning [code]SUCCESS[/code]. [br] +## Returns [code]FAILURE[/code] if [member target_var] is not a valid [Node2D] instance. + +## Blackboard variable that stores our target (expecting Node2D). +@export var target_var: StringName = &"target" + +# Display a customized name (requires @tool). +func _generate_name() -> String: + return "FaceTarget " + LimboUtility.decorate_var(target_var) + + +# Called each time this task is ticked (aka executed). +func _tick(_delta: float) -> Status: + var target: Node2D = blackboard.get_var(target_var) + if not is_instance_valid(target): + return FAILURE + var dir: float = target.global_position.x - agent.global_position.x + agent.velocity = Vector2.ZERO + agent.face_dir(dir) + return SUCCESS diff --git a/demo/ai/tasks/face_target.gd.uid b/demo/ai/tasks/face_target.gd.uid new file mode 100644 index 0000000..eae4fd5 --- /dev/null +++ b/demo/ai/tasks/face_target.gd.uid @@ -0,0 +1 @@ +uid://dbo0kq2cwb4qv diff --git a/demo/ai/tasks/get_first_in_group.gd b/demo/ai/tasks/get_first_in_group.gd new file mode 100644 index 0000000..bd4e642 --- /dev/null +++ b/demo/ai/tasks/get_first_in_group.gd @@ -0,0 +1,34 @@ +#* +#* get_first_in_group.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +@tool +extends BTAction +## Stores the first node in the [member group] on the blackboard, returning [code]SUCCESS[/code]. [br] +## Returns [code]FAILURE[/code] if the group contains 0 nodes. + +## Name of the SceneTree group. +@export var group: StringName + +## Blackboard variable in which the task will store the acquired node. +@export var output_var: StringName = &"target" + + +func _generate_name() -> String: + return "GetFirstNodeInGroup \"%s\" ➜%s" % [ + group, + LimboUtility.decorate_var(output_var) + ] + +func _tick(_delta: float) -> Status: + var nodes: Array[Node] = agent.get_tree().get_nodes_in_group(group) + if nodes.size() == 0: + return FAILURE + blackboard.set_var(output_var, nodes[0]) + return SUCCESS diff --git a/demo/ai/tasks/get_first_in_group.gd.uid b/demo/ai/tasks/get_first_in_group.gd.uid new file mode 100644 index 0000000..0fc8270 --- /dev/null +++ b/demo/ai/tasks/get_first_in_group.gd.uid @@ -0,0 +1 @@ +uid://ccr43pgd4488l diff --git a/demo/ai/tasks/in_range.gd b/demo/ai/tasks/in_range.gd new file mode 100644 index 0000000..0e1eb28 --- /dev/null +++ b/demo/ai/tasks/in_range.gd @@ -0,0 +1,54 @@ +#* +#* in_range.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +@tool +extends BTCondition +## InRange condition checks if the agent is within a range of target, +## defined by [member distance_min] and [member distance_max]. [br] +## Returns [code]SUCCESS[/code] if the agent is within the given range; +## otherwise, returns [code]FAILURE[/code]. + +## Minimum distance to target. +@export var distance_min: float + +## Maximum distance to target. +@export var distance_max: float + +## Blackboard variable that holds the target (expecting Node2D). +@export var target_var: StringName = &"target" + +var _min_distance_squared: float +var _max_distance_squared: float + + +# Called to generate a display name for the task. +func _generate_name() -> String: + return "InRange (%d, %d) of %s" % [distance_min, distance_max, + LimboUtility.decorate_var(target_var)] + + +# Called to initialize the task. +func _setup() -> void: + ## Small performance optimization + _min_distance_squared = distance_min * distance_min + _max_distance_squared = distance_max * distance_max + + +# Called when the task is executed. +func _tick(_delta: float) -> Status: + var target: Node2D = blackboard.get_var(target_var, null) + if not is_instance_valid(target): + return FAILURE + + var dist_sq: float = agent.global_position.distance_squared_to(target.global_position) + if dist_sq >= _min_distance_squared and dist_sq <= _max_distance_squared: + return SUCCESS + else: + return FAILURE diff --git a/demo/ai/tasks/in_range.gd.uid b/demo/ai/tasks/in_range.gd.uid new file mode 100644 index 0000000..c5e1a9a --- /dev/null +++ b/demo/ai/tasks/in_range.gd.uid @@ -0,0 +1 @@ +uid://b7v2utjmtge0x diff --git a/demo/ai/tasks/is_aligned_with_target.gd b/demo/ai/tasks/is_aligned_with_target.gd new file mode 100644 index 0000000..c15ea3a --- /dev/null +++ b/demo/ai/tasks/is_aligned_with_target.gd @@ -0,0 +1,35 @@ +#* +#* is_aligned_with_target.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +@tool +extends BTCondition +## Checks if the agent is horizontally aligned with the target. [br] +## Returns [code]SUCCESS[/code] if the agent is horizontally aligned with the target. +## Returns [code]FAILURE[/code] if not aligned or if target is not a valid node instance. + + +@export var target_var: StringName = &"target" +@export var tolerance: float = 30.0 + + +# Display a customized name (requires @tool). +func _generate_name() -> String: + return "IsAlignedWithTarget " + LimboUtility.decorate_var(target_var) + + +# Called each time this task is ticked (aka executed). +func _tick(_delta: float) -> Status: + var target := blackboard.get_var(target_var) as Node2D + if not is_instance_valid(target): + return FAILURE + var y_diff: float = absf(target.global_position.y - agent.global_position.y) + if y_diff < tolerance: + return SUCCESS + return FAILURE diff --git a/demo/ai/tasks/is_aligned_with_target.gd.uid b/demo/ai/tasks/is_aligned_with_target.gd.uid new file mode 100644 index 0000000..bbfee1c --- /dev/null +++ b/demo/ai/tasks/is_aligned_with_target.gd.uid @@ -0,0 +1 @@ +uid://dbhd2dvt77sm4 diff --git a/demo/ai/tasks/move_forward.gd b/demo/ai/tasks/move_forward.gd new file mode 100644 index 0000000..bac5483 --- /dev/null +++ b/demo/ai/tasks/move_forward.gd @@ -0,0 +1,39 @@ +#* +#* move_forward.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +@tool +extends BTAction +## Applies velocity in the direction the agent is facing on each tick +## until the [member duration] is exceeded. [br] +## Returns [code]SUCCESS[/code] if the elapsed time exceeds [member duration]. [br] +## Returns [code]RUNNING[/code] if the elapsed time does not exceed [member duration]. [br] + +## Blackboard variable that stores desired speed. +@export var speed_var: StringName = &"speed" + +## How long to perform this task (in seconds). +@export var duration: float = 0.1 + +# Display a customized name (requires @tool). +func _generate_name() -> String: + return "MoveForward speed: %s duration: %ss" % [ + LimboUtility.decorate_var(speed_var), + duration] + +# Called each time this task is ticked (aka executed). +func _tick(_delta: float) -> Status: + var facing: float = agent.get_facing() + var speed: float = blackboard.get_var(speed_var, 100.0) + var desired_velocity: Vector2 = Vector2.RIGHT * facing * speed + agent.move(desired_velocity) + agent.update_facing() + if elapsed_time > duration: + return SUCCESS + return RUNNING diff --git a/demo/ai/tasks/move_forward.gd.uid b/demo/ai/tasks/move_forward.gd.uid new file mode 100644 index 0000000..964ef16 --- /dev/null +++ b/demo/ai/tasks/move_forward.gd.uid @@ -0,0 +1 @@ +uid://b8ljqe213ud7d diff --git a/demo/ai/tasks/pursue.gd b/demo/ai/tasks/pursue.gd new file mode 100644 index 0000000..aee5eaa --- /dev/null +++ b/demo/ai/tasks/pursue.gd @@ -0,0 +1,79 @@ +#* +#* pursue.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +@tool +extends BTAction +## Move towards the target until the agent is flanking it. [br] +## Returns [code]RUNNING[/code] while moving towards the target but not yet at the desired position. [br] +## Returns [code]SUCCESS[/code] when at the desired position relative to the target (flanking it). [br] +## Returns [code]FAILURE[/code] if the target is not a valid [Node2D] instance. [br] + +## How close should the agent be to the desired position to return SUCCESS. +const TOLERANCE := 30.0 + +## Blackboard variable that stores our target (expecting Node2D). +@export var target_var: StringName = &"target" + +## Blackboard variable that stores desired speed. +@export var speed_var: StringName = &"speed" + +## Desired distance from target. +@export var approach_distance: float = 100.0 + +var _waypoint: Vector2 + + +# Display a customized name (requires @tool). +func _generate_name() -> String: + return "Pursue %s" % [LimboUtility.decorate_var(target_var)] + + +# Called each time this task is entered. +func _enter() -> void: + var target: Node2D = blackboard.get_var(target_var, null) + if is_instance_valid(target): + # Movement is performed in smaller steps. + # For each step, we select a new waypoint. + _select_new_waypoint(_get_desired_position(target)) + + +# Called each time this task is ticked (aka executed). +func _tick(_delta: float) -> Status: + var target: Node2D = blackboard.get_var(target_var, null) + if not is_instance_valid(target): + return FAILURE + + var desired_pos: Vector2 = _get_desired_position(target) + if agent.global_position.distance_to(desired_pos) < TOLERANCE: + return SUCCESS + + if agent.global_position.distance_to(_waypoint) < TOLERANCE: + _select_new_waypoint(desired_pos) + + var speed: float = blackboard.get_var(speed_var, 200.0) + var desired_velocity: Vector2 = agent.global_position.direction_to(_waypoint) * speed + agent.move(desired_velocity) + agent.update_facing() + return RUNNING + + +## Get the closest flanking position to target. +func _get_desired_position(target: Node2D) -> Vector2: + var side: float = signf(agent.global_position.x - target.global_position.x) + var desired_pos: Vector2 = target.global_position + desired_pos.x += approach_distance * side + return desired_pos + + +## Select an intermidiate waypoint towards the desired position. +func _select_new_waypoint(desired_position: Vector2) -> void: + var distance_vector: Vector2 = desired_position - agent.global_position + var angle_variation: float = randf_range(-0.2, 0.2) + _waypoint = agent.global_position + distance_vector.limit_length(150.0).rotated(angle_variation) diff --git a/demo/ai/tasks/pursue.gd.uid b/demo/ai/tasks/pursue.gd.uid new file mode 100644 index 0000000..443b39e --- /dev/null +++ b/demo/ai/tasks/pursue.gd.uid @@ -0,0 +1 @@ +uid://dcjgktglb1slf diff --git a/demo/ai/tasks/select_flanking_pos.gd b/demo/ai/tasks/select_flanking_pos.gd new file mode 100644 index 0000000..78687ff --- /dev/null +++ b/demo/ai/tasks/select_flanking_pos.gd @@ -0,0 +1,74 @@ +#* +#* select_flanking_pos.gd +#* ============================================================================= +#* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors. +#* +#* 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. +#* ============================================================================= +#* +@tool +extends BTAction +## Selects a position on the target's side and stores it on the +## blackboard, returning [code]SUCCESS[/code]. [br] +## Returns [code]FAILURE[/code] if the target is not valid. + +enum AgentSide { + CLOSEST, + FARTHEST, + BACK, + FRONT, +} + +## Blackboard variable that holds current target (should be a Node2D instance). +@export var target_var: StringName = &"target" + +## Which agent's side should we flank? +@export var flank_side: AgentSide = AgentSide.CLOSEST + +## Minimum range relative to the target. +@export var range_min: int = 300 + +## Maximum range relative to the target. +@export var range_max: int = 400 + +## Blackboard variable that will be used to store selected position. +@export var position_var: StringName = &"pos" + + +# Display a customized name (requires @tool). +func _generate_name() -> String: + return "SelectFlankingPos target: %s range: [%s, %s] side: %s ➜%s" % [ + LimboUtility.decorate_var(target_var), + range_min, + range_max, + AgentSide.keys()[flank_side], + LimboUtility.decorate_var(position_var)] + + +# Called each time this task is ticked (aka executed). +func _tick(_delta: float) -> Status: + var target := blackboard.get_var(target_var) as Node2D + if not is_instance_valid(target): + return FAILURE + + var dir: float # 1.0 is right, -1.0 is left (relative to target) + match flank_side: + AgentSide.FARTHEST: + dir = signf(target.global_position.x - agent.global_position.x) + AgentSide.CLOSEST : + dir = -signf(target.global_position.x - agent.global_position.x) + AgentSide.BACK: + dir = -target.get_facing() + AgentSide.FRONT: + dir = target.get_facing() + + var flank_pos: Vector2 + var offset := Vector2(dir * randf_range(range_min, range_max), 0.0) + flank_pos = target.global_position + offset + if not agent.is_good_position(flank_pos): + # Choose the opposite side if the preferred side is not good (i.e., inside a collision shape). + flank_pos = target.global_position - offset + blackboard.set_var(position_var, flank_pos) + return SUCCESS diff --git a/demo/ai/tasks/select_flanking_pos.gd.uid b/demo/ai/tasks/select_flanking_pos.gd.uid new file mode 100644 index 0000000..314bdc6 --- /dev/null +++ b/demo/ai/tasks/select_flanking_pos.gd.uid @@ -0,0 +1 @@ +uid://ct71h72pech3b diff --git a/demo/ai/tasks/select_random_nearby_pos.gd b/demo/ai/tasks/select_random_nearby_pos.gd new file mode 100644 index 0000000..1b108a5 --- /dev/null +++ b/demo/ai/tasks/select_random_nearby_pos.gd @@ -0,0 +1,34 @@ +@tool +extends BTAction +## Selects a random position nearby within the specified range and stores it on the blackboard. [br] +## Returns [code]SUCCESS[/code]. + +## Minimum distance to the desired position. +@export var range_min: float = 300.0 + +## Maximum distance to the desired position. +@export var range_max: float = 500.0 + +## Blackboard variable that will be used to store the desired position. +@export var position_var: StringName = &"pos" + + +# Display a customized name (requires @tool). +func _generate_name() -> String: + return "SelectRandomNearbyPos range: [%s, %s] ➜%s" % [ + range_min, range_max, + LimboUtility.decorate_var(position_var)] + + +# Called each time this task is ticked (aka executed). +func _tick(_delta: float) -> Status: + var pos: Vector2 + var is_good_position: bool = false + while not is_good_position: + # Randomize until we find a good position (good position == not outside the arena). + var angle: float = randf() * TAU + var rand_distance: float = randf_range(range_min, range_max) + pos = agent.global_position + Vector2(sin(angle), cos(angle)) * rand_distance + is_good_position = agent.is_good_position(pos) + blackboard.set_var(position_var, pos) + return SUCCESS diff --git a/demo/ai/tasks/select_random_nearby_pos.gd.uid b/demo/ai/tasks/select_random_nearby_pos.gd.uid new file mode 100644 index 0000000..3a9684d --- /dev/null +++ b/demo/ai/tasks/select_random_nearby_pos.gd.uid @@ -0,0 +1 @@ +uid://bicxffqmm7ek diff --git a/demo/ai/trees/01_agent_melee_simple.tres b/demo/ai/trees/01_agent_melee_simple.tres new file mode 100644 index 0000000..7f09c7b --- /dev/null +++ b/demo/ai/trees/01_agent_melee_simple.tres @@ -0,0 +1,88 @@ +[gd_resource type="BehaviorTree" load_steps=21 format=3 uid="uid://bpdm5jnegi38"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_2jpsu"] +[ext_resource type="Script" uid="uid://dcjgktglb1slf" path="res://demo/ai/tasks/pursue.gd" id="2_h5db5"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="3_bpmfp"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" + +[sub_resource type="BBNode" id="BBNode_nrd4b"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"] +animation_player = SubResource("BBNode_nrd4b") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"] +min_duration = 0.7 +max_duration = 1.5 + +[sub_resource type="BTSequence" id="BTSequence_yhjh1"] +custom_name = "Pause before action" +children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8")] + +[sub_resource type="BBNode" id="BBNode_wpj6d"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"] +animation_player = SubResource("BBNode_wpj6d") +animation_name = &"walk" +blend = 0.1 + +[sub_resource type="BTAction" id="BTAction_ulbrf"] +script = ExtResource("1_2jpsu") +group = &"player" +output_var = &"target" + +[sub_resource type="BTAction" id="BTAction_a4jqi"] +script = ExtResource("2_h5db5") +target_var = &"target" +speed_var = &"speed" +approach_distance = 100.0 + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"] +time_limit = 2.0 +children = [SubResource("BTAction_a4jqi")] + +[sub_resource type="BTSequence" id="BTSequence_1xfnq"] +custom_name = "Pursue player" +children = [SubResource("BTPlayAnimation_olf37"), SubResource("BTAction_ulbrf"), SubResource("BTTimeLimit_xek5v")] + +[sub_resource type="BTAction" id="BTAction_kidxn"] +script = ExtResource("3_bpmfp") +target_var = &"target" + +[sub_resource type="BTWait" id="BTWait_tadkc"] +duration = 0.1 + +[sub_resource type="BBNode" id="BBNode_s8evu"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ppmxd"] +await_completion = 2.0 +animation_player = SubResource("BBNode_s8evu") +animation_name = &"attack_1" + +[sub_resource type="BTSequence" id="BTSequence_ww5v2"] +custom_name = "Melee attack" +children = [SubResource("BTAction_kidxn"), SubResource("BTWait_tadkc"), SubResource("BTPlayAnimation_ppmxd")] + +[sub_resource type="BTSequence" id="BTSequence_pxl2k"] +children = [SubResource("BTSequence_yhjh1"), SubResource("BTSequence_1xfnq"), SubResource("BTSequence_ww5v2")] + +[resource] +description = "Welcome to the [b]LimboAI[/b] demo project! This demo project consists of three parts: +- If you're new to behavior trees, you can access the [b]Tutorial[/b] by clicking the \"Begin Tutorial\" button on the toolbar. +- To experience the demo game, just click the \"Switch to Game\" button. +- On this screen, you can inspect the AI behavior tree in action for each agent in the game." +blackboard_plan = SubResource("BlackboardPlan_46tbn") +root_task = SubResource("BTSequence_pxl2k") diff --git a/demo/ai/trees/02_agent_charger.tres b/demo/ai/trees/02_agent_charger.tres new file mode 100644 index 0000000..a8458de --- /dev/null +++ b/demo/ai/trees/02_agent_charger.tres @@ -0,0 +1,120 @@ +[gd_resource type="BehaviorTree" load_steps=28 format=3 uid="uid://ylife72ym5et"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_657p6"] +[ext_resource type="Script" uid="uid://ct71h72pech3b" path="res://demo/ai/tasks/select_flanking_pos.gd" id="2_t3udh"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="3_u2ra5"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="4_xwjl7"] +[ext_resource type="Script" uid="uid://b8ljqe213ud7d" path="res://demo/ai/tasks/move_forward.gd" id="5_ucvak"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_qd806"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" +var/charge_speed/name = &"charge_speed" +var/charge_speed/type = 3 +var/charge_speed/value = 1000.0 +var/charge_speed/hint = 1 +var/charge_speed/hint_string = "10,1000,10" + +[sub_resource type="BBNode" id="BBNode_yrurg"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ha2ag"] +animation_player = SubResource("BBNode_yrurg") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_cedqr"] +max_duration = 3.0 + +[sub_resource type="BTSequence" id="BTSequence_l3v31"] +custom_name = "Short break" +children = [SubResource("BTPlayAnimation_ha2ag"), SubResource("BTRandomWait_cedqr")] + +[sub_resource type="BTAction" id="BTAction_pp23y"] +script = ExtResource("1_657p6") +group = &"player" +output_var = &"target" + +[sub_resource type="BTAction" id="BTAction_pmvd0"] +script = ExtResource("2_t3udh") +target_var = &"target" +flank_side = 0 +range_min = 500 +range_max = 600 +position_var = &"flank_pos" + +[sub_resource type="BBNode" id="BBNode_xh3wr"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_h0poo"] +animation_player = SubResource("BBNode_xh3wr") +animation_name = &"walk" +blend = 0.1 + +[sub_resource type="BTAction" id="BTAction_87mi0"] +script = ExtResource("3_u2ra5") +target_position_var = &"flank_pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_is5ag"] +time_limit = 3.0 +children = [SubResource("BTAction_87mi0")] + +[sub_resource type="BTSequence" id="BTSequence_p6pgg"] +custom_name = "Flank target" +children = [SubResource("BTAction_pp23y"), SubResource("BTAction_pmvd0"), SubResource("BTPlayAnimation_h0poo"), SubResource("BTTimeLimit_is5ag")] + +[sub_resource type="BTAction" id="BTAction_q5g4a"] +script = ExtResource("4_xwjl7") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_bfijg"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_4okoy"] +await_completion = 2.0 +animation_player = SubResource("BBNode_bfijg") +animation_name = &"charge_prepare" +blend = 0.1 + +[sub_resource type="BTWait" id="BTWait_ovu3r"] +duration = 0.6 + +[sub_resource type="BTSequence" id="BTSequence_mde2g"] +custom_name = "Anticipation" +children = [SubResource("BTAction_q5g4a"), SubResource("BTPlayAnimation_4okoy"), SubResource("BTWait_ovu3r")] + +[sub_resource type="BBNode" id="BBNode_kpp70"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_8s1wq"] +animation_player = SubResource("BBNode_kpp70") +animation_name = &"charge" +blend = 0.05 + +[sub_resource type="BTAction" id="BTAction_o18uk"] +script = ExtResource("5_ucvak") +speed_var = &"charge_speed" +duration = 1.5 + +[sub_resource type="BTSequence" id="BTSequence_8lur1"] +custom_name = "Charge!" +children = [SubResource("BTPlayAnimation_8s1wq"), SubResource("BTAction_o18uk")] + +[sub_resource type="BTSequence" id="BTSequence_pjuov"] +custom_name = "Charge Attack" +children = [SubResource("BTSequence_l3v31"), SubResource("BTSequence_p6pgg"), SubResource("BTSequence_mde2g"), SubResource("BTSequence_8lur1")] + +[resource] +description = "A [dec]Decorator[/dec] is a type of task that typically has only one child. Decorators are commonly used to alter the behavior or status of their child task. In this behavior tree, the [dec]TimeLimit[/dec] decorator sets a maximum time for the [act]Arrive[/act] action to complete its work. If the child task exceeds this time limit without finishing, it will be aborted, and the TimeLimit decorator will return [FAILURE]." +blackboard_plan = SubResource("BlackboardPlan_qd806") +root_task = SubResource("BTSequence_pjuov") diff --git a/demo/ai/trees/03_agent_imp.tres b/demo/ai/trees/03_agent_imp.tres new file mode 100644 index 0000000..f3e34f3 --- /dev/null +++ b/demo/ai/trees/03_agent_imp.tres @@ -0,0 +1,120 @@ +[gd_resource type="BehaviorTree" load_steps=30 format=3 uid="uid://c2bxoo68ywb27"] + +[ext_resource type="Script" uid="uid://bicxffqmm7ek" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="1_cdtqu"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="2_31fsn"] +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="3_y1r1a"] +[ext_resource type="Script" uid="uid://dcjgktglb1slf" path="res://demo/ai/tasks/pursue.gd" id="4_jlgat"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="5_o4ggh"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" + +[sub_resource type="BBNode" id="BBNode_3y70b"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_klk26"] +animation_player = SubResource("BBNode_3y70b") +animation_name = &"walk" +blend = 0.1 + +[sub_resource type="BTAction" id="BTAction_chmiy"] +script = ExtResource("1_cdtqu") +range_min = 200.0 +range_max = 500.0 +position_var = &"pos" + +[sub_resource type="BTAction" id="BTAction_5kivl"] +script = ExtResource("2_31fsn") +target_position_var = &"pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BTSequence" id="BTSequence_k184c"] +custom_name = "Chaotic Walk" +children = [SubResource("BTPlayAnimation_klk26"), SubResource("BTAction_chmiy"), SubResource("BTAction_5kivl")] + +[sub_resource type="BTProbability" id="BTProbability_ifsry"] +children = [SubResource("BTSequence_k184c")] + +[sub_resource type="BBNode" id="BBNode_nrd4b"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"] +animation_player = SubResource("BBNode_nrd4b") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"] +min_duration = 0.7 +max_duration = 1.5 + +[sub_resource type="BTSequence" id="BTSequence_n5ltc"] +custom_name = "Pause before action" +children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8")] + +[sub_resource type="BBNode" id="BBNode_wpj6d"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"] +animation_player = SubResource("BBNode_wpj6d") +animation_name = &"walk" +blend = 0.1 + +[sub_resource type="BTAction" id="BTAction_ulbrf"] +script = ExtResource("3_y1r1a") +group = &"player" +output_var = &"target" + +[sub_resource type="BTAction" id="BTAction_a4jqi"] +script = ExtResource("4_jlgat") +target_var = &"target" +speed_var = &"speed" +approach_distance = 100.0 + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"] +time_limit = 2.0 +children = [SubResource("BTAction_a4jqi")] + +[sub_resource type="BTSequence" id="BTSequence_1xfnq"] +custom_name = "Pursue player" +children = [SubResource("BTPlayAnimation_olf37"), SubResource("BTAction_ulbrf"), SubResource("BTTimeLimit_xek5v")] + +[sub_resource type="BTAction" id="BTAction_kidxn"] +script = ExtResource("5_o4ggh") +target_var = &"target" + +[sub_resource type="BTWait" id="BTWait_tadkc"] +duration = 0.1 + +[sub_resource type="BBNode" id="BBNode_s8evu"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ppmxd"] +await_completion = 2.0 +animation_player = SubResource("BBNode_s8evu") +animation_name = &"attack_1" + +[sub_resource type="BTSequence" id="BTSequence_ww5v2"] +custom_name = "Melee attack" +children = [SubResource("BTAction_kidxn"), SubResource("BTWait_tadkc"), SubResource("BTPlayAnimation_ppmxd")] + +[sub_resource type="BTSequence" id="BTSequence_pxl2k"] +custom_name = "Engage player" +children = [SubResource("BTSequence_n5ltc"), SubResource("BTSequence_1xfnq"), SubResource("BTSequence_ww5v2")] + +[sub_resource type="BTSelector" id="BTSelector_y3llm"] +children = [SubResource("BTProbability_ifsry"), SubResource("BTSequence_pxl2k")] + +[resource] +description = "Here, the [dec]Probability[/dec] decorator allows the execution of its branch in 50% of cases. This introduces a slight variation to the behavior each time the [comp]Chaotic walk[/comp] sequence is considered by the [comp]Selector[/comp]. This sequence can be selected several times in a row as long as the Probability decorator permits it. The [comp]Engage player[/comp] sequence is only executed if Probability returns [FAILURE]." +blackboard_plan = SubResource("BlackboardPlan_46tbn") +root_task = SubResource("BTSelector_y3llm") diff --git a/demo/ai/trees/04_agent_skirmisher.tres b/demo/ai/trees/04_agent_skirmisher.tres new file mode 100644 index 0000000..0fd6350 --- /dev/null +++ b/demo/ai/trees/04_agent_skirmisher.tres @@ -0,0 +1,190 @@ +[gd_resource type="BehaviorTree" load_steps=44 format=3 uid="uid://qqmjvbeibatn"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_2883n"] +[ext_resource type="Script" uid="uid://ct71h72pech3b" path="res://demo/ai/tasks/select_flanking_pos.gd" id="2_cjso2"] +[ext_resource type="Script" uid="uid://dcjgktglb1slf" path="res://demo/ai/tasks/pursue.gd" id="2_lpckh"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="3_treio"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="4_57x51"] +[ext_resource type="Script" uid="uid://b7v2utjmtge0x" path="res://demo/ai/tasks/in_range.gd" id="5_p5dih"] +[ext_resource type="Script" uid="uid://bi5e8366xi5s5" path="res://demo/ai/tasks/back_away.gd" id="6_fkv0k"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" +var/fast_speed/name = &"fast_speed" +var/fast_speed/type = 3 +var/fast_speed/value = 600.0 +var/fast_speed/hint = 1 +var/fast_speed/hint_string = "10,1000,10" +var/slow_speed/name = &"slow_speed" +var/slow_speed/type = 3 +var/slow_speed/value = 300.0 +var/slow_speed/hint = 1 +var/slow_speed/hint_string = "10,1000,10" + +[sub_resource type="BTAction" id="BTAction_ulbrf"] +script = ExtResource("1_2883n") +group = &"player" +output_var = &"target" + +[sub_resource type="BBNode" id="BBNode_nrd4b"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"] +animation_player = SubResource("BBNode_nrd4b") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"] +min_duration = 2.0 +max_duration = 3.0 + +[sub_resource type="BTSequence" id="BTSequence_yhjh1"] +custom_name = "Summoning sickness" +children = [SubResource("BTAction_ulbrf"), SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8")] + +[sub_resource type="BTRunLimit" id="BTRunLimit_tq3e1"] +children = [SubResource("BTSequence_yhjh1")] + +[sub_resource type="BTCondition" id="BTCondition_uk4dg"] +script = ExtResource("5_p5dih") +distance_min = 0.0 +distance_max = 300.0 +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_7c0g0"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_sty80"] +animation_player = SubResource("BBNode_7c0g0") +animation_name = &"walk" +blend = 0.1 +speed = 1.2 + +[sub_resource type="BTAction" id="BTAction_jryg6"] +script = ExtResource("2_lpckh") +target_var = &"target" +speed_var = &"speed" +approach_distance = 100.0 + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_lkphr"] +time_limit = 1.0 +children = [SubResource("BTAction_jryg6")] + +[sub_resource type="BTAction" id="BTAction_kidxn"] +script = ExtResource("4_57x51") +target_var = &"target" + +[sub_resource type="BTWait" id="BTWait_tadkc"] +duration = 0.2 + +[sub_resource type="BBNode" id="BBNode_kcqly"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_hngi6"] +await_completion = 2.0 +animation_player = SubResource("BBNode_kcqly") +animation_name = &"attack_3" + +[sub_resource type="BTWait" id="BTWait_cm8jy"] +duration = 0.5 + +[sub_resource type="BTSequence" id="BTSequence_ww5v2"] +custom_name = "Melee attack" +children = [SubResource("BTCondition_uk4dg"), SubResource("BTPlayAnimation_sty80"), SubResource("BTTimeLimit_lkphr"), SubResource("BTAction_kidxn"), SubResource("BTWait_tadkc"), SubResource("BTPlayAnimation_hngi6"), SubResource("BTWait_cm8jy")] + +[sub_resource type="BTCooldown" id="BTCooldown_ksvfy"] +duration = 2.0 +children = [SubResource("BTSequence_ww5v2")] + +[sub_resource type="BTCondition" id="BTCondition_fpufi"] +script = ExtResource("5_p5dih") +distance_min = 0.0 +distance_max = 300.0 +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_3iqcf"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ee0ff"] +animation_player = SubResource("BBNode_3iqcf") +animation_name = &"walk" +blend = 0.1 +speed = -0.7 + +[sub_resource type="BTAction" id="BTAction_4ye2y"] +script = ExtResource("6_fkv0k") +speed_var = &"slow_speed" +max_angle_deviation = 0.7 + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_cns1i"] +time_limit = 1.5 +children = [SubResource("BTAction_4ye2y")] + +[sub_resource type="BTAlwaysSucceed" id="BTAlwaysSucceed_nw4ep"] +children = [SubResource("BTTimeLimit_cns1i")] + +[sub_resource type="BBNode" id="BBNode_81x7t"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_e61er"] +animation_player = SubResource("BBNode_81x7t") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_jw0cm"] + +[sub_resource type="BTSequence" id="BTSequence_y12eg"] +custom_name = "Disengage" +children = [SubResource("BTCondition_fpufi"), SubResource("BTPlayAnimation_ee0ff"), SubResource("BTAlwaysSucceed_nw4ep"), SubResource("BTPlayAnimation_e61er"), SubResource("BTRandomWait_jw0cm")] + +[sub_resource type="BBNode" id="BBNode_wpj6d"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"] +animation_player = SubResource("BBNode_wpj6d") +animation_name = &"walk" +blend = 0.1 +speed = 1.2 + +[sub_resource type="BTAction" id="BTAction_g5ayy"] +script = ExtResource("2_cjso2") +target_var = &"target" +flank_side = 2 +range_min = 90 +range_max = 90 +position_var = &"flank_pos" + +[sub_resource type="BTAction" id="BTAction_tv4lt"] +script = ExtResource("3_treio") +target_position_var = &"flank_pos" +speed_var = &"fast_speed" +tolerance = 50.0 +avoid_var = &"target" + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"] +children = [SubResource("BTAction_tv4lt")] + +[sub_resource type="BTSequence" id="BTSequence_rgwic"] +custom_name = "Flank from behind" +children = [SubResource("BTPlayAnimation_olf37"), SubResource("BTAction_g5ayy"), SubResource("BTTimeLimit_xek5v")] + +[sub_resource type="BTSelector" id="BTSelector_2jnau"] +children = [SubResource("BTRunLimit_tq3e1"), SubResource("BTCooldown_ksvfy"), SubResource("BTSequence_y12eg"), SubResource("BTSequence_rgwic")] + +[resource] +description = "Like actions, conditions do not contain child tasks within them. Instead, they evaluate specific criteria and return either a [SUCCESS] or [FAILURE] based on the agent's or environment's state (for example, \"IsLowOnHealth\", \"IsTargetInSight\"). Conditions are commonly employed alongside sequences to interrupt their execution if a particular requirement is not met. + +In our example, if the target is not within the specified range, the [con]InRange[/con] condition will return [FAILURE], causing the [comp]sequence[/comp] to be aborted. +" +blackboard_plan = SubResource("BlackboardPlan_46tbn") +root_task = SubResource("BTSelector_2jnau") diff --git a/demo/ai/trees/05_agent_ranged.tres b/demo/ai/trees/05_agent_ranged.tres new file mode 100644 index 0000000..afdc814 --- /dev/null +++ b/demo/ai/trees/05_agent_ranged.tres @@ -0,0 +1,182 @@ +[gd_resource type="BehaviorTree" load_steps=41 format=3 uid="uid://cqluon1y1hnn5"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_4xk1i"] +[ext_resource type="Script" uid="uid://dbhd2dvt77sm4" path="res://demo/ai/tasks/is_aligned_with_target.gd" id="2_a8qex"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="3_q4r2p"] +[ext_resource type="Script" uid="uid://ct71h72pech3b" path="res://demo/ai/tasks/select_flanking_pos.gd" id="4_53hao"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="5_aexyq"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" +var/run_speed/name = &"run_speed" +var/run_speed/type = 3 +var/run_speed/value = 600.0 +var/run_speed/hint = 1 +var/run_speed/hint_string = "10,1000,10" + +[sub_resource type="BBNode" id="BBNode_nrd4b"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"] +animation_player = SubResource("BBNode_nrd4b") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"] +min_duration = 0.7 +max_duration = 1.5 + +[sub_resource type="BTAction" id="BTAction_c4cxo"] +script = ExtResource("1_4xk1i") +group = &"player" +output_var = &"target" + +[sub_resource type="BTSequence" id="BTSequence_yhjh1"] +custom_name = "Take a break" +children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8"), SubResource("BTAction_c4cxo")] + +[sub_resource type="BBNode" id="BBNode_ok0r5"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_unftu"] +animation_player = SubResource("BBNode_ok0r5") +animation_name = &"walk" +blend = 0.1 +speed = 1.5 + +[sub_resource type="BTAction" id="BTAction_op6l6"] +script = ExtResource("4_53hao") +target_var = &"target" +flank_side = 1 +range_min = 400 +range_max = 1000 +position_var = &"pos" + +[sub_resource type="BTAction" id="BTAction_ycjun"] +script = ExtResource("3_q4r2p") +target_position_var = &"pos" +speed_var = &"run_speed" +tolerance = 50.0 +avoid_var = &"target" + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_gadc6"] +time_limit = 7.0 +children = [SubResource("BTAction_ycjun")] + +[sub_resource type="BTAction" id="BTAction_poqpu"] +script = ExtResource("5_aexyq") +target_var = &"target" + +[sub_resource type="BTSequence" id="BTSequence_0gdqn"] +custom_name = "Change flank" +children = [SubResource("BTPlayAnimation_unftu"), SubResource("BTAction_op6l6"), SubResource("BTTimeLimit_gadc6"), SubResource("BTAction_poqpu")] + +[sub_resource type="BTCooldown" id="BTCooldown_2lneu"] +duration = 7.0 +children = [SubResource("BTSequence_0gdqn")] + +[sub_resource type="BTProbability" id="BTProbability_6sydk"] +run_chance = 0.3 +children = [SubResource("BTCooldown_2lneu")] + +[sub_resource type="BTAction" id="BTAction_kuuw2"] +script = ExtResource("4_53hao") +target_var = &"target" +flank_side = 0 +range_min = 400 +range_max = 1000 +position_var = &"shoot_pos" + +[sub_resource type="BBNode" id="BBNode_kc64r"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_panch"] +animation_player = SubResource("BBNode_kc64r") +animation_name = &"walk" +blend = 0.1 + +[sub_resource type="BTAction" id="BTAction_66hsk"] +script = ExtResource("3_q4r2p") +target_position_var = &"shoot_pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_24ath"] +children = [SubResource("BTAction_66hsk")] + +[sub_resource type="BTAction" id="BTAction_enw2m"] +script = ExtResource("5_aexyq") +target_var = &"target" + +[sub_resource type="BTCondition" id="BTCondition_1fnyc"] +script = ExtResource("2_a8qex") +target_var = &"target" +tolerance = 150.0 + +[sub_resource type="BBNode" id="BBNode_s6vt4"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qa8jy"] +animation_player = SubResource("BBNode_s6vt4") +animation_name = &"throw_prepare" +blend = 0.1 + +[sub_resource type="BTWait" id="BTWait_gbcyb"] + +[sub_resource type="BBNode" id="BBNode_qkfqt"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_0ktds"] +await_completion = 1.0 +animation_player = SubResource("BBNode_qkfqt") +animation_name = &"throw" +blend = 0.05 + +[sub_resource type="BBNode" id="BBNode_1yxc5"] +saved_value = NodePath(".") +resource_name = "." + +[sub_resource type="BTCallMethod" id="BTCallMethod_yx4fk"] +node = SubResource("BBNode_1yxc5") +method = &"throw_ninja_star" + +[sub_resource type="BTWait" id="BTWait_d2ib4"] +duration = 0.2 + +[sub_resource type="BTSequence" id="BTSequence_rgbq3"] +custom_name = "Throw ninja star" +children = [SubResource("BTPlayAnimation_qa8jy"), SubResource("BTWait_gbcyb"), SubResource("BTPlayAnimation_0ktds"), SubResource("BTCallMethod_yx4fk"), SubResource("BTWait_d2ib4")] +metadata/_weight_ = 1.0 + +[sub_resource type="BTRepeat" id="BTRepeat_g08ia"] +times = 3 +children = [SubResource("BTSequence_rgbq3")] + +[sub_resource type="BTSequence" id="BTSequence_lhg7f"] +custom_name = "Get into position" +children = [SubResource("BTAction_kuuw2"), SubResource("BTPlayAnimation_panch"), SubResource("BTTimeLimit_24ath"), SubResource("BTAction_enw2m"), SubResource("BTCondition_1fnyc"), SubResource("BTRepeat_g08ia")] +metadata/_weight_ = 1.0 + +[sub_resource type="BTSelector" id="BTSelector_1rrya"] +children = [SubResource("BTProbability_6sydk"), SubResource("BTSequence_lhg7f")] + +[sub_resource type="BTSequence" id="BTSequence_pxl2k"] +custom_name = "Main" +children = [SubResource("BTSequence_yhjh1"), SubResource("BTSelector_1rrya")] + +[resource] +description = "Here, the [dec]Probability[/dec] decorator permits the execution of its branch in 30% of cases. This introduces a slight variation to the behavior each time the \"Change flank\" sequence is considered by the [comp]Selector[/comp]. + +The [dec]Repeat[/dec] decorator is handy for doing something multiple times within a behavior tree. In our example, it's used to make the [comp]Throw ninja star[/comp] sequence perform three times in a row." +blackboard_plan = SubResource("BlackboardPlan_46tbn") +root_task = SubResource("BTSequence_pxl2k") diff --git a/demo/ai/trees/06_agent_melee_combo.tres b/demo/ai/trees/06_agent_melee_combo.tres new file mode 100644 index 0000000..9158f4f --- /dev/null +++ b/demo/ai/trees/06_agent_melee_combo.tres @@ -0,0 +1,163 @@ +[gd_resource type="BehaviorTree" load_steps=39 format=3 uid="uid://cpncl1db8j12f"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_sf4l8"] +[ext_resource type="Script" uid="uid://ct71h72pech3b" path="res://demo/ai/tasks/select_flanking_pos.gd" id="2_5nwkp"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="3_3tom2"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="4_hi228"] +[ext_resource type="Script" uid="uid://b8ljqe213ud7d" path="res://demo/ai/tasks/move_forward.gd" id="5_au5yc"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" +var/charge_speed/name = &"charge_speed" +var/charge_speed/type = 3 +var/charge_speed/value = 1000.0 +var/charge_speed/hint = 0 +var/charge_speed/hint_string = "" + +[sub_resource type="BBNode" id="BBNode_nrd4b"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"] +animation_player = SubResource("BBNode_nrd4b") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"] +min_duration = 0.7 +max_duration = 1.5 + +[sub_resource type="BTAction" id="BTAction_ulbrf"] +script = ExtResource("1_sf4l8") +group = &"player" +output_var = &"target" + +[sub_resource type="BTSequence" id="BTSequence_yhjh1"] +custom_name = "Pause before action" +children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8"), SubResource("BTAction_ulbrf")] + +[sub_resource type="BTAction" id="BTAction_85keo"] +script = ExtResource("2_5nwkp") +target_var = &"target" +flank_side = 0 +range_min = 300 +range_max = 400 +position_var = &"pos" + +[sub_resource type="BBNode" id="BBNode_wpj6d"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"] +animation_player = SubResource("BBNode_wpj6d") +animation_name = &"walk" +blend = 0.1 + +[sub_resource type="BTAction" id="BTAction_ygjnc"] +script = ExtResource("3_3tom2") +target_position_var = &"pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"] +children = [SubResource("BTAction_ygjnc")] + +[sub_resource type="BTSequence" id="BTSequence_1xfnq"] +custom_name = "Align with player" +children = [SubResource("BTAction_85keo"), SubResource("BTPlayAnimation_olf37"), SubResource("BTTimeLimit_xek5v")] + +[sub_resource type="BTAction" id="BTAction_kidxn"] +script = ExtResource("4_hi228") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_giv5l"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_usdja"] +animation_player = SubResource("BBNode_giv5l") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTWait" id="BTWait_tadkc"] +duration = 0.4 + +[sub_resource type="BBNode" id="BBNode_s8evu"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ppmxd"] +await_completion = 2.0 +animation_player = SubResource("BBNode_s8evu") +animation_name = &"attack_1" + +[sub_resource type="BTAction" id="BTAction_u22bc"] +script = ExtResource("5_au5yc") +speed_var = &"charge_speed" +duration = 0.1 + +[sub_resource type="BTParallel" id="BTParallel_ec2e3"] +num_successes_required = 2 +children = [SubResource("BTPlayAnimation_ppmxd"), SubResource("BTAction_u22bc")] + +[sub_resource type="BTWait" id="BTWait_c0lo0"] +duration = 0.2 + +[sub_resource type="BBNode" id="BBNode_3oljv"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_q4uis"] +await_completion = 2.0 +animation_player = SubResource("BBNode_3oljv") +animation_name = &"attack_2" + +[sub_resource type="BTAction" id="BTAction_yuxl3"] +script = ExtResource("5_au5yc") +speed_var = &"charge_speed" +duration = 0.1 + +[sub_resource type="BTParallel" id="BTParallel_thojy"] +num_successes_required = 2 +children = [SubResource("BTPlayAnimation_q4uis"), SubResource("BTAction_yuxl3")] + +[sub_resource type="BTWait" id="BTWait_y3pmv"] +duration = 0.2 + +[sub_resource type="BBNode" id="BBNode_ot40l"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ye5pt"] +await_completion = 2.0 +animation_player = SubResource("BBNode_ot40l") +animation_name = &"attack_3" + +[sub_resource type="BTAction" id="BTAction_rwp18"] +script = ExtResource("5_au5yc") +speed_var = &"charge_speed" +duration = 0.1 + +[sub_resource type="BTParallel" id="BTParallel_qmdfb"] +num_successes_required = 2 +children = [SubResource("BTPlayAnimation_ye5pt"), SubResource("BTAction_rwp18")] + +[sub_resource type="BTWait" id="BTWait_nxyko"] +duration = 0.5 + +[sub_resource type="BTSequence" id="BTSequence_ww5v2"] +custom_name = "Combo Melee attack" +children = [SubResource("BTAction_kidxn"), SubResource("BTPlayAnimation_usdja"), SubResource("BTWait_tadkc"), SubResource("BTParallel_ec2e3"), SubResource("BTWait_c0lo0"), SubResource("BTParallel_thojy"), SubResource("BTWait_y3pmv"), SubResource("BTParallel_qmdfb"), SubResource("BTWait_nxyko")] + +[sub_resource type="BTSequence" id="BTSequence_pxl2k"] +children = [SubResource("BTSequence_yhjh1"), SubResource("BTSequence_1xfnq"), SubResource("BTSequence_ww5v2")] + +[resource] +description = "In some scenarios, you might need to execute multiple tasks at the same time until specific conditions are fulfilled. To achieve this, the [comp]Parallel[/comp] composite is an invaluable tool. This composite task allows its children to be executed simultaneously during each tick until a specified number of successes or failures is reached. In this example, it will execute both the [act]PlayAnimation[/act] and [act]MoveForward[/act] actions each tick until both actions have finished with a [SUCCESS] status." +blackboard_plan = SubResource("BlackboardPlan_46tbn") +root_task = SubResource("BTSequence_pxl2k") diff --git a/demo/ai/trees/07_agent_melee_nuanced.tres b/demo/ai/trees/07_agent_melee_nuanced.tres new file mode 100644 index 0000000..8a7b074 --- /dev/null +++ b/demo/ai/trees/07_agent_melee_nuanced.tres @@ -0,0 +1,219 @@ +[gd_resource type="BehaviorTree" load_steps=49 format=3 uid="uid://c2u6sljqkim0n"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_08fik"] +[ext_resource type="Script" uid="uid://ct71h72pech3b" path="res://demo/ai/tasks/select_flanking_pos.gd" id="2_te3yo"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="3_svwk8"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="4_mvsyw"] +[ext_resource type="Script" uid="uid://dcjgktglb1slf" path="res://demo/ai/tasks/pursue.gd" id="5_r1ou0"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_46tbn"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" +var/flank_speed/name = &"flank_speed" +var/flank_speed/type = 3 +var/flank_speed/value = 600.0 +var/flank_speed/hint = 1 +var/flank_speed/hint_string = "10,1000,10" + +[sub_resource type="BBNode" id="BBNode_nrd4b"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"] +animation_player = SubResource("BBNode_nrd4b") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_xlud8"] +min_duration = 0.7 +max_duration = 1.5 + +[sub_resource type="BTAction" id="BTAction_c4cxo"] +script = ExtResource("1_08fik") +group = &"player" +output_var = &"target" + +[sub_resource type="BTSequence" id="BTSequence_yhjh1"] +custom_name = "Pause before action" +children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8"), SubResource("BTAction_c4cxo")] + +[sub_resource type="BBNode" id="BBNode_kc64r"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_panch"] +animation_player = SubResource("BBNode_kc64r") +animation_name = &"walk" +blend = 0.1 +speed = 1.5 + +[sub_resource type="BTAction" id="BTAction_6e48s"] +script = ExtResource("2_te3yo") +target_var = &"target" +flank_side = 1 +range_min = 400 +range_max = 600 +position_var = &"flank_pos" + +[sub_resource type="BTAction" id="BTAction_66hsk"] +script = ExtResource("3_svwk8") +target_position_var = &"flank_pos" +speed_var = &"flank_speed" +tolerance = 50.0 +avoid_var = &"target" + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_24ath"] +children = [SubResource("BTAction_66hsk")] + +[sub_resource type="BTAction" id="BTAction_enw2m"] +script = ExtResource("4_mvsyw") +target_var = &"target" + +[sub_resource type="BTSequence" id="BTSequence_lhg7f"] +custom_name = "Flank player" +children = [SubResource("BTPlayAnimation_panch"), SubResource("BTAction_6e48s"), SubResource("BTTimeLimit_24ath"), SubResource("BTAction_enw2m")] +metadata/_weight_ = 1.0 + +[sub_resource type="BTCooldown" id="BTCooldown_skw41"] +duration = 6.0 +children = [SubResource("BTSequence_lhg7f")] +metadata/_weight_ = 2.0 + +[sub_resource type="BBNode" id="BBNode_wpj6d"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"] +animation_player = SubResource("BBNode_wpj6d") +animation_name = &"walk" +blend = 0.1 + +[sub_resource type="BTAction" id="BTAction_a4jqi"] +script = ExtResource("5_r1ou0") +target_var = &"target" +speed_var = &"speed" +approach_distance = 100.0 + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"] +time_limit = 2.0 +children = [SubResource("BTAction_a4jqi")] + +[sub_resource type="BTAction" id="BTAction_kidxn"] +script = ExtResource("4_mvsyw") +target_var = &"target" + +[sub_resource type="BTWait" id="BTWait_tadkc"] +duration = 0.1 + +[sub_resource type="BBNode" id="BBNode_g8qww"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_a8yqu"] +await_completion = 2.0 +animation_player = SubResource("BBNode_g8qww") +animation_name = &"attack_2" + +[sub_resource type="BTWait" id="BTWait_vjstl"] +duration = 0.1 + +[sub_resource type="BBNode" id="BBNode_rfop0"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_8oyw6"] +await_completion = 2.0 +animation_player = SubResource("BBNode_rfop0") +animation_name = &"attack_3" + +[sub_resource type="BTSequence" id="BTSequence_1xfnq"] +custom_name = "Approach and melee attack" +children = [SubResource("BTPlayAnimation_olf37"), SubResource("BTTimeLimit_xek5v"), SubResource("BTAction_kidxn"), SubResource("BTWait_tadkc"), SubResource("BTPlayAnimation_a8yqu"), SubResource("BTWait_vjstl"), SubResource("BTPlayAnimation_8oyw6")] +metadata/_weight_ = 4.0 + +[sub_resource type="BTAction" id="BTAction_mf87t"] +script = ExtResource("2_te3yo") +target_var = &"target" +flank_side = 0 +range_min = 350 +range_max = 600 +position_var = &"pos" + +[sub_resource type="BBNode" id="BBNode_cx111"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_mfbeu"] +animation_player = SubResource("BBNode_cx111") +animation_name = &"walk" +blend = 0.1 + +[sub_resource type="BTAction" id="BTAction_6nx58"] +script = ExtResource("3_svwk8") +target_position_var = &"pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_tidwl"] +time_limit = 3.0 +children = [SubResource("BTAction_6nx58")] + +[sub_resource type="BTAction" id="BTAction_8q20y"] +script = ExtResource("4_mvsyw") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_s6vt4"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qa8jy"] +animation_player = SubResource("BBNode_s6vt4") +animation_name = &"throw_prepare" +blend = 0.1 +speed = 0.7 + +[sub_resource type="BTWait" id="BTWait_gbcyb"] + +[sub_resource type="BBNode" id="BBNode_qkfqt"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_0ktds"] +await_completion = 1.0 +animation_player = SubResource("BBNode_qkfqt") +animation_name = &"throw" +blend = 0.05 + +[sub_resource type="BBNode" id="BBNode_1yxc5"] +saved_value = NodePath(".") +resource_name = "." + +[sub_resource type="BTCallMethod" id="BTCallMethod_yx4fk"] +node = SubResource("BBNode_1yxc5") +method = &"throw_ninja_star" + +[sub_resource type="BTRandomWait" id="BTRandomWait_2pmoe"] +max_duration = 1.5 + +[sub_resource type="BTSequence" id="BTSequence_rgbq3"] +custom_name = "Throw ninja star" +children = [SubResource("BTAction_mf87t"), SubResource("BTPlayAnimation_mfbeu"), SubResource("BTTimeLimit_tidwl"), SubResource("BTAction_8q20y"), SubResource("BTPlayAnimation_qa8jy"), SubResource("BTWait_gbcyb"), SubResource("BTPlayAnimation_0ktds"), SubResource("BTCallMethod_yx4fk"), SubResource("BTRandomWait_2pmoe")] +metadata/_weight_ = 2.0 + +[sub_resource type="BTProbabilitySelector" id="BTProbabilitySelector_rjsiq"] +abort_on_failure = true +children = [SubResource("BTCooldown_skw41"), SubResource("BTSequence_1xfnq"), SubResource("BTSequence_rgbq3")] + +[sub_resource type="BTSequence" id="BTSequence_pxl2k"] +custom_name = "Main" +children = [SubResource("BTSequence_yhjh1"), SubResource("BTProbabilitySelector_rjsiq")] + +[resource] +description = "[comp]ProbabilitySelector[/comp] chooses a child task to execute based on attached probabilities. Probability distribution is calculated based on weights assigned to each child task. +" +blackboard_plan = SubResource("BlackboardPlan_46tbn") +root_task = SubResource("BTSequence_pxl2k") diff --git a/demo/ai/trees/08_agent_demon.tres b/demo/ai/trees/08_agent_demon.tres new file mode 100644 index 0000000..c45489c --- /dev/null +++ b/demo/ai/trees/08_agent_demon.tres @@ -0,0 +1,200 @@ +[gd_resource type="BehaviorTree" load_steps=49 format=3 uid="uid://cpcnbi81jqge4"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_ce4la"] +[ext_resource type="Script" uid="uid://b7v2utjmtge0x" path="res://demo/ai/tasks/in_range.gd" id="2_atyuj"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="3_3mw7l"] +[ext_resource type="Script" uid="uid://bi5e8366xi5s5" path="res://demo/ai/tasks/back_away.gd" id="4_6dr32"] +[ext_resource type="Script" uid="uid://ct71h72pech3b" path="res://demo/ai/tasks/select_flanking_pos.gd" id="5_dho0d"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="6_0pfsl"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_8ay3j"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" + +[sub_resource type="BBNode" id="BBNode_lpri5"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_p3e7a"] +animation_player = SubResource("BBNode_lpri5") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_j6cjm"] +min_duration = 2.0 +max_duration = 3.0 + +[sub_resource type="BTSequence" id="BTSequence_5thv4"] +custom_name = "Chill" +children = [SubResource("BTPlayAnimation_p3e7a"), SubResource("BTRandomWait_j6cjm")] + +[sub_resource type="BTCooldown" id="BTCooldown_oms7a"] +trigger_on_failure = true +children = [SubResource("BTSequence_5thv4")] + +[sub_resource type="BTAction" id="BTAction_ohfp7"] +script = ExtResource("1_ce4la") +group = &"player" +output_var = &"target" + +[sub_resource type="BTCondition" id="BTCondition_7a5nv"] +script = ExtResource("2_atyuj") +distance_min = 0.0 +distance_max = 150.0 +target_var = &"target" + +[sub_resource type="BTAction" id="BTAction_ddvrs"] +script = ExtResource("3_3mw7l") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_c4nfu"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_yytkn"] +await_completion = 3.0 +animation_player = SubResource("BBNode_c4nfu") +animation_name = &"attack_3" +blend = 0.1 + +[sub_resource type="BTCooldown" id="BTCooldown_ejg6q"] +duration = 3.0 +children = [SubResource("BTPlayAnimation_yytkn")] + +[sub_resource type="BTSequence" id="BTSequence_eikr4"] +custom_name = "Melee" +children = [SubResource("BTAction_ohfp7"), SubResource("BTCondition_7a5nv"), SubResource("BTAction_ddvrs"), SubResource("BTCooldown_ejg6q")] + +[sub_resource type="BTCondition" id="BTCondition_h75v8"] +script = ExtResource("2_atyuj") +distance_min = 0.0 +distance_max = 300.0 +target_var = &"target" + +[sub_resource type="BTAction" id="BTAction_wpt7j"] +script = ExtResource("3_3mw7l") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_iv62h"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wnaul"] +animation_player = SubResource("BBNode_iv62h") +animation_name = &"walk" +blend = 0.1 +speed = -1.0 + +[sub_resource type="BTAction" id="BTAction_h2efl"] +script = ExtResource("4_6dr32") +speed_var = &"speed" +max_angle_deviation = 0.7 + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_wm5g2"] +time_limit = 1.0 +children = [SubResource("BTAction_h2efl")] + +[sub_resource type="BTSequence" id="BTSequence_wh4dl"] +custom_name = "Back away" +children = [SubResource("BTCondition_h75v8"), SubResource("BTAction_wpt7j"), SubResource("BTPlayAnimation_wnaul"), SubResource("BTTimeLimit_wm5g2")] + +[sub_resource type="BTComment" id="BTComment_mqte5"] +custom_name = "Get into position" + +[sub_resource type="BBNode" id="BBNode_edmui"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_vjtpq"] +animation_player = SubResource("BBNode_edmui") +animation_name = &"walk" +blend = 0.1 + +[sub_resource type="BTAction" id="BTAction_4mmh0"] +script = ExtResource("5_dho0d") +target_var = &"target" +flank_side = 0 +range_min = 300 +range_max = 700 +position_var = &"pos" + +[sub_resource type="BTAction" id="BTAction_vb5c3"] +script = ExtResource("6_0pfsl") +target_position_var = &"pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_jyks2"] +children = [SubResource("BTAction_vb5c3")] + +[sub_resource type="BTComment" id="BTComment_ym6nj"] +custom_name = "Short break before action" + +[sub_resource type="BTAction" id="BTAction_fkevy"] +script = ExtResource("3_3mw7l") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_lh25u"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_vcjeq"] +animation_player = SubResource("BBNode_lh25u") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTWait" id="BTWait_42smh"] +duration = 0.2 + +[sub_resource type="BTComment" id="BTComment_nbp2b"] +custom_name = "Spit fire!" + +[sub_resource type="BBNode" id="BBNode_cqw71"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_214yn"] +await_completion = 3.0 +animation_player = SubResource("BBNode_cqw71") +animation_name = &"spit" +blend = 0.1 + +[sub_resource type="BBNode" id="BBNode_dv5b5"] +saved_value = NodePath(".") +resource_name = "." + +[sub_resource type="BTCallMethod" id="BTCallMethod_lk7i6"] +node = SubResource("BBNode_dv5b5") +method = &"spit_fire" + +[sub_resource type="BTComment" id="BTComment_fndxk"] +custom_name = "Wind down" + +[sub_resource type="BBNode" id="BBNode_m68ui"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_m7gyp"] +animation_player = SubResource("BBNode_m68ui") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_v0el8"] +min_duration = 0.7 +max_duration = 1.5 + +[sub_resource type="BTSequence" id="BTSequence_djtph"] +custom_name = "Spit fire" +children = [SubResource("BTComment_mqte5"), SubResource("BTPlayAnimation_vjtpq"), SubResource("BTAction_4mmh0"), SubResource("BTTimeLimit_jyks2"), SubResource("BTComment_ym6nj"), SubResource("BTAction_fkevy"), SubResource("BTPlayAnimation_vcjeq"), SubResource("BTWait_42smh"), SubResource("BTComment_nbp2b"), SubResource("BTPlayAnimation_214yn"), SubResource("BTCallMethod_lk7i6"), SubResource("BTComment_fndxk"), SubResource("BTPlayAnimation_m7gyp"), SubResource("BTRandomWait_v0el8")] + +[sub_resource type="BTSelector" id="BTSelector_feba6"] +children = [SubResource("BTCooldown_oms7a"), SubResource("BTSequence_eikr4"), SubResource("BTSequence_wh4dl"), SubResource("BTSequence_djtph")] + +[resource] +description = "Here, we use the [con]InRange[/con] condition task together with [comp]Sequence[/comp] and [comp]Selector[/comp] to create a reactive behavior for this agent. When the player comes close, this agent will attempt to hit them with a melee attack and move away afterward for a better ranged position." +blackboard_plan = SubResource("BlackboardPlan_8ay3j") +root_task = SubResource("BTSelector_feba6") diff --git a/demo/ai/trees/09_agent_summoner.tres b/demo/ai/trees/09_agent_summoner.tres new file mode 100644 index 0000000..825f62b --- /dev/null +++ b/demo/ai/trees/09_agent_summoner.tres @@ -0,0 +1,155 @@ +[gd_resource type="BehaviorTree" load_steps=35 format=3 uid="uid://cpxk7jnqpwwlc"] + +[ext_resource type="Script" uid="uid://bicxffqmm7ek" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="1_sgn0p"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="2_pshl2"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_58oq1"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 300.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" +var/summon_cooldown/name = &"summon_cooldown" +var/summon_cooldown/type = 1 +var/summon_cooldown/value = false +var/summon_cooldown/hint = 0 +var/summon_cooldown/hint_string = "" + +[sub_resource type="BBNode" id="BBNode_b7euf"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_sot6a"] +animation_player = SubResource("BBNode_b7euf") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_0wc6p"] + +[sub_resource type="BTSequence" id="BTSequence_kwkxc"] +custom_name = "Summoning sickness" +children = [SubResource("BTPlayAnimation_sot6a"), SubResource("BTRandomWait_0wc6p")] + +[sub_resource type="BTRunLimit" id="BTRunLimit_x2jr4"] +children = [SubResource("BTSequence_kwkxc")] + +[sub_resource type="BBVariant" id="BBVariant_y3x7n"] +type = 2 +saved_value = 6 +resource_name = "6" + +[sub_resource type="BTCheckAgentProperty" id="BTCheckAgentProperty_olmdj"] +property = &"summon_count" +check_type = 1 +value = SubResource("BBVariant_y3x7n") + +[sub_resource type="BTComment" id="BTComment_ef6y0"] +custom_name = "Variable $summon_cooldown is updated by the Cooldown task below" + +[sub_resource type="BBVariant" id="BBVariant_hgde2"] +type = 1 +saved_value = false +resource_name = "false" + +[sub_resource type="BTCheckVar" id="BTCheckVar_hc3o3"] +variable = &"summon_cooldown" +value = SubResource("BBVariant_hgde2") +children = [SubResource("BTComment_ef6y0")] + +[sub_resource type="BBNode" id="BBNode_q8bei"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_6leni"] +animation_player = SubResource("BBNode_q8bei") +animation_name = &"summon" +blend = 0.1 + +[sub_resource type="BTWait" id="BTWait_8og18"] +duration = 0.5 + +[sub_resource type="BTAction" id="BTAction_yeyns"] +script = ExtResource("1_sgn0p") +range_min = 300.0 +range_max = 500.0 +position_var = &"minion_pos" + +[sub_resource type="BBVariant" id="BBVariant_wfjwy"] +type = 5 +value_source = 1 +variable = &"minion_pos" +resource_name = "$minion_pos" + +[sub_resource type="BBNode" id="BBNode_v271m"] +saved_value = NodePath(".") +resource_name = "." + +[sub_resource type="BTCallMethod" id="BTCallMethod_4ath5"] +node = SubResource("BBNode_v271m") +method = &"summon_minion" +args = Array[BBVariant]([SubResource("BBVariant_wfjwy")]) + +[sub_resource type="BTCooldown" id="BTCooldown_25f70"] +duration = 6.0 +cooldown_state_var = &"summon_cooldown" +children = [SubResource("BTCallMethod_4ath5")] + +[sub_resource type="BTWait" id="BTWait_tdhfn"] + +[sub_resource type="BTSequence" id="BTSequence_2n742"] +custom_name = "Summon minion" +children = [SubResource("BTCheckAgentProperty_olmdj"), SubResource("BTCheckVar_hc3o3"), SubResource("BTPlayAnimation_6leni"), SubResource("BTWait_8og18"), SubResource("BTAction_yeyns"), SubResource("BTCooldown_25f70"), SubResource("BTWait_tdhfn")] + +[sub_resource type="BTAction" id="BTAction_33wje"] +script = ExtResource("1_sgn0p") +range_min = 300.0 +range_max = 700.0 +position_var = &"pos" + +[sub_resource type="BBNode" id="BBNode_w5fh2"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qbxm8"] +animation_player = SubResource("BBNode_w5fh2") +animation_name = &"walk" +blend = 0.1 + +[sub_resource type="BTAction" id="BTAction_dfifw"] +script = ExtResource("2_pshl2") +target_position_var = &"pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_i05cm"] +time_limit = 3.0 +children = [SubResource("BTAction_dfifw")] + +[sub_resource type="BBNode" id="BBNode_vinxt"] +saved_value = NodePath("AnimationPlayer") +resource_name = "AnimationPlayer" + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_t7drr"] +animation_player = SubResource("BBNode_vinxt") +animation_name = &"idle" +blend = 0.1 + +[sub_resource type="BTRandomWait" id="BTRandomWait_axjfh"] + +[sub_resource type="BTSequence" id="BTSequence_ks71q"] +custom_name = "Chill" +children = [SubResource("BTPlayAnimation_t7drr"), SubResource("BTRandomWait_axjfh")] + +[sub_resource type="BTSequence" id="BTSequence_dss4d"] +custom_name = "Reposition" +children = [SubResource("BTAction_33wje"), SubResource("BTPlayAnimation_qbxm8"), SubResource("BTTimeLimit_i05cm"), SubResource("BTSequence_ks71q")] + +[sub_resource type="BTSelector" id="BTSelector_gp6q5"] +children = [SubResource("BTRunLimit_x2jr4"), SubResource("BTSequence_2n742"), SubResource("BTSequence_dss4d")] + +[resource] +description = "[con]CheckAgentProperty[/con] examines the agent’s property value and compares it to a given value or a blackboard variable. In this example, it checks if the [color=cyan]summon_count[/color] property is less than 6. +You can also check or share a [dec]Cooldown[/dec] in different parts of the behavior tree if you provide a blackboard variable for the [dec]Cooldown[/dec] decorator to use. [con]CheckVar[/con] is responsible here for examining the cooldown variable named \"summon_cooldown\"." +blackboard_plan = SubResource("BlackboardPlan_58oq1") +root_task = SubResource("BTSelector_gp6q5") diff --git a/demo/ai/trees/tutorial/tutorial_01_welcome.tres b/demo/ai/trees/tutorial/tutorial_01_welcome.tres new file mode 100644 index 0000000..84f1d04 --- /dev/null +++ b/demo/ai/trees/tutorial/tutorial_01_welcome.tres @@ -0,0 +1,29 @@ +[gd_resource type="BehaviorTree" load_steps=5 format=3 uid="uid://b1mfh8yad7rmw"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" + +[sub_resource type="BBNode" id="BBNode_fq0jf"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_rsejo"] +animation_player = SubResource("BBNode_fq0jf") +animation_name = &"idle" + +[sub_resource type="BTSequence" id="BTSequence_4bq32"] +children = [SubResource("BTPlayAnimation_rsejo")] + +[resource] +description = "Welcome to the [b]LimboAI Tutorial[/b]! + +Here, you'll learn how to use behavior trees to craft AI for your games. We'll start with the basics and gradually move to more advanced topics. Strap in for a quick and engaging introduction to behavior trees. + +Press ➡ button in the top-right corner to proceed. +Press ⬅ button any time you want to go back to a previous chapter." +blackboard_plan = SubResource("BlackboardPlan_ewfwq") +root_task = SubResource("BTSequence_4bq32") diff --git a/demo/ai/trees/tutorial/tutorial_02_introduction.tres b/demo/ai/trees/tutorial/tutorial_02_introduction.tres new file mode 100644 index 0000000..985582b --- /dev/null +++ b/demo/ai/trees/tutorial/tutorial_02_introduction.tres @@ -0,0 +1,45 @@ +[gd_resource type="BehaviorTree" load_steps=9 format=3 uid="uid://b1i0xo0o676va"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" +var/flank_speed/name = &"flank_speed" +var/flank_speed/type = 3 +var/flank_speed/value = 600.0 +var/flank_speed/hint = 1 +var/flank_speed/hint_string = "10,1000,10" + +[sub_resource type="BBNode" id="BBNode_wu06u"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_dubaq"] +animation_player = SubResource("BBNode_wu06u") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_meli1"] +duration = 5.0 + +[sub_resource type="BBNode" id="BBNode_mgehh"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_0fqno"] +animation_player = SubResource("BBNode_mgehh") +animation_name = &"dance" + +[sub_resource type="BTWait" id="BTWait_m3h4o"] +duration = 5.0 + +[sub_resource type="BTSequence" id="BTSequence_rbfdh"] +children = [SubResource("BTPlayAnimation_dubaq"), SubResource("BTWait_meli1"), SubResource("BTPlayAnimation_0fqno"), SubResource("BTWait_m3h4o")] + +[resource] +description = "Behavior trees are designed to simplify the creation of responsive and modular behaviors for games. They consist of tasks that represent specific actions or decision-making rules. Tasks can be broadly categorized into two groups: control tasks and leaf tasks. [b]Control tasks[/b] dictate the execution flow within the tree, while [b]leaf tasks[/b] represent specific actions to perform (such as moving or attacking) or conditions that need to be checked. Typically, it's the leaf tasks that perform the actual work in behavior trees. + +A behavior tree is usually processed each frame (physics frame by default). It is traversed from top to bottom, with the control tasks determining the control flow. Each task has a [color=cyan]_tick[/color] method, which performs the task's work and returns a status indicating its progress: [SUCCESS], [FAILURE], or [RUNNING]. [SUCCESS] and [FAILURE] indicate the outcome of finished work, while [RUNNING] status is returned when a task requires more than one tick to complete its job. These statuses determine how the tree progresses, with the [RUNNING] status usually meaning that the tree will continue execution during the next frame." +blackboard_plan = SubResource("BlackboardPlan_ewfwq") +root_task = SubResource("BTSequence_rbfdh") diff --git a/demo/ai/trees/tutorial/tutorial_03_types.tres b/demo/ai/trees/tutorial/tutorial_03_types.tres new file mode 100644 index 0000000..7e68a91 --- /dev/null +++ b/demo/ai/trees/tutorial/tutorial_03_types.tres @@ -0,0 +1,97 @@ +[gd_resource type="BehaviorTree" load_steps=24 format=3 uid="uid://cb0ybf24ahnc3"] + +[ext_resource type="Script" uid="uid://bicxffqmm7ek" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="1_as4cg"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="2_dlpnp"] +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="3_uv18s"] +[ext_resource type="Script" uid="uid://b7v2utjmtge0x" path="res://demo/ai/tasks/in_range.gd" id="4_k3g8t"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="5_thvy5"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" + +[sub_resource type="BBNode" id="BBNode_20ku0"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_57u80"] +animation_player = SubResource("BBNode_20ku0") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_11xvc"] +script = ExtResource("1_as4cg") +range_min = 300.0 +range_max = 500.0 +position_var = &"pos" + +[sub_resource type="BTAction" id="BTAction_tdkpj"] +script = ExtResource("2_dlpnp") +target_position_var = &"pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BTSequence" id="BTSequence_echit"] +children = [SubResource("BTPlayAnimation_57u80"), SubResource("BTAction_11xvc"), SubResource("BTAction_tdkpj")] + +[sub_resource type="BTProbability" id="BTProbability_g0ol3"] +children = [SubResource("BTSequence_echit")] + +[sub_resource type="BTAction" id="BTAction_124bm"] +script = ExtResource("3_uv18s") +group = &"player" +output_var = &"target" + +[sub_resource type="BTCondition" id="BTCondition_n25o8"] +script = ExtResource("4_k3g8t") +distance_min = 0.0 +distance_max = 200.0 +target_var = &"target" + +[sub_resource type="BTAction" id="BTAction_1hfgr"] +script = ExtResource("5_thvy5") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_ilr2h"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_mrsu3"] +animation_player = SubResource("BBNode_ilr2h") +animation_name = &"attack_1" + +[sub_resource type="BTSequence" id="BTSequence_5vug3"] +children = [SubResource("BTAction_124bm"), SubResource("BTCondition_n25o8"), SubResource("BTAction_1hfgr"), SubResource("BTPlayAnimation_mrsu3")] + +[sub_resource type="BBNode" id="BBNode_fq0jf"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_rsejo"] +animation_player = SubResource("BBNode_fq0jf") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_dl31p"] +duration = 2.0 + +[sub_resource type="BTSequence" id="BTSequence_vx4uy"] +children = [SubResource("BTPlayAnimation_rsejo"), SubResource("BTWait_dl31p")] + +[sub_resource type="BTSelector" id="BTSelector_tdpek"] +children = [SubResource("BTProbability_g0ol3"), SubResource("BTSequence_5vug3"), SubResource("BTSequence_vx4uy")] + +[resource] +description = "There are four types of tasks: +[ul][act]Actions[/act] are leaf tasks that perform the actual work.[/ul] +[ul][con]Conditions[/con] are leaf tasks that conduct various checks.[/ul] +[ul][comp]Composites[/comp] can have one or more child tasks, and dictate the execution flow of their children.[/ul] +[ul][dec]Decorators[/dec] can only have a single child and they change how their child task operates.[/ul] + +Let's take a look into actions first. [act]Actions[/act] are responsible for most of the work and often change the game state in a significant manner. For instance, [act]PlayAnimation[/act] instructs the AnimationPlayer to start a specified animation, with the option to wait for its completion. On the other hand, the [act]Wait[/act] task simply pauses for a set duration before returning [SUCCESS]. + +Next, we'll explore the core composite tasks, such as [comp]Sequence[/comp] and [comp]Selector[/comp]. These are among the most crucial composites that you should know about." +blackboard_plan = SubResource("BlackboardPlan_ewfwq") +root_task = SubResource("BTSelector_tdpek") diff --git a/demo/ai/trees/tutorial/tutorial_04_sequence.tres b/demo/ai/trees/tutorial/tutorial_04_sequence.tres new file mode 100644 index 0000000..950f9da --- /dev/null +++ b/demo/ai/trees/tutorial/tutorial_04_sequence.tres @@ -0,0 +1,62 @@ +[gd_resource type="BehaviorTree" load_steps=15 format=3 uid="uid://dln8ywvtqedt7"] + +[ext_resource type="Script" uid="uid://bicxffqmm7ek" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="1_gk66j"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="2_v5eou"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" + +[sub_resource type="BBNode" id="BBNode_fq0jf"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_rsejo"] +animation_player = SubResource("BBNode_fq0jf") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_dl31p"] +duration = 3.0 + +[sub_resource type="BBNode" id="BBNode_6d0yy"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wsspf"] +animation_player = SubResource("BBNode_6d0yy") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_fc1oo"] +script = ExtResource("1_gk66j") +range_min = 300.0 +range_max = 500.0 +position_var = &"pos" + +[sub_resource type="BTAction" id="BTAction_djl5v"] +script = ExtResource("2_v5eou") +target_position_var = &"pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BTFail" id="BTFail_i2f36"] + +[sub_resource type="BTComment" id="BTComment_4i06i"] +custom_name = "👇️ Sequence is never going to reach this task, because it fails at the previous step." + +[sub_resource type="BTWait" id="BTWait_yxpnx"] +duration = 888.0 + +[sub_resource type="BTSequence" id="BTSequence_vx4uy"] +children = [SubResource("BTPlayAnimation_rsejo"), SubResource("BTWait_dl31p"), SubResource("BTPlayAnimation_wsspf"), SubResource("BTAction_fc1oo"), SubResource("BTAction_djl5v"), SubResource("BTFail_i2f36"), SubResource("BTComment_4i06i"), SubResource("BTWait_yxpnx")] + +[resource] +description = "The [comp]Sequence[/comp] is one of the core composite tasks. It executes its child tasks sequentially, from first to last, until one of them returns [FAILURE], or all of them result in [SUCCESS]. In other words, if any child task results in [FAILURE], the Sequence execution will be aborted, and the Sequence itself will return [FAILURE]. + +In our example, you can observe a simple [comp]Sequence[/comp] in action. Notice how it fails when it reaches the [act]Fail[/act] action and never proceeds to the [act]Wait 888 sec[/act] action afterward. By the way, the simple [act]Fail[/act] task is quite useful for troubleshooting. Its sole function is to return [FAILURE]. +" +blackboard_plan = SubResource("BlackboardPlan_ewfwq") +root_task = SubResource("BTSequence_vx4uy") diff --git a/demo/ai/trees/tutorial/tutorial_05_selector.tres b/demo/ai/trees/tutorial/tutorial_05_selector.tres new file mode 100644 index 0000000..1443f15 --- /dev/null +++ b/demo/ai/trees/tutorial/tutorial_05_selector.tres @@ -0,0 +1,108 @@ +[gd_resource type="BehaviorTree" load_steps=26 format=3 uid="uid://bf4r652fv5kwi"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_3ed74"] +[ext_resource type="Script" uid="uid://bicxffqmm7ek" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="1_rvh1c"] +[ext_resource type="Script" uid="uid://b7v2utjmtge0x" path="res://demo/ai/tasks/in_range.gd" id="2_jfsyt"] +[ext_resource type="Script" uid="uid://dcjgktglb1slf" path="res://demo/ai/tasks/pursue.gd" id="2_nnswb"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="2_t62a0"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" + +[sub_resource type="BTCondition" id="BTCondition_x0uu7"] +script = ExtResource("2_jfsyt") +distance_min = 0.0 +distance_max = 200.0 +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_icf24"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_iiei3"] +animation_player = SubResource("BBNode_icf24") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_824oc"] +script = ExtResource("1_rvh1c") +range_min = 700.0 +range_max = 800.0 +position_var = &"pos" + +[sub_resource type="BTAction" id="BTAction_y1you"] +script = ExtResource("2_t62a0") +target_position_var = &"pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BBNode" id="BBNode_ayt56"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_l1tdg"] +animation_player = SubResource("BBNode_ayt56") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_hh8ys"] +duration = 3.0 + +[sub_resource type="BTSequence" id="BTSequence_cgwor"] +children = [SubResource("BTCondition_x0uu7"), SubResource("BTPlayAnimation_iiei3"), SubResource("BTAction_824oc"), SubResource("BTAction_y1you"), SubResource("BTPlayAnimation_l1tdg"), SubResource("BTWait_hh8ys")] + +[sub_resource type="BTCondition" id="BTCondition_d6aub"] +script = ExtResource("2_jfsyt") +distance_min = 200.0 +distance_max = 10000.0 +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_6d0yy"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wsspf"] +animation_player = SubResource("BBNode_6d0yy") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_wc11r"] +script = ExtResource("2_nnswb") +target_var = &"target" +speed_var = &"speed" +approach_distance = 100.0 + +[sub_resource type="BBNode" id="BBNode_aw5jj"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_3aihc"] +animation_player = SubResource("BBNode_aw5jj") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_1o163"] +duration = 3.0 + +[sub_resource type="BTSequence" id="BTSequence_vx4uy"] +children = [SubResource("BTCondition_d6aub"), SubResource("BTPlayAnimation_wsspf"), SubResource("BTAction_wc11r"), SubResource("BTPlayAnimation_3aihc"), SubResource("BTWait_1o163")] + +[sub_resource type="BTAction" id="BTAction_2murg"] +script = ExtResource("1_3ed74") +group = &"player" +output_var = &"target" + +[sub_resource type="BTSelector" id="BTSelector_ddhoo"] +children = [SubResource("BTSequence_cgwor"), SubResource("BTSequence_vx4uy"), SubResource("BTAction_2murg")] + +[resource] +description = "The [comp]Selector[/comp] is another essential composite task. It executes its child tasks sequentially, from first to last, until one of them returns [SUCCESS] or all of them result in [FAILURE]. In other words, when a child task results in [FAILURE], it moves on to the next one until it finds the one that returns [SUCCESS]. Once a child task results in [SUCCESS], the Selector stops and also returns [SUCCESS]. + +To understand the [comp]Selector[/comp], it helps to see it as the opposite of the [comp]Sequence[/comp]. While the Sequence continues iterating over children as long as they return [SUCCESS], the Selector does the same but as long as they return [FAILURE]. The purpose of the Selector is to find a child that succeeds. It's often useful to place higher priority tasks at the top so that the Selector attempts them first. + +[comp]Selector[/comp] is frequently used with [comp]Sequence[/comp] and [con]Condition[/con] tasks to control the behavior tree's flow. A condition task would prevent a Sequence from proceeding if it evaluates to [FAILURE], and thus the Selector would try the next child. + +In our example, the [con]InRange[/con] condition checks how far Junior is from the target. When Junior is farther than 200 pixels from the target, he'll attempt to approach it. If he is closer than 200 pixels from the target, he would try to walk away. Thanks to the Selector, only one of these behaviors will be performed at a time, based on the result of the [con]InRange[/con] check. Junior seems to have a dilemma — unable to decide whether to stay or go." +blackboard_plan = SubResource("BlackboardPlan_ewfwq") +root_task = SubResource("BTSelector_ddhoo") diff --git a/demo/ai/trees/tutorial/tutorial_06_decorators.tres b/demo/ai/trees/tutorial/tutorial_06_decorators.tres new file mode 100644 index 0000000..3e646a3 --- /dev/null +++ b/demo/ai/trees/tutorial/tutorial_06_decorators.tres @@ -0,0 +1,136 @@ +[gd_resource type="BehaviorTree" load_steps=34 format=3 uid="uid://beiki511huxb8"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_3xoj7"] +[ext_resource type="Script" uid="uid://b7v2utjmtge0x" path="res://demo/ai/tasks/in_range.gd" id="2_08b67"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="3_orhnl"] +[ext_resource type="Script" uid="uid://bicxffqmm7ek" path="res://demo/ai/tasks/select_random_nearby_pos.gd" id="4_oyght"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="5_5o1gy"] +[ext_resource type="Script" uid="uid://dcjgktglb1slf" path="res://demo/ai/tasks/pursue.gd" id="6_rpn40"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" + +[sub_resource type="BTAction" id="BTAction_2murg"] +script = ExtResource("1_3xoj7") +group = &"player" +output_var = &"target" + +[sub_resource type="BTRunLimit" id="BTRunLimit_60b8b"] +children = [SubResource("BTAction_2murg")] + +[sub_resource type="BTCondition" id="BTCondition_m15aa"] +script = ExtResource("2_08b67") +distance_min = 0.0 +distance_max = 200.0 +target_var = &"target" + +[sub_resource type="BTAction" id="BTAction_oc76s"] +script = ExtResource("3_orhnl") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_6d0yy"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wsspf"] +await_completion = 5.0 +animation_player = SubResource("BBNode_6d0yy") +animation_name = &"attack_1" + +[sub_resource type="BTSequence" id="BTSequence_e0f8v"] +children = [SubResource("BTCondition_m15aa"), SubResource("BTAction_oc76s"), SubResource("BTPlayAnimation_wsspf")] + +[sub_resource type="BTCooldown" id="BTCooldown_3tvjt"] +children = [SubResource("BTSequence_e0f8v")] +duration = 5.0 + +[sub_resource type="BTCondition" id="BTCondition_x0uu7"] +script = ExtResource("2_08b67") +distance_min = 0.0 +distance_max = 200.0 +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_icf24"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_iiei3"] +animation_player = SubResource("BBNode_icf24") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_824oc"] +script = ExtResource("4_oyght") +range_min = 700.0 +range_max = 800.0 +position_var = &"pos" + +[sub_resource type="BTAction" id="BTAction_y1you"] +script = ExtResource("5_5o1gy") +target_position_var = &"pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BBNode" id="BBNode_ayt56"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_l1tdg"] +animation_player = SubResource("BBNode_ayt56") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_hh8ys"] +duration = 3.0 + +[sub_resource type="BTSequence" id="BTSequence_cgwor"] +children = [SubResource("BTCondition_x0uu7"), SubResource("BTPlayAnimation_iiei3"), SubResource("BTAction_824oc"), SubResource("BTAction_y1you"), SubResource("BTPlayAnimation_l1tdg"), SubResource("BTWait_hh8ys")] + +[sub_resource type="BTCondition" id="BTCondition_d6aub"] +script = ExtResource("2_08b67") +distance_min = 200.0 +distance_max = 10000.0 +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_rpwld"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_dug2k"] +animation_player = SubResource("BBNode_rpwld") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_wc11r"] +script = ExtResource("6_rpn40") +target_var = &"target" +speed_var = &"speed" +approach_distance = 100.0 + +[sub_resource type="BBNode" id="BBNode_aw5jj"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_3aihc"] +animation_player = SubResource("BBNode_aw5jj") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_1o163"] +duration = 0.5 + +[sub_resource type="BTSequence" id="BTSequence_vx4uy"] +children = [SubResource("BTCondition_d6aub"), SubResource("BTPlayAnimation_dug2k"), SubResource("BTAction_wc11r"), SubResource("BTPlayAnimation_3aihc"), SubResource("BTWait_1o163")] + +[sub_resource type="BTSelector" id="BTSelector_ddhoo"] +children = [SubResource("BTRunLimit_60b8b"), SubResource("BTCooldown_3tvjt"), SubResource("BTSequence_cgwor"), SubResource("BTSequence_vx4uy")] + +[resource] +description = "Let's improve our previous behavior, and take the opportunity to discuss [dec]Decorators[/dec]. As mentioned earlier, decorators are control tasks that should only have a single child. Typically, a decorator either alters how its child operates or modifies its return status. They are often a useful tool for introducing variance into behaviors that otherwise lack it. + +In our example, we utilize the [dec]RunLimit[/dec] decorator to restrict its child from running more than once. After executing the first time, the child will never receive another tick. This is quite handy for all sorts of setup logic! + +Now, let's examine another decorator we use here - the [dec]Cooldown[/dec]. This decorator executes its child task only if the specified duration time has passed since the previous execution of the child task. The first time the attack sequence results in [SUCCESS], it triggers the cooldown, preventing the [comp]Sequence[/comp] from being executed for the next 5 seconds. During this period, the Cooldown returns [FAILURE] until the specified duration time elapses. It's important to note that it only counts executions that finished with [SUCCESS]. This means that [con]InRange[/con] can be utilized here without triggering the Cooldown!" +blackboard_plan = SubResource("BlackboardPlan_ewfwq") +root_task = SubResource("BTSelector_ddhoo") diff --git a/demo/ai/trees/tutorial/tutorial_07_more_decorators.tres b/demo/ai/trees/tutorial/tutorial_07_more_decorators.tres new file mode 100644 index 0000000..f525ad4 --- /dev/null +++ b/demo/ai/trees/tutorial/tutorial_07_more_decorators.tres @@ -0,0 +1,143 @@ +[gd_resource type="BehaviorTree" load_steps=36 format=3 uid="uid://tep50j4d6kgp"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_f605f"] +[ext_resource type="Script" uid="uid://b7v2utjmtge0x" path="res://demo/ai/tasks/in_range.gd" id="2_mj1cj"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="3_86p0r"] +[ext_resource type="Script" uid="uid://bi5e8366xi5s5" path="res://demo/ai/tasks/back_away.gd" id="4_u0vk1"] +[ext_resource type="Script" uid="uid://dcjgktglb1slf" path="res://demo/ai/tasks/pursue.gd" id="6_1yikm"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" + +[sub_resource type="BTAction" id="BTAction_2murg"] +script = ExtResource("1_f605f") +group = &"player" +output_var = &"target" + +[sub_resource type="BTRunLimit" id="BTRunLimit_60b8b"] +children = [SubResource("BTAction_2murg")] + +[sub_resource type="BTCondition" id="BTCondition_m15aa"] +script = ExtResource("2_mj1cj") +distance_min = 0.0 +distance_max = 200.0 +target_var = &"target" + +[sub_resource type="BTAction" id="BTAction_oc76s"] +script = ExtResource("3_86p0r") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_6d0yy"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wsspf"] +await_completion = 5.0 +animation_player = SubResource("BBNode_6d0yy") +animation_name = &"attack_1" + +[sub_resource type="BBNode" id="BBNode_w45kn"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_d2lad"] +await_completion = 5.0 +animation_player = SubResource("BBNode_w45kn") +animation_name = &"attack_2" + +[sub_resource type="BTSequence" id="BTSequence_e0f8v"] +children = [SubResource("BTCondition_m15aa"), SubResource("BTAction_oc76s"), SubResource("BTPlayAnimation_wsspf"), SubResource("BTPlayAnimation_d2lad")] + +[sub_resource type="BTCooldown" id="BTCooldown_3tvjt"] +children = [SubResource("BTSequence_e0f8v")] +duration = 5.0 + +[sub_resource type="BTCondition" id="BTCondition_x0uu7"] +script = ExtResource("2_mj1cj") +distance_min = 0.0 +distance_max = 200.0 +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_wksgd"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_umlwj"] +animation_player = SubResource("BBNode_wksgd") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_6q0k4"] +script = ExtResource("4_u0vk1") +speed_var = &"speed" +max_angle_deviation = 0.7 + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_6eii7"] +children = [SubResource("BTAction_6q0k4")] +time_limit = 2.0 + +[sub_resource type="BTAlwaysSucceed" id="BTAlwaysSucceed_ieord"] +children = [SubResource("BTTimeLimit_6eii7")] + +[sub_resource type="BBNode" id="BBNode_ayt56"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_l1tdg"] +animation_player = SubResource("BBNode_ayt56") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_hh8ys"] +duration = 3.0 + +[sub_resource type="BTSequence" id="BTSequence_cgwor"] +children = [SubResource("BTCondition_x0uu7"), SubResource("BTPlayAnimation_umlwj"), SubResource("BTAlwaysSucceed_ieord"), SubResource("BTPlayAnimation_l1tdg"), SubResource("BTWait_hh8ys")] + +[sub_resource type="BTCondition" id="BTCondition_d6aub"] +script = ExtResource("2_mj1cj") +distance_min = 200.0 +distance_max = 10000.0 +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_rpwld"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_dug2k"] +animation_player = SubResource("BBNode_rpwld") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_wc11r"] +script = ExtResource("6_1yikm") +target_var = &"target" +speed_var = &"speed" +approach_distance = 100.0 + +[sub_resource type="BBNode" id="BBNode_aw5jj"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_3aihc"] +animation_player = SubResource("BBNode_aw5jj") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_1o163"] +duration = 0.5 + +[sub_resource type="BTSequence" id="BTSequence_vx4uy"] +children = [SubResource("BTCondition_d6aub"), SubResource("BTPlayAnimation_dug2k"), SubResource("BTAction_wc11r"), SubResource("BTPlayAnimation_3aihc"), SubResource("BTWait_1o163")] + +[sub_resource type="BTSelector" id="BTSelector_ddhoo"] +children = [SubResource("BTRunLimit_60b8b"), SubResource("BTCooldown_3tvjt"), SubResource("BTSequence_cgwor"), SubResource("BTSequence_vx4uy")] + +[resource] +description = "Let's explore some other [dec]Decorators[/dec]. Here's a slightly improved version of the previous behavior. We incorporate the [dec]TimeLimit[/dec] decorator with the [act]Back Away[/act] action to achieve a similar effect as before (walking away from the target). The TimeLimit decorator ensures that the child task does not take too long to finish its work. If the time runs out, the task's execution will be aborted, and TimeLimit will return [FAILURE]. + +Another useful decorator is [dec]AlwaysSucceed[/dec], which converts any [FAILURE] returned by its child into [SUCCESS]. We use this decorator here because TimeLimit may result in [FAILURE], but we still want the [comp]Sequence[/comp] to continue. Also, there are similar decorators such as [dec]AlwaysFail[/dec] and [dec]Invert[/dec], which you can use in your behavior trees as needed. + +We also add a second attack, so that Junior feels more badass now. We've got a little hit-and-run behavior going on here!" +blackboard_plan = SubResource("BlackboardPlan_ewfwq") +root_task = SubResource("BTSelector_ddhoo") diff --git a/demo/ai/trees/tutorial/tutorial_08_final_touch.tres b/demo/ai/trees/tutorial/tutorial_08_final_touch.tres new file mode 100644 index 0000000..ab756b2 --- /dev/null +++ b/demo/ai/trees/tutorial/tutorial_08_final_touch.tres @@ -0,0 +1,204 @@ +[gd_resource type="BehaviorTree" load_steps=52 format=3 uid="uid://dp0cglcytwcj5"] + +[ext_resource type="Script" uid="uid://ccr43pgd4488l" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_o5ahw"] +[ext_resource type="Script" uid="uid://ct71h72pech3b" path="res://demo/ai/tasks/select_flanking_pos.gd" id="2_er25a"] +[ext_resource type="Script" uid="uid://df82exuqnfdb2" path="res://demo/ai/tasks/arrive_pos.gd" id="3_ed1xo"] +[ext_resource type="Script" uid="uid://dbo0kq2cwb4qv" path="res://demo/ai/tasks/face_target.gd" id="4_128ei"] +[ext_resource type="Script" uid="uid://b7v2utjmtge0x" path="res://demo/ai/tasks/in_range.gd" id="5_er18b"] +[ext_resource type="Script" uid="uid://bi5e8366xi5s5" path="res://demo/ai/tasks/back_away.gd" id="6_1urfq"] +[ext_resource type="Script" uid="uid://dcjgktglb1slf" path="res://demo/ai/tasks/pursue.gd" id="7_ekws5"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_ewfwq"] +var/speed/name = &"speed" +var/speed/type = 3 +var/speed/value = 400.0 +var/speed/hint = 1 +var/speed/hint_string = "10,1000,10" + +[sub_resource type="BTAction" id="BTAction_2murg"] +script = ExtResource("1_o5ahw") +group = &"player" +output_var = &"target" + +[sub_resource type="BTRunLimit" id="BTRunLimit_60b8b"] +children = [SubResource("BTAction_2murg")] + +[sub_resource type="BTCondition" id="BTCondition_m15aa"] +script = ExtResource("5_er18b") +distance_min = 0.0 +distance_max = 200.0 +target_var = &"target" + +[sub_resource type="BTAction" id="BTAction_oc76s"] +script = ExtResource("4_128ei") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_6d0yy"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wsspf"] +await_completion = 5.0 +animation_player = SubResource("BBNode_6d0yy") +animation_name = &"attack_1" + +[sub_resource type="BBNode" id="BBNode_w45kn"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_d2lad"] +await_completion = 5.0 +animation_player = SubResource("BBNode_w45kn") +animation_name = &"attack_2" + +[sub_resource type="BTSequence" id="BTSequence_e0f8v"] +children = [SubResource("BTCondition_m15aa"), SubResource("BTAction_oc76s"), SubResource("BTPlayAnimation_wsspf"), SubResource("BTPlayAnimation_d2lad")] + +[sub_resource type="BTCooldown" id="BTCooldown_3tvjt"] +children = [SubResource("BTSequence_e0f8v")] +duration = 5.0 + +[sub_resource type="BTCondition" id="BTCondition_x0uu7"] +script = ExtResource("5_er18b") +distance_min = 0.0 +distance_max = 200.0 +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_wksgd"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_umlwj"] +animation_player = SubResource("BBNode_wksgd") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_6q0k4"] +script = ExtResource("6_1urfq") +speed_var = &"speed" +max_angle_deviation = 0.7 + +[sub_resource type="BTTimeLimit" id="BTTimeLimit_6eii7"] +children = [SubResource("BTAction_6q0k4")] +time_limit = 2.0 + +[sub_resource type="BTAlwaysSucceed" id="BTAlwaysSucceed_ieord"] +children = [SubResource("BTTimeLimit_6eii7")] + +[sub_resource type="BBNode" id="BBNode_ayt56"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_l1tdg"] +animation_player = SubResource("BBNode_ayt56") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_hh8ys"] +duration = 3.0 + +[sub_resource type="BTSequence" id="BTSequence_cgwor"] +children = [SubResource("BTCondition_x0uu7"), SubResource("BTPlayAnimation_umlwj"), SubResource("BTAlwaysSucceed_ieord"), SubResource("BTPlayAnimation_l1tdg"), SubResource("BTWait_hh8ys")] + +[sub_resource type="BTAction" id="BTAction_n0rxm"] +script = ExtResource("2_er25a") +target_var = &"target" +flank_side = 0 +range_min = 400 +range_max = 500 +position_var = &"pos" + +[sub_resource type="BBNode" id="BBNode_icf24"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_iiei3"] +animation_player = SubResource("BBNode_icf24") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_g2up4"] +script = ExtResource("3_ed1xo") +target_position_var = &"pos" +speed_var = &"speed" +tolerance = 50.0 +avoid_var = &"" + +[sub_resource type="BTAction" id="BTAction_d5lkr"] +script = ExtResource("4_128ei") +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_h4k80"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_40yja"] +animation_player = SubResource("BBNode_h4k80") +animation_name = &"throw_prepare" + +[sub_resource type="BTWait" id="BTWait_2dc1v"] + +[sub_resource type="BBNode" id="BBNode_slipn"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qnpjq"] +await_completion = 5.0 +animation_player = SubResource("BBNode_slipn") +animation_name = &"throw" + +[sub_resource type="BBNode" id="BBNode_qaqnn"] +resource_name = "." +saved_value = NodePath(".") + +[sub_resource type="BTCallMethod" id="BTCallMethod_yd0fn"] +node = SubResource("BBNode_qaqnn") +method = &"throw_ninja_star" + +[sub_resource type="BTSequence" id="BTSequence_ws7nq"] +children = [SubResource("BTAction_n0rxm"), SubResource("BTPlayAnimation_iiei3"), SubResource("BTAction_g2up4"), SubResource("BTAction_d5lkr"), SubResource("BTPlayAnimation_40yja"), SubResource("BTWait_2dc1v"), SubResource("BTPlayAnimation_qnpjq"), SubResource("BTCallMethod_yd0fn")] + +[sub_resource type="BTProbability" id="BTProbability_omklt"] +children = [SubResource("BTSequence_ws7nq")] +run_chance = 0.25 + +[sub_resource type="BTCondition" id="BTCondition_d6aub"] +script = ExtResource("5_er18b") +distance_min = 200.0 +distance_max = 10000.0 +target_var = &"target" + +[sub_resource type="BBNode" id="BBNode_rpwld"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_dug2k"] +animation_player = SubResource("BBNode_rpwld") +animation_name = &"walk" + +[sub_resource type="BTAction" id="BTAction_wc11r"] +script = ExtResource("7_ekws5") +target_var = &"target" +speed_var = &"speed" +approach_distance = 100.0 + +[sub_resource type="BBNode" id="BBNode_aw5jj"] +resource_name = "AnimationPlayer" +saved_value = NodePath("AnimationPlayer") + +[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_3aihc"] +animation_player = SubResource("BBNode_aw5jj") +animation_name = &"idle" + +[sub_resource type="BTWait" id="BTWait_1o163"] +duration = 0.5 + +[sub_resource type="BTSequence" id="BTSequence_vx4uy"] +children = [SubResource("BTCondition_d6aub"), SubResource("BTPlayAnimation_dug2k"), SubResource("BTAction_wc11r"), SubResource("BTPlayAnimation_3aihc"), SubResource("BTWait_1o163")] + +[sub_resource type="BTSelector" id="BTSelector_ddhoo"] +children = [SubResource("BTRunLimit_60b8b"), SubResource("BTCooldown_3tvjt"), SubResource("BTSequence_cgwor"), SubResource("BTProbability_omklt"), SubResource("BTSequence_vx4uy")] + +[resource] +description = "And for the final touch, we've added throwing ninja stars to our previous behavior. The [dec]Probability[/dec] decorator adds a little variance so that we don't throw ninja stars all the time. This decorator executes its child task with a certain probability, so when it's not 100%, sometimes it will return [FAILURE] instead. Some of the work in this [comp]Sequence[/comp] is done by actions you've seen already, and the [act]CallMethod[/act] action invokes the [color=cyan]throw_ninja_star[/color] method on the agent node. By the way, the agent is always the owner of the BTPlayer node, which executes this behavior tree. + +This concludes our tutorial. Hopefully, this little endeavor has been useful to you. You can learn more by reading the [b]Online Documentation[/b], which covers topics like creating your own tasks. Also, check out the [b]Showcase[/b], which presents behaviors of agents made for this little demo. Simply click \"End Tutorial\" to return to the [b]Showcase[/b]." +blackboard_plan = SubResource("BlackboardPlan_ewfwq") +root_task = SubResource("BTSelector_ddhoo") diff --git a/demo/assets/agent_bobby.png b/demo/assets/agent_bobby.png new file mode 100644 index 0000000..14de872 Binary files /dev/null and b/demo/assets/agent_bobby.png differ diff --git a/demo/assets/agent_bobby.png.import b/demo/assets/agent_bobby.png.import new file mode 100644 index 0000000..de79d79 --- /dev/null +++ b/demo/assets/agent_bobby.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dlo1ine6p5di4" +path="res://.godot/imported/agent_bobby.png-8c7c0553d4eefdb06245554fd2603238.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_bobby.png" +dest_files=["res://.godot/imported/agent_bobby.png-8c7c0553d4eefdb06245554fd2603238.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/agent_charger.png b/demo/assets/agent_charger.png new file mode 100644 index 0000000..3b6ea44 Binary files /dev/null and b/demo/assets/agent_charger.png differ diff --git a/demo/assets/agent_charger.png.import b/demo/assets/agent_charger.png.import new file mode 100644 index 0000000..bfe08b6 --- /dev/null +++ b/demo/assets/agent_charger.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ce16nc0wy2s8" +path="res://.godot/imported/agent_charger.png-4fbef6fc86342f0b358c84f3e6790641.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_charger.png" +dest_files=["res://.godot/imported/agent_charger.png-4fbef6fc86342f0b358c84f3e6790641.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/agent_combo.png b/demo/assets/agent_combo.png new file mode 100644 index 0000000..ca9d815 Binary files /dev/null and b/demo/assets/agent_combo.png differ diff --git a/demo/assets/agent_combo.png.import b/demo/assets/agent_combo.png.import new file mode 100644 index 0000000..8128a64 --- /dev/null +++ b/demo/assets/agent_combo.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bo0ibp7tvjbba" +path="res://.godot/imported/agent_combo.png-1aabf55a6f7673e34d40eadba34cb086.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_combo.png" +dest_files=["res://.godot/imported/agent_combo.png-1aabf55a6f7673e34d40eadba34cb086.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/agent_demon.png b/demo/assets/agent_demon.png new file mode 100644 index 0000000..a92603e Binary files /dev/null and b/demo/assets/agent_demon.png differ diff --git a/demo/assets/agent_demon.png.import b/demo/assets/agent_demon.png.import new file mode 100644 index 0000000..17b163f --- /dev/null +++ b/demo/assets/agent_demon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1tx7u8ho0r4v" +path="res://.godot/imported/agent_demon.png-8a62722d1d31985ee3a39cfef745c53a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_demon.png" +dest_files=["res://.godot/imported/agent_demon.png-8a62722d1d31985ee3a39cfef745c53a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/agent_imp.png b/demo/assets/agent_imp.png new file mode 100644 index 0000000..cadf474 Binary files /dev/null and b/demo/assets/agent_imp.png differ diff --git a/demo/assets/agent_imp.png.import b/demo/assets/agent_imp.png.import new file mode 100644 index 0000000..08994d3 --- /dev/null +++ b/demo/assets/agent_imp.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://h70okn6hmxum" +path="res://.godot/imported/agent_imp.png-9fb23c43583296c91b2a8a01f05daad9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_imp.png" +dest_files=["res://.godot/imported/agent_imp.png-9fb23c43583296c91b2a8a01f05daad9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/agent_junior_pieces.png b/demo/assets/agent_junior_pieces.png new file mode 100644 index 0000000..e8cf873 Binary files /dev/null and b/demo/assets/agent_junior_pieces.png differ diff --git a/demo/assets/agent_junior_pieces.png.import b/demo/assets/agent_junior_pieces.png.import new file mode 100644 index 0000000..4d87dcc --- /dev/null +++ b/demo/assets/agent_junior_pieces.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b0oeqsc0xksto" +path="res://.godot/imported/agent_junior_pieces.png-95690b27968ceea039daac5098fd3722.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_junior_pieces.png" +dest_files=["res://.godot/imported/agent_junior_pieces.png-95690b27968ceea039daac5098fd3722.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/agent_melee_nuanced.png b/demo/assets/agent_melee_nuanced.png new file mode 100644 index 0000000..3a7585b Binary files /dev/null and b/demo/assets/agent_melee_nuanced.png differ diff --git a/demo/assets/agent_melee_nuanced.png.import b/demo/assets/agent_melee_nuanced.png.import new file mode 100644 index 0000000..604cb7a --- /dev/null +++ b/demo/assets/agent_melee_nuanced.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://usu3j55d6dgc" +path="res://.godot/imported/agent_melee_nuanced.png-653a64ea55e3175afadb5b209be8b1d0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_melee_nuanced.png" +dest_files=["res://.godot/imported/agent_melee_nuanced.png-653a64ea55e3175afadb5b209be8b1d0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/agent_melee_simple.png b/demo/assets/agent_melee_simple.png new file mode 100644 index 0000000..502d196 Binary files /dev/null and b/demo/assets/agent_melee_simple.png differ diff --git a/demo/assets/agent_melee_simple.png.import b/demo/assets/agent_melee_simple.png.import new file mode 100644 index 0000000..f25826b --- /dev/null +++ b/demo/assets/agent_melee_simple.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cw8s50856x8ct" +path="res://.godot/imported/agent_melee_simple.png-78a6d279aa99849a5b7788dd5762650f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_melee_simple.png" +dest_files=["res://.godot/imported/agent_melee_simple.png-78a6d279aa99849a5b7788dd5762650f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/agent_ranged.png b/demo/assets/agent_ranged.png new file mode 100644 index 0000000..3debe06 Binary files /dev/null and b/demo/assets/agent_ranged.png differ diff --git a/demo/assets/agent_ranged.png.import b/demo/assets/agent_ranged.png.import new file mode 100644 index 0000000..d83f37d --- /dev/null +++ b/demo/assets/agent_ranged.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cjts4ennjtepg" +path="res://.godot/imported/agent_ranged.png-a7be7db55c56f7b1c12ada6338a036cf.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_ranged.png" +dest_files=["res://.godot/imported/agent_ranged.png-a7be7db55c56f7b1c12ada6338a036cf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/agent_skirmisher.png b/demo/assets/agent_skirmisher.png new file mode 100644 index 0000000..7552e96 Binary files /dev/null and b/demo/assets/agent_skirmisher.png differ diff --git a/demo/assets/agent_skirmisher.png.import b/demo/assets/agent_skirmisher.png.import new file mode 100644 index 0000000..b227fcc --- /dev/null +++ b/demo/assets/agent_skirmisher.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://l042ovqqsy3l" +path="res://.godot/imported/agent_skirmisher.png-fb22c42e0c82e689e3a451b83b1f6ff9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_skirmisher.png" +dest_files=["res://.godot/imported/agent_skirmisher.png-fb22c42e0c82e689e3a451b83b1f6ff9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/agent_summoner.png b/demo/assets/agent_summoner.png new file mode 100644 index 0000000..0147818 Binary files /dev/null and b/demo/assets/agent_summoner.png differ diff --git a/demo/assets/agent_summoner.png.import b/demo/assets/agent_summoner.png.import new file mode 100644 index 0000000..8234f4a --- /dev/null +++ b/demo/assets/agent_summoner.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ombnpn2edldt" +path="res://.godot/imported/agent_summoner.png-3beb6fd299df05d9586c6b74edd2bbc6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/agent_summoner.png" +dest_files=["res://.godot/imported/agent_summoner.png-3beb6fd299df05d9586c6b74edd2bbc6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/arrow_left.png b/demo/assets/arrow_left.png new file mode 100644 index 0000000..c6af99e Binary files /dev/null and b/demo/assets/arrow_left.png differ diff --git a/demo/assets/arrow_left.png.import b/demo/assets/arrow_left.png.import new file mode 100644 index 0000000..cd4ea5e --- /dev/null +++ b/demo/assets/arrow_left.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dc1wu244fnetf" +path="res://.godot/imported/arrow_left.png-a7d3530ca98c17c281c9ef74dcdcb927.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/arrow_left.png" +dest_files=["res://.godot/imported/arrow_left.png-a7d3530ca98c17c281c9ef74dcdcb927.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/arrow_right.png b/demo/assets/arrow_right.png new file mode 100644 index 0000000..70ec85b Binary files /dev/null and b/demo/assets/arrow_right.png differ diff --git a/demo/assets/arrow_right.png.import b/demo/assets/arrow_right.png.import new file mode 100644 index 0000000..bdf534c --- /dev/null +++ b/demo/assets/arrow_right.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bjakugmqbbtw7" +path="res://.godot/imported/arrow_right.png-21f7ddc963756a50bd3974181b5e0d02.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/arrow_right.png" +dest_files=["res://.godot/imported/arrow_right.png-21f7ddc963756a50bd3974181b5e0d02.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/dummy.png b/demo/assets/dummy.png new file mode 100644 index 0000000..531fd19 Binary files /dev/null and b/demo/assets/dummy.png differ diff --git a/demo/assets/dummy.png.import b/demo/assets/dummy.png.import new file mode 100644 index 0000000..8d75969 --- /dev/null +++ b/demo/assets/dummy.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cltutcxjx8jnl" +path="res://.godot/imported/dummy.png-30069efb95d1cabfca0861ca5010c667.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/dummy.png" +dest_files=["res://.godot/imported/dummy.png-30069efb95d1cabfca0861ca5010c667.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/env_clouds.png b/demo/assets/env_clouds.png new file mode 100644 index 0000000..ab61eff Binary files /dev/null and b/demo/assets/env_clouds.png differ diff --git a/demo/assets/env_clouds.png.import b/demo/assets/env_clouds.png.import new file mode 100644 index 0000000..d8d21aa --- /dev/null +++ b/demo/assets/env_clouds.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://65b6yuobhxf8" +path="res://.godot/imported/env_clouds.png-28d790def9247e51c19b24eae86c1a64.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/env_clouds.png" +dest_files=["res://.godot/imported/env_clouds.png-28d790def9247e51c19b24eae86c1a64.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/env_gong.png b/demo/assets/env_gong.png new file mode 100644 index 0000000..4fd80e2 Binary files /dev/null and b/demo/assets/env_gong.png differ diff --git a/demo/assets/env_gong.png.import b/demo/assets/env_gong.png.import new file mode 100644 index 0000000..2227594 --- /dev/null +++ b/demo/assets/env_gong.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://i476iia1ua8q" +path="res://.godot/imported/env_gong.png-22c1657db8aed530e7d811b2b20b4a2d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/env_gong.png" +dest_files=["res://.godot/imported/env_gong.png-22c1657db8aed530e7d811b2b20b4a2d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/env_ground.png b/demo/assets/env_ground.png new file mode 100644 index 0000000..cfb2749 Binary files /dev/null and b/demo/assets/env_ground.png differ diff --git a/demo/assets/env_ground.png.import b/demo/assets/env_ground.png.import new file mode 100644 index 0000000..87610b1 --- /dev/null +++ b/demo/assets/env_ground.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cc7b22sy46gwn" +path="res://.godot/imported/env_ground.png-b29c6c47be0779294403cf6615d9dae2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/env_ground.png" +dest_files=["res://.godot/imported/env_ground.png-b29c6c47be0779294403cf6615d9dae2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/env_plants.png b/demo/assets/env_plants.png new file mode 100644 index 0000000..3008cf4 Binary files /dev/null and b/demo/assets/env_plants.png differ diff --git a/demo/assets/env_plants.png.import b/demo/assets/env_plants.png.import new file mode 100644 index 0000000..616c11c --- /dev/null +++ b/demo/assets/env_plants.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://4kw2ks8doc0w" +path="res://.godot/imported/env_plants.png-40a908ca223303e0aacba2fca71781c6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/env_plants.png" +dest_files=["res://.godot/imported/env_plants.png-40a908ca223303e0aacba2fca71781c6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/env_rocks.png b/demo/assets/env_rocks.png new file mode 100644 index 0000000..55c7830 Binary files /dev/null and b/demo/assets/env_rocks.png differ diff --git a/demo/assets/env_rocks.png.import b/demo/assets/env_rocks.png.import new file mode 100644 index 0000000..3ed17be --- /dev/null +++ b/demo/assets/env_rocks.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b3g14elmg0m36" +path="res://.godot/imported/env_rocks.png-12fea7b4727d1ddca76c06fd66910dd0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/env_rocks.png" +dest_files=["res://.godot/imported/env_rocks.png-12fea7b4727d1ddca76c06fd66910dd0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/fireball.png b/demo/assets/fireball.png new file mode 100644 index 0000000..6d2ddf6 Binary files /dev/null and b/demo/assets/fireball.png differ diff --git a/demo/assets/fireball.png.import b/demo/assets/fireball.png.import new file mode 100644 index 0000000..554b787 --- /dev/null +++ b/demo/assets/fireball.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://235liwnxn1n5" +path="res://.godot/imported/fireball.png-22a46715cd71373bf765d22c23e664a9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/fireball.png" +dest_files=["res://.godot/imported/fireball.png-22a46715cd71373bf765d22c23e664a9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/fonts/junction_bold.otf b/demo/assets/fonts/junction_bold.otf new file mode 100644 index 0000000..45a6697 Binary files /dev/null and b/demo/assets/fonts/junction_bold.otf differ diff --git a/demo/assets/fonts/junction_bold.otf.import b/demo/assets/fonts/junction_bold.otf.import new file mode 100644 index 0000000..441c753 --- /dev/null +++ b/demo/assets/fonts/junction_bold.otf.import @@ -0,0 +1,35 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://n231m6uqsq6x" +path="res://.godot/imported/junction_bold.otf-4db2200a8b1a6423bafe2a4e7c7abbde.fontdata" + +[deps] + +source_file="res://demo/assets/fonts/junction_bold.otf" +dest_files=["res://.godot/imported/junction_bold.otf-4db2200a8b1a6423bafe2a4e7c7abbde.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 +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/demo/assets/fonts/knewave_regular.ttf b/demo/assets/fonts/knewave_regular.ttf new file mode 100644 index 0000000..a98f750 Binary files /dev/null and b/demo/assets/fonts/knewave_regular.ttf differ diff --git a/demo/assets/fonts/knewave_regular.ttf.import b/demo/assets/fonts/knewave_regular.ttf.import new file mode 100644 index 0000000..12961d2 --- /dev/null +++ b/demo/assets/fonts/knewave_regular.ttf.import @@ -0,0 +1,35 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://d25vkmce7mhlt" +path="res://.godot/imported/knewave_regular.ttf-955953b059f713782c7b07e66ab341ec.fontdata" + +[deps] + +source_file="res://demo/assets/fonts/knewave_regular.ttf" +dest_files=["res://.godot/imported/knewave_regular.ttf-955953b059f713782c7b07e66ab341ec.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 +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/demo/assets/fx.png b/demo/assets/fx.png new file mode 100644 index 0000000..1bd586d Binary files /dev/null and b/demo/assets/fx.png differ diff --git a/demo/assets/fx.png.import b/demo/assets/fx.png.import new file mode 100644 index 0000000..684838b --- /dev/null +++ b/demo/assets/fx.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dj4oayt5ttvh8" +path="res://.godot/imported/fx.png-6477c60e66067f48f360430ec23ddc02.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/fx.png" +dest_files=["res://.godot/imported/fx.png-6477c60e66067f48f360430ec23ddc02.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/hp_bar.png b/demo/assets/hp_bar.png new file mode 100644 index 0000000..1bc265b Binary files /dev/null and b/demo/assets/hp_bar.png differ diff --git a/demo/assets/hp_bar.png.import b/demo/assets/hp_bar.png.import new file mode 100644 index 0000000..a707489 --- /dev/null +++ b/demo/assets/hp_bar.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://hnwi23oef752" +path="res://.godot/imported/hp_bar.png-c23edb5054c777f587fbf3d4206298bd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/hp_bar.png" +dest_files=["res://.godot/imported/hp_bar.png-c23edb5054c777f587fbf3d4206298bd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/hp_over.png b/demo/assets/hp_over.png new file mode 100644 index 0000000..b04a763 Binary files /dev/null and b/demo/assets/hp_over.png differ diff --git a/demo/assets/hp_over.png.import b/demo/assets/hp_over.png.import new file mode 100644 index 0000000..9f6e24b --- /dev/null +++ b/demo/assets/hp_over.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cls8jtnu413o8" +path="res://.godot/imported/hp_over.png-417c2786f2f485db8c5f858f3f94e7e9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/hp_over.png" +dest_files=["res://.godot/imported/hp_over.png-417c2786f2f485db8c5f858f3f94e7e9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/hp_under.png b/demo/assets/hp_under.png new file mode 100644 index 0000000..79d4747 Binary files /dev/null and b/demo/assets/hp_under.png differ diff --git a/demo/assets/hp_under.png.import b/demo/assets/hp_under.png.import new file mode 100644 index 0000000..f3b6d9a --- /dev/null +++ b/demo/assets/hp_under.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dlw15foygohrk" +path="res://.godot/imported/hp_under.png-c993a547f4fdb0f3b9d06eb23ae4e804.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/hp_under.png" +dest_files=["res://.godot/imported/hp_under.png-c993a547f4fdb0f3b9d06eb23ae4e804.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/icon.svg b/demo/assets/icon.svg new file mode 100644 index 0000000..b53af7e --- /dev/null +++ b/demo/assets/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/demo/assets/icon.svg.import b/demo/assets/icon.svg.import new file mode 100644 index 0000000..201efda --- /dev/null +++ b/demo/assets/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://do6oi8vmfneur" +path="res://.godot/imported/icon.svg-e526cd5ce5fe587ad30e60477eb51fdf.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/icon.svg" +dest_files=["res://.godot/imported/icon.svg-e526cd5ce5fe587ad30e60477eb51fdf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/demo/assets/logo.png b/demo/assets/logo.png new file mode 100644 index 0000000..0533077 Binary files /dev/null and b/demo/assets/logo.png differ diff --git a/demo/assets/logo.png.import b/demo/assets/logo.png.import new file mode 100644 index 0000000..e0d85bf --- /dev/null +++ b/demo/assets/logo.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://tyu0ua1ju38l" +path="res://.godot/imported/logo.png-627f053fd17248d48d9d002bdb02afc3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/logo.png" +dest_files=["res://.godot/imported/logo.png-627f053fd17248d48d9d002bdb02afc3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/shadow.png b/demo/assets/shadow.png new file mode 100644 index 0000000..683dc83 Binary files /dev/null and b/demo/assets/shadow.png differ diff --git a/demo/assets/shadow.png.import b/demo/assets/shadow.png.import new file mode 100644 index 0000000..5ec9cc1 --- /dev/null +++ b/demo/assets/shadow.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dwhhxj5557qrb" +path="res://.godot/imported/shadow.png-f4b948130f51dfdf8369bd133baa3734.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/shadow.png" +dest_files=["res://.godot/imported/shadow.png-f4b948130f51dfdf8369bd133baa3734.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/smoke.png b/demo/assets/smoke.png new file mode 100644 index 0000000..725246d Binary files /dev/null and b/demo/assets/smoke.png differ diff --git a/demo/assets/smoke.png.import b/demo/assets/smoke.png.import new file mode 100644 index 0000000..2701e6c --- /dev/null +++ b/demo/assets/smoke.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bdusy0qqtw0th" +path="res://.godot/imported/smoke.png-d041a59b8025f6af550257daa38b3580.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/smoke.png" +dest_files=["res://.godot/imported/smoke.png-d041a59b8025f6af550257daa38b3580.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/assets/ui.theme b/demo/assets/ui.theme new file mode 100644 index 0000000..e010fad Binary files /dev/null and b/demo/assets/ui.theme differ diff --git a/demo/assets/weapon_ninja_star.png b/demo/assets/weapon_ninja_star.png new file mode 100644 index 0000000..4b8e539 Binary files /dev/null and b/demo/assets/weapon_ninja_star.png differ diff --git a/demo/assets/weapon_ninja_star.png.import b/demo/assets/weapon_ninja_star.png.import new file mode 100644 index 0000000..1f4aa94 --- /dev/null +++ b/demo/assets/weapon_ninja_star.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://2uyxh7sy8qny" +path="res://.godot/imported/weapon_ninja_star.png-be058a7d9eff80095d1c513b22f898e0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://demo/assets/weapon_ninja_star.png" +dest_files=["res://.godot/imported/weapon_ninja_star.png-be058a7d9eff80095d1c513b22f898e0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/demo/props/dummy.gd b/demo/props/dummy.gd new file mode 100644 index 0000000..06fc9f3 --- /dev/null +++ b/demo/props/dummy.gd @@ -0,0 +1,15 @@ +extends CharacterBody2D + +@onready var animation_player: AnimationPlayer = $AnimationPlayer +@onready var hurtbox: Hurtbox = $Hurtbox +@onready var root: Node2D = $Root + + +func _on_health_damaged(_amount: float, _knockback: Vector2) -> void: + root.scale.x = -signf(hurtbox.last_attack_vector.x) + animation_player.clear_queue() + animation_player.play(&"hurt", 0.1) + + +func get_facing() -> float: + return signf(root.scale.x) diff --git a/demo/props/dummy.gd.uid b/demo/props/dummy.gd.uid new file mode 100644 index 0000000..8721937 --- /dev/null +++ b/demo/props/dummy.gd.uid @@ -0,0 +1 @@ +uid://mapy7metn1kt diff --git a/demo/props/dummy.tscn b/demo/props/dummy.tscn new file mode 100644 index 0000000..134f851 --- /dev/null +++ b/demo/props/dummy.tscn @@ -0,0 +1,405 @@ +[gd_scene load_steps=11 format=3 uid="uid://c5fhe3tulhlco"] + +[ext_resource type="Script" uid="uid://mapy7metn1kt" path="res://demo/props/dummy.gd" id="1_kqftw"] +[ext_resource type="Texture2D" uid="uid://cltutcxjx8jnl" path="res://demo/assets/dummy.png" id="1_vdhcl"] +[ext_resource type="Texture2D" uid="uid://dwhhxj5557qrb" path="res://demo/assets/shadow.png" id="2_535g7"] +[ext_resource type="Script" uid="uid://dq5h6yydckjc1" path="res://demo/agents/scripts/hurtbox.gd" id="4_pkfnd"] +[ext_resource type="Script" uid="uid://5byn62y1oa76" path="res://demo/agents/scripts/health.gd" id="5_8qcls"] + +[sub_resource type="Animation" id="Animation_1o3gy"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/Stick:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, -1)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/Stick:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/Stick:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Stick/Body:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, -49)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Stick/Body:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Stick/Body:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} + +[sub_resource type="Animation" id="Animation_3r20x"] +resource_name = "hurt" +length = 0.25 +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/Stick:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(0, -1), Vector2(0, -1)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/Stick:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, -0.273996] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/Stick:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Stick/Body:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(0, -49), Vector2(0, -49), Vector2(0, -49), Vector2(0, -49)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Stick/Body:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [0.0, -0.524778, -0.267304, -0.377565] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Stick/Body:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.1, 0.15, 0.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.9, 1.1), Vector2(0.9, 1.1), Vector2(0.9, 1.1)] +} + +[sub_resource type="Animation" id="Animation_sf5ej"] +resource_name = "idle" +length = 1.2 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Rig:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Rig:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Rig:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Root/Rig/Stick:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, -1)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Root/Rig/Stick:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Root/Rig/Stick:scale") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Root/Rig/Stick/Body:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6, 0.9, 1.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(0, -49), Vector2(0, -49), Vector2(0, -49), Vector2(0, -49), Vector2(0, -49)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Root/Rig/Stick/Body:rotation") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6, 0.9, 1.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [-0.0523599, 0.0, 0.0523599, 0.0, -0.0523599] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Root/Rig/Stick/Body:scale") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 0.3, 0.6, 0.9, 1.2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(0.95, 1.05), Vector2(1.05, 0.95), Vector2(0.95, 1.05), Vector2(1.05, 0.95), Vector2(0.95, 1.05)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_blnjx"] +_data = { +&"RESET": SubResource("Animation_1o3gy"), +&"hurt": SubResource("Animation_3r20x"), +&"idle": SubResource("Animation_sf5ej") +} + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_pknym"] +size = Vector2(80, 35) + +[node name="Dummy" type="CharacterBody2D" groups=["player"]] +script = ExtResource("1_kqftw") + +[node name="Root" type="Node2D" parent="."] +metadata/_edit_lock_ = true + +[node name="Rig" type="Node2D" parent="Root"] + +[node name="Shadow" type="Sprite2D" parent="Root/Rig"] +modulate = Color(1, 1, 1, 0.290196) +texture = ExtResource("2_535g7") + +[node name="Stick" type="Sprite2D" parent="Root/Rig"] +position = Vector2(0, -1) +texture = ExtResource("1_vdhcl") +offset = Vector2(-1, -28) +region_enabled = true +region_rect = Rect2(100.613, 0, 22.3875, 64.0292) + +[node name="Body" type="Sprite2D" parent="Root/Rig/Stick"] +position = Vector2(0, -49) +texture = ExtResource("1_vdhcl") +offset = Vector2(-1, -56) +region_enabled = true +region_rect = Rect2(0, 0, 99.6683, 136) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_blnjx") +} +autoplay = "idle" +next/hurt = &"idle" +blend_times = [&"idle", &"hurt", 0.05, &"hurt", &"idle", 0.3] + +[node name="Hurtbox" type="Area2D" parent="." node_paths=PackedStringArray("health")] +collision_layer = 4 +collision_mask = 0 +script = ExtResource("4_pkfnd") +health = NodePath("../Health") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hurtbox"] +shape = SubResource("RectangleShape2D_pknym") +debug_color = Color(0.466325, 0.590206, 0.107862, 0.42) +metadata/_edit_lock_ = true + +[node name="Health" type="Node" parent="."] +script = ExtResource("5_8qcls") +max_health = 1e+07 + +[connection signal="damaged" from="Health" to="." method="_on_health_damaged"] diff --git a/demo/props/gong.gd b/demo/props/gong.gd new file mode 100644 index 0000000..adf21ed --- /dev/null +++ b/demo/props/gong.gd @@ -0,0 +1,15 @@ +extends StaticBody2D + +signal gong_struck + +var enabled: bool = true + +@onready var animation_player: AnimationPlayer = $AnimationPlayer + + +func _on_health_damaged(_amount: float, _knockback: Vector2) -> void: + if not enabled: + return + animation_player.play(&"struck") + gong_struck.emit() + enabled = false diff --git a/demo/props/gong.gd.uid b/demo/props/gong.gd.uid new file mode 100644 index 0000000..c7a4e90 --- /dev/null +++ b/demo/props/gong.gd.uid @@ -0,0 +1 @@ +uid://d3cmj6skb7k07 diff --git a/demo/props/gong.tscn b/demo/props/gong.tscn new file mode 100644 index 0000000..47d7906 --- /dev/null +++ b/demo/props/gong.tscn @@ -0,0 +1,930 @@ +[gd_scene load_steps=12 format=3 uid="uid://bpd1wmw2f7bvg"] + +[ext_resource type="Script" uid="uid://d3cmj6skb7k07" path="res://demo/props/gong.gd" id="1_77c1i"] +[ext_resource type="Texture2D" uid="uid://i476iia1ua8q" path="res://demo/assets/env_gong.png" id="1_kbnv6"] +[ext_resource type="Texture2D" uid="uid://dwhhxj5557qrb" path="res://demo/assets/shadow.png" id="1_vl1mv"] +[ext_resource type="Texture2D" uid="uid://dj4oayt5ttvh8" path="res://demo/assets/fx.png" id="2_dib3m"] +[ext_resource type="Script" uid="uid://dq5h6yydckjc1" path="res://demo/agents/scripts/hurtbox.gd" id="5_xeb5y"] +[ext_resource type="Script" uid="uid://5byn62y1oa76" path="res://demo/agents/scripts/health.gd" id="6_6a3q1"] + +[sub_resource type="Animation" id="Animation_i5ovs"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Gong:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Gong:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Gong:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("FX/WaveL1:visible") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("FX/WaveL1:modulate") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1)] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("FX/WaveL1:position") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-65, -89)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("FX/WaveL1:rotation") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [1.57058] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("FX/WaveL1:scale") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.5, 0.5)] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("FX/WaverR1:position") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(70, -89)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("FX/WaverR1:rotation") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [4.71215] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("FX/WaverR1:scale") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.5, 0.5)] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("FX/WaverR1:visible") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("FX/WaverR1:modulate") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("FX/WaveL2:position") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-65, -89)] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("FX/WaveL2:rotation") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [1.57058] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("FX/WaveL2:scale") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.5, 0.5)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("FX/WaverR2:position") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(70, -89)] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("FX/WaverR2:rotation") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [4.71215] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("FX/WaverR2:scale") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.5, 0.5)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("FX/WaveL3:position") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-65, -89)] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("FX/WaveL3:rotation") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [1.57058] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("FX/WaveL3:scale") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.5, 0.5)] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("FX/WaverR3:position") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(70, -89)] +} +tracks/23/type = "value" +tracks/23/imported = false +tracks/23/enabled = true +tracks/23/path = NodePath("FX/WaverR3:rotation") +tracks/23/interp = 1 +tracks/23/loop_wrap = true +tracks/23/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [4.71215] +} +tracks/24/type = "value" +tracks/24/imported = false +tracks/24/enabled = true +tracks/24/path = NodePath("FX/WaverR3:scale") +tracks/24/interp = 1 +tracks/24/loop_wrap = true +tracks/24/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.5, 0.5)] +} +tracks/25/type = "value" +tracks/25/imported = false +tracks/25/enabled = true +tracks/25/path = NodePath("FX/WaveL2:visible") +tracks/25/interp = 1 +tracks/25/loop_wrap = true +tracks/25/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/26/type = "value" +tracks/26/imported = false +tracks/26/enabled = true +tracks/26/path = NodePath("FX/WaveL2:modulate") +tracks/26/interp = 1 +tracks/26/loop_wrap = true +tracks/26/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1)] +} +tracks/27/type = "value" +tracks/27/imported = false +tracks/27/enabled = true +tracks/27/path = NodePath("FX/WaverR2:visible") +tracks/27/interp = 1 +tracks/27/loop_wrap = true +tracks/27/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/28/type = "value" +tracks/28/imported = false +tracks/28/enabled = true +tracks/28/path = NodePath("FX/WaverR2:modulate") +tracks/28/interp = 1 +tracks/28/loop_wrap = true +tracks/28/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1)] +} +tracks/29/type = "value" +tracks/29/imported = false +tracks/29/enabled = true +tracks/29/path = NodePath("FX/WaveL3:visible") +tracks/29/interp = 1 +tracks/29/loop_wrap = true +tracks/29/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/30/type = "value" +tracks/30/imported = false +tracks/30/enabled = true +tracks/30/path = NodePath("FX/WaveL3:modulate") +tracks/30/interp = 1 +tracks/30/loop_wrap = true +tracks/30/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1)] +} +tracks/31/type = "value" +tracks/31/imported = false +tracks/31/enabled = true +tracks/31/path = NodePath("FX/WaverR3:visible") +tracks/31/interp = 1 +tracks/31/loop_wrap = true +tracks/31/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/32/type = "value" +tracks/32/imported = false +tracks/32/enabled = true +tracks/32/path = NodePath("FX/WaverR3:modulate") +tracks/32/interp = 1 +tracks/32/loop_wrap = true +tracks/32/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1)] +} + +[sub_resource type="Animation" id="Animation_ie54r"] +resource_name = "struck" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Root/Gong:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Root/Gong:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Root/Gong:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(1.1, 0.9), Vector2(0.9, 1.1), Vector2(1.08, 0.92), Vector2(0.92, 1.08), Vector2(1.06, 0.94), Vector2(0.94, 1.06), Vector2(1.04, 0.96), Vector2(0.96, 1.04), Vector2(1.02, 0.98), Vector2(0.98, 1.02), Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("FX/WaveL1:visible") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("FX/WaveL1:modulate") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1), Color(0.607843, 0.898039, 1, 0)] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("FX/WaveL1:position") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(-65, -89), Vector2(-165, -89)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("FX/WaveL1:rotation") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [1.57058, 1.57058] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("FX/WaveL1:scale") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(0.5, 0.5), Vector2(1, 1)] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("FX/WaverR1:position") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(70, -89), Vector2(170, -89)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("FX/WaverR1:rotation") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [4.71215, 4.71215] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("FX/WaverR1:scale") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(0.5, 0.5), Vector2(1, 1)] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("FX/WaverR1:visible") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("FX/WaverR1:modulate") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0.1, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1), Color(0.607843, 0.898039, 1, 0)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("FX/WaveL2:position") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 0.2, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-65, -89), Vector2(-65, -89), Vector2(-165, -89)] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("FX/WaveL2:rotation") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 0.2, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [1.57058, 1.57058, 1.57058] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("FX/WaveL2:scale") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 0.2, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(0.5, 0.5), Vector2(0.5, 0.5), Vector2(1, 1)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("FX/WaverR2:position") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 0.2, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(70, -89), Vector2(70, -89), Vector2(170, -89)] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("FX/WaverR2:rotation") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 0.2, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [4.71215, 4.71215, 4.71215] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("FX/WaverR2:scale") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0, 0.2, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(0.5, 0.5), Vector2(0.5, 0.5), Vector2(1, 1)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("FX/WaveL3:position") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 0.4, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-65, -89), Vector2(-65, -89), Vector2(-165, -89)] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("FX/WaveL3:rotation") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 0.4), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [1.57058, 1.57058] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("FX/WaveL3:scale") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0, 0.4, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(0.5, 0.5), Vector2(0.5, 0.5), Vector2(1, 1)] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("FX/WaverR3:position") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0, 0.4, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(70, -89), Vector2(70, -89), Vector2(170, -89)] +} +tracks/23/type = "value" +tracks/23/imported = false +tracks/23/enabled = true +tracks/23/path = NodePath("FX/WaverR3:rotation") +tracks/23/interp = 1 +tracks/23/loop_wrap = true +tracks/23/keys = { +"times": PackedFloat32Array(0, 0.4), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [4.71215, 4.71215] +} +tracks/24/type = "value" +tracks/24/imported = false +tracks/24/enabled = true +tracks/24/path = NodePath("FX/WaverR3:scale") +tracks/24/interp = 1 +tracks/24/loop_wrap = true +tracks/24/keys = { +"times": PackedFloat32Array(0, 0.4, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(0.5, 0.5), Vector2(0.5, 0.5), Vector2(1, 1)] +} +tracks/25/type = "value" +tracks/25/imported = false +tracks/25/enabled = true +tracks/25/path = NodePath("FX/WaveL2:visible") +tracks/25/interp = 1 +tracks/25/loop_wrap = true +tracks/25/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [false, true] +} +tracks/26/type = "value" +tracks/26/imported = false +tracks/26/enabled = true +tracks/26/path = NodePath("FX/WaveL2:modulate") +tracks/26/interp = 1 +tracks/26/loop_wrap = true +tracks/26/keys = { +"times": PackedFloat32Array(0, 0.2, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1), Color(0.329412, 0.352941, 0.392157, 1), Color(0.607843, 0.898039, 1, 0)] +} +tracks/27/type = "value" +tracks/27/imported = false +tracks/27/enabled = true +tracks/27/path = NodePath("FX/WaverR2:visible") +tracks/27/interp = 1 +tracks/27/loop_wrap = true +tracks/27/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [false, true] +} +tracks/28/type = "value" +tracks/28/imported = false +tracks/28/enabled = true +tracks/28/path = NodePath("FX/WaverR2:modulate") +tracks/28/interp = 1 +tracks/28/loop_wrap = true +tracks/28/keys = { +"times": PackedFloat32Array(0, 0.2, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1), Color(0.329412, 0.352941, 0.392157, 1), Color(0.607843, 0.898039, 1, 0)] +} +tracks/29/type = "value" +tracks/29/imported = false +tracks/29/enabled = true +tracks/29/path = NodePath("FX/WaveL3:visible") +tracks/29/interp = 1 +tracks/29/loop_wrap = true +tracks/29/keys = { +"times": PackedFloat32Array(0, 0.4), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [false, true] +} +tracks/30/type = "value" +tracks/30/imported = false +tracks/30/enabled = true +tracks/30/path = NodePath("FX/WaveL3:modulate") +tracks/30/interp = 1 +tracks/30/loop_wrap = true +tracks/30/keys = { +"times": PackedFloat32Array(-0.00147765, 0.4, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1), Color(0.329412, 0.352941, 0.392157, 1), Color(0.607843, 0.898039, 1, 0)] +} +tracks/31/type = "value" +tracks/31/imported = false +tracks/31/enabled = true +tracks/31/path = NodePath("FX/WaverR3:visible") +tracks/31/interp = 1 +tracks/31/loop_wrap = true +tracks/31/keys = { +"times": PackedFloat32Array(0, 0.4), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [false, true] +} +tracks/32/type = "value" +tracks/32/imported = false +tracks/32/enabled = true +tracks/32/path = NodePath("FX/WaverR3:modulate") +tracks/32/interp = 1 +tracks/32/loop_wrap = true +tracks/32/keys = { +"times": PackedFloat32Array(-0.00147765, 0.4, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Color(0.329412, 0.352941, 0.392157, 1), Color(0.329412, 0.352941, 0.392157, 1), Color(0.607843, 0.898039, 1, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_332s2"] +_data = { +&"RESET": SubResource("Animation_i5ovs"), +&"struck": SubResource("Animation_ie54r") +} + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_nixvt"] +radius = 20.91 +height = 186.37 + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_ru7jf"] +radius = 39.2 +height = 253.42 + +[node name="Gong" type="StaticBody2D"] +script = ExtResource("1_77c1i") +metadata/_edit_horizontal_guides_ = [111.0] + +[node name="Root" type="Node2D" parent="."] +metadata/_edit_lock_ = true + +[node name="Shadow" type="Sprite2D" parent="Root"] +modulate = Color(1, 1, 1, 0.329412) +position = Vector2(0, -8) +scale = Vector2(2.31, 1.7) +texture = ExtResource("1_vl1mv") + +[node name="Gong" type="Sprite2D" parent="Root"] +texture = ExtResource("1_kbnv6") +offset = Vector2(0, -110) + +[node name="FX" type="Node2D" parent="."] +metadata/_edit_lock_ = true + +[node name="WaveL1" type="Sprite2D" parent="FX"] +visible = false +modulate = Color(0.329412, 0.352941, 0.392157, 1) +position = Vector2(-65, -89) +rotation = 1.57058 +scale = Vector2(0.5, 0.5) +texture = ExtResource("2_dib3m") +region_enabled = true +region_rect = Rect2(0, 0, 191, 74) + +[node name="WaverR1" type="Sprite2D" parent="FX"] +visible = false +modulate = Color(0.329412, 0.352941, 0.392157, 1) +position = Vector2(70, -89) +rotation = 4.71215 +scale = Vector2(0.5, 0.5) +texture = ExtResource("2_dib3m") +region_enabled = true +region_rect = Rect2(0, 0, 191, 74) + +[node name="WaveL2" type="Sprite2D" parent="FX"] +visible = false +modulate = Color(0.329412, 0.352941, 0.392157, 1) +position = Vector2(-65, -89) +rotation = 1.57058 +scale = Vector2(0.5, 0.5) +texture = ExtResource("2_dib3m") +region_enabled = true +region_rect = Rect2(0, 0, 191, 74) + +[node name="WaverR2" type="Sprite2D" parent="FX"] +visible = false +modulate = Color(0.329412, 0.352941, 0.392157, 1) +position = Vector2(70, -89) +rotation = 4.71215 +scale = Vector2(0.5, 0.5) +texture = ExtResource("2_dib3m") +region_enabled = true +region_rect = Rect2(0, 0, 191, 74) + +[node name="WaveL3" type="Sprite2D" parent="FX"] +visible = false +modulate = Color(0.329412, 0.352941, 0.392157, 1) +position = Vector2(-65, -89) +rotation = 1.57058 +scale = Vector2(0.5, 0.5) +texture = ExtResource("2_dib3m") +region_enabled = true +region_rect = Rect2(0, 0, 191, 74) + +[node name="WaverR3" type="Sprite2D" parent="FX"] +visible = false +modulate = Color(0.329412, 0.352941, 0.392157, 1) +position = Vector2(70, -89) +rotation = 4.71215 +scale = Vector2(0.5, 0.5) +texture = ExtResource("2_dib3m") +region_enabled = true +region_rect = Rect2(0, 0, 191, 74) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_332s2") +} + +[node name="GongSFX" type="AudioStreamPlayer" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(0, -14.395) +rotation = 1.5708 +shape = SubResource("CapsuleShape2D_nixvt") + +[node name="Hurtbox" type="Area2D" parent="." node_paths=PackedStringArray("health")] +collision_layer = 8 +collision_mask = 0 +script = ExtResource("5_xeb5y") +health = NodePath("../Health") + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="Hurtbox"] +position = Vector2(0, -14.395) +rotation = 1.5708 +shape = SubResource("CapsuleShape2D_ru7jf") +debug_color = Color(0.886275, 0.109804, 0.756863, 0.419608) + +[node name="Health" type="Node" parent="."] +script = ExtResource("6_6a3q1") +max_health = 1e+11 + +[connection signal="damaged" from="Health" to="." method="_on_health_damaged"] diff --git a/demo/scenes/base/arena.tscn b/demo/scenes/base/arena.tscn new file mode 100644 index 0000000..0bdecf2 --- /dev/null +++ b/demo/scenes/base/arena.tscn @@ -0,0 +1,5142 @@ +[gd_scene load_steps=8 format=3 uid="uid://bsig1usigbbuy"] + +[ext_resource type="Texture2D" uid="uid://65b6yuobhxf8" path="res://demo/assets/env_clouds.png" id="1_1blat"] +[ext_resource type="Texture2D" uid="uid://b3g14elmg0m36" path="res://demo/assets/env_rocks.png" id="1_145kx"] +[ext_resource type="Texture2D" uid="uid://cc7b22sy46gwn" path="res://demo/assets/env_ground.png" id="1_vifjc"] +[ext_resource type="Texture2D" uid="uid://4kw2ks8doc0w" path="res://demo/assets/env_plants.png" id="2_kesm7"] + +[sub_resource type="Animation" id="Animation_gwtgs"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Environment/Clouds/Cloud11:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3784, 345)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Environment/Clouds/Cloud1:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(764, 358)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Environment/Clouds/Cloud13:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(4005, 2983)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Environment/Clouds/Cloud5:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-152, 2723)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Environment/Clouds/Cloud6:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3293, 936)] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Environment/Clouds/Cloud2:position") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(85, 1505)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Environment/Clouds/Cloud16:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3434, 3542)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Environment/Clouds/Cloud7:position") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1380, 3802)] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Environment/Clouds/Cloud3:position") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(503, 1222)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Environment/Clouds/Cloud14:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(4174, 3309)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Environment/Clouds/Cloud15:position") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(4695, 2800)] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Environment/Clouds/Cloud8:position") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(152, 3383)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Environment/Clouds/Cloud4:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(164, 1669)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Environment/Clouds/Cloud9:position") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(328, 3474)] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Environment/Clouds/Cloud10:position") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(933, 515)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Environment/Clouds/Cloud12:position") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(4570, 1222)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Environment/Clouds/Cloud11:scale") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Environment/Clouds/Cloud1:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("Environment/Clouds/Cloud13:scale") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Environment/Clouds/Cloud5:scale") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Environment/Clouds/Cloud6:scale") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Environment/Clouds/Cloud2:scale") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("Environment/Clouds/Cloud16:scale") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/23/type = "value" +tracks/23/imported = false +tracks/23/enabled = true +tracks/23/path = NodePath("Environment/Clouds/Cloud7:scale") +tracks/23/interp = 1 +tracks/23/loop_wrap = true +tracks/23/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/24/type = "value" +tracks/24/imported = false +tracks/24/enabled = true +tracks/24/path = NodePath("Environment/Clouds/Cloud3:scale") +tracks/24/interp = 1 +tracks/24/loop_wrap = true +tracks/24/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/25/type = "value" +tracks/25/imported = false +tracks/25/enabled = true +tracks/25/path = NodePath("Environment/Clouds/Cloud14:scale") +tracks/25/interp = 1 +tracks/25/loop_wrap = true +tracks/25/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/26/type = "value" +tracks/26/imported = false +tracks/26/enabled = true +tracks/26/path = NodePath("Environment/Clouds/Cloud15:scale") +tracks/26/interp = 1 +tracks/26/loop_wrap = true +tracks/26/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/27/type = "value" +tracks/27/imported = false +tracks/27/enabled = true +tracks/27/path = NodePath("Environment/Clouds/Cloud8:scale") +tracks/27/interp = 1 +tracks/27/loop_wrap = true +tracks/27/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/28/type = "value" +tracks/28/imported = false +tracks/28/enabled = true +tracks/28/path = NodePath("Environment/Clouds/Cloud4:scale") +tracks/28/interp = 1 +tracks/28/loop_wrap = true +tracks/28/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/29/type = "value" +tracks/29/imported = false +tracks/29/enabled = true +tracks/29/path = NodePath("Environment/Clouds/Cloud9:scale") +tracks/29/interp = 1 +tracks/29/loop_wrap = true +tracks/29/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/30/type = "value" +tracks/30/imported = false +tracks/30/enabled = true +tracks/30/path = NodePath("Environment/Clouds/Cloud10:scale") +tracks/30/interp = 1 +tracks/30/loop_wrap = true +tracks/30/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/31/type = "value" +tracks/31/imported = false +tracks/31/enabled = true +tracks/31/path = NodePath("Environment/Clouds/Cloud12:scale") +tracks/31/interp = 1 +tracks/31/loop_wrap = true +tracks/31/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/32/type = "value" +tracks/32/imported = false +tracks/32/enabled = true +tracks/32/path = NodePath("Environment/Clouds/Cloud1:visible") +tracks/32/interp = 1 +tracks/32/loop_wrap = true +tracks/32/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/33/type = "value" +tracks/33/imported = false +tracks/33/enabled = true +tracks/33/path = NodePath("Environment/Clouds/Cloud13:visible") +tracks/33/interp = 1 +tracks/33/loop_wrap = true +tracks/33/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/34/type = "value" +tracks/34/imported = false +tracks/34/enabled = true +tracks/34/path = NodePath("Environment/Clouds/Cloud5:visible") +tracks/34/interp = 1 +tracks/34/loop_wrap = true +tracks/34/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/35/type = "value" +tracks/35/imported = false +tracks/35/enabled = true +tracks/35/path = NodePath("Environment/Clouds/Cloud6:visible") +tracks/35/interp = 1 +tracks/35/loop_wrap = true +tracks/35/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/36/type = "value" +tracks/36/imported = false +tracks/36/enabled = true +tracks/36/path = NodePath("Environment/Clouds/Cloud2:visible") +tracks/36/interp = 1 +tracks/36/loop_wrap = true +tracks/36/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/37/type = "value" +tracks/37/imported = false +tracks/37/enabled = true +tracks/37/path = NodePath("Environment/Clouds/Cloud16:visible") +tracks/37/interp = 1 +tracks/37/loop_wrap = true +tracks/37/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/38/type = "value" +tracks/38/imported = false +tracks/38/enabled = true +tracks/38/path = NodePath("Environment/Clouds/Cloud7:visible") +tracks/38/interp = 1 +tracks/38/loop_wrap = true +tracks/38/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/39/type = "value" +tracks/39/imported = false +tracks/39/enabled = true +tracks/39/path = NodePath("Environment/Clouds/Cloud3:visible") +tracks/39/interp = 1 +tracks/39/loop_wrap = true +tracks/39/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/40/type = "value" +tracks/40/imported = false +tracks/40/enabled = true +tracks/40/path = NodePath("Environment/Clouds/Cloud14:visible") +tracks/40/interp = 1 +tracks/40/loop_wrap = true +tracks/40/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/41/type = "value" +tracks/41/imported = false +tracks/41/enabled = true +tracks/41/path = NodePath("Environment/Clouds/Cloud15:visible") +tracks/41/interp = 1 +tracks/41/loop_wrap = true +tracks/41/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/42/type = "value" +tracks/42/imported = false +tracks/42/enabled = true +tracks/42/path = NodePath("Environment/Clouds/Cloud8:visible") +tracks/42/interp = 1 +tracks/42/loop_wrap = true +tracks/42/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/43/type = "value" +tracks/43/imported = false +tracks/43/enabled = true +tracks/43/path = NodePath("Environment/Clouds/Cloud4:visible") +tracks/43/interp = 1 +tracks/43/loop_wrap = true +tracks/43/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/44/type = "value" +tracks/44/imported = false +tracks/44/enabled = true +tracks/44/path = NodePath("Environment/Clouds/Cloud9:visible") +tracks/44/interp = 1 +tracks/44/loop_wrap = true +tracks/44/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/45/type = "value" +tracks/45/imported = false +tracks/45/enabled = true +tracks/45/path = NodePath("Environment/Clouds/Cloud10:visible") +tracks/45/interp = 1 +tracks/45/loop_wrap = true +tracks/45/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/46/type = "value" +tracks/46/imported = false +tracks/46/enabled = true +tracks/46/path = NodePath("Environment/Clouds/Cloud12:visible") +tracks/46/interp = 1 +tracks/46/loop_wrap = true +tracks/46/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/47/type = "value" +tracks/47/imported = false +tracks/47/enabled = true +tracks/47/path = NodePath("Environment/Clouds/Cloud11:visible") +tracks/47/interp = 1 +tracks/47/loop_wrap = true +tracks/47/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/48/type = "value" +tracks/48/imported = false +tracks/48/enabled = true +tracks/48/path = NodePath("Environment/Clouds/Cloud17:position") +tracks/48/interp = 1 +tracks/48/loop_wrap = true +tracks/48/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-2737.13, 367.814)] +} +tracks/49/type = "value" +tracks/49/imported = false +tracks/49/enabled = true +tracks/49/path = NodePath("Environment/Clouds/Cloud17:scale") +tracks/49/interp = 1 +tracks/49/loop_wrap = true +tracks/49/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1.35085, 1.15254)] +} +tracks/50/type = "value" +tracks/50/imported = false +tracks/50/enabled = true +tracks/50/path = NodePath("Environment/Clouds/Cloud18:position") +tracks/50/interp = 1 +tracks/50/loop_wrap = true +tracks/50/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-1254.92, 3539.61)] +} +tracks/51/type = "value" +tracks/51/imported = false +tracks/51/enabled = true +tracks/51/path = NodePath("Environment/Clouds/Cloud18:scale") +tracks/51/interp = 1 +tracks/51/loop_wrap = true +tracks/51/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.898305, 0.898305)] +} +tracks/52/type = "value" +tracks/52/imported = false +tracks/52/enabled = true +tracks/52/path = NodePath("Environment/Clouds/Cloud19:position") +tracks/52/interp = 1 +tracks/52/loop_wrap = true +tracks/52/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-2912.7, 1260.29)] +} +tracks/53/type = "value" +tracks/53/imported = false +tracks/53/enabled = true +tracks/53/path = NodePath("Environment/Clouds/Cloud19:scale") +tracks/53/interp = 1 +tracks/53/loop_wrap = true +tracks/53/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1.10169, 1.10169)] +} +tracks/54/type = "value" +tracks/54/imported = false +tracks/54/enabled = true +tracks/54/path = NodePath("Environment/Clouds/Cloud20:position") +tracks/54/interp = 1 +tracks/54/loop_wrap = true +tracks/54/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-3251.5, 3437.56)] +} +tracks/55/type = "value" +tracks/55/imported = false +tracks/55/enabled = true +tracks/55/path = NodePath("Environment/Clouds/Cloud20:scale") +tracks/55/interp = 1 +tracks/55/loop_wrap = true +tracks/55/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/56/type = "value" +tracks/56/imported = false +tracks/56/enabled = true +tracks/56/path = NodePath("Environment/Clouds/Cloud21:position") +tracks/56/interp = 1 +tracks/56/loop_wrap = true +tracks/56/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-3181.26, 3581.44)] +} +tracks/57/type = "value" +tracks/57/imported = false +tracks/57/enabled = true +tracks/57/path = NodePath("Environment/Clouds/Cloud21:scale") +tracks/57/interp = 1 +tracks/57/loop_wrap = true +tracks/57/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.949153, 0.949153)] +} +tracks/58/type = "value" +tracks/58/imported = false +tracks/58/enabled = true +tracks/58/path = NodePath("Environment/Clouds/Cloud22:position") +tracks/58/interp = 1 +tracks/58/loop_wrap = true +tracks/58/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-420.856, 367.017)] +} +tracks/59/type = "value" +tracks/59/imported = false +tracks/59/enabled = true +tracks/59/path = NodePath("Environment/Clouds/Cloud22:scale") +tracks/59/interp = 1 +tracks/59/loop_wrap = true +tracks/59/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/60/type = "value" +tracks/60/imported = false +tracks/60/enabled = true +tracks/60/path = NodePath("Environment/Clouds/Cloud17:visible") +tracks/60/interp = 1 +tracks/60/loop_wrap = true +tracks/60/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/61/type = "value" +tracks/61/imported = false +tracks/61/enabled = true +tracks/61/path = NodePath("Environment/Clouds/Cloud18:visible") +tracks/61/interp = 1 +tracks/61/loop_wrap = true +tracks/61/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/62/type = "value" +tracks/62/imported = false +tracks/62/enabled = true +tracks/62/path = NodePath("Environment/Clouds/Cloud19:visible") +tracks/62/interp = 1 +tracks/62/loop_wrap = true +tracks/62/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/63/type = "value" +tracks/63/imported = false +tracks/63/enabled = true +tracks/63/path = NodePath("Environment/Clouds/Cloud20:visible") +tracks/63/interp = 1 +tracks/63/loop_wrap = true +tracks/63/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/64/type = "value" +tracks/64/imported = false +tracks/64/enabled = true +tracks/64/path = NodePath("Environment/Clouds/Cloud21:visible") +tracks/64/interp = 1 +tracks/64/loop_wrap = true +tracks/64/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/65/type = "value" +tracks/65/imported = false +tracks/65/enabled = true +tracks/65/path = NodePath("Environment/Clouds/Cloud22:visible") +tracks/65/interp = 1 +tracks/65/loop_wrap = true +tracks/65/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/66/type = "value" +tracks/66/imported = false +tracks/66/enabled = true +tracks/66/path = NodePath("Environment/Clouds/Cloud28:position") +tracks/66/interp = 1 +tracks/66/loop_wrap = true +tracks/66/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-461, 1787)] +} +tracks/67/type = "value" +tracks/67/imported = false +tracks/67/enabled = true +tracks/67/path = NodePath("Environment/Clouds/Cloud28:scale") +tracks/67/interp = 1 +tracks/67/loop_wrap = true +tracks/67/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1.10169, 1.10169)] +} +tracks/68/type = "value" +tracks/68/imported = false +tracks/68/enabled = true +tracks/68/path = NodePath("Environment/Clouds/Cloud23:position") +tracks/68/interp = 1 +tracks/68/loop_wrap = true +tracks/68/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-1493, 3040)] +} +tracks/69/type = "value" +tracks/69/imported = false +tracks/69/enabled = true +tracks/69/path = NodePath("Environment/Clouds/Cloud23:scale") +tracks/69/interp = 1 +tracks/69/loop_wrap = true +tracks/69/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.898305, 0.898305)] +} +tracks/70/type = "value" +tracks/70/imported = false +tracks/70/enabled = true +tracks/70/path = NodePath("Environment/Clouds/Cloud24:position") +tracks/70/interp = 1 +tracks/70/loop_wrap = true +tracks/70/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-510, 2429)] +} +tracks/71/type = "value" +tracks/71/imported = false +tracks/71/enabled = true +tracks/71/path = NodePath("Environment/Clouds/Cloud24:scale") +tracks/71/interp = 1 +tracks/71/loop_wrap = true +tracks/71/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1.15254, 1.15254)] +} +tracks/72/type = "value" +tracks/72/imported = false +tracks/72/enabled = true +tracks/72/path = NodePath("Environment/Clouds/Cloud25:position") +tracks/72/interp = 1 +tracks/72/loop_wrap = true +tracks/72/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-712, 1373)] +} +tracks/73/type = "value" +tracks/73/imported = false +tracks/73/enabled = true +tracks/73/path = NodePath("Environment/Clouds/Cloud25:scale") +tracks/73/interp = 1 +tracks/73/loop_wrap = true +tracks/73/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1.10169, 1.10169)] +} +tracks/74/type = "value" +tracks/74/imported = false +tracks/74/enabled = true +tracks/74/path = NodePath("Environment/Clouds/Cloud26:position") +tracks/74/interp = 1 +tracks/74/loop_wrap = true +tracks/74/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-269, 2004)] +} +tracks/75/type = "value" +tracks/75/imported = false +tracks/75/enabled = true +tracks/75/path = NodePath("Environment/Clouds/Cloud26:scale") +tracks/75/interp = 1 +tracks/75/loop_wrap = true +tracks/75/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.79661, 0.79661)] +} +tracks/76/type = "value" +tracks/76/imported = false +tracks/76/enabled = true +tracks/76/path = NodePath("Environment/Clouds/Cloud27:position") +tracks/76/interp = 1 +tracks/76/loop_wrap = true +tracks/76/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-1656, 2353)] +} +tracks/77/type = "value" +tracks/77/imported = false +tracks/77/enabled = true +tracks/77/path = NodePath("Environment/Clouds/Cloud27:scale") +tracks/77/interp = 1 +tracks/77/loop_wrap = true +tracks/77/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.949153, 0.949153)] +} +tracks/78/type = "value" +tracks/78/imported = false +tracks/78/enabled = true +tracks/78/path = NodePath("Environment/Clouds/Cloud23:visible") +tracks/78/interp = 1 +tracks/78/loop_wrap = true +tracks/78/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/79/type = "value" +tracks/79/imported = false +tracks/79/enabled = true +tracks/79/path = NodePath("Environment/Clouds/Cloud24:visible") +tracks/79/interp = 1 +tracks/79/loop_wrap = true +tracks/79/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/80/type = "value" +tracks/80/imported = false +tracks/80/enabled = true +tracks/80/path = NodePath("Environment/Clouds/Cloud25:visible") +tracks/80/interp = 1 +tracks/80/loop_wrap = true +tracks/80/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/81/type = "value" +tracks/81/imported = false +tracks/81/enabled = true +tracks/81/path = NodePath("Environment/Clouds/Cloud26:visible") +tracks/81/interp = 1 +tracks/81/loop_wrap = true +tracks/81/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/82/type = "value" +tracks/82/imported = false +tracks/82/enabled = true +tracks/82/path = NodePath("Environment/Clouds/Cloud27:visible") +tracks/82/interp = 1 +tracks/82/loop_wrap = true +tracks/82/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/83/type = "value" +tracks/83/imported = false +tracks/83/enabled = true +tracks/83/path = NodePath("Environment/Clouds/Cloud28:visible") +tracks/83/interp = 1 +tracks/83/loop_wrap = true +tracks/83/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/84/type = "value" +tracks/84/imported = false +tracks/84/enabled = true +tracks/84/path = NodePath("Environment/Clouds/Cloud29:position") +tracks/84/interp = 1 +tracks/84/loop_wrap = true +tracks/84/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3890, 2612.5)] +} +tracks/85/type = "value" +tracks/85/imported = false +tracks/85/enabled = true +tracks/85/path = NodePath("Environment/Clouds/Cloud29:scale") +tracks/85/interp = 1 +tracks/85/loop_wrap = true +tracks/85/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/86/type = "value" +tracks/86/imported = false +tracks/86/enabled = true +tracks/86/path = NodePath("Environment/Clouds/Cloud30:position") +tracks/86/interp = 1 +tracks/86/loop_wrap = true +tracks/86/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3832, 1394.5)] +} +tracks/87/type = "value" +tracks/87/imported = false +tracks/87/enabled = true +tracks/87/path = NodePath("Environment/Clouds/Cloud30:scale") +tracks/87/interp = 1 +tracks/87/loop_wrap = true +tracks/87/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/88/type = "value" +tracks/88/imported = false +tracks/88/enabled = true +tracks/88/path = NodePath("Environment/Clouds/Cloud31:position") +tracks/88/interp = 1 +tracks/88/loop_wrap = true +tracks/88/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3472, 3106)] +} +tracks/89/type = "value" +tracks/89/imported = false +tracks/89/enabled = true +tracks/89/path = NodePath("Environment/Clouds/Cloud31:scale") +tracks/89/interp = 1 +tracks/89/loop_wrap = true +tracks/89/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/90/type = "value" +tracks/90/imported = false +tracks/90/enabled = true +tracks/90/path = NodePath("Environment/Clouds/Cloud32:position") +tracks/90/interp = 1 +tracks/90/loop_wrap = true +tracks/90/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3095, 2689.5)] +} +tracks/91/type = "value" +tracks/91/imported = false +tracks/91/enabled = true +tracks/91/path = NodePath("Environment/Clouds/Cloud32:scale") +tracks/91/interp = 1 +tracks/91/loop_wrap = true +tracks/91/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/92/type = "value" +tracks/92/imported = false +tracks/92/enabled = true +tracks/92/path = NodePath("Environment/Clouds/Cloud33:position") +tracks/92/interp = 1 +tracks/92/loop_wrap = true +tracks/92/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(4016, 1558.5)] +} +tracks/93/type = "value" +tracks/93/imported = false +tracks/93/enabled = true +tracks/93/path = NodePath("Environment/Clouds/Cloud33:scale") +tracks/93/interp = 1 +tracks/93/loop_wrap = true +tracks/93/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/94/type = "value" +tracks/94/imported = false +tracks/94/enabled = true +tracks/94/path = NodePath("Environment/Clouds/Cloud29:visible") +tracks/94/interp = 1 +tracks/94/loop_wrap = true +tracks/94/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/95/type = "value" +tracks/95/imported = false +tracks/95/enabled = true +tracks/95/path = NodePath("Environment/Clouds/Cloud30:visible") +tracks/95/interp = 1 +tracks/95/loop_wrap = true +tracks/95/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/96/type = "value" +tracks/96/imported = false +tracks/96/enabled = true +tracks/96/path = NodePath("Environment/Clouds/Cloud31:visible") +tracks/96/interp = 1 +tracks/96/loop_wrap = true +tracks/96/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/97/type = "value" +tracks/97/imported = false +tracks/97/enabled = true +tracks/97/path = NodePath("Environment/Clouds/Cloud32:visible") +tracks/97/interp = 1 +tracks/97/loop_wrap = true +tracks/97/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/98/type = "value" +tracks/98/imported = false +tracks/98/enabled = true +tracks/98/path = NodePath("Environment/Clouds/Cloud33:visible") +tracks/98/interp = 1 +tracks/98/loop_wrap = true +tracks/98/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/99/type = "value" +tracks/99/imported = false +tracks/99/enabled = true +tracks/99/path = NodePath("Environment/Clouds/Cloud34:position") +tracks/99/interp = 1 +tracks/99/loop_wrap = true +tracks/99/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3863, 1375)] +} +tracks/100/type = "value" +tracks/100/imported = false +tracks/100/enabled = true +tracks/100/path = NodePath("Environment/Clouds/Cloud34:scale") +tracks/100/interp = 1 +tracks/100/loop_wrap = true +tracks/100/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/101/type = "value" +tracks/101/imported = false +tracks/101/enabled = true +tracks/101/path = NodePath("Environment/Clouds/Cloud35:position") +tracks/101/interp = 1 +tracks/101/loop_wrap = true +tracks/101/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3521.25, 3087)] +} +tracks/102/type = "value" +tracks/102/imported = false +tracks/102/enabled = true +tracks/102/path = NodePath("Environment/Clouds/Cloud35:scale") +tracks/102/interp = 1 +tracks/102/loop_wrap = true +tracks/102/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/103/type = "value" +tracks/103/imported = false +tracks/103/enabled = true +tracks/103/path = NodePath("Environment/Clouds/Cloud36:position") +tracks/103/interp = 1 +tracks/103/loop_wrap = true +tracks/103/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3609.25, 3161)] +} +tracks/104/type = "value" +tracks/104/imported = false +tracks/104/enabled = true +tracks/104/path = NodePath("Environment/Clouds/Cloud36:scale") +tracks/104/interp = 1 +tracks/104/loop_wrap = true +tracks/104/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/105/type = "value" +tracks/105/imported = false +tracks/105/enabled = true +tracks/105/path = NodePath("Environment/Clouds/Cloud37:position") +tracks/105/interp = 1 +tracks/105/loop_wrap = true +tracks/105/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3754.25, 1447)] +} +tracks/106/type = "value" +tracks/106/imported = false +tracks/106/enabled = true +tracks/106/path = NodePath("Environment/Clouds/Cloud37:scale") +tracks/106/interp = 1 +tracks/106/loop_wrap = true +tracks/106/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/107/type = "value" +tracks/107/imported = false +tracks/107/enabled = true +tracks/107/path = NodePath("Environment/Clouds/Cloud38:position") +tracks/107/interp = 1 +tracks/107/loop_wrap = true +tracks/107/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(2915.25, 2833)] +} +tracks/108/type = "value" +tracks/108/imported = false +tracks/108/enabled = true +tracks/108/path = NodePath("Environment/Clouds/Cloud38:scale") +tracks/108/interp = 1 +tracks/108/loop_wrap = true +tracks/108/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.898305, 0.898305)] +} +tracks/109/type = "value" +tracks/109/imported = false +tracks/109/enabled = true +tracks/109/path = NodePath("Environment/Clouds/Cloud39:position") +tracks/109/interp = 1 +tracks/109/loop_wrap = true +tracks/109/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(3270.25, 2207)] +} +tracks/110/type = "value" +tracks/110/imported = false +tracks/110/enabled = true +tracks/110/path = NodePath("Environment/Clouds/Cloud39:scale") +tracks/110/interp = 1 +tracks/110/loop_wrap = true +tracks/110/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/111/type = "value" +tracks/111/imported = false +tracks/111/enabled = true +tracks/111/path = NodePath("Environment/Clouds/Cloud34:visible") +tracks/111/interp = 1 +tracks/111/loop_wrap = true +tracks/111/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/112/type = "value" +tracks/112/imported = false +tracks/112/enabled = true +tracks/112/path = NodePath("Environment/Clouds/Cloud35:visible") +tracks/112/interp = 1 +tracks/112/loop_wrap = true +tracks/112/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/113/type = "value" +tracks/113/imported = false +tracks/113/enabled = true +tracks/113/path = NodePath("Environment/Clouds/Cloud36:visible") +tracks/113/interp = 1 +tracks/113/loop_wrap = true +tracks/113/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/114/type = "value" +tracks/114/imported = false +tracks/114/enabled = true +tracks/114/path = NodePath("Environment/Clouds/Cloud37:visible") +tracks/114/interp = 1 +tracks/114/loop_wrap = true +tracks/114/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/115/type = "value" +tracks/115/imported = false +tracks/115/enabled = true +tracks/115/path = NodePath("Environment/Clouds/Cloud38:visible") +tracks/115/interp = 1 +tracks/115/loop_wrap = true +tracks/115/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/116/type = "value" +tracks/116/imported = false +tracks/116/enabled = true +tracks/116/path = NodePath("Environment/Clouds/Cloud39:visible") +tracks/116/interp = 1 +tracks/116/loop_wrap = true +tracks/116/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} + +[sub_resource type="Animation" id="Animation_75lmk"] +resource_name = "float" +length = 60.2 +loop_mode = 1 +step = 0.2 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Environment/Clouds/Cloud11:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-878, 345), Vector2(8280, 329), Vector2(-878, 345)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Environment/Clouds/Cloud1:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-149, 377), Vector2(6644, 318), Vector2(-149, 377)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Environment/Clouds/Cloud13:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-856, 3012), Vector2(6701, 2975), Vector2(-856, 3012)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Environment/Clouds/Cloud5:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-152, 2723), Vector2(6304, 2691), Vector2(-152, 2723)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Environment/Clouds/Cloud6:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-1169, 936), Vector2(6941, 936), Vector2(-1169, 936)] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Environment/Clouds/Cloud2:position") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-210, 1505), Vector2(7109, 1489), Vector2(-210, 1505)] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Environment/Clouds/Cloud16:position") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-733, 3542), Vector2(6978, 3478), Vector2(-733, 3542)] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("Environment/Clouds/Cloud7:position") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-1427, 3831), Vector2(6420, 3842), Vector2(-1427, 3831)] +} +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Environment/Clouds/Cloud3:position") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-258, 1222), Vector2(6551, 1238), Vector2(-258, 1222)] +} +tracks/9/type = "value" +tracks/9/imported = false +tracks/9/enabled = true +tracks/9/path = NodePath("Environment/Clouds/Cloud14:position") +tracks/9/interp = 1 +tracks/9/loop_wrap = true +tracks/9/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-259, 3309), Vector2(7190, 3301), Vector2(-259, 3309)] +} +tracks/10/type = "value" +tracks/10/imported = false +tracks/10/enabled = true +tracks/10/path = NodePath("Environment/Clouds/Cloud15:position") +tracks/10/interp = 1 +tracks/10/loop_wrap = true +tracks/10/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-947, 2800), Vector2(7711, 2824), Vector2(-947, 2800)] +} +tracks/11/type = "value" +tracks/11/imported = false +tracks/11/enabled = true +tracks/11/path = NodePath("Environment/Clouds/Cloud8:position") +tracks/11/interp = 1 +tracks/11/loop_wrap = true +tracks/11/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-171, 3383), Vector2(6224, 3431), Vector2(-171, 3383)] +} +tracks/12/type = "value" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath("Environment/Clouds/Cloud4:position") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-26, 1669), Vector2(6716, 1797), Vector2(-26, 1669)] +} +tracks/13/type = "value" +tracks/13/imported = false +tracks/13/enabled = true +tracks/13/path = NodePath("Environment/Clouds/Cloud9:position") +tracks/13/interp = 1 +tracks/13/loop_wrap = true +tracks/13/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-500, 3474), Vector2(6192, 3626), Vector2(-500, 3474)] +} +tracks/14/type = "value" +tracks/14/imported = false +tracks/14/enabled = true +tracks/14/path = NodePath("Environment/Clouds/Cloud10:position") +tracks/14/interp = 1 +tracks/14/loop_wrap = true +tracks/14/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-285, 515), Vector2(6173, 595), Vector2(-285, 515)] +} +tracks/15/type = "value" +tracks/15/imported = false +tracks/15/enabled = true +tracks/15/path = NodePath("Environment/Clouds/Cloud12:position") +tracks/15/interp = 1 +tracks/15/loop_wrap = true +tracks/15/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(-444, 1222), Vector2(8090, 1286), Vector2(-444, 1222)] +} +tracks/16/type = "value" +tracks/16/imported = false +tracks/16/enabled = true +tracks/16/path = NodePath("Environment/Clouds/Cloud11:scale") +tracks/16/interp = 1 +tracks/16/loop_wrap = true +tracks/16/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/17/type = "value" +tracks/17/imported = false +tracks/17/enabled = true +tracks/17/path = NodePath("Environment/Clouds/Cloud1:scale") +tracks/17/interp = 1 +tracks/17/loop_wrap = true +tracks/17/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.69, 1.3), Vector2(1, 1)] +} +tracks/18/type = "value" +tracks/18/imported = false +tracks/18/enabled = true +tracks/18/path = NodePath("Environment/Clouds/Cloud13:scale") +tracks/18/interp = 1 +tracks/18/loop_wrap = true +tracks/18/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/19/type = "value" +tracks/19/imported = false +tracks/19/enabled = true +tracks/19/path = NodePath("Environment/Clouds/Cloud5:scale") +tracks/19/interp = 1 +tracks/19/loop_wrap = true +tracks/19/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.8, 0.8), Vector2(1, 1)] +} +tracks/20/type = "value" +tracks/20/imported = false +tracks/20/enabled = true +tracks/20/path = NodePath("Environment/Clouds/Cloud6:scale") +tracks/20/interp = 1 +tracks/20/loop_wrap = true +tracks/20/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.2, 1.2), Vector2(1, 1)] +} +tracks/21/type = "value" +tracks/21/imported = false +tracks/21/enabled = true +tracks/21/path = NodePath("Environment/Clouds/Cloud2:scale") +tracks/21/interp = 1 +tracks/21/loop_wrap = true +tracks/21/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/22/type = "value" +tracks/22/imported = false +tracks/22/enabled = true +tracks/22/path = NodePath("Environment/Clouds/Cloud16:scale") +tracks/22/interp = 1 +tracks/22/loop_wrap = true +tracks/22/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.8, 0.8), Vector2(1, 1)] +} +tracks/23/type = "value" +tracks/23/imported = false +tracks/23/enabled = true +tracks/23/path = NodePath("Environment/Clouds/Cloud7:scale") +tracks/23/interp = 1 +tracks/23/loop_wrap = true +tracks/23/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.2, 1.2), Vector2(1, 1)] +} +tracks/24/type = "value" +tracks/24/imported = false +tracks/24/enabled = true +tracks/24/path = NodePath("Environment/Clouds/Cloud3:scale") +tracks/24/interp = 1 +tracks/24/loop_wrap = true +tracks/24/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.2, 1.2), Vector2(1, 1)] +} +tracks/25/type = "value" +tracks/25/imported = false +tracks/25/enabled = true +tracks/25/path = NodePath("Environment/Clouds/Cloud14:scale") +tracks/25/interp = 1 +tracks/25/loop_wrap = true +tracks/25/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/26/type = "value" +tracks/26/imported = false +tracks/26/enabled = true +tracks/26/path = NodePath("Environment/Clouds/Cloud15:scale") +tracks/26/interp = 1 +tracks/26/loop_wrap = true +tracks/26/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.6, 0.6), Vector2(1, 1)] +} +tracks/27/type = "value" +tracks/27/imported = false +tracks/27/enabled = true +tracks/27/path = NodePath("Environment/Clouds/Cloud8:scale") +tracks/27/interp = 1 +tracks/27/loop_wrap = true +tracks/27/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/28/type = "value" +tracks/28/imported = false +tracks/28/enabled = true +tracks/28/path = NodePath("Environment/Clouds/Cloud4:scale") +tracks/28/interp = 1 +tracks/28/loop_wrap = true +tracks/28/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/29/type = "value" +tracks/29/imported = false +tracks/29/enabled = true +tracks/29/path = NodePath("Environment/Clouds/Cloud9:scale") +tracks/29/interp = 1 +tracks/29/loop_wrap = true +tracks/29/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(0.9, 0.9), Vector2(1, 1)] +} +tracks/30/type = "value" +tracks/30/imported = false +tracks/30/enabled = true +tracks/30/path = NodePath("Environment/Clouds/Cloud10:scale") +tracks/30/interp = 1 +tracks/30/loop_wrap = true +tracks/30/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.2, 1.2), Vector2(1, 1)] +} +tracks/31/type = "value" +tracks/31/imported = false +tracks/31/enabled = true +tracks/31/path = NodePath("Environment/Clouds/Cloud12:scale") +tracks/31/interp = 1 +tracks/31/loop_wrap = true +tracks/31/keys = { +"times": PackedFloat32Array(0, 59, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1.2, 1.2), Vector2(1, 1)] +} +tracks/32/type = "value" +tracks/32/imported = false +tracks/32/enabled = true +tracks/32/path = NodePath("Environment/Clouds/Cloud1:visible") +tracks/32/interp = 1 +tracks/32/loop_wrap = true +tracks/32/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/33/type = "value" +tracks/33/imported = false +tracks/33/enabled = true +tracks/33/path = NodePath("Environment/Clouds/Cloud13:visible") +tracks/33/interp = 1 +tracks/33/loop_wrap = true +tracks/33/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/34/type = "value" +tracks/34/imported = false +tracks/34/enabled = true +tracks/34/path = NodePath("Environment/Clouds/Cloud5:visible") +tracks/34/interp = 1 +tracks/34/loop_wrap = true +tracks/34/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/35/type = "value" +tracks/35/imported = false +tracks/35/enabled = true +tracks/35/path = NodePath("Environment/Clouds/Cloud6:visible") +tracks/35/interp = 1 +tracks/35/loop_wrap = true +tracks/35/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/36/type = "value" +tracks/36/imported = false +tracks/36/enabled = true +tracks/36/path = NodePath("Environment/Clouds/Cloud2:visible") +tracks/36/interp = 1 +tracks/36/loop_wrap = true +tracks/36/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/37/type = "value" +tracks/37/imported = false +tracks/37/enabled = true +tracks/37/path = NodePath("Environment/Clouds/Cloud16:visible") +tracks/37/interp = 1 +tracks/37/loop_wrap = true +tracks/37/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/38/type = "value" +tracks/38/imported = false +tracks/38/enabled = true +tracks/38/path = NodePath("Environment/Clouds/Cloud7:visible") +tracks/38/interp = 1 +tracks/38/loop_wrap = true +tracks/38/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/39/type = "value" +tracks/39/imported = false +tracks/39/enabled = true +tracks/39/path = NodePath("Environment/Clouds/Cloud3:visible") +tracks/39/interp = 1 +tracks/39/loop_wrap = true +tracks/39/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/40/type = "value" +tracks/40/imported = false +tracks/40/enabled = true +tracks/40/path = NodePath("Environment/Clouds/Cloud14:visible") +tracks/40/interp = 1 +tracks/40/loop_wrap = true +tracks/40/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/41/type = "value" +tracks/41/imported = false +tracks/41/enabled = true +tracks/41/path = NodePath("Environment/Clouds/Cloud15:visible") +tracks/41/interp = 1 +tracks/41/loop_wrap = true +tracks/41/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/42/type = "value" +tracks/42/imported = false +tracks/42/enabled = true +tracks/42/path = NodePath("Environment/Clouds/Cloud8:visible") +tracks/42/interp = 1 +tracks/42/loop_wrap = true +tracks/42/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/43/type = "value" +tracks/43/imported = false +tracks/43/enabled = true +tracks/43/path = NodePath("Environment/Clouds/Cloud4:visible") +tracks/43/interp = 1 +tracks/43/loop_wrap = true +tracks/43/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/44/type = "value" +tracks/44/imported = false +tracks/44/enabled = true +tracks/44/path = NodePath("Environment/Clouds/Cloud9:visible") +tracks/44/interp = 1 +tracks/44/loop_wrap = true +tracks/44/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/45/type = "value" +tracks/45/imported = false +tracks/45/enabled = true +tracks/45/path = NodePath("Environment/Clouds/Cloud10:visible") +tracks/45/interp = 1 +tracks/45/loop_wrap = true +tracks/45/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/46/type = "value" +tracks/46/imported = false +tracks/46/enabled = true +tracks/46/path = NodePath("Environment/Clouds/Cloud12:visible") +tracks/46/interp = 1 +tracks/46/loop_wrap = true +tracks/46/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/47/type = "value" +tracks/47/imported = false +tracks/47/enabled = true +tracks/47/path = NodePath("Environment/Clouds/Cloud11:visible") +tracks/47/interp = 1 +tracks/47/loop_wrap = true +tracks/47/keys = { +"times": PackedFloat32Array(0, 59, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/48/type = "value" +tracks/48/imported = false +tracks/48/enabled = true +tracks/48/path = NodePath("Environment/Clouds/Cloud17:position") +tracks/48/interp = 1 +tracks/48/loop_wrap = true +tracks/48/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-1928, 1432), Vector2(-1928, 1432), Vector2(4049, 1536), Vector2(-1928, 1432)] +} +tracks/49/type = "value" +tracks/49/imported = false +tracks/49/enabled = true +tracks/49/path = NodePath("Environment/Clouds/Cloud17:scale") +tracks/49/interp = 1 +tracks/49/loop_wrap = true +tracks/49/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1.35085, 1.15254), Vector2(1.35085, 1.15254), Vector2(1.35085, 1.15254), Vector2(1.35085, 1.15254)] +} +tracks/50/type = "value" +tracks/50/imported = false +tracks/50/enabled = true +tracks/50/path = NodePath("Environment/Clouds/Cloud18:position") +tracks/50/interp = 1 +tracks/50/loop_wrap = true +tracks/50/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-865, 3055), Vector2(-865, 3055), Vector2(3895.5, 3103.47), Vector2(-865, 3055)] +} +tracks/51/type = "value" +tracks/51/imported = false +tracks/51/enabled = true +tracks/51/path = NodePath("Environment/Clouds/Cloud18:scale") +tracks/51/interp = 1 +tracks/51/loop_wrap = true +tracks/51/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(0.898305, 0.898305), Vector2(0.898305, 0.898305), Vector2(0.898305, 0.898305), Vector2(0.898305, 0.898305)] +} +tracks/52/type = "value" +tracks/52/imported = false +tracks/52/enabled = true +tracks/52/path = NodePath("Environment/Clouds/Cloud19:position") +tracks/52/interp = 1 +tracks/52/loop_wrap = true +tracks/52/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-1050, 1157), Vector2(-1050, 1157), Vector2(3710.5, 1205.47), Vector2(-1050, 1157)] +} +tracks/53/type = "value" +tracks/53/imported = false +tracks/53/enabled = true +tracks/53/path = NodePath("Environment/Clouds/Cloud19:scale") +tracks/53/interp = 1 +tracks/53/loop_wrap = true +tracks/53/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1.10169, 1.10169), Vector2(1.10169, 1.10169), Vector2(1.10169, 1.10169), Vector2(1.10169, 1.10169)] +} +tracks/54/type = "value" +tracks/54/imported = false +tracks/54/enabled = true +tracks/54/path = NodePath("Environment/Clouds/Cloud20:position") +tracks/54/interp = 1 +tracks/54/loop_wrap = true +tracks/54/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-2964, 2611), Vector2(-2964, 2611), Vector2(4117, 2739), Vector2(-2964, 2611)] +} +tracks/55/type = "value" +tracks/55/imported = false +tracks/55/enabled = true +tracks/55/path = NodePath("Environment/Clouds/Cloud20:scale") +tracks/55/interp = 1 +tracks/55/loop_wrap = true +tracks/55/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/56/type = "value" +tracks/56/imported = false +tracks/56/enabled = true +tracks/56/path = NodePath("Environment/Clouds/Cloud21:position") +tracks/56/interp = 1 +tracks/56/loop_wrap = true +tracks/56/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-493, 2589), Vector2(-493, 2589), Vector2(4267.5, 2637.47), Vector2(-493, 2589)] +} +tracks/57/type = "value" +tracks/57/imported = false +tracks/57/enabled = true +tracks/57/path = NodePath("Environment/Clouds/Cloud21:scale") +tracks/57/interp = 1 +tracks/57/loop_wrap = true +tracks/57/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(0.949153, 0.949153), Vector2(0.949153, 0.949153), Vector2(0.949153, 0.949153), Vector2(0.949153, 0.949153)] +} +tracks/58/type = "value" +tracks/58/imported = false +tracks/58/enabled = true +tracks/58/path = NodePath("Environment/Clouds/Cloud22:position") +tracks/58/interp = 1 +tracks/58/loop_wrap = true +tracks/58/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-1333, 2015), Vector2(-1333, 2015), Vector2(3427.5, 2063.47), Vector2(-1333, 2015)] +} +tracks/59/type = "value" +tracks/59/imported = false +tracks/59/enabled = true +tracks/59/path = NodePath("Environment/Clouds/Cloud22:scale") +tracks/59/interp = 1 +tracks/59/loop_wrap = true +tracks/59/keys = { +"times": PackedFloat32Array(0, 12, 47, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/60/type = "value" +tracks/60/imported = false +tracks/60/enabled = true +tracks/60/path = NodePath("Environment/Clouds/Cloud17:visible") +tracks/60/interp = 1 +tracks/60/loop_wrap = true +tracks/60/keys = { +"times": PackedFloat32Array(0, 47, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/61/type = "value" +tracks/61/imported = false +tracks/61/enabled = true +tracks/61/path = NodePath("Environment/Clouds/Cloud18:visible") +tracks/61/interp = 1 +tracks/61/loop_wrap = true +tracks/61/keys = { +"times": PackedFloat32Array(0, 47, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/62/type = "value" +tracks/62/imported = false +tracks/62/enabled = true +tracks/62/path = NodePath("Environment/Clouds/Cloud19:visible") +tracks/62/interp = 1 +tracks/62/loop_wrap = true +tracks/62/keys = { +"times": PackedFloat32Array(0, 47, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/63/type = "value" +tracks/63/imported = false +tracks/63/enabled = true +tracks/63/path = NodePath("Environment/Clouds/Cloud20:visible") +tracks/63/interp = 1 +tracks/63/loop_wrap = true +tracks/63/keys = { +"times": PackedFloat32Array(0, 47, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/64/type = "value" +tracks/64/imported = false +tracks/64/enabled = true +tracks/64/path = NodePath("Environment/Clouds/Cloud21:visible") +tracks/64/interp = 1 +tracks/64/loop_wrap = true +tracks/64/keys = { +"times": PackedFloat32Array(0, 47, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/65/type = "value" +tracks/65/imported = false +tracks/65/enabled = true +tracks/65/path = NodePath("Environment/Clouds/Cloud22:visible") +tracks/65/interp = 1 +tracks/65/loop_wrap = true +tracks/65/keys = { +"times": PackedFloat32Array(0, 47, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/66/type = "value" +tracks/66/imported = false +tracks/66/enabled = true +tracks/66/path = NodePath("Environment/Clouds/Cloud28:position") +tracks/66/interp = 1 +tracks/66/loop_wrap = true +tracks/66/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-461, 1787), Vector2(-461, 1787), Vector2(3829.5, 1787), Vector2(-461, 1787)] +} +tracks/67/type = "value" +tracks/67/imported = false +tracks/67/enabled = true +tracks/67/path = NodePath("Environment/Clouds/Cloud28:scale") +tracks/67/interp = 1 +tracks/67/loop_wrap = true +tracks/67/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(0.9, 0.9), Vector2(1, 1)] +} +tracks/68/type = "value" +tracks/68/imported = false +tracks/68/enabled = true +tracks/68/path = NodePath("Environment/Clouds/Cloud23:position") +tracks/68/interp = 1 +tracks/68/loop_wrap = true +tracks/68/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-1493, 3040), Vector2(-1493, 3040), Vector2(3139.75, 3040), Vector2(-1493, 3040)] +} +tracks/69/type = "value" +tracks/69/imported = false +tracks/69/enabled = true +tracks/69/path = NodePath("Environment/Clouds/Cloud23:scale") +tracks/69/interp = 1 +tracks/69/loop_wrap = true +tracks/69/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/70/type = "value" +tracks/70/imported = false +tracks/70/enabled = true +tracks/70/path = NodePath("Environment/Clouds/Cloud24:position") +tracks/70/interp = 1 +tracks/70/loop_wrap = true +tracks/70/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-510, 2429), Vector2(-510, 2429), Vector2(4122.75, 2429), Vector2(-510, 2429)] +} +tracks/71/type = "value" +tracks/71/imported = false +tracks/71/enabled = true +tracks/71/path = NodePath("Environment/Clouds/Cloud24:scale") +tracks/71/interp = 1 +tracks/71/loop_wrap = true +tracks/71/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/72/type = "value" +tracks/72/imported = false +tracks/72/enabled = true +tracks/72/path = NodePath("Environment/Clouds/Cloud25:position") +tracks/72/interp = 1 +tracks/72/loop_wrap = true +tracks/72/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-712, 1373), Vector2(-712, 1373), Vector2(3920.75, 1373), Vector2(-712, 1373)] +} +tracks/73/type = "value" +tracks/73/imported = false +tracks/73/enabled = true +tracks/73/path = NodePath("Environment/Clouds/Cloud25:scale") +tracks/73/interp = 1 +tracks/73/loop_wrap = true +tracks/73/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/74/type = "value" +tracks/74/imported = false +tracks/74/enabled = true +tracks/74/path = NodePath("Environment/Clouds/Cloud26:position") +tracks/74/interp = 1 +tracks/74/loop_wrap = true +tracks/74/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-269, 2004), Vector2(-269, 2004), Vector2(4021.5, 2004), Vector2(-269, 2004)] +} +tracks/75/type = "value" +tracks/75/imported = false +tracks/75/enabled = true +tracks/75/path = NodePath("Environment/Clouds/Cloud26:scale") +tracks/75/interp = 1 +tracks/75/loop_wrap = true +tracks/75/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(0.9, 0.9), Vector2(1, 1)] +} +tracks/76/type = "value" +tracks/76/imported = false +tracks/76/enabled = true +tracks/76/path = NodePath("Environment/Clouds/Cloud27:position") +tracks/76/interp = 1 +tracks/76/loop_wrap = true +tracks/76/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(-1656, 2353), Vector2(-1656, 2353), Vector2(2634.5, 2353), Vector2(-1656, 2353)] +} +tracks/77/type = "value" +tracks/77/imported = false +tracks/77/enabled = true +tracks/77/path = NodePath("Environment/Clouds/Cloud27:scale") +tracks/77/interp = 1 +tracks/77/loop_wrap = true +tracks/77/keys = { +"times": PackedFloat32Array(0, 30, 56, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(0.9, 0.9), Vector2(1, 1)] +} +tracks/78/type = "value" +tracks/78/imported = false +tracks/78/enabled = true +tracks/78/path = NodePath("Environment/Clouds/Cloud23:visible") +tracks/78/interp = 1 +tracks/78/loop_wrap = true +tracks/78/keys = { +"times": PackedFloat32Array(0, 56, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/79/type = "value" +tracks/79/imported = false +tracks/79/enabled = true +tracks/79/path = NodePath("Environment/Clouds/Cloud24:visible") +tracks/79/interp = 1 +tracks/79/loop_wrap = true +tracks/79/keys = { +"times": PackedFloat32Array(0, 56, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/80/type = "value" +tracks/80/imported = false +tracks/80/enabled = true +tracks/80/path = NodePath("Environment/Clouds/Cloud25:visible") +tracks/80/interp = 1 +tracks/80/loop_wrap = true +tracks/80/keys = { +"times": PackedFloat32Array(0, 56, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/81/type = "value" +tracks/81/imported = false +tracks/81/enabled = true +tracks/81/path = NodePath("Environment/Clouds/Cloud26:visible") +tracks/81/interp = 1 +tracks/81/loop_wrap = true +tracks/81/keys = { +"times": PackedFloat32Array(0, 56, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/82/type = "value" +tracks/82/imported = false +tracks/82/enabled = true +tracks/82/path = NodePath("Environment/Clouds/Cloud27:visible") +tracks/82/interp = 1 +tracks/82/loop_wrap = true +tracks/82/keys = { +"times": PackedFloat32Array(0, 56, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/83/type = "value" +tracks/83/imported = false +tracks/83/enabled = true +tracks/83/path = NodePath("Environment/Clouds/Cloud28:visible") +tracks/83/interp = 1 +tracks/83/loop_wrap = true +tracks/83/keys = { +"times": PackedFloat32Array(0, 56, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/84/type = "value" +tracks/84/imported = false +tracks/84/enabled = true +tracks/84/path = NodePath("Environment/Clouds/Cloud29:position") +tracks/84/interp = 1 +tracks/84/loop_wrap = true +tracks/84/keys = { +"times": PackedFloat32Array(0, 20, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(3890, 2612.5), Vector2(7216.5, 2622.5), Vector2(3890, 2612.5)] +} +tracks/85/type = "value" +tracks/85/imported = false +tracks/85/enabled = true +tracks/85/path = NodePath("Environment/Clouds/Cloud29:scale") +tracks/85/interp = 1 +tracks/85/loop_wrap = true +tracks/85/keys = { +"times": PackedFloat32Array(0, 20, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/86/type = "value" +tracks/86/imported = false +tracks/86/enabled = true +tracks/86/path = NodePath("Environment/Clouds/Cloud30:position") +tracks/86/interp = 1 +tracks/86/loop_wrap = true +tracks/86/keys = { +"times": PackedFloat32Array(0, 20, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(3832, 1394.5), Vector2(7158.5, 1404.5), Vector2(3832, 1394.5)] +} +tracks/87/type = "value" +tracks/87/imported = false +tracks/87/enabled = true +tracks/87/path = NodePath("Environment/Clouds/Cloud30:scale") +tracks/87/interp = 1 +tracks/87/loop_wrap = true +tracks/87/keys = { +"times": PackedFloat32Array(0, 20, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/88/type = "value" +tracks/88/imported = false +tracks/88/enabled = true +tracks/88/path = NodePath("Environment/Clouds/Cloud31:position") +tracks/88/interp = 1 +tracks/88/loop_wrap = true +tracks/88/keys = { +"times": PackedFloat32Array(0, 20, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(3472, 3106), Vector2(6798.5, 3116), Vector2(3472, 3106)] +} +tracks/89/type = "value" +tracks/89/imported = false +tracks/89/enabled = true +tracks/89/path = NodePath("Environment/Clouds/Cloud31:scale") +tracks/89/interp = 1 +tracks/89/loop_wrap = true +tracks/89/keys = { +"times": PackedFloat32Array(0, 20, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/90/type = "value" +tracks/90/imported = false +tracks/90/enabled = true +tracks/90/path = NodePath("Environment/Clouds/Cloud32:position") +tracks/90/interp = 1 +tracks/90/loop_wrap = true +tracks/90/keys = { +"times": PackedFloat32Array(0, 20, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(3095, 2689.5), Vector2(6421.5, 2699.5), Vector2(3095, 2689.5)] +} +tracks/91/type = "value" +tracks/91/imported = false +tracks/91/enabled = true +tracks/91/path = NodePath("Environment/Clouds/Cloud32:scale") +tracks/91/interp = 1 +tracks/91/loop_wrap = true +tracks/91/keys = { +"times": PackedFloat32Array(0, 20, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/92/type = "value" +tracks/92/imported = false +tracks/92/enabled = true +tracks/92/path = NodePath("Environment/Clouds/Cloud33:position") +tracks/92/interp = 1 +tracks/92/loop_wrap = true +tracks/92/keys = { +"times": PackedFloat32Array(0, 20, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(4016, 1558.5), Vector2(7342.5, 1568.5), Vector2(4016, 1558.5)] +} +tracks/93/type = "value" +tracks/93/imported = false +tracks/93/enabled = true +tracks/93/path = NodePath("Environment/Clouds/Cloud33:scale") +tracks/93/interp = 1 +tracks/93/loop_wrap = true +tracks/93/keys = { +"times": PackedFloat32Array(0, 20, 60), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)] +} +tracks/94/type = "value" +tracks/94/imported = false +tracks/94/enabled = true +tracks/94/path = NodePath("Environment/Clouds/Cloud29:visible") +tracks/94/interp = 1 +tracks/94/loop_wrap = true +tracks/94/keys = { +"times": PackedFloat32Array(0, 20, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/95/type = "value" +tracks/95/imported = false +tracks/95/enabled = true +tracks/95/path = NodePath("Environment/Clouds/Cloud30:visible") +tracks/95/interp = 1 +tracks/95/loop_wrap = true +tracks/95/keys = { +"times": PackedFloat32Array(0, 20, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/96/type = "value" +tracks/96/imported = false +tracks/96/enabled = true +tracks/96/path = NodePath("Environment/Clouds/Cloud31:visible") +tracks/96/interp = 1 +tracks/96/loop_wrap = true +tracks/96/keys = { +"times": PackedFloat32Array(0, 20, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/97/type = "value" +tracks/97/imported = false +tracks/97/enabled = true +tracks/97/path = NodePath("Environment/Clouds/Cloud32:visible") +tracks/97/interp = 1 +tracks/97/loop_wrap = true +tracks/97/keys = { +"times": PackedFloat32Array(0, 20, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/98/type = "value" +tracks/98/imported = false +tracks/98/enabled = true +tracks/98/path = NodePath("Environment/Clouds/Cloud33:visible") +tracks/98/interp = 1 +tracks/98/loop_wrap = true +tracks/98/keys = { +"times": PackedFloat32Array(0, 20, 60.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} +tracks/99/type = "value" +tracks/99/imported = false +tracks/99/enabled = true +tracks/99/path = NodePath("Environment/Clouds/Cloud34:position") +tracks/99/interp = 1 +tracks/99/loop_wrap = true +tracks/99/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(3863, 1375), Vector2(3863, 1375), Vector2(7431, 1375), Vector2(3863, 1375)] +} +tracks/100/type = "value" +tracks/100/imported = false +tracks/100/enabled = true +tracks/100/path = NodePath("Environment/Clouds/Cloud34:scale") +tracks/100/interp = 1 +tracks/100/loop_wrap = true +tracks/100/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/101/type = "value" +tracks/101/imported = false +tracks/101/enabled = true +tracks/101/path = NodePath("Environment/Clouds/Cloud35:position") +tracks/101/interp = 1 +tracks/101/loop_wrap = true +tracks/101/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(3521.25, 3087), Vector2(3521.25, 3087), Vector2(7089.25, 3087), Vector2(3521.25, 3087)] +} +tracks/102/type = "value" +tracks/102/imported = false +tracks/102/enabled = true +tracks/102/path = NodePath("Environment/Clouds/Cloud35:scale") +tracks/102/interp = 1 +tracks/102/loop_wrap = true +tracks/102/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/103/type = "value" +tracks/103/imported = false +tracks/103/enabled = true +tracks/103/path = NodePath("Environment/Clouds/Cloud36:position") +tracks/103/interp = 1 +tracks/103/loop_wrap = true +tracks/103/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(3609.25, 3161), Vector2(3609.25, 3161), Vector2(7177.25, 3161), Vector2(3609.25, 3161)] +} +tracks/104/type = "value" +tracks/104/imported = false +tracks/104/enabled = true +tracks/104/path = NodePath("Environment/Clouds/Cloud36:scale") +tracks/104/interp = 1 +tracks/104/loop_wrap = true +tracks/104/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/105/type = "value" +tracks/105/imported = false +tracks/105/enabled = true +tracks/105/path = NodePath("Environment/Clouds/Cloud37:position") +tracks/105/interp = 1 +tracks/105/loop_wrap = true +tracks/105/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(3754.25, 1447), Vector2(3754.25, 1447), Vector2(7322.25, 1447), Vector2(3754.25, 1447)] +} +tracks/106/type = "value" +tracks/106/imported = false +tracks/106/enabled = true +tracks/106/path = NodePath("Environment/Clouds/Cloud37:scale") +tracks/106/interp = 1 +tracks/106/loop_wrap = true +tracks/106/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/107/type = "value" +tracks/107/imported = false +tracks/107/enabled = true +tracks/107/path = NodePath("Environment/Clouds/Cloud38:position") +tracks/107/interp = 1 +tracks/107/loop_wrap = true +tracks/107/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(2915.25, 2833), Vector2(2915.25, 2833), Vector2(6483.25, 2833), Vector2(2915.25, 2833)] +} +tracks/108/type = "value" +tracks/108/imported = false +tracks/108/enabled = true +tracks/108/path = NodePath("Environment/Clouds/Cloud38:scale") +tracks/108/interp = 1 +tracks/108/loop_wrap = true +tracks/108/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(0.898305, 0.898305), Vector2(0.898305, 0.898305), Vector2(1.3, 1.3), Vector2(0.898305, 0.898305)] +} +tracks/109/type = "value" +tracks/109/imported = false +tracks/109/enabled = true +tracks/109/path = NodePath("Environment/Clouds/Cloud39:position") +tracks/109/interp = 1 +tracks/109/loop_wrap = true +tracks/109/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(3270.25, 2207), Vector2(3270.25, 2207), Vector2(6838.25, 2207), Vector2(3270.25, 2207)] +} +tracks/110/type = "value" +tracks/110/imported = false +tracks/110/enabled = true +tracks/110/path = NodePath("Environment/Clouds/Cloud39:scale") +tracks/110/interp = 1 +tracks/110/loop_wrap = true +tracks/110/keys = { +"times": PackedFloat32Array(0, 22, 35, 60), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(1, 1), Vector2(1.3, 1.3), Vector2(1, 1)] +} +tracks/111/type = "value" +tracks/111/imported = false +tracks/111/enabled = true +tracks/111/path = NodePath("Environment/Clouds/Cloud34:visible") +tracks/111/interp = 1 +tracks/111/loop_wrap = true +tracks/111/keys = { +"times": PackedFloat32Array(0, 22, 35, 60.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [true, true, false, true] +} +tracks/112/type = "value" +tracks/112/imported = false +tracks/112/enabled = true +tracks/112/path = NodePath("Environment/Clouds/Cloud35:visible") +tracks/112/interp = 1 +tracks/112/loop_wrap = true +tracks/112/keys = { +"times": PackedFloat32Array(0, 22, 35, 60.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [true, true, false, true] +} +tracks/113/type = "value" +tracks/113/imported = false +tracks/113/enabled = true +tracks/113/path = NodePath("Environment/Clouds/Cloud36:visible") +tracks/113/interp = 1 +tracks/113/loop_wrap = true +tracks/113/keys = { +"times": PackedFloat32Array(0, 22, 35, 60.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [true, true, false, true] +} +tracks/114/type = "value" +tracks/114/imported = false +tracks/114/enabled = true +tracks/114/path = NodePath("Environment/Clouds/Cloud37:visible") +tracks/114/interp = 1 +tracks/114/loop_wrap = true +tracks/114/keys = { +"times": PackedFloat32Array(0, 22, 35, 60.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [true, true, false, true] +} +tracks/115/type = "value" +tracks/115/imported = false +tracks/115/enabled = true +tracks/115/path = NodePath("Environment/Clouds/Cloud38:visible") +tracks/115/interp = 1 +tracks/115/loop_wrap = true +tracks/115/keys = { +"times": PackedFloat32Array(0, 22, 35, 60.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [true, true, false, true] +} +tracks/116/type = "value" +tracks/116/imported = false +tracks/116/enabled = true +tracks/116/path = NodePath("Environment/Clouds/Cloud39:visible") +tracks/116/interp = 1 +tracks/116/loop_wrap = true +tracks/116/keys = { +"times": PackedFloat32Array(0, 22, 35, 60.2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [true, true, false, true] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_an3cu"] +_data = { +&"RESET": SubResource("Animation_gwtgs"), +&"float": SubResource("Animation_75lmk") +} + +[node name="Arena" type="Node2D"] +y_sort_enabled = true +metadata/_edit_vertical_guides_ = [962.0] +metadata/_edit_horizontal_guides_ = [541.0] + +[node name="Environment" type="Node2D" parent="."] +top_level = true +z_index = -1 +metadata/_edit_lock_ = true + +[node name="Sky" type="ColorRect" parent="Environment"] +custom_minimum_size = Vector2(6000, 4000) +offset_left = -2048.0 +offset_top = -1498.0 +offset_right = 3952.0 +offset_bottom = 2502.0 +color = Color(0.537255, 0.745098, 0.854902, 1) +metadata/_edit_lock_ = true + +[node name="Clouds" type="Node2D" parent="Environment"] +modulate = Color(1, 1, 1, 0.792157) +position = Vector2(-1998, -1508) +metadata/_edit_lock_ = true + +[node name="Cloud1" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(764, 358) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud13" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(4005, 2983) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud5" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-152, 2723) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud6" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(3293, 936) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud2" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(85, 1505) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud16" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(3434, 3542) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud7" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(1380, 3802) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud3" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(503, 1222) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud14" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(4174, 3309) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud15" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(4695, 2800) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud8" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(152, 3383) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud4" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(164, 1669) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud9" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(328, 3474) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud10" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(933, 515) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud12" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(4570, 1222) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud11" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(3784, 345) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud17" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-2737.13, 367.814) +scale = Vector2(1.35085, 1.15254) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud18" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-1254.92, 3539.61) +scale = Vector2(0.898305, 0.898305) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud19" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-2912.7, 1260.29) +scale = Vector2(1.10169, 1.10169) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud20" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-3251.5, 3437.56) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud21" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-3181.26, 3581.44) +scale = Vector2(0.949153, 0.949153) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud22" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-420.856, 367.017) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud23" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-1493, 3040) +scale = Vector2(0.898305, 0.898305) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud24" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-510, 2429) +scale = Vector2(1.15254, 1.15254) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud25" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-712, 1373) +scale = Vector2(1.10169, 1.10169) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud26" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-269, 2004) +scale = Vector2(0.79661, 0.79661) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud27" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-1656, 2353) +scale = Vector2(0.949153, 0.949153) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud28" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(-461, 1787) +scale = Vector2(1.10169, 1.10169) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud29" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(3890, 2612.5) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud30" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(3832, 1394.5) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud31" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(3472, 3106) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud32" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(3095, 2689.5) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud33" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(4016, 1558.5) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud34" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(3863, 1375) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud35" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(3521.25, 3087) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud36" type="Sprite2D" parent="Environment/Clouds"] +position = Vector2(3609.25, 3161) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud37" type="Sprite2D" parent="Environment/Clouds"] +visible = false +position = Vector2(3754.25, 1447) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud38" type="Sprite2D" parent="Environment/Clouds"] +visible = false +position = Vector2(2915.25, 2833) +scale = Vector2(0.898305, 0.898305) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud39" type="Sprite2D" parent="Environment/Clouds"] +visible = false +position = Vector2(3270.25, 2207) +texture = ExtResource("1_1blat") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="CloudsAnimationPlayer" type="AnimationPlayer" parent="Environment"] +root_node = NodePath("../..") +libraries = { +&"": SubResource("AnimationLibrary_an3cu") +} +autoplay = "float" + +[node name="Ground" type="Node2D" parent="Environment"] +metadata/_edit_lock_ = true + +[node name="Rocks" type="Sprite2D" parent="Environment/Ground"] +position = Vector2(986, 1264) +texture = ExtResource("1_145kx") + +[node name="Floor" type="Sprite2D" parent="Environment/Ground"] +position = Vector2(938, 568) +texture = ExtResource("1_vifjc") + +[node name="Limits" type="StaticBody2D" parent="Environment"] +metadata/_edit_lock_ = true + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Environment/Limits"] +visible = false +polygon = PackedVector2Array(-814, 535, -380, 190, -306, -21, 87, -46, 346, -330, 870, -373, 1115, -418, 1363, -334, 1613, -324, 1854, -225, 2208, -197, 2675, 309, 2642, 741, 2244, 1140, 1618, 1271, 1360, 1193, 865, 1423, 706, 1377, -113, 1192, -452, 1035, -488, 902, -625, 803, -734, 680, -1660, 719, -1331, 2205, 3170, 2304, 3988, 404, 2999, -1433, 131, -1364, -1715, 264, -1659, 716, -737, 676) +metadata/_edit_lock_ = true + +[node name="Props" type="Node2D" parent="."] +y_sort_enabled = true +metadata/_edit_lock_ = true + +[node name="Shrooms" type="Node2D" parent="Props"] +y_sort_enabled = true +metadata/_edit_lock_ = true + +[node name="ShroomFat1" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(316, -293) +rotation = -0.47206 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomFat3" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(889.983, -375.68) +rotation = 0.0723415 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomRed1" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(211, -172) +rotation = -0.554414 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed2" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(477, -354) +rotation = -0.131447 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed3" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1069, -418) +rotation = 0.210047 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed4" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1184, -390) +rotation = -0.111158 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed5" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1522, -323) +rotation = -0.111158 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed6" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1776, -257) +rotation = 0.0517097 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed7" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2002, -212) +rotation = -0.0711099 +scale = Vector2(1.26843, 1.26843) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomBlue1" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-18, -43) +rotation = -0.390338 +scale = Vector2(1.27499, 1.17746) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue2" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(653, -364) +rotation = -0.390338 +scale = Vector2(1.27499, 1.17746) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue3" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1251, -379) +rotation = -0.0470768 +scale = Vector2(1.27499, 1.17746) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue4" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1357, -339) +rotation = 0.382315 +scale = Vector2(1.27499, 1.17746) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue5" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2188, -215) +rotation = 0.177698 +scale = Vector2(1.27499, 1.17746) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomThinFlip1" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(451.932, -348.31) +rotation = -3.01653 +scale = Vector2(0.729666, -0.765873) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThinFlip2" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1324, -351) +rotation = -2.73344 +scale = Vector2(0.729666, -0.765873) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThinFlip3" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2151.93, -234.31) +rotation = -3.0381 +scale = Vector2(0.729666, -0.765873) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomFat2" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1901.98, -226.68) +rotation = -0.202467 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomYellow1" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(53, -53) +rotation = 0.0837674 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow2" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(283, -266) +rotation = -0.486485 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow4" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1009, -410) +rotation = 0.0837674 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow5" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1632, -326) +rotation = -0.179329 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow6" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1668, -313) +rotation = 0.49724 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow7" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2082, -232) +rotation = -0.300902 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomThin2" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-112.5, -30.0442) +rotation = -0.0993826 +scale = Vector2(0.762573, 0.762573) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin3" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(104, -70) +rotation = 0.0063462 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin4" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(202.5, -223.044) +rotation = -0.108585 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin5" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(381.5, -325.044) +rotation = -0.027 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin6" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(542.5, -367.044) +rotation = -0.027 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin7" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(790.5, -372.044) +rotation = 0.336266 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin8" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1266, -377) +rotation = 0.481942 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin9" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1436.5, -326.044) +rotation = -0.0734592 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin10" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1666.5, -292.044) +rotation = -0.106563 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomRed8" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2289, -167) +rotation = 0.0517097 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomThin1" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-122, -58) +rotation = 0.434625 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin11" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2088.5, -233.044) +rotation = -0.0820285 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin12" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-800, 471) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin13" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-457, 62) +rotation = -0.368511 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin14" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-350.5, -23.0442) +rotation = 0.348356 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThinFlip4" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-660.068, 388.69) +rotation = -3.01653 +scale = Vector2(0.729666, -0.765873) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomFat4" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-819, 547) +rotation = -0.338786 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomFat5" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-510, 252) +rotation = -0.121513 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomFat6" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-192, -54) +rotation = -0.182008 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomBlue6" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-713, 715) +rotation = -0.434928 +scale = Vector2(1.11803, 1.02553) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue7" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-724, 448) +rotation = 0.0185129 +scale = Vector2(1.27499, 1.17746) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue8" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-405, -1.00002) +rotation = 0.0185129 +scale = Vector2(1.08529, 0.99636) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomRed9" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-725, 776) +rotation = -0.737596 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomYellow3" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-601, 352) +rotation = 0.0245847 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow8" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-394, 213) +rotation = 0.304539 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow9" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-297, -12) +rotation = 0.0245847 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomThin15" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-472, 2) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomYellow10" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2302, -93.9999) +rotation = 0.443771 +scale = Vector2(1.48644, 1.42174) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomFat7" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2673, 269) +rotation = 0.249999 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomFat8" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2408.98, -10.6802) +rotation = 0.249999 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomRed10" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2673, 603) +rotation = -0.205529 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed11" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2457, 62.9999) +rotation = 0.133289 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomThinFlip5" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2758.93, 383.69) +rotation = -2.72375 +scale = Vector2(0.729666, -0.765873) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomYellow11" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2680, 496) +rotation = 0.443771 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow12" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2502, 122) +rotation = 0.443771 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomRed12" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2558, 184) +rotation = 0.439175 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomBlue9" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2721, 315) +rotation = 0.0185129 +scale = Vector2(1.27499, 1.17746) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomThin16" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2610, 225) +rotation = -0.321984 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin17" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2387.5, 11.9558) +rotation = -0.0440143 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomRed13" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-556, 849) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed14" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(770, 1513) +rotation = 0.159869 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed15" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1349, 1241) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed16" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1261, 1284) +rotation = -0.542647 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed17" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2312, 1116) +rotation = -0.294691 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomRed18" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2508, 864) +rotation = -0.259673 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -124) +region_enabled = true +region_rect = Rect2(667.382, 0, 217.218, 259.018) + +[node name="ShroomYellow13" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-503, 876) +rotation = 0.218248 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow14" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(58, 1208) +rotation = 0.116333 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow15" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(529, 1365) +rotation = 0.0404178 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow16" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(934, 1419) +rotation = -0.0691034 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow17" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1605.04, 1336.65) +rotation = -0.0585388 +scale = Vector2(1, 1.00276) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow18" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1943, 1282) +rotation = 0.0341268 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomYellow19" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2631, 819) +rotation = -0.0863327 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomFat9" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-379, 1132) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomThinFlip6" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-583, 1039) +rotation = -2.70279 +scale = Vector2(0.729666, -0.765873) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThinFlip7" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(168.932, 1262.69) +rotation = -2.70279 +scale = Vector2(0.729666, -0.765873) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThinFlip8" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(903.932, 1420.69) +rotation = -3.09863 +scale = Vector2(0.729666, -0.765873) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThinFlip9" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1684.93, 1303.69) +rotation = -3.09863 +scale = Vector2(0.729666, -0.765873) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin18" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-277.5, 1192.96) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin19" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(104.5, 1254.96) +rotation = 0.328221 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin20" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(673, 1509) +rotation = 0.388862 +scale = Vector2(0.799106, 0.799106) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomFat10" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-683.017, 859.32) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomFat11" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(357.983, 1353.32) +rotation = -0.210709 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomFat12" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1047, 1369) +rotation = 0.0773245 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomFat13" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1796.98, 1283.32) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomFat14" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2416, 1002) +rotation = -0.543407 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -118) +region_enabled = true +region_rect = Rect2(364.026, 0, 303.355, 246.522) + +[node name="ShroomThin21" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(446.5, 1378.96) +rotation = 0.388862 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin22" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1842, 1288) +rotation = 0.47074 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin23" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2473, 905) +rotation = -0.509121 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin24" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2570.5, 827.956) +rotation = -0.0398957 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomBlue10" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-80, 1198) +rotation = -0.110138 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue11" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-231, 1209) +rotation = 0.335187 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue12" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(638, 1380) +rotation = -0.110138 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue13" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1454, 1249) +rotation = -0.110138 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue14" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2203, 1198) +rotation = -0.110138 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue15" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2100, 1241) +rotation = -0.440792 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomBlue16" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2712, 770) +rotation = -0.0419129 +scale = Vector2(1.27499, 1.17746) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -115) +region_enabled = true +region_rect = Rect2(175.8, 0, 188.1, 246.522) + +[node name="ShroomThinFlip10" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2238.93, 1162.69) +rotation = 2.58643 +scale = Vector2(0.729666, -0.765873) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin25" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(2136.5, 1225.96) +rotation = -0.0459579 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin26" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(1512, 1310) +rotation = -0.223667 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomThin27" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-12.5, 1227.96) +rotation = -0.194346 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomYellow20" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-577, 977) +rotation = -0.196464 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="ShroomThin28" type="Sprite2D" parent="Props/Shrooms"] +position = Vector2(-645, 1030) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -110) +region_enabled = true +region_rect = Rect2(886.896, 0, 99.9249, 222.903) + +[node name="ShroomYellow21" type="Sprite2D" parent="Props/Shrooms"] +y_sort_enabled = true +position = Vector2(731, -360) +rotation = 0.0837674 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -116) +region_enabled = true +region_rect = Rect2(-0.296913, 2.76804, 172.051, 239.67) + +[node name="Grass" type="Node2D" parent="Props"] +y_sort_enabled = true +metadata/_edit_lock_ = true + +[node name="Grass1" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-438, -25) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass2" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-356, -28) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass3" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-210, -64) +rotation = -0.191355 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass4" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-279, -60) +rotation = -0.351512 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass5" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-140, -66) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass6" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-76, -63) +rotation = 0.150085 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass7" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-6, -64) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass8" type="Sprite2D" parent="Props/Grass"] +position = Vector2(51, -70) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass9" type="Sprite2D" parent="Props/Grass"] +position = Vector2(105, -82) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass10" type="Sprite2D" parent="Props/Grass"] +position = Vector2(162, -106) +rotation = -0.447914 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass11" type="Sprite2D" parent="Props/Grass"] +position = Vector2(178, -174) +rotation = -0.826729 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass12" type="Sprite2D" parent="Props/Grass"] +position = Vector2(209, -232) +rotation = -0.708204 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass13" type="Sprite2D" parent="Props/Grass"] +position = Vector2(241, -276) +rotation = -0.614925 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass14" type="Sprite2D" parent="Props/Grass"] +position = Vector2(334, -323) +rotation = -0.476317 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass15" type="Sprite2D" parent="Props/Grass"] +position = Vector2(385, -352) +rotation = -0.3282 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass16" type="Sprite2D" parent="Props/Grass"] +position = Vector2(441, -376) +rotation = -0.219466 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass17" type="Sprite2D" parent="Props/Grass"] +position = Vector2(513, -388) +rotation = -0.0260885 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass18" type="Sprite2D" parent="Props/Grass"] +position = Vector2(571, -394) +rotation = 0.123957 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass19" type="Sprite2D" parent="Props/Grass"] +position = Vector2(627.224, -381.064) +rotation = 0.0929263 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass20" type="Sprite2D" parent="Props/Grass"] +position = Vector2(692, -382) +rotation = 0.10344 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass21" type="Sprite2D" parent="Props/Grass"] +position = Vector2(760, -376) +rotation = 0.000137895 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass22" type="Sprite2D" parent="Props/Grass"] +position = Vector2(813, -380) +rotation = 0.193515 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass23" type="Sprite2D" parent="Props/Grass"] +position = Vector2(863, -394) +rotation = 0.0942186 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass24" type="Sprite2D" parent="Props/Grass"] +position = Vector2(953, -417) +rotation = -0.108891 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass25" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1025, -436) +rotation = -0.219926 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass26" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1090, -444) +rotation = -0.0691996 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass27" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1148, -438) +rotation = 0.0942186 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass28" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1206, -419) +rotation = 0.325109 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass29" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1288, -387) +rotation = 0.372396 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass30" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1341, -367) +rotation = 0.4261 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass31" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1392.22, -349.064) +rotation = 0.248156 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass32" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1470, -345) +rotation = 0.140579 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass33" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1537, -344) +rotation = 0.151143 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass34" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1603, -342) +rotation = 0.101008 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass35" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1659, -336) +rotation = 0.248156 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass36" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1719, -319) +rotation = 0.28446 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass37" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1781.22, -292.064) +rotation = 0.440044 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass38" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1842.22, -257.064) +rotation = 0.352407 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass39" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1915, -248) +rotation = 0.342354 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass40" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1987, -236) +rotation = 0.0942217 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass41" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2063, -246) +rotation = 0.0141966 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass42" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2133, -247) +rotation = 0.107299 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass43" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2205, -237) +rotation = 0.352407 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass44" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2271.22, -219.064) +rotation = 0.342354 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass45" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2301, -137) +rotation = 0.940869 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass46" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2351, -42) +rotation = 0.458519 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass47" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2442, -4) +rotation = 0.3067 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass48" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2491, 36.0001) +rotation = 0.534738 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass49" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2517.19, 77.2042) +rotation = 0.830507 +scale = Vector2(1.00312, 1) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass50" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2575, 147) +rotation = 0.976222 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass51" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2552, 127) +rotation = 0.668316 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass52" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2618, 199) +rotation = 0.534738 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass53" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2711, 264) +rotation = 0.830507 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass54" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-368, 174) +rotation = -0.456926 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass55" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-443, 208) +rotation = -0.199051 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass56" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-496, 229) +rotation = -0.456926 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass57" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-593, 303) +rotation = -0.456926 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass58" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-652, 357) +rotation = -0.456926 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass59" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-698.776, 402.936) +rotation = -0.456926 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass60" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-771, 447) +rotation = -0.456926 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass61" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-801, 488) +rotation = -0.986285 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass62" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2713, 523) +rotation = -0.236838 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass63" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2723, 333) +rotation = -0.0377601 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass74" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-528, 883) +rotation = 0.425283 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass75" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-567, 879) +rotation = -0.145538 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass76" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-618, 878) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass77" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-702, 875) +rotation = -0.136894 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass78" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-640, 870) +rotation = 0.0992107 +scale = Vector2(0.89227, 0.890196) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass73" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2726, 803) +rotation = -0.177835 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass72" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2687.59, 820.894) +rotation = -0.335356 +scale = Vector2(0.996004, 0.997321) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass71" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2635, 831) +rotation = -0.335356 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass70" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2584, 850) +rotation = -0.335356 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass69" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2534, 878) +rotation = -0.335356 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass68" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2485, 937) +rotation = -0.335356 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass67" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2472, 984) +rotation = -0.335356 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass66" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2442, 1015) +rotation = -0.335356 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass65" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2404, 1033) +rotation = -0.335356 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass64" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2357, 1063) +rotation = -0.419734 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass79" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2328, 1128) +rotation = -0.449816 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass80" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2321, 1180) +rotation = -0.194528 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass81" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2309, 1201) +rotation = -0.24821 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass82" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2283, 1232) +rotation = -0.335356 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass83" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2231, 1246) +rotation = -0.0390497 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass84" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2172, 1251) +rotation = -0.0459226 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass85" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2116, 1252) +rotation = -0.140489 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass86" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2062, 1263) +rotation = -0.295208 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass87" type="Sprite2D" parent="Props/Grass"] +position = Vector2(2011, 1282) +rotation = -0.261242 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass88" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1964, 1309) +rotation = -0.138799 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass89" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1906, 1315) +rotation = 0.0341306 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass90" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1857, 1309) +rotation = -0.00321719 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass91" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1795, 1307) +rotation = -0.0304235 +scale = Vector2(0.994353, 0.99967) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass92" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1639, 1358) +rotation = -0.250016 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass93" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1563, 1353) +rotation = 0.257884 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass94" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1739, 1322) +rotation = -0.22541 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass95" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1691, 1341) +rotation = -0.244855 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass96" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1506, 1318) +rotation = 0.717251 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass97" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1466, 1276) +rotation = 0.644911 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass98" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1425, 1259) +rotation = 0.0565641 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass99" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1366, 1265) +rotation = -0.149705 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass100" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1308, 1292) +rotation = -0.153005 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass101" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1255, 1311) +rotation = 0.0565641 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass102" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1137, 1337) +rotation = 0.0565641 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass103" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1096, 1376) +rotation = -0.369265 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass104" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1051, 1418) +rotation = -0.358503 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass105" type="Sprite2D" parent="Props/Grass"] +position = Vector2(947, 1450) +rotation = -0.124099 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass106" type="Sprite2D" parent="Props/Grass"] +position = Vector2(988, 1444) +rotation = 0.0565641 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass107" type="Sprite2D" parent="Props/Grass"] +position = Vector2(1203, 1319) +rotation = -0.10731 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass108" type="Sprite2D" parent="Props/Grass"] +position = Vector2(851, 1493) +rotation = -0.241176 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass109" type="Sprite2D" parent="Props/Grass"] +position = Vector2(894, 1462) +rotation = -0.0791258 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass110" type="Sprite2D" parent="Props/Grass"] +position = Vector2(823, 1532) +rotation = -0.36178 +scale = Vector2(0.896039, 0.929433) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass111" type="Sprite2D" parent="Props/Grass"] +position = Vector2(778, 1556) +rotation = -0.183817 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass112" type="Sprite2D" parent="Props/Grass"] +position = Vector2(711, 1555) +rotation = 0.23761 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass113" type="Sprite2D" parent="Props/Grass"] +position = Vector2(661, 1543) +rotation = 0.23761 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass114" type="Sprite2D" parent="Props/Grass"] +position = Vector2(678, 1421) +rotation = 0.450015 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass115" type="Sprite2D" parent="Props/Grass"] +position = Vector2(653, 1408) +rotation = 0.246509 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass116" type="Sprite2D" parent="Props/Grass"] +position = Vector2(603, 1405) +rotation = -0.0914229 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass117" type="Sprite2D" parent="Props/Grass"] +position = Vector2(547, 1414) +rotation = -0.119099 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass118" type="Sprite2D" parent="Props/Grass"] +position = Vector2(489, 1402) +rotation = 0.450015 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass119" type="Sprite2D" parent="Props/Grass"] +position = Vector2(436, 1385) +rotation = 0.305517 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass120" type="Sprite2D" parent="Props/Grass"] +position = Vector2(395, 1383) +rotation = -0.203084 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass121" type="Sprite2D" parent="Props/Grass"] +position = Vector2(352, 1390) +rotation = -0.194154 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass122" type="Sprite2D" parent="Props/Grass"] +position = Vector2(257, 1351) +rotation = 0.488442 +scale = Vector2(0.984626, 0.967626) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass123" type="Sprite2D" parent="Props/Grass"] +position = Vector2(288, 1385) +rotation = 0.450015 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass124" type="Sprite2D" parent="Props/Grass"] +position = Vector2(221, 1329) +rotation = 0.132079 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass125" type="Sprite2D" parent="Props/Grass"] +position = Vector2(174, 1314) +rotation = 0.346821 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass126" type="Sprite2D" parent="Props/Grass"] +position = Vector2(133, 1299) +rotation = 0.450015 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass127" type="Sprite2D" parent="Props/Grass"] +position = Vector2(88, 1271) +rotation = 0.450015 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass128" type="Sprite2D" parent="Props/Grass"] +position = Vector2(44.224, 1260.94) +rotation = 0.0963627 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass129" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-4.776, 1248.94) +rotation = 0.0963627 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass130" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-52.776, 1239.94) +rotation = 0.0963627 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass131" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-113, 1228) +rotation = 0.0963627 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass132" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-168, 1233) +rotation = -0.0568394 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass133" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-225, 1238) +rotation = 0.0963627 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass134" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-281, 1225) +rotation = 0.599394 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass135" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-313, 1160) +rotation = -0.539764 +scale = Vector2(0.920388, 0.98772) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass136" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-366, 1176) +rotation = 0.109422 +scale = Vector2(0.936615, 0.872008) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass137" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-423, 1151) +rotation = 0.527011 +scale = Vector2(0.824352, 0.816612) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass138" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-471, 1133) +rotation = 0.452393 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass139" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-541, 1058) +rotation = 0.138139 +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass140" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-590, 1054) +rotation = -0.110402 +scale = Vector2(0.845736, 0.853483) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) + +[node name="Grass141" type="Sprite2D" parent="Props/Grass"] +position = Vector2(-642, 1052) +texture = ExtResource("2_kesm7") +offset = Vector2(0, -42) +region_enabled = true +region_rect = Rect2(996.053, 4.65938, 177.044, 92.8809) diff --git a/demo/scenes/base/clouds.tscn b/demo/scenes/base/clouds.tscn new file mode 100644 index 0000000..331faa6 --- /dev/null +++ b/demo/scenes/base/clouds.tscn @@ -0,0 +1,256 @@ +[gd_scene load_steps=2 format=3 uid="uid://dt2jlrqffpyw"] + +[ext_resource type="Texture2D" uid="uid://65b6yuobhxf8" path="res://demo/assets/env_clouds.png" id="1_eigiy"] + +[node name="Clouds" type="Node2D"] +modulate = Color(1, 1, 1, 0.792157) +position = Vector2(-1998, -1508) +metadata/_edit_lock_ = true + +[node name="Cloud1" type="Sprite2D" parent="."] +position = Vector2(764, 358) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud13" type="Sprite2D" parent="."] +position = Vector2(4005, 2983) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud5" type="Sprite2D" parent="."] +position = Vector2(-152, 2723) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud6" type="Sprite2D" parent="."] +position = Vector2(3293, 936) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud2" type="Sprite2D" parent="."] +position = Vector2(85, 1505) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud16" type="Sprite2D" parent="."] +position = Vector2(3434, 3542) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud7" type="Sprite2D" parent="."] +position = Vector2(1380, 3802) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud3" type="Sprite2D" parent="."] +position = Vector2(503, 1222) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud14" type="Sprite2D" parent="."] +position = Vector2(4174, 3309) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud15" type="Sprite2D" parent="."] +position = Vector2(4695, 2800) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud8" type="Sprite2D" parent="."] +position = Vector2(152, 3383) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud4" type="Sprite2D" parent="."] +position = Vector2(164, 1669) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud9" type="Sprite2D" parent="."] +position = Vector2(328, 3474) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud10" type="Sprite2D" parent="."] +position = Vector2(933, 515) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud12" type="Sprite2D" parent="."] +position = Vector2(4570, 1222) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud11" type="Sprite2D" parent="."] +position = Vector2(3784, 345) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud17" type="Sprite2D" parent="."] +position = Vector2(-2737.13, 367.814) +scale = Vector2(1.35085, 1.15254) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud18" type="Sprite2D" parent="."] +position = Vector2(-1254.92, 3539.61) +scale = Vector2(0.898305, 0.898305) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud19" type="Sprite2D" parent="."] +position = Vector2(-2912.7, 1260.29) +scale = Vector2(1.10169, 1.10169) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud20" type="Sprite2D" parent="."] +position = Vector2(-3251.5, 3437.56) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud21" type="Sprite2D" parent="."] +position = Vector2(-3181.26, 3581.44) +scale = Vector2(0.949153, 0.949153) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud22" type="Sprite2D" parent="."] +position = Vector2(-420.856, 367.017) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud23" type="Sprite2D" parent="."] +position = Vector2(-1493, 3040) +scale = Vector2(0.898305, 0.898305) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud24" type="Sprite2D" parent="."] +position = Vector2(-510, 2429) +scale = Vector2(1.15254, 1.15254) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud25" type="Sprite2D" parent="."] +position = Vector2(-712, 1373) +scale = Vector2(1.10169, 1.10169) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud26" type="Sprite2D" parent="."] +position = Vector2(-269, 2004) +scale = Vector2(0.79661, 0.79661) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud27" type="Sprite2D" parent="."] +position = Vector2(-1656, 2353) +scale = Vector2(0.949153, 0.949153) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud28" type="Sprite2D" parent="."] +position = Vector2(-461, 1787) +scale = Vector2(1.10169, 1.10169) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud29" type="Sprite2D" parent="."] +position = Vector2(3890, 2612.5) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud30" type="Sprite2D" parent="."] +position = Vector2(3832, 1394.5) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud31" type="Sprite2D" parent="."] +position = Vector2(3472, 3106) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud32" type="Sprite2D" parent="."] +position = Vector2(3095, 2689.5) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud33" type="Sprite2D" parent="."] +position = Vector2(4016, 1558.5) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud34" type="Sprite2D" parent="."] +position = Vector2(3863, 1375) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(12, 7, 455, 168) + +[node name="Cloud35" type="Sprite2D" parent="."] +position = Vector2(3521.25, 3087) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud36" type="Sprite2D" parent="."] +position = Vector2(3609.25, 3161) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(507, 7, 193, 88) + +[node name="Cloud37" type="Sprite2D" parent="."] +visible = false +position = Vector2(3754.25, 1447) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(501, 99, 210, 92) + +[node name="Cloud38" type="Sprite2D" parent="."] +visible = false +position = Vector2(2915.25, 2833) +scale = Vector2(0.898305, 0.898305) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) + +[node name="Cloud39" type="Sprite2D" parent="."] +visible = false +position = Vector2(3270.25, 2207) +texture = ExtResource("1_eigiy") +region_enabled = true +region_rect = Rect2(10, 189, 644, 165) diff --git a/demo/scenes/base/code_edit.gd b/demo/scenes/base/code_edit.gd new file mode 100644 index 0000000..5416996 --- /dev/null +++ b/demo/scenes/base/code_edit.gd @@ -0,0 +1,140 @@ +#* +#* code_edit.gd +#* ============================================================================= +#* Copyright 2024 Serhii Snitsaruk +#* +#* 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. +#* ============================================================================= +#* + +extends CodeEdit + +const RESERVED_WORDS := [ + # Control flow. + "break", + "continue", + "elif", + "else", + "for", + "if", + "match", + "pass", + "return", + "when", + "while", + # Declarations. + "class", + "class_name", + "const", + "enum", + "extends", + "func", + "namespace", + "signal", + "static", + "trait", + "var", + # Other keywords. + "await", + "breakpoint", + "self", + "super", + "yield", + # Operators. + "and", + "as", + "in", + "is", + "not", + "or", + # Special values. + "false", + "null", + "true", + # Constants. + "INF", + "NAN", + "PI", + "TAU", + # Functions. + "assert", + "preload", +] + +const TYPE_WORDS := [ + "bool", + "int", + "float", + "void", + "String", + "Vector2", + "Vector2i", + "Rect2", + "Rect2i", + "Vector3", + "Vector3i", + "Transform2D", + "Vector4", + "Vector4i", + "Plane", + "Quaternion", + "AABB", + "Basis", + "Transform3D", + "Projection", + "Color", + "StringName", + "NodePath", + "RID", + "Callable", + "Signal", + "Dictionary", + "Array", + "PackedByteArray", + "PackedInt32Array", + "PackedInt64Array", + "PackedFloat32Array", + "PackedFloat64Array", + "PackedStringArray", + "PackedVector2Array", + "PackedVector3Array", + "PackedColorArray", + # Other types + "Status", +] + + +func _ready() -> void: + var highlighter := CodeHighlighter.new() + syntax_highlighter = highlighter + highlighter.number_color = Color.AQUAMARINE + highlighter.symbol_color = Color.CORNFLOWER_BLUE + highlighter.function_color = Color.DEEP_SKY_BLUE + highlighter.member_variable_color = Color.LIGHT_BLUE + + # Engine types + for c in ClassDB.get_class_list(): + syntax_highlighter.add_keyword_color(c, Color.AQUAMARINE) + + syntax_highlighter.add_color_region("#", "", Color.DIM_GRAY, true) + syntax_highlighter.add_color_region("@", " ", Color.GOLDENROD) + syntax_highlighter.add_color_region("\"", "\"", Color.GOLD) + + for keyword in RESERVED_WORDS: + syntax_highlighter.add_keyword_color(keyword, Color.INDIAN_RED) + + for typeword in TYPE_WORDS: + syntax_highlighter.add_keyword_color(typeword, Color.AQUAMARINE) + + +func set_source_code(source_code: String) -> void: + # Hide license header + var idx: int = source_code.find("#*") + while idx != - 1: + source_code = source_code.substr(0, idx) + source_code.substr(source_code.findn("\n", idx) + 1) + idx = source_code.findn("#*", idx) + + text = "" # Workaround + text = source_code diff --git a/demo/scenes/base/code_edit.gd.uid b/demo/scenes/base/code_edit.gd.uid new file mode 100644 index 0000000..667ed34 --- /dev/null +++ b/demo/scenes/base/code_edit.gd.uid @@ -0,0 +1 @@ +uid://cb8thyd7vi2nj diff --git a/demo/scenes/base/toggle_fullscreen.gd b/demo/scenes/base/toggle_fullscreen.gd new file mode 100644 index 0000000..172889a --- /dev/null +++ b/demo/scenes/base/toggle_fullscreen.gd @@ -0,0 +1,18 @@ +extends Button + + +func _ready() -> void: + pressed.connect(_toggle_fullscreen) + + # Set scaling properties and base resolution + get_window().mode = Window.MODE_FULLSCREEN + get_window().content_scale_aspect = Window.CONTENT_SCALE_ASPECT_KEEP + get_window().content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS + get_window().content_scale_size = Vector2i(1920,1080) + + +func _toggle_fullscreen() -> void: + if get_window().mode != Window.MODE_FULLSCREEN: + get_window().mode = Window.MODE_FULLSCREEN + else: + get_window().mode = Window.MODE_MAXIMIZED diff --git a/demo/scenes/base/toggle_fullscreen.gd.uid b/demo/scenes/base/toggle_fullscreen.gd.uid new file mode 100644 index 0000000..10e1acb --- /dev/null +++ b/demo/scenes/base/toggle_fullscreen.gd.uid @@ -0,0 +1 @@ +uid://c5p1i8ofpv7qn diff --git a/demo/scenes/game.gd b/demo/scenes/game.gd new file mode 100644 index 0000000..0fbcd77 --- /dev/null +++ b/demo/scenes/game.gd @@ -0,0 +1,84 @@ +extends Node2D + +const Simple := preload("res://demo/agents/01_agent_melee_simple.tscn") +const Charger := preload("res://demo/agents/02_agent_charger.tscn") +const Imp := preload("res://demo/agents/03_agent_imp.tscn") +const Skirmisher := preload("res://demo/agents/04_agent_skirmisher.tscn") +const Ranged := preload("res://demo/agents/05_agent_ranged.tscn") +const Combo := preload("res://demo/agents/06_agent_melee_combo.tscn") +const Nuanced := preload("res://demo/agents/07_agent_melee_nuanced.tscn") +const Demon := preload("res://demo/agents/08_agent_demon.tscn") +const Summoner := preload("res://demo/agents/09_agent_summoner.tscn") + +const WAVES: Array = [ + [Simple, Simple, Nuanced], + [Simple, Nuanced, Charger], + [Simple, Simple, Simple, Ranged, Nuanced], + [Simple, Simple, Summoner], + [Ranged, Skirmisher, Nuanced, Simple, Simple], + [Nuanced, Nuanced, Combo, Ranged, Simple], + [Demon, Charger, Simple, Simple, Simple, Skirmisher], + [Demon, Demon, Nuanced, Combo], + [Summoner, Ranged, Nuanced, Nuanced, Ranged, Skirmisher, Simple], + [Demon, Demon, Summoner, Skirmisher, Nuanced, Nuanced, Combo], +] + +@export var wave_index: int = -1 +@export var agents_alive: int = 0 + +@onready var gong: StaticBody2D = $Gong +@onready var player: CharacterBody2D = $Player +@onready var spawn_points: Node2D = $SpawnPoints +@onready var hp_bar: TextureProgressBar = %HPBar +@onready var round_counter: Label = %RoundCounter + + +func _ready() -> void: + hp_bar.max_value = player.get_health().max_health + player.get_health().damaged.connect(func(_a,_b): hp_bar.value = player.get_health().get_current()) + player.death.connect(_on_player_death) + + +func _update_round_counter() -> void: + round_counter.text = "Round %s/%s" % [wave_index + 1, WAVES.size()] + + +func _on_gong_gong_struck() -> void: + _start_round() + + +func _start_round() -> void: + wave_index += 1 + if wave_index >= WAVES.size(): + player.set_victorious() + round_counter.text = "Victorious!" + return + + await get_tree().create_timer(3.0).timeout + _update_round_counter() + + var spawns: Array = spawn_points.get_children() + spawns.shuffle() + for i in WAVES[wave_index].size(): + var agent_resource: PackedScene = WAVES[wave_index][i] + var agent: CharacterBody2D = agent_resource.instantiate() + add_child(agent) + agent.global_position = spawns[i].global_position + agent.death.connect(_on_agent_death) + agent.play_summoning_effect() + agents_alive += 1 + + +func _on_agent_death() -> void: + agents_alive -= 1 + if agents_alive == 0: + _start_round() + + +func _on_player_death() -> void: + await get_tree().create_timer(3.0).timeout + get_tree().reload_current_scene() + + +func _on_switch_to_showcase_pressed() -> void: + get_tree().change_scene_to_file("res://demo/scenes/showcase.tscn") diff --git a/demo/scenes/game.gd.uid b/demo/scenes/game.gd.uid new file mode 100644 index 0000000..9e1f203 --- /dev/null +++ b/demo/scenes/game.gd.uid @@ -0,0 +1 @@ +uid://bwhv180m71qs4 diff --git a/demo/scenes/game.tscn b/demo/scenes/game.tscn new file mode 100644 index 0000000..9437d9f --- /dev/null +++ b/demo/scenes/game.tscn @@ -0,0 +1,196 @@ +[gd_scene load_steps=15 format=3 uid="uid://clyhgbpfpmtw7"] + +[ext_resource type="Script" uid="uid://bwhv180m71qs4" path="res://demo/scenes/game.gd" id="1_qw71e"] +[ext_resource type="Theme" uid="uid://boqtjf88xcpu4" path="res://demo/assets/ui.theme" id="2_r21q3"] +[ext_resource type="Texture2D" uid="uid://tyu0ua1ju38l" path="res://demo/assets/logo.png" id="3_g0us4"] +[ext_resource type="FontFile" uid="uid://d25vkmce7mhlt" path="res://demo/assets/fonts/knewave_regular.ttf" id="4_w0vii"] +[ext_resource type="Script" uid="uid://c5p1i8ofpv7qn" path="res://demo/scenes/base/toggle_fullscreen.gd" id="5_m16ov"] +[ext_resource type="Texture2D" uid="uid://dlw15foygohrk" path="res://demo/assets/hp_under.png" id="6_622dk"] +[ext_resource type="Texture2D" uid="uid://cls8jtnu413o8" path="res://demo/assets/hp_over.png" id="7_430mt"] +[ext_resource type="Texture2D" uid="uid://hnwi23oef752" path="res://demo/assets/hp_bar.png" id="8_invih"] +[ext_resource type="PackedScene" uid="uid://bsig1usigbbuy" path="res://demo/scenes/base/arena.tscn" id="9_k3uu1"] +[ext_resource type="PackedScene" uid="uid://bpd1wmw2f7bvg" path="res://demo/props/gong.tscn" id="10_tftjb"] +[ext_resource type="PackedScene" uid="uid://d07ag5dcje13i" path="res://demo/agents/player/player.tscn" id="11_bndob"] + +[sub_resource type="LabelSettings" id="LabelSettings_qvxvp"] +font = ExtResource("4_w0vii") +font_size = 33 +outline_size = 11 +outline_color = Color(0.258915, 0.234974, 0.191974, 1) + +[sub_resource type="LabelSettings" id="LabelSettings_628x3"] +font = ExtResource("4_w0vii") +font_size = 36 +font_color = Color(1, 1, 0.239216, 1) +outline_size = 20 +outline_color = Color(0.211521, 0.23888, 0.290166, 1) + +[sub_resource type="LabelSettings" id="LabelSettings_grcwx"] +font = ExtResource("4_w0vii") +font_size = 37 +outline_size = 12 +outline_color = Color(0.317525, 0.344884, 0.388373, 1) + +[node name="Game" type="Node2D"] +y_sort_enabled = true +script = ExtResource("1_qw71e") + +[node name="UI Layer" type="CanvasLayer" parent="."] + +[node name="Control" type="Control" parent="UI Layer"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("2_r21q3") + +[node name="Toolbar" type="PanelContainer" parent="UI Layer/Control"] +custom_minimum_size = Vector2(0, 54.26) +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 64.0 +grow_horizontal = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="UI Layer/Control/Toolbar"] +layout_mode = 2 +theme_override_constants/separation = 4 + +[node name="ToggleFullscreen" type="Button" parent="UI Layer/Control/Toolbar/HBoxContainer"] +layout_mode = 2 +focus_mode = 0 +theme_override_fonts/font = ExtResource("4_w0vii") +theme_override_font_sizes/font_size = 22 +text = "Toggle Fullscreen" +script = ExtResource("5_m16ov") + +[node name="Switch to Showcase" type="Button" parent="UI Layer/Control/Toolbar/HBoxContainer"] +layout_mode = 2 +focus_mode = 0 +theme_override_fonts/font = ExtResource("4_w0vii") +theme_override_font_sizes/font_size = 22 +text = "Switch to Showcase +" + +[node name="RoundCounter" type="Label" parent="UI Layer/Control/Toolbar/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 6 +text = "Strike the Gong to begin!" +label_settings = SubResource("LabelSettings_qvxvp") + +[node name="HPBar" type="TextureProgressBar" parent="UI Layer/Control/Toolbar/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +value = 100.0 +texture_under = ExtResource("6_622dk") +texture_over = ExtResource("7_430mt") +texture_progress = ExtResource("8_invih") + +[node name="Logo" type="TextureRect" parent="UI Layer/Control"] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -1899.0 +offset_top = -130.0 +offset_right = -1643.0 +offset_bottom = -45.0 +grow_horizontal = 0 +grow_vertical = 0 +texture = ExtResource("3_g0us4") + +[node name="Demo project" type="Label" parent="UI Layer/Control/Logo"] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -316.0 +offset_top = -72.0 +offset_right = 13.0 +offset_bottom = 74.0 +grow_horizontal = 0 +grow_vertical = 0 +text = "demo project" +label_settings = SubResource("LabelSettings_628x3") +horizontal_alignment = 2 +vertical_alignment = 1 + +[node name="Keys" type="Label" parent="UI Layer/Control"] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -336.0 +offset_top = -208.0 +offset_right = -18.0 +offset_bottom = -25.0 +grow_horizontal = 0 +grow_vertical = 0 +text = "Move WASD +Dodge SPACE +Attack ENTER / F +" +label_settings = SubResource("LabelSettings_grcwx") + +[node name="Arena" parent="." instance=ExtResource("9_k3uu1")] +metadata/_edit_lock_ = true + +[node name="Gong" parent="." instance=ExtResource("10_tftjb")] +position = Vector2(923, -21) + +[node name="Player" parent="." instance=ExtResource("11_bndob")] +position = Vector2(843, 455) + +[node name="Camera2D" type="Camera2D" parent="Player"] +position = Vector2(0, -100) +zoom = Vector2(0.88, 0.88) +process_callback = 0 +position_smoothing_enabled = true +drag_horizontal_enabled = true +drag_vertical_enabled = true +drag_top_margin = 0.1 +drag_bottom_margin = 0.1 + +[node name="SpawnPoints" type="Node2D" parent="."] + +[node name="SpawnPosition1" type="Marker2D" parent="SpawnPoints"] +position = Vector2(512, -180) + +[node name="SpawnPosition2" type="Marker2D" parent="SpawnPoints"] +position = Vector2(1421, -150) + +[node name="SpawnPosition3" type="Marker2D" parent="SpawnPoints"] +position = Vector2(1512, 300) + +[node name="SpawnPosition4" type="Marker2D" parent="SpawnPoints"] +position = Vector2(2264, 345) + +[node name="SpawnPosition5" type="Marker2D" parent="SpawnPoints"] +position = Vector2(1655, 789) + +[node name="SpawnPosition6" type="Marker2D" parent="SpawnPoints"] +position = Vector2(823, 826) + +[node name="SpawnPosition7" type="Marker2D" parent="SpawnPoints"] +position = Vector2(67, 648) + +[node name="SpawnPosition8" type="Marker2D" parent="SpawnPoints"] +position = Vector2(-399, 434) + +[node name="SpawnPosition9" type="Marker2D" parent="SpawnPoints"] +position = Vector2(629, 417) + +[node name="SpawnPosition10" type="Marker2D" parent="SpawnPoints"] +position = Vector2(1859, 3) + +[connection signal="pressed" from="UI Layer/Control/Toolbar/HBoxContainer/Switch to Showcase" to="." method="_on_switch_to_showcase_pressed"] +[connection signal="gong_struck" from="Gong" to="." method="_on_gong_gong_struck"] diff --git a/demo/scenes/showcase.gd b/demo/scenes/showcase.gd new file mode 100644 index 0000000..2b09558 --- /dev/null +++ b/demo/scenes/showcase.gd @@ -0,0 +1,156 @@ +#* +#* showcase.gd +#* ============================================================================= +#* Copyright 2024 Serhii Snitsaruk +#* +#* 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. +#* ============================================================================= +#* + +extends Node2D + +@onready var behavior_tree_view: BehaviorTreeView = %BehaviorTreeView +@onready var camera: Camera2D = $Camera2D +@onready var agent_selection: MenuButton = %AgentSelection +@onready var previous: Button = %Previous +@onready var next: Button = %Next +@onready var minimize_description: Button = %MinimizeDescription +@onready var description: RichTextLabel = %Description +@onready var begin_tutorial: Button = %BeginTutorial +@onready var navigation_hint: Label = %NavigationHint +@onready var scene_title: Label = %SceneTitle +@onready var code_popup = %CodePopup +@onready var code_edit = %CodeEdit + +var bt_player: BTPlayer +var selected_tree_index: int = -1 +var agent_files: Array[String] +var agents_dir: String +var is_tutorial: bool = false + + +func _ready() -> void: + code_popup.hide() + + agent_selection.get_popup().id_pressed.connect(_on_agent_selection_id_pressed) + previous.pressed.connect(func(): _on_agent_selection_id_pressed(selected_tree_index - 1)) + next.pressed.connect(func(): _on_agent_selection_id_pressed(selected_tree_index + 1)) + + _initialize() + + +func _physics_process(_delta: float) -> void: + var inst: BTInstance = bt_player.get_bt_instance() + var bt_data: BehaviorTreeData = BehaviorTreeData.create_from_bt_instance(inst) + behavior_tree_view.update_tree(bt_data) + + +func _initialize() -> void: + if is_tutorial: + _populate_agent_files("res://demo/agents/tutorial/") + begin_tutorial.text = "End Tutorial" + navigation_hint.text = "Navigate ➤" + scene_title.text = "Tutorial" + _on_agent_selection_id_pressed(0) + else: + _populate_agent_files("res://demo/agents/") + begin_tutorial.text = "Begin Tutorial" + navigation_hint.text = "Select Agent ➤" + scene_title.text = "Showcase" + _on_agent_selection_id_pressed(0) + + +func _attach_camera(agent: CharacterBody2D) -> void: + await get_tree().process_frame + camera.get_parent().remove_child(camera) + agent.add_child(camera) + camera.position = Vector2(400.0, 0.0) + + +func _populate_agent_files(p_path: String = "res://demo/agents/") -> void: + var popup: PopupMenu = agent_selection.get_popup() + popup.clear() + popup.reset_size() + agent_files.clear() + agents_dir = p_path + + var dir := DirAccess.open(p_path) + if dir: + dir.list_dir_begin() + var file_name: String = dir.get_next() + while file_name != "": + if dir.current_is_dir() or file_name.begins_with("agent_base"): + file_name = dir.get_next() + continue + agent_files.append(file_name.get_file().trim_suffix(".remap")) + file_name = dir.get_next() + dir.list_dir_end() + + agent_files.sort() + for i in agent_files.size(): + popup.add_item(agent_files[i], i) + + +func _load_agent(file_name: String) -> void: + var agent_res := load(file_name) as PackedScene + assert(agent_res != null) + + for child in get_children(): + if child is CharacterBody2D and child.name != "Dummy": + child.die() + + var agent: CharacterBody2D = agent_res.instantiate() + add_child(agent) + bt_player = agent.find_child("BTPlayer") + description.text = _parse_description(bt_player.behavior_tree.description) + _attach_camera(agent) + + +func _parse_description(p_desc: String) -> String: + return p_desc \ + .replace("[SUCCESS]", "[color=PaleGreen]SUCCESS[/color]") \ + .replace("[FAILURE]", "[color=IndianRed]FAILURE[/color]") \ + .replace("[RUNNING]", "[color=orange]RUNNING[/color]") \ + .replace("[comp]", "[color=CornflowerBlue][b]") \ + .replace("[/comp]", "[/b][/color]") \ + .replace("[act]", "[color=white][b]") \ + .replace("[/act]", "[/b][/color]") \ + .replace("[dec]", "[color=MediumOrchid][b]") \ + .replace("[/dec]", "[/b][/color]") \ + .replace("[con]", "[color=orange][b]") \ + .replace("[/con]", "[/b][/color]") + + +func _on_agent_selection_id_pressed(id: int) -> void: + assert(id >= 0 and id < agent_files.size()) + selected_tree_index = id + _load_agent(agents_dir.path_join(agent_files[id])) + agent_selection.text = bt_player.behavior_tree.resource_path.get_file() + if agent_selection.text.to_lower() != agent_selection.text: + # Treat filename as a title + agent_selection.text = agent_selection.text.trim_suffix(".tres") + previous.disabled = id == 0 + next.disabled = id == (agent_files.size() - 1) + + +func _on_switch_to_game_pressed() -> void: + get_tree().change_scene_to_file("res://demo/scenes/game.tscn") + + +func _on_minimize_description_button_down() -> void: + description.visible = not description.visible + minimize_description.text = "-" if description.visible else "+" + + +func _on_tutorial_pressed() -> void: + is_tutorial = not is_tutorial + _initialize() + + +func _on_behavior_tree_view_task_selected(_type_name: String, p_script_path: String) -> void: + if not p_script_path.is_empty(): + var sc: Script = load(p_script_path) + code_edit.set_source_code(sc.source_code) + code_popup.popup.call_deferred() diff --git a/demo/scenes/showcase.gd.uid b/demo/scenes/showcase.gd.uid new file mode 100644 index 0000000..3420d58 --- /dev/null +++ b/demo/scenes/showcase.gd.uid @@ -0,0 +1 @@ +uid://qpj1dk7ugnja diff --git a/demo/scenes/showcase.tscn b/demo/scenes/showcase.tscn new file mode 100644 index 0000000..8d1f2be --- /dev/null +++ b/demo/scenes/showcase.tscn @@ -0,0 +1,288 @@ +[gd_scene load_steps=16 format=3 uid="uid://b3ae14mc2ty3y"] + +[ext_resource type="Script" uid="uid://qpj1dk7ugnja" path="res://demo/scenes/showcase.gd" id="1_l12ql"] +[ext_resource type="Theme" uid="uid://boqtjf88xcpu4" path="res://demo/assets/ui.theme" id="2_3d7dj"] +[ext_resource type="FontFile" uid="uid://d25vkmce7mhlt" path="res://demo/assets/fonts/knewave_regular.ttf" id="3_7vli5"] +[ext_resource type="FontFile" uid="uid://n231m6uqsq6x" path="res://demo/assets/fonts/junction_bold.otf" id="4_7ubu6"] +[ext_resource type="Texture2D" uid="uid://dc1wu244fnetf" path="res://demo/assets/arrow_left.png" id="5_bvrtp"] +[ext_resource type="Texture2D" uid="uid://tyu0ua1ju38l" path="res://demo/assets/logo.png" id="5_rwygb"] +[ext_resource type="Script" uid="uid://c5p1i8ofpv7qn" path="res://demo/scenes/base/toggle_fullscreen.gd" id="6_uggpo"] +[ext_resource type="Texture2D" uid="uid://bjakugmqbbtw7" path="res://demo/assets/arrow_right.png" id="7_5do2y"] +[ext_resource type="PackedScene" uid="uid://bsig1usigbbuy" path="res://demo/scenes/base/arena.tscn" id="7_42nq6"] +[ext_resource type="PackedScene" uid="uid://c5fhe3tulhlco" path="res://demo/props/dummy.tscn" id="8_apshw"] +[ext_resource type="Script" uid="uid://cb8thyd7vi2nj" path="res://demo/scenes/base/code_edit.gd" id="9_txke7"] + +[sub_resource type="LabelSettings" id="LabelSettings_rdr7a"] +font = ExtResource("3_7vli5") +font_size = 33 +outline_size = 11 +outline_color = Color(0.258915, 0.234974, 0.191974, 1) + +[sub_resource type="LabelSettings" id="LabelSettings_3uhve"] +font = ExtResource("3_7vli5") +font_size = 26 +font_color = Color(0.804089, 0.811917, 0.823636, 1) +outline_size = 10 +outline_color = Color(0.145083, 0.168536, 0.203708, 1) + +[sub_resource type="LabelSettings" id="LabelSettings_la4ui"] +font = ExtResource("3_7vli5") +font_size = 36 +font_color = Color(1, 1, 0.239216, 1) +outline_size = 20 +outline_color = Color(0.211521, 0.23888, 0.290166, 1) + +[sub_resource type="LabelSettings" id="LabelSettings_tlprv"] +font = ExtResource("3_7vli5") +font_size = 23 +font_color = Color(0.804089, 0.811917, 0.823636, 1) +outline_size = 10 +outline_color = Color(0.145083, 0.168536, 0.203708, 1) + +[node name="AgentShowcase" type="Node2D"] +y_sort_enabled = true +script = ExtResource("1_l12ql") + +[node name="UI Layer" type="CanvasLayer" parent="."] + +[node name="Control" type="Control" parent="UI Layer"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("2_3d7dj") + +[node name="Toolbar" type="PanelContainer" parent="UI Layer/Control"] +custom_minimum_size = Vector2(0, 54.26) +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_right = -612.0 +offset_bottom = 58.0 +grow_horizontal = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="UI Layer/Control/Toolbar"] +layout_mode = 2 +theme_override_constants/separation = 4 + +[node name="ToggleFullscreen" type="Button" parent="UI Layer/Control/Toolbar/HBoxContainer"] +layout_mode = 2 +focus_mode = 0 +theme_override_fonts/font = ExtResource("3_7vli5") +theme_override_font_sizes/font_size = 22 +text = "Toggle Fullscreen" +script = ExtResource("6_uggpo") + +[node name="SwitchToGame" type="Button" parent="UI Layer/Control/Toolbar/HBoxContainer"] +layout_mode = 2 +focus_mode = 0 +theme_override_fonts/font = ExtResource("3_7vli5") +theme_override_font_sizes/font_size = 22 +text = "Switch to Game" + +[node name="BeginTutorial" type="Button" parent="UI Layer/Control/Toolbar/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +focus_mode = 0 +theme_override_fonts/font = ExtResource("3_7vli5") +theme_override_font_sizes/font_size = 22 +text = "Begin Tutorial +" + +[node name="SceneTitle" type="Label" parent="UI Layer/Control/Toolbar/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 6 +text = "Tutorial" +label_settings = SubResource("LabelSettings_rdr7a") + +[node name="NavigationHint" type="Label" parent="UI Layer/Control/Toolbar/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 8 +text = "Select Agent ➤" +label_settings = SubResource("LabelSettings_3uhve") +horizontal_alignment = 2 + +[node name="BehaviorInspector" type="PanelContainer" parent="UI Layer/Control"] +layout_mode = 1 +anchors_preset = 11 +anchor_left = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -612.0 +grow_horizontal = 0 +grow_vertical = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="UI Layer/Control/BehaviorInspector"] +custom_minimum_size = Vector2(600, 0) +layout_mode = 2 +theme_override_constants/separation = 4 + +[node name="HBoxContainer" type="HBoxContainer" parent="UI Layer/Control/BehaviorInspector/VBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 4 + +[node name="Previous" type="Button" parent="UI Layer/Control/BehaviorInspector/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +focus_mode = 0 +theme_override_font_sizes/font_size = 28 +icon = ExtResource("5_bvrtp") + +[node name="AgentSelection" type="MenuButton" parent="UI Layer/Control/BehaviorInspector/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(400, 50) +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_fonts/font = ExtResource("4_7ubu6") +theme_override_font_sizes/font_size = 30 +text = "02_agent_imp.tres +" +flat = false + +[node name="Next" type="Button" parent="UI Layer/Control/BehaviorInspector/VBoxContainer/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +focus_mode = 0 +theme_override_font_sizes/font_size = 28 +icon = ExtResource("7_5do2y") + +[node name="BehaviorTreeView" type="BehaviorTreeView" parent="UI Layer/Control/BehaviorInspector/VBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(600, 0) +layout_mode = 2 +size_flags_vertical = 3 + +[node name="PanelContainer" type="PanelContainer" parent="UI Layer/Control"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -8.0 +offset_right = -612.0 +grow_horizontal = 2 +grow_vertical = 0 + +[node name="Control" type="Control" parent="UI Layer/Control/PanelContainer"] +layout_mode = 2 + +[node name="Logo" type="TextureRect" parent="UI Layer/Control/PanelContainer/Control"] +layout_mode = 1 +offset_top = -128.0 +offset_right = 256.0 +offset_bottom = -43.0 +texture = ExtResource("5_rwygb") + +[node name="Demo project" type="Label" parent="UI Layer/Control/PanelContainer/Control/Logo"] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -316.0 +offset_top = -72.0 +offset_right = 13.0 +offset_bottom = 74.0 +grow_horizontal = 0 +grow_vertical = 0 +text = "demo project" +label_settings = SubResource("LabelSettings_la4ui") +horizontal_alignment = 2 +vertical_alignment = 1 + +[node name="Header" type="HBoxContainer" parent="UI Layer/Control/PanelContainer/Control"] +layout_mode = 2 +offset_left = 3.0 +offset_top = -43.0 +offset_right = 1299.0 +offset_bottom = -7.0 +theme_override_constants/separation = 8 + +[node name="Label" type="Label" parent="UI Layer/Control/PanelContainer/Control/Header"] +layout_mode = 2 +size_flags_horizontal = 10 +text = "Description" +label_settings = SubResource("LabelSettings_tlprv") + +[node name="MinimizeDescription" type="Button" parent="UI Layer/Control/PanelContainer/Control/Header"] +unique_name_in_owner = true +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 +focus_mode = 0 +theme_override_fonts/font = ExtResource("3_7vli5") +text = "-" + +[node name="MarginContainer" type="MarginContainer" parent="UI Layer/Control/PanelContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 6 +theme_override_constants/margin_bottom = 6 + +[node name="VBoxContainer" type="VBoxContainer" parent="UI Layer/Control/PanelContainer/MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="Description" type="RichTextLabel" parent="UI Layer/Control/PanelContainer/MarginContainer/VBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(0, 140) +layout_mode = 2 +size_flags_vertical = 3 +theme_override_font_sizes/bold_italics_font_size = 20 +theme_override_font_sizes/italics_font_size = 20 +theme_override_font_sizes/mono_font_size = 20 +theme_override_font_sizes/normal_font_size = 20 +theme_override_font_sizes/bold_font_size = 20 +bbcode_enabled = true +text = "[b]Behavior Trees[/b] are composed of tasks that represent specific actions or decision-making rules. Tasks can be broadly categorized into two main types: control tasks and leaf tasks. Control tasks determine the execution flow within the tree. They include Sequence, Selector, and Invert. Leaf tasks represent specific actions to perform, like moving or attacking, or conditions that need to be checked. The BTTask class provides the foundation for various building blocks of the Behavior Trees. BT tasks can share data with the help of the Blackboard." +fit_content = true + +[node name="CodePopup" type="PopupPanel" parent="UI Layer/Control"] +unique_name_in_owner = true +position = Vector2i(0, 60) +size = Vector2i(1024, 708) +visible = true + +[node name="CodeEdit" type="CodeEdit" parent="UI Layer/Control/CodePopup"] +unique_name_in_owner = true +custom_minimum_size = Vector2(800, 700) +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 4.0 +offset_top = 4.0 +offset_right = -4.0 +offset_bottom = -4.0 +grow_horizontal = 2 +grow_vertical = 2 +gutters_draw_line_numbers = true +script = ExtResource("9_txke7") + +[node name="Camera2D" type="Camera2D" parent="."] +position = Vector2(400, 0) +zoom = Vector2(0.88, 0.88) +process_callback = 0 +position_smoothing_enabled = true +drag_horizontal_enabled = true +drag_vertical_enabled = true +drag_left_margin = 0.1 +drag_top_margin = 0.1 +drag_right_margin = 0.0 +drag_bottom_margin = 0.1 + +[node name="Arena" parent="." instance=ExtResource("7_42nq6")] +metadata/_edit_lock_ = true + +[node name="Dummy" parent="." instance=ExtResource("8_apshw")] +position = Vector2(1106, 423) + +[connection signal="pressed" from="UI Layer/Control/Toolbar/HBoxContainer/SwitchToGame" to="." method="_on_switch_to_game_pressed"] +[connection signal="pressed" from="UI Layer/Control/Toolbar/HBoxContainer/BeginTutorial" to="." method="_on_tutorial_pressed"] +[connection signal="task_selected" from="UI Layer/Control/BehaviorInspector/VBoxContainer/BehaviorTreeView" to="." method="_on_behavior_tree_view_task_selected"] +[connection signal="button_down" from="UI Layer/Control/PanelContainer/Control/Header/MinimizeDescription" to="." method="_on_minimize_description_button_down"] diff --git a/environments/test_level.tscn b/environments/test_level.tscn new file mode 100644 index 0000000..8ad61be --- /dev/null +++ b/environments/test_level.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=6 format=3 uid="uid://chh7i0p81kr7x"] + +[ext_resource type="PackedScene" uid="uid://b6cat7mj1lmpb" path="res://characters/samus/samus.tscn" id="1_5hnle"] +[ext_resource type="Texture2D" uid="uid://cc51mfc3keg8n" path="res://addons/kenney_prototype_textures/dark/texture_01.png" id="1_5vm83"] +[ext_resource type="Texture2D" uid="uid://oh0q8v8hjc7c" path="res://addons/kenney_prototype_textures/orange/texture_01.png" id="2_nfqdm"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_sodpf"] +albedo_texture = ExtResource("1_5vm83") +uv1_triplanar = true + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_a5u7v"] +albedo_texture = ExtResource("2_nfqdm") +uv1_triplanar = true + +[node name="TestLevel" type="Node3D"] + +[node name="CSGCombiner3D" type="CSGCombiner3D" parent="."] +use_collision = true + +[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.87659, -0.25, -3.31314) +size = Vector3(28.3694, 0.5, 22.0172) +material = SubResource("StandardMaterial3D_sodpf") + +[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.5, 1, 0.25) +size = Vector3(1, 2, 3.5) +material = SubResource("StandardMaterial3D_a5u7v") + +[node name="Samus" parent="." instance=ExtResource("1_5hnle")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5, 0.362916, -0.5) diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..9d8b7fa --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..959d955 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://wfoljnwif2ig" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +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..9288082 --- /dev/null +++ b/project.godot @@ -0,0 +1,56 @@ +; 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="TankControl FixedCamera" +run/main_scene="uid://chh7i0p81kr7x" +config/features=PackedStringArray("4.4", "Forward Plus") +config/icon="res://icon.svg" + +[autoload] + +PhantomCameraManager="*res://addons/phantom_camera/scripts/managers/phantom_camera_manager.gd" +Global="*res://scripts/global.gd" + +[editor] + +version_control/plugin_name="GitPlugin" +version_control/autoload_on_startup=true + +[editor_plugins] + +enabled=PackedStringArray("res://addons/phantom_camera/plugin.cfg", "res://addons/script_spliter/plugin.cfg") + +[file_customization] + +folder_colors={ +"res://addons/": "red", +"res://characters/": "orange", +"res://environments/": "yellow", +"res://scripts/": "green" +} + +[input] + +Quit={ +"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":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +Debug={ +"deadzone": 0.2, +"events": [] +} + +[rendering] + +textures/canvas_textures/default_texture_filter=0 +textures/default_filters/use_nearest_mipmap_filter=true diff --git a/scripts/characters/samus/idle.gd b/scripts/characters/samus/idle.gd new file mode 100644 index 0000000..930a04c --- /dev/null +++ b/scripts/characters/samus/idle.gd @@ -0,0 +1,7 @@ +extends LimboState + +@export var animation_player: AnimationPlayer +@export var animation: StringName + +func _enter() -> void: + animation_player.play(animation) diff --git a/scripts/characters/samus/idle.gd.uid b/scripts/characters/samus/idle.gd.uid new file mode 100644 index 0000000..65691d5 --- /dev/null +++ b/scripts/characters/samus/idle.gd.uid @@ -0,0 +1 @@ +uid://dohyq145fqsdy diff --git a/scripts/global.gd b/scripts/global.gd new file mode 100644 index 0000000..1de7107 --- /dev/null +++ b/scripts/global.gd @@ -0,0 +1,5 @@ +extends Node + +func _input(event: InputEvent) -> void: + if event.is_action("Quit"): + get_tree().quit() diff --git a/scripts/global.gd.uid b/scripts/global.gd.uid new file mode 100644 index 0000000..99a64eb --- /dev/null +++ b/scripts/global.gd.uid @@ -0,0 +1 @@ +uid://m3dspgwiob61