generated from krampus/template-godot4
This commit is contained in:
parent
38404acb3c
commit
2cf7010c92
@ -7,7 +7,7 @@ const JUMP_FORCE := 4.5
|
||||
const GROUND_FRICTION := 0.3
|
||||
const AIR_FRICTION := 0.03
|
||||
|
||||
const SPRAY_SCALE := 8
|
||||
const SPRAY_SCALE := 16
|
||||
|
||||
var gravity: Vector3 = (
|
||||
ProjectSettings.get_setting("physics/3d/default_gravity")
|
||||
@ -16,8 +16,7 @@ var gravity: Vector3 = (
|
||||
|
||||
@onready var camera_pivot: Node3D = %CameraPivot
|
||||
@onready var spray_muzzle: Marker3D = %SprayMuzzle
|
||||
@onready var ray_cast_left: RayCast3D = %RayCastLeft
|
||||
@onready var ray_cast_right: RayCast3D = %RayCastRight
|
||||
@onready var raycast: RayCast3D = %RayCast3D
|
||||
|
||||
@onready var spray_effect: MeshInstance3D = %SprayEffect
|
||||
|
||||
@ -41,18 +40,13 @@ func _scale_spray_point(point: Vector3) -> float:
|
||||
|
||||
|
||||
func fire_spray() -> void:
|
||||
if ray_cast_left.is_colliding() and ray_cast_right.is_colliding():
|
||||
var collider := ray_cast_left.get_collider()
|
||||
if collider is GunkBody and collider == ray_cast_right.get_collider():
|
||||
var point_left := ray_cast_left.get_collision_point()
|
||||
var point_right := ray_cast_right.get_collision_point()
|
||||
(collider as GunkBody).paint_bar(
|
||||
point_left,
|
||||
ray_cast_left.get_collision_normal(),
|
||||
_scale_spray_point(point_left),
|
||||
point_right,
|
||||
ray_cast_right.get_collision_normal(),
|
||||
_scale_spray_point(point_right)
|
||||
if raycast.is_colliding():
|
||||
var collider := raycast.get_collider()
|
||||
if collider is GunkBody:
|
||||
var point := raycast.get_collision_point()
|
||||
var point_scale := point.distance_to(spray_muzzle.global_position) * SPRAY_SCALE
|
||||
(collider as GunkBody).paint_continuous(
|
||||
point, raycast.get_collision_normal(), point_scale
|
||||
)
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@ albedo_color = Color(0, 1, 0.301961, 0.254902)
|
||||
|
||||
[sub_resource type="PrismMesh" id="PrismMesh_ow0jh"]
|
||||
material = SubResource("StandardMaterial3D_ng43h")
|
||||
size = Vector3(0.5, 2, 0.1)
|
||||
size = Vector3(0.2, 2, 0.2)
|
||||
|
||||
[sub_resource type="QuadMesh" id="QuadMesh_cn0yq"]
|
||||
size = Vector2(1, 0.05)
|
||||
@ -38,13 +38,9 @@ mesh = SubResource("BoxMesh_ua7a2")
|
||||
unique_name_in_owner = true
|
||||
transform = Transform3D(1, 0, 0, 0, 0.997564, -0.0697565, 0, 0.0697565, 0.997564, 0, 0, -0.15)
|
||||
|
||||
[node name="RayCastLeft" type="RayCast3D" parent="CameraPivot/SprayNozzle/SprayMuzzle" groups=["SprayCast"]]
|
||||
[node name="RayCast3D" type="RayCast3D" parent="CameraPivot/SprayNozzle/SprayMuzzle" groups=["SprayCast"]]
|
||||
unique_name_in_owner = true
|
||||
target_position = Vector3(-0.25, 0, -2)
|
||||
|
||||
[node name="RayCastRight" type="RayCast3D" parent="CameraPivot/SprayNozzle/SprayMuzzle" groups=["SprayCast"]]
|
||||
unique_name_in_owner = true
|
||||
target_position = Vector3(0.25, 0, -2)
|
||||
target_position = Vector3(0, 0, -2)
|
||||
|
||||
[node name="SprayEffect" type="MeshInstance3D" parent="CameraPivot/SprayNozzle/SprayMuzzle"]
|
||||
unique_name_in_owner = true
|
||||
|
@ -1,25 +1,19 @@
|
||||
class_name GunkBody extends StaticBody3D
|
||||
## StaticBody3D with an associated "gunkable" mesh.
|
||||
|
||||
const CONTINUITY_LIMIT := 64
|
||||
const BUFFER_LIMIT := 3
|
||||
const FACE_EPSILON := 0.4
|
||||
const MASK_COLOR := Color.RED
|
||||
|
||||
const WRAPPINGS := [
|
||||
Vector2(-1, -1),
|
||||
Vector2(-1, 0),
|
||||
Vector2(-1, 1),
|
||||
Vector2(0, -1),
|
||||
Vector2(0, 0),
|
||||
Vector2(0, 1),
|
||||
Vector2(1, -1),
|
||||
Vector2(1, 0),
|
||||
Vector2(1, 1),
|
||||
]
|
||||
|
||||
@export var mask_dim := 1024
|
||||
|
||||
var meshtool := MeshDataTool.new()
|
||||
|
||||
var _polyline_buffer: Array[Vector2] = []
|
||||
var _continuous := false
|
||||
var _painted_this_frame := false
|
||||
|
||||
@onready var mesh_instance: MeshInstance3D = $MeshInstance3D
|
||||
@onready var mesh: ArrayMesh = mesh_instance.mesh
|
||||
@onready var gunk_mat: ShaderMaterial = mesh_instance.get_surface_override_material(0).next_pass
|
||||
@ -86,73 +80,25 @@ func _get_uv(point: Vector3, normal: Vector3) -> Vector2:
|
||||
return (uv1 * bc.x) + (uv2 * bc.y) + (uv3 * bc.z)
|
||||
|
||||
|
||||
## Paint a circle on the mask at a given point & normal on the mesh.
|
||||
func paint_mask(point: Vector3, normal: Vector3, radius: float) -> void:
|
||||
var local_point := point * global_transform
|
||||
var local_normal := normal * global_basis
|
||||
var uv := _get_uv(local_point, local_normal)
|
||||
if uv == Vector2.INF:
|
||||
return
|
||||
var px_center: Vector2 = uv * mask_control.size
|
||||
mask_control.queue_draw(
|
||||
func() -> void: mask_control.draw_circle(px_center, radius, MASK_COLOR, true, -1, true)
|
||||
)
|
||||
func paint_continuous(point: Vector3, normal: Vector3, width: float) -> void:
|
||||
var px := _get_uv(point * global_transform, normal * global_basis) * mask_control.size
|
||||
if _polyline_buffer and px.distance_to(_polyline_buffer[0]) <= CONTINUITY_LIMIT:
|
||||
_polyline_buffer.push_front(px)
|
||||
if len(_polyline_buffer) > BUFFER_LIMIT:
|
||||
_polyline_buffer.pop_back()
|
||||
var polyline := PackedVector2Array(_polyline_buffer)
|
||||
mask_control.queue_draw(
|
||||
func() -> void: mask_control.draw_polyline(polyline, MASK_COLOR, width * 2, true)
|
||||
)
|
||||
else:
|
||||
_polyline_buffer = [px]
|
||||
mask_control.queue_draw(
|
||||
func() -> void: mask_control.draw_circle(px, width, MASK_COLOR, true, -1, true)
|
||||
)
|
||||
_painted_this_frame = true
|
||||
|
||||
|
||||
func paint_line(
|
||||
point_a: Vector3, normal_a: Vector3, point_b: Vector3, normal_b: Vector3, width: float
|
||||
) -> void:
|
||||
var uv_a := _get_uv(point_a * global_transform, normal_a * global_basis)
|
||||
var uv_b := _get_uv(point_b * global_transform, normal_b * global_basis)
|
||||
if uv_a == Vector2.INF or uv_b == Vector2.INF:
|
||||
return
|
||||
var px_a := uv_a * mask_control.size
|
||||
var px_b := uv_b * mask_control.size
|
||||
mask_control.queue_draw(
|
||||
func() -> void: mask_control.draw_line(px_a, px_b, MASK_COLOR, width, true)
|
||||
)
|
||||
|
||||
|
||||
func _render_bar(uv_a: Vector2, scale_a: float, uv_b: Vector2, scale_b: float) -> void:
|
||||
var diff := (uv_b - uv_a).normalized()
|
||||
var ortho := diff.orthogonal()
|
||||
|
||||
var points := PackedVector2Array(
|
||||
[
|
||||
uv_a + ortho * scale_a,
|
||||
uv_a - ortho * scale_a,
|
||||
uv_b - ortho * scale_b,
|
||||
uv_b + ortho * scale_b,
|
||||
]
|
||||
)
|
||||
|
||||
mask_control.queue_draw(func() -> void: mask_control.draw_colored_polygon(points, MASK_COLOR))
|
||||
|
||||
|
||||
func paint_bar(
|
||||
point_a: Vector3,
|
||||
normal_a: Vector3,
|
||||
scale_a: float,
|
||||
point_b: Vector3,
|
||||
normal_b: Vector3,
|
||||
scale_b: float
|
||||
) -> void:
|
||||
var uv_a := _get_uv(point_a * global_transform, normal_a * global_basis) * mask_control.size
|
||||
var uv_b := _get_uv(point_b * global_transform, normal_b * global_basis) * mask_control.size
|
||||
if uv_a == Vector2.INF or uv_b == Vector2.INF:
|
||||
return # TODO just draw square around one valid point
|
||||
|
||||
var closest_b := uv_b
|
||||
var wrapped_a := uv_a
|
||||
var dist_sq := INF
|
||||
|
||||
for wrap_vec: Vector2 in WRAPPINGS:
|
||||
var wrapped_b := uv_b + wrap_vec * mask_dim
|
||||
var d := wrapped_b.distance_squared_to(uv_a)
|
||||
if d < dist_sq:
|
||||
closest_b = wrapped_b
|
||||
wrapped_a = uv_a - wrap_vec * mask_dim
|
||||
dist_sq = d
|
||||
|
||||
_render_bar(uv_a, scale_a, closest_b, scale_b)
|
||||
_render_bar(wrapped_a, scale_a, uv_b, scale_b)
|
||||
func _process(_delta: float) -> void:
|
||||
if not _painted_this_frame:
|
||||
_polyline_buffer = []
|
||||
_painted_this_frame = false
|
||||
|
Loading…
x
Reference in New Issue
Block a user