@icon("uid://ck86evu4iyhyg") @tool extends Marker3D class_name BuyancyProbe ## How much force is applied upward @export var float_strength: float = 1.0 @export var max_float_force:float = 500.0 var currentdepth:float @export_category("Debug") @export var debug :bool = false @export var show_probe :bool = false: set(_value): show_probe = _value if !show_probe && sphere_preview != null: sphere_preview.queue_free() var sphere_preview:MeshInstance3D @onready var debug_sphere:SphereMesh = SphereMesh.new() @export_category("Wave") var noise: Image var wave_speed: float = 1.0 var noise_scale: float var height_scale: float @onready var ocean_mat: ShaderMaterial = preload("uid://cf3lxmfb2d7c8") @onready var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity") @onready var defaultDampe: float = ProjectSettings.get_setting("physics/3d/default_angular_damp") @onready var OceanNode:Ocean = get_tree().get_first_node_in_group("Ocean") var Oceantime:float @onready var parentRigid:RigidBody3D = get_parent() func _init() -> void: pass # Called when the node enters the scene tree for the first time. func _ready() -> void: if ocean_mat != null: update_param() if show_probe: sphere_preview = MeshInstance3D.new() sphere_preview.set_name("Sphere") add_child(sphere_preview) debug_sphere.radius = 0.1 debug_sphere.height = 0.2 sphere_preview.mesh = debug_sphere func _physics_process(_delta: float) -> void: if not Engine.is_editor_hint(): var depth = get_wave_height(global_position,Oceantime) - global_position.y #print(depth) if depth > 0.0 && parentRigid != null: var float_force = parentRigid.mass * float_strength #parentRigid.gravity_scale = 0.3 #parentRigid.angular_damp = 15.0 parentRigid.apply_force(Vector3.UP * clamp(gravity * depth * float_force,-max_float_force,max_float_force) ,global_position-parentRigid.global_position) if debug: print(str(self)+" is applying a force of "+str(Vector3.UP * clamp(gravity * depth * float_force,-max_float_force,max_float_force) ,global_position-parentRigid.global_position)+"to "+str(parentRigid)) func _process(_delta: float) -> void: if OceanNode != null: Oceantime = OceanNode.wave_time if show_probe && sphere_preview != null: sphere_preview.global_position = global_position sphere_preview.global_position.y = get_wave_height(global_position,Oceantime) # Calculate the wave height using a sine function. func get_wave_height(world_position: Vector3, time: float) -> float: var uv_x = wrapf(world_position.x / noise_scale + time * wave_speed, 0, 1) var uv_y = wrapf(world_position.z / noise_scale + time * wave_speed, 0, 1) if noise != null: var pixel_pos = Vector2(uv_x * noise.get_width(), uv_y * noise.get_height()) return OceanNode.global_position.y + noise.get_pixelv(pixel_pos).r * height_scale; return world_position.y func update_param(): if ocean_mat != null: wave_speed = ocean_mat.get_shader_parameter("wave_speed") noise = ocean_mat.get_shader_parameter("wave").noise.get_seamless_image(512, 512) noise_scale = ocean_mat.get_shader_parameter("noise_scale") wave_speed = ocean_mat.get_shader_parameter("wave_speed") height_scale = ocean_mat.get_shader_parameter("height_scale") func _get_configuration_warnings(): var warnings = [] if get_parent() is not RigidBody3D: warnings.append("This node need to be a direct child of a RigidBody3D") return warnings