Removed tilemap baker addon
This commit is contained in:
parent
b6c7f93b1d
commit
e58e2d730d
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 popcar2
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,16 +0,0 @@
|
|||
# Godot Tilemap Collision Baker
|
||||
|
||||
![showcase](./showcase.gif)
|
||||
|
||||
**Note: This script is for Godot 4, it may need some tinkering to work on Godot 3.x**
|
||||
---
|
||||
Godot Tilemap Baker is a tool to easily pre-bake collisions on square tilemaps. This can be useful for many reasons, the biggest one being that using the [default tileset collision can cause issues with rigidbodies](https://github.com/godotengine/godot/issues/72372) because objects tend to get stuck in-between tiles. TilemapBaker was built with this in mind, so floors and ceilings are always one smooth rectangle collider. It should also ^theoretically be more optimized because you end up with way less colliders.
|
||||
|
||||
## How to use
|
||||
Simply attach the `TilemapCollisionBaker` script to an empty StaticBody2D, then point to your Tilemap in the inspector, and hit "Run Script". This is going to wrap your tileset with large box colliders, to be added as children to this node.
|
||||
|
||||
You can also select a specific tile layer to bake collisions for, which can be useful if you have slopes or water on separate layers for example.
|
||||
|
||||
Don't forget to remove your collisions from the tileset (if you ever had any) when using this tool.
|
||||
|
||||
Loved the project? [Consider buying me a cup of Ko-Fi!](https://ko-fi.com/popcar2)
|
|
@ -1,168 +0,0 @@
|
|||
@tool
|
||||
extends StaticBody2D
|
||||
|
||||
## This script pre-bakes collisions for square tilemaps, therefore optimizing code
|
||||
## and getting rid of weird physics bugs!
|
||||
##
|
||||
## How it works TLDR:
|
||||
## This script finds the position of every tile on the layer you've selected from the top left
|
||||
## It then goes to the right until it reaches an edge, then created a rectange CollisionShape2D
|
||||
## and places it in the correct position and size. It keeps doing this until it reaches the end.
|
||||
## For further optimizations, it combines different rows of CollisionShapes if
|
||||
## they are the same size.
|
||||
|
||||
## Your TileMap Node
|
||||
@export var tilemap_nodepath: NodePath
|
||||
|
||||
## The tilemap layer to bake collisions on.
|
||||
## You can bake for multiple layers by disabling delete_children_on_run and running multiple times.
|
||||
@export var target_tiles_layer: int = 0
|
||||
|
||||
## Whether or not you want the children of this node to be deleted on run or not.
|
||||
## Be careful with this!
|
||||
@export var delete_children_on_run: bool = true
|
||||
|
||||
## A fake button to run the code. Bakes collisions and adds colliders as children to this node!
|
||||
@export var run_script: bool = false : set = run_code
|
||||
|
||||
func run_code(_fake_bool = null):
|
||||
var tile_map: TileMap = get_node(tilemap_nodepath)
|
||||
if tile_map == null:
|
||||
print("Hey, you forgot to set your Tilemap Nodepath.")
|
||||
return
|
||||
|
||||
if delete_children_on_run:
|
||||
delete_children()
|
||||
|
||||
var tile_size = tile_map.tile_set.tile_size
|
||||
var tilemap_locations = tile_map.get_used_cells(target_tiles_layer)
|
||||
|
||||
if tilemap_locations.size() == 0:
|
||||
print("Hey, this tilemap is empty (did you choose the correct layer?)")
|
||||
return
|
||||
|
||||
# I use .pop_back() to go through the array, so I sort them from bottom right to top left.
|
||||
tilemap_locations.sort_custom(sortVectorsByY)
|
||||
|
||||
var last_loc: Vector2i = Vector2i(-99999, -99999)
|
||||
var size: Vector2i = Vector2i(1, 1)
|
||||
var xMarginStart = 0
|
||||
|
||||
print("Starting first pass (Creating initial colliders)...")
|
||||
|
||||
var first_colliders_arr = []
|
||||
## First pass: add horizontal rect colliders starting from the top left
|
||||
while true:
|
||||
var temp_loc = tilemap_locations.pop_back()
|
||||
|
||||
if temp_loc == null:
|
||||
# Add the last collider and break out of loop
|
||||
var newXPos = (xMarginStart + abs(last_loc.x - xMarginStart) / 2.0 + 0.5) * tile_size.x
|
||||
@warning_ignore("integer_division")
|
||||
var newYPos = last_loc.y * tile_size.y - (-tile_size.y / 2)
|
||||
first_colliders_arr.append(createCollisionShape(Vector2i(newXPos, newYPos), size, tile_size))
|
||||
print("Finished calculating first pass!")
|
||||
break
|
||||
|
||||
if last_loc == Vector2i(-99999, -99999):
|
||||
last_loc = temp_loc
|
||||
xMarginStart = temp_loc.x
|
||||
continue
|
||||
|
||||
if last_loc.y == temp_loc.y and abs(last_loc.x - temp_loc.x) == 1:
|
||||
size += Vector2i(1,0)
|
||||
else:
|
||||
var newXPos = (xMarginStart + abs(last_loc.x - xMarginStart) / 2.0 + 0.5) * tile_size.x
|
||||
@warning_ignore("integer_division")
|
||||
var newYPos = last_loc.y * tile_size.y - (-tile_size.y / 2)
|
||||
first_colliders_arr.append(createCollisionShape(Vector2i(newXPos, newYPos), size, tile_size))
|
||||
size = Vector2i(1, 1)
|
||||
xMarginStart = temp_loc.x
|
||||
#print("New row placed at (%s, %s)" % [newXPos, newYPos])
|
||||
|
||||
last_loc = temp_loc
|
||||
|
||||
## Sort collider nodes for use in second pass
|
||||
first_colliders_arr.sort_custom(sortNodesByX)
|
||||
|
||||
var last_collider_pos: Vector2 = Vector2(-99999, -99999)
|
||||
var last_collider
|
||||
var colliders_to_merge = 1 # Used to count how many colliders will merge
|
||||
|
||||
var second_colliders_arr = []
|
||||
|
||||
print("Starting second pass (Merging colliders)...")
|
||||
|
||||
## Second pass: Merge colliders that are on top of eachother and are the same size
|
||||
while true:
|
||||
var temp_collider = first_colliders_arr.pop_back()
|
||||
|
||||
if temp_collider == null:
|
||||
# Add final merged collider and break
|
||||
last_collider.shape.size.y = tile_size.y * colliders_to_merge
|
||||
last_collider.position.y -= (colliders_to_merge / 2.0 - 0.5) * tile_size.y
|
||||
second_colliders_arr.append(last_collider)
|
||||
|
||||
print("Finished baking tilemap collisions!")
|
||||
break
|
||||
|
||||
if last_collider_pos == Vector2(-99999, -99999):
|
||||
last_collider_pos = temp_collider.position
|
||||
last_collider = temp_collider
|
||||
continue
|
||||
|
||||
var tile_y_distance = abs(temp_collider.position.y - last_collider_pos.y) / tile_size.y
|
||||
if last_collider_pos.x == temp_collider.position.x and tile_y_distance == 1:
|
||||
#print("Adding 1 to the merge")
|
||||
colliders_to_merge += 1
|
||||
last_collider_pos = temp_collider.position
|
||||
else:
|
||||
#print("Merging %s colliders" % colliders_to_merge)
|
||||
last_collider_pos = temp_collider.position
|
||||
last_collider.shape.size.y = tile_size.y * colliders_to_merge
|
||||
last_collider.position.y -= (colliders_to_merge / 2.0 - 0.5) * tile_size.y
|
||||
second_colliders_arr.append(last_collider)
|
||||
|
||||
colliders_to_merge = 1
|
||||
|
||||
last_collider = temp_collider
|
||||
|
||||
## Adds all colliders as children to this node
|
||||
for collider in second_colliders_arr:
|
||||
add_child(collider, true)
|
||||
collider.owner = get_tree().edited_scene_root
|
||||
|
||||
## Move this node's position to cover the tilemap
|
||||
position = tile_map.position
|
||||
|
||||
func createCollisionShape(pos, size, tile_size) -> CollisionShape2D:
|
||||
var collisionShape = CollisionShape2D.new()
|
||||
var rectangleShape = RectangleShape2D.new()
|
||||
|
||||
rectangleShape.size = size * tile_size
|
||||
collisionShape.set_shape(rectangleShape)
|
||||
collisionShape.position = pos
|
||||
|
||||
return collisionShape
|
||||
|
||||
func delete_children():
|
||||
for child in get_children():
|
||||
child.queue_free()
|
||||
|
||||
## Sorts array of vectors in ascending order with respect to Y
|
||||
func sortVectorsByY(a, b):
|
||||
if a.y > b.y:
|
||||
return true
|
||||
if a.y == b.y:
|
||||
if a.x > b.x:
|
||||
return true
|
||||
return false
|
||||
|
||||
## Sorts array of nodes in ascending order with respects to position
|
||||
func sortNodesByX(a, b):
|
||||
if a.position.x > b.position.x:
|
||||
return true
|
||||
if a.position.x == b.position.x:
|
||||
if a.position.y > b.position.y:
|
||||
return true
|
||||
return false
|
Binary file not shown.
Before Width: | Height: | Size: 505 KiB |
Loading…
Reference in New Issue