├── LICENSE ├── README.md └── addons └── nklbdev.parallax ├── Parallax.gd ├── icon.png ├── plugin.cfg ├── plugin_manager.gd ├── type_icon.svg └── type_icon.svg.import /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 nklbdev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Parallax 2D node for Godot 4 2 | Provides parallax 2D node to avoid using ParallaxBackground 3 | 4 | This is a plugin for [Godot Engine](https://godotengine.org) 4.X that provides new class `Parallax` inherited from Node2D that moves itself relative to actual viewport center. It helps create beautiful volumetric decorations like foliage, distant or near objects ant other effects based on following viewport. 5 | 6 | This is a port of the [similar plugin](https://godotengine.org/asset-library/asset/1557) from Godot 3.4.X to 4.X.X 7 | 8 | You can: 9 | - Disable/enable it in game and optionally in editor 10 | - Control motion_scale and motion_offset like in ParallaxLayer 11 | - Set process mode (Process / Physics process) 12 | 13 | [![image](https://user-images.githubusercontent.com/7024016/202920689-7782adb5-d22f-4873-bc6c-0c1dc5445a81.png)](https://user-images.githubusercontent.com/7024016/202920636-4e71b6a4-32e3-490f-ab75-32e63cfb4dca.png) 14 | 15 | [Screencast on YouTube](https://youtu.be/kTPX_Etzy2Y) 16 | 17 | ## Installation 18 | 19 | Simply download it from [Godot Asset Library](https://godotengine.org/asset-library/asset/1607). 20 | 21 | Alternatively, download or clone this repository and copy the contents of the 22 | `addons` folder to your own project's `addons` folder. 23 | 24 | Then enable the plugin on the Project Settings and use new class in your scenes. 25 | 26 | ## License 27 | 28 | [MIT License](LICENSE). Copyright (c) 2022 Nikolay Lebedev aka nklbdev. 29 | -------------------------------------------------------------------------------- /addons/nklbdev.parallax/Parallax.gd: -------------------------------------------------------------------------------- 1 | @tool @icon("type_icon.svg") 2 | extends Node2D 3 | 4 | const __max_arrow_size: float = 6.0 5 | const __line_width: float = 1.4 6 | const __arrow_points: Array = [Vector2.ZERO, Vector2(-1, 0.5), Vector2(-1, -0.5)] 7 | var __draw_color: Color 8 | var __draw_enabled_color: Color 9 | var __draw_disabled_color: Color 10 | @onready var __is_editor: bool = Engine.is_editor_hint() 11 | @onready var __packed_arrow_points: PackedVector2Array = PackedVector2Array(__arrow_points) 12 | 13 | enum MotionProcessMode { 14 | PROCESS = 0, 15 | PHYSICS_PROCESS = 1 16 | } 17 | 18 | @export var enabled: bool = true : set = __set_enabled 19 | func __set_enabled(value: bool): 20 | if enabled == value: 21 | return 22 | enabled = value 23 | __update_position() 24 | __update_draw_color() 25 | 26 | @export var enabled_in_editor: bool = false : set = __set_enabled_in_editor 27 | func __set_enabled_in_editor(value: bool): 28 | if enabled_in_editor == value: 29 | return 30 | enabled_in_editor = value 31 | if __is_editor and not enabled_in_editor: 32 | position = Vector2.ZERO 33 | else: 34 | __update_position() 35 | 36 | @export var motion_scale: Vector2 = Vector2.ZERO : set = __set_motion_scale 37 | func __set_motion_scale(value: Vector2): 38 | if motion_scale == value: 39 | return 40 | motion_scale = value 41 | __update_position() 42 | 43 | @export var motion_offset: Vector2 = Vector2.ZERO : set = __set_motion_offset 44 | func __set_motion_offset(value: Vector2): 45 | if motion_offset == value: 46 | return 47 | motion_offset = value 48 | __update_position() 49 | 50 | @export var motion_process_mode: MotionProcessMode = MotionProcessMode.PROCESS 51 | 52 | func __update_position() -> void: 53 | if enabled and (enabled_in_editor or not __is_editor) and is_inside_tree(): 54 | var parent_node_2d: Node2D = get_parent() as Node2D 55 | if parent_node_2d != null: 56 | var screen_center_local: Vector2 = (parent_node_2d.get_viewport_transform() * parent_node_2d.get_global_transform()) \ 57 | .affine_inverse() * Vector2(get_viewport_rect().size / 2) 58 | position = screen_center_local * parent_node_2d.global_scale * motion_scale * parent_node_2d.global_scale + motion_offset 59 | queue_redraw() 60 | 61 | func _process(_delta: float) -> void: 62 | if __is_editor or motion_process_mode == MotionProcessMode.PROCESS: 63 | __update_position() 64 | 65 | func _physics_process(delta: float) -> void: 66 | if not __is_editor and motion_process_mode == MotionProcessMode.PHYSICS_PROCESS: 67 | __update_position() 68 | 69 | func _draw(): 70 | if __is_editor or get_tree().debug_collisions_hint: 71 | __draw_arrow(-position, -motion_offset) 72 | __draw_arrow(-motion_offset, Vector2.ZERO, true) 73 | 74 | func _enter_tree(): 75 | # connect to project_settings_changed when signal will be added 76 | # https://github.com/godotengine/godot/pull/62038 77 | __on_project_settings_changed() 78 | 79 | func _exit_tree(): 80 | # disconnect from project_settings_changed when signal will be added 81 | # https://github.com/godotengine/godot/pull/62038 82 | pass 83 | 84 | func __update_draw_color(): 85 | __draw_color = __draw_enabled_color if enabled else __draw_disabled_color 86 | 87 | func __on_project_settings_changed(): 88 | __draw_enabled_color = ProjectSettings.get_setting("debug/shapes/collision/shape_color") as Color 89 | var gray = __draw_enabled_color.v 90 | __draw_disabled_color = Color(gray, gray, gray) 91 | __update_draw_color() 92 | 93 | func __draw_arrow(from: Vector2, to: Vector2, with_triangle: bool = false) -> void: 94 | from = from.rotated(-rotation) / scale 95 | to = to.rotated(-rotation) / scale 96 | draw_circle(from, 2.5, __draw_color) 97 | if not with_triangle: 98 | draw_line(from, to, __draw_color, __line_width) 99 | return 100 | var distance: float = from.distance_to(to) 101 | var arrow_size: float = clampf(distance * 2 / 3, __line_width, __max_arrow_size) 102 | 103 | var path: Vector2 = to - from 104 | if distance < __line_width: 105 | arrow_size = distance 106 | else: 107 | draw_line(from, to - path.normalized() * arrow_size, __draw_color, __line_width) 108 | 109 | draw_colored_polygon(Transform2D(path.angle(), Vector2.ONE * arrow_size, 0, to) * __packed_arrow_points, __draw_color) 110 | -------------------------------------------------------------------------------- /addons/nklbdev.parallax/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nklbdev/godot-4-parallax-node/09d657a788d0de5778b016fd9769f083176ff0b9/addons/nklbdev.parallax/icon.png -------------------------------------------------------------------------------- /addons/nklbdev.parallax/plugin.cfg: -------------------------------------------------------------------------------- 1 | [plugin] 2 | 3 | name="Parallax Node" 4 | description="Provides parallax 2D node to avoid using ParallaxBackground" 5 | author="Nikolay Lebedev aka nklbdev" 6 | version="1.0.1" 7 | script="plugin_manager.gd" 8 | -------------------------------------------------------------------------------- /addons/nklbdev.parallax/plugin_manager.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends EditorPlugin 3 | 4 | const __class_name: String = "Parallax" 5 | const __base_class_name: String = "Node2D" 6 | const __script: GDScript = preload("Parallax.gd") 7 | const __icon_texture: Texture2D = preload("type_icon.svg") 8 | 9 | func _enter_tree(): 10 | add_custom_type(__class_name, __base_class_name, __script, __icon_texture) 11 | 12 | func _exit_tree(): 13 | remove_custom_type(__class_name) 14 | -------------------------------------------------------------------------------- /addons/nklbdev.parallax/type_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 38 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /addons/nklbdev.parallax/type_icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bcwgjego6ds1w" 6 | path="res://.godot/imported/type_icon.svg-7f41329f71cac632a6061f37ed722b27.ctex" 7 | metadata={ 8 | "has_editor_variant": true, 9 | "vram_texture": false 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://addons/nklbdev.parallax/type_icon.svg" 15 | dest_files=["res://.godot/imported/type_icon.svg-7f41329f71cac632a6061f37ed722b27.ctex"] 16 | 17 | [params] 18 | 19 | compress/mode=0 20 | compress/high_quality=false 21 | compress/lossy_quality=0.7 22 | compress/hdr_compression=1 23 | compress/normal_map=0 24 | compress/channel_pack=0 25 | mipmaps/generate=false 26 | mipmaps/limit=-1 27 | roughness/mode=0 28 | roughness/src_normal="" 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/normal_map_invert_y=false 32 | process/hdr_as_srgb=false 33 | process/hdr_clamp_exposure=false 34 | process/size_limit=0 35 | detect_3d/compress_to=1 36 | svg/scale=1.0 37 | editor/scale_with_editor_scale=true 38 | editor/convert_colors_with_editor_theme=false 39 | --------------------------------------------------------------------------------