|
|
|
|
Reply From: |
Austin |
func _create_collision_polygon():
var bm = BitMap.new()
bm.create_from_image_alpha(texture.get_data())
var rect = Rect2(position.x, position.y, texture.get_width(), texture.get_height())
var my_array = bm.opaque_to_polygons(rect)
var my_polygon = Polygon2D.new()
my_polygon.set_polygons(my_array)
get_parent().get_node("CollisionPolygon2D").set_polygon(my_polygon.polygons[0])
Put this in a script attached to the sprite where the sprite has a StaticBody2D as its parent and its sibling is a CollisionPolygon2D. Make sure the sprite is not centered.
NOTE: This collision is not perfect and seems to be slightly incorrect on some parts. This can be fixed by replacing var my_array = bm.opaque_to_polygons(rect)
with var my_array = bm.opaque_to_polygons(rect, 0.0001)
, although the second argument could probably be replaced with some other small number.
EDIT: Here is a way to do it when the image is made of multiple parts (the StaticBody2D node does not need to have a CollisionPolygon2D manually added):
func _create_collision_polygon():
var bm = BitMap.new()
bm.create_from_image_alpha(texture.get_data())
var rect = Rect2(position.x, position.y, texture.get_width(), texture.get_height())
var my_array = bm.opaque_to_polygons(rect, 0.0001)
var my_polygon = Polygon2D.new()
my_polygon.set_polygons(my_array)
for i in range(my_polygon.polygons.size()):
var my_collision = CollisionPolygon2D.new()
my_collision.set_polygon(my_polygon.polygons[i])
my_collision.scale = scale
get_parent().call_deferred("add_child", my_collision)
EDIT2: And here is how I made it work with centered sprites:
func _create_collision_polygon():
var bm = BitMap.new()
bm.create_from_image_alpha(texture.get_data())
var rect = Rect2(position.x, position.y, texture.get_width(), texture.get_height())
var my_array = bm.opaque_to_polygons(rect, 0.0001)
var my_polygon = Polygon2D.new()
my_polygon.set_polygons(my_array)
var offsetX = 0
var offsetY = 0
if (texture.get_width() % 2 != 0):
offsetX = 1
if (texture.get_height() % 2 != 0):
offsetY = 1
for i in range(my_polygon.polygons.size()):
var my_collision = CollisionPolygon2D.new()
my_collision.set_polygon(my_polygon.polygons[i])
my_collision.position -= Vector2((texture.get_width() / 2) + offsetX, (texture.get_height() / 2) + offsetY) * scale.x
my_collision.scale = scale
get_parent().call_deferred("add_child", my_collision)
Is there a way to export the results of this to a saved file, like a tscn file. I have large maps that I would like to pre-compile.
This works great. Just to add that I think you need to call my_polygon.free() at the end of the function because Godot starts complaining about unfreed memory otherwise.
Rokner | 2021-09-21 00:32