Created
June 24, 2025 17:32
-
-
Save Lightnet/36856ae0a4a5a56608772bf96aa839c5 to your computer and use it in GitHub Desktop.
sample test rope circle uv texture.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@tool | |
extends MeshInstance3D | |
@export var rope_length: float = 5.0 # Total length of the rope | |
@export var segments: int = 20 # Number of segments | |
@export var radius: float = 0.1 # Thickness of the rope | |
@export var sides: int = 8 # Number of sides for the rope's cross-section | |
func _ready() -> void: | |
generate_rope() | |
func _process(_delta: float) -> void: | |
if Engine.is_editor_hint(): # Update in editor for @tool | |
generate_rope() | |
func generate_rope() -> void: | |
# Create or get the ImmediateMesh | |
if mesh == null: | |
mesh = ImmediateMesh.new() | |
else: | |
mesh.clear_surfaces() | |
# Begin drawing the mesh | |
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES) | |
# Generate points along a simple straight line (modify for curves if needed) | |
var points: Array[Vector3] = [] | |
for i in range(segments + 1): | |
var t: float = float(i) / segments | |
points.append(Vector3(0, -t * rope_length, 0)) # Straight down | |
# Generate the rope mesh by creating a tube along the points | |
for i in range(segments): | |
var p0: Vector3 = points[i] | |
var p1: Vector3 = points[i + 1] | |
# Calculate the direction and basis vectors for the cross-section | |
var dir: Vector3 = (p1 - p0).normalized() | |
var right: Vector3 = dir.cross(Vector3.UP).normalized() | |
if right == Vector3.ZERO: # Handle edge case for vertical direction | |
right = dir.cross(Vector3.FORWARD).normalized() | |
var up: Vector3 = dir.cross(right).normalized() | |
# Create vertices for the current and next cross-section | |
for j in range(sides): | |
var angle0: float = j * TAU / sides | |
var angle1: float = (j + 1) * TAU / sides | |
# Vertices for the current segment's cross-section | |
var v0: Vector3 = p0 + radius * (cos(angle0) * right + sin(angle0) * up) | |
var v1: Vector3 = p0 + radius * (cos(angle1) * right + sin(angle1) * up) | |
var v2: Vector3 = p1 + radius * (cos(angle0) * right + sin(angle0) * up) | |
var v3: Vector3 = p1 + radius * (cos(angle1) * right + sin(angle1) * up) | |
# Normals (pointing outward from the rope's surface) | |
var n0: Vector3 = (cos(angle0) * right + sin(angle0) * up).normalized() | |
var n1: Vector3 = (cos(angle1) * right + sin(angle1) * up).normalized() | |
# UVs (simple cylindrical mapping) | |
var uv0: Vector2 = Vector2(float(j) / sides, float(i) / segments) | |
var uv1: Vector2 = Vector2(float(j + 1) / sides, float(i) / segments) | |
var uv2: Vector2 = Vector2(float(j) / sides, float(i + 1) / segments) | |
var uv3: Vector2 = Vector2(float(j + 1) / sides, float(i + 1) / segments) | |
# Add triangles with correct counterclockwise winding order for front face | |
# Triangle 1: v0, v2, v1 (counterclockwise when viewed from outside) | |
mesh.surface_set_normal(n0) | |
mesh.surface_set_uv(uv0) | |
mesh.surface_add_vertex(v0) | |
mesh.surface_set_normal(n0) | |
mesh.surface_set_uv(uv2) | |
mesh.surface_add_vertex(v2) | |
mesh.surface_set_normal(n1) | |
mesh.surface_set_uv(uv1) | |
mesh.surface_add_vertex(v1) | |
# Triangle 2: v1, v2, v3 (counterclockwise when viewed from outside) | |
mesh.surface_set_normal(n1) | |
mesh.surface_set_uv(uv1) | |
mesh.surface_add_vertex(v1) | |
mesh.surface_set_normal(n0) | |
mesh.surface_set_uv(uv2) | |
mesh.surface_add_vertex(v2) | |
mesh.surface_set_normal(n1) | |
mesh.surface_set_uv(uv3) | |
mesh.surface_add_vertex(v3) | |
# End the surface | |
mesh.surface_end() | |
# Assign a material (optional, for visibility in editor) | |
if material_override == null: | |
var mat = StandardMaterial3D.new() | |
mat.albedo_color = Color.GRAY | |
mat.cull_mode = StandardMaterial3D.CULL_BACK # Ensure backface culling | |
material_override = mat |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment