Boat/Boats/buyancy_probe.gd

95 lines
3.4 KiB
GDScript3
Raw Normal View History

2025-03-25 10:49:02 +00:00
@icon("uid://ck86evu4iyhyg")
@tool
2025-03-25 00:22:03 +00:00
extends Marker3D
class_name BuyancyProbe
## How much force is applied upward
2025-04-07 10:32:21 +00:00
@export var float_strength: float = 1.0
@export var max_float_force:float = 500.0
2025-03-25 00:22:03 +00:00
var currentdepth:float
@export_category("Debug")
2025-04-07 10:32:21 +00:00
@export var debug :bool = false
@export var show_probe :bool = false:
set(_value):
show_probe = _value
2025-03-27 08:29:54 +00:00
if !show_probe && sphere_preview != null:
sphere_preview.queue_free()
2025-03-25 00:22:03 +00:00
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")
2025-03-25 00:22:03 +00:00
@onready var OceanNode:Ocean = get_tree().get_first_node_in_group("Ocean")
var Oceantime:float
2025-03-25 10:49:02 +00:00
@onready var parentRigid:RigidBody3D = get_parent()
2025-04-07 10:32:21 +00:00
2025-04-07 16:23:29 +00:00
func _init() -> void:
pass
2025-03-25 00:22:03 +00:00
# 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:
2025-03-25 10:49:02 +00:00
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
2025-03-25 10:49:02 +00:00
parentRigid.apply_force(Vector3.UP * clamp(gravity * depth * float_force,-max_float_force,max_float_force) ,global_position-parentRigid.global_position)
2025-04-07 10:32:21 +00:00
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))
2025-03-25 10:49:02 +00:00
2025-03-25 00:22:03 +00:00
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)
2025-03-25 17:23:14 +00:00
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
2025-03-25 00:22:03 +00:00
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")
2025-03-25 10:49:02 +00:00
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