HUD post-processing in Godot - godot

I have a project in Godot that renders billboarded quads on top of enemies. The quads(meshinstances) are children nodes of the enemy nodes. I want to render just the quads to a viewport for post-processing, but the quads need to have the same position on screen that the enemies have (like a target reticle).
How can I apply a shader effect to the billboards only and not to the rest of the scene?

The Camera has a cull_mask property that lets you filter which layers it will see. And VisualInstances (such as MeshInstances) have a layers property that lets you specify to which layers they belong (by default they all belong to the first layer).
You can configure the layers names in Project Settings -> General -> Layer Names -> 3d Render. Do not confuse them with 3d Physics.
Thus, you can give a different layer to those quad MeshInstance you want, and then setup a new Viewport with a new Camera as child (make sure it is current) with a cull_mask that will only render that layer. That way only those MeshInstance will be rendered on that Viewport.
You probably want to to keep the properties of the Camera in sync with the Camera on main Viewport (not only its global_transform, but also fov or any other property you might change). You can archive this by copying its properties on _process of a script attached to the Camera which is inside the new Viewport.

Related

How to make a custom collider that will deform with a skeleton in Godot

I would like to make a collision detector for a mesh I have imported from blender. The mesh is parented to a skeleton, which I use to deform the mesh. I would like to attach a collider to it in order to implement physics. Instead of attaching a general shape collider like a cube or sphere to the mesh, I want it to be an accurate copy of the mesh itself. I've tried adding a Trimesh Static Body, which does make a collider the same shape as the mesh, however since it's static, it won't deform with a skeleton. Is there a way to generate a collider the same shape as a mesh that would deform with a skeleton and also stay with the mesh as it moves around?
You can make a collider the same shape as a skeleton / mesh that is deformed by a skeleton by using the BoneAttachement node, which is a subcategory of the Spatial class. By using this node, you can attach a primitive shape collider to each bone in your skeleton. This will result in a mostly accurate collider shape made up of many smaller colliders that will deform and stay with the skeleton.
Step 1:
Add a BoneAttachment node as a child of the Skeleton node in your model. Set the bone name property to whatever bone you would like the collision shape to follow. After this is done, any nodes parented to this BoneAttachment node will copy the transform of the bone which it is set to.
Step 2:
Add either a KinematicBody or an Area node as a child of the BoneAttachment node. Don't add a RigidBody, because they're meant to be controlled by physics only, so this won't work if you add it.
If you add a KinematicBody node, your collider won't be affected by physics, but other objects like a RigidBody will still collide and bounce off of it.
If you add an Area node, your collider won't directly affect any physics objects that come into contact with it (objects will pass right through it), but you can write a script that will cause some effect to happen when objects contact it. For example, you could make it so that when an object enters the area, a force is applied to it and it gets pushed away.
Step 3:
Add a CollisionShape node as a child of whatever PhysicsBody you chose in the last step. Choose the shape and configure its transform so it copies the shape of the part of the mesh you are working on. Then, repeat these steps for each bone of the skeleton until you have an accurately shaped collider.

How to make the character draw correctly in relation to objects, being on different sides from them on Godot?

Using tile maps is pretty convenient, but there is one drawback. All tiles are on the same layer. This does not allow performing some operations with graphics, as, for example, in my case
I need that when my character is in front of some tile (wall), his sprite is drawn in front, and when in the back, vice versa.
This can be achieved by changing the position of the tilemap layer, but then only one tile will be drawn correctly. The tiles on the other side of the character will be drawn at the same level. How can the problem be solved?
Add a YSort node to your scene and place your player inside of it. The YSort arranges nodes so that the lower they are on the screen, the closer they are to it.
For example, if my player were below a fence, he would stand in front. If he were above the fence, he would be drawn behind it.
This video displays the effect you're going for, using autotile and YSort together https://www.youtube.com/watch?v=RPgTlxb7Bno.

What is the Godot way to define (and refer) custom rectangle areas?

I'm coming from Phaser + Tiled world, where, if I need some rectangle area in game world (like Player's area, spawning area, and so on) I can just draw rectangle in Tiled and then get it coordinates from Phaser.js and use as I need. And I seem to stuck to do similar things in Godot.
For some of tasks I can use Area2D with rectangle inside and collision events. But it is not always enough.
How can I just define rectangle on screen, and get its coordinates? For Sprite object and for Node2D I cannot get bounding rectangle. I can use Area2D + Rectangle and refer to rectangle's 'extent' property to get width/height, but that seems to be overhead for me - Area2D is used in collision detection.
What can I do in general? And what could be done in Godot for following scenarios?
Camera limits. I have Sprite with background gradient which I scale to needed world size, and I'd like to set camera limits on that Sprite's width/height.
Hero movement limits. Half of world is not accessible for player, so any move to x > MIDDLE shall be denied. I can just setup constant MIDDLE in the code, but I'd like to draw allowed area as rectangle and refer to it coordinates.
Spawn area. Mark some place of world (that could be just point, not rectangle) where new objects shall be created by code.
You could use the Rect2 class in a script to define custom rectangles. You can then use it to check whether it contains a Vector2 or another Rect2.

Pygame sprites always on top example?

I was wondering if someone could give me simple example of how to always draw sprites in pygame on --the top layer-- whilst an animation is being blitted on screen?
The senario I'm trying to solve is having an animated sprite (eg a man walking on the spot) and various other objects passing him, whilst he is still animated.
My solution so far has the animation layering on top of the "passing objects" which is not what I want.
Thanks in advance.
I think you've partially answered your own question here.
It's a matter of organizing what gets drawn first. Some side-scrolling 2D games use a "layer" solution, in which there is a background layer, a middleground layer, and a foreground layer, and the drawing system renders one layer after another.
I've also seen Pokémon top-down style games simply sort the sprites by their vertical position, so sprites "nearest" to the camera are drawn last, and thus on top of the other sprites.
See how the current implementation of Scene2D in libGDX gives each Actor a z-index property which can later be used to organize Actors into layers.
Just draw your sprites with a LayeredUpdates group:
class pygame.sprite.LayeredUpdates
LayeredUpdates is a sprite group that handles layers and draws like OrderedUpdates.
LayeredUpdates(*spites, **kwargs) -> LayeredUpdates
You can set the default layer through kwargs using ‘default_layer’ and an integer for the layer. The default layer is 0.
If the sprite you add has an attribute layer then that layer will be used. If the **kwarg contains ‘layer’ then the sprites passed will be added to that layer (overriding the sprite.layer attribute). If neither sprite has attribute layer nor **kwarg then the default layer is used to add the sprites.
and give your sprites the correct layer value.

2d tile based game design, how do I draw a map with a viewport?

I've been struggling with this for a while.
Presently, I have a grid of 100 by 100 tiles, which belong to a Map.
The Map implements IDrawable. I call Draw() and it draws itself at 0,0 which is fine.
However, I want to expand this to draw essentially a viewport. The player will be drawn on the screen in the middle, and thus I want to display say, 10 tiles in each direction (rather than the entire map).
I'm having trouble thinking up the architecture for this one. I'm in the mindset that things should draw themselves, ie I say player1.Draw() and it draws itself. This would have worked before, where it drew the player at x,y on the screen, but with a viewport it will no longer know where to draw itself.
So should the viewport be told to draw, and examine every object in the game and draw those which are visible? Should the map tiles be objects that are subjected to this? Or should the viewport intelligently draw the map by coupling both together?
I'd love to know how typical scrolling tile games accomplish this.
If it matters, I'm using XNA
Edit to add: Can you do graphics manipulation such as trying the HTML rendering approach, where you tell things to draw, and they return a graphic of themselves, and then the parent places the graphic in the correct location? I'm thinking, if I had 2 viewports side by side for splitscreen, how would I stop them drawing outside the edges?
Possible design:
There's a 2D "world" that contains object instances.
"Object instance" is a sprite reference + its coordinates in the world.
When you draw scene, you request list of visible objects that exist in given 2D area, THEN you draw them.
With such design world can be very huge.
I'm in the mindset that things should draw themselves, ie I say player1.Draw() and it draws itself.
visible things should draw themselves. Objects outside of viewport are not visible.
, how would I stop them drawing outside the edges?
Not sure about XNA, but OpenGL has "scissors test"/"glViewport" and Direct3D 9 has "SetViewport" method that allows you to use part of the screen/window for rendering. There are also clipplanes and stencil buffer (using stencil for 2D clipping is overkill, though) You could also render to texture then render the texture. There are many ways to deal with this.
So should the viewport be told to draw, and examine every object in the game and draw those which are visible?
For a large world, you shouldn't examine every object, because it will be slow. You should be able to find visible object without testing every one of them. For that you'll need some kind of space partitioning - quad trees (because we are in 2D), k-d trees, etc. This way you should be able to handle few thousands (or even hundreds of thousands) of objects, as long as you don't see them all at once.
Should the map tiles be objects that are subjected to this?
If you keep drawing invisible things, FPS will drop.
and they return a graphic of themselves
For 2D game this may be very slow. Remember KISS principle.
Some basic ideas, not specifically for XNA:
objects draw themselves to a "virtual screen" in world coordinates, they don't draw themselves to the screen directly
drawable objects get a "graphics context" object which offers you a drawing API. The "graphics context" knows about the current viewport bounds and realizes the coordinate transformation from world coordinates to screen coordinates (for every drawing operations). The graphics context also does the direct drawing to the screen (or to a background screen buffer, if you need double buffering).
when you have many objects outside the visible bounds of your viewport, then as a performance optimization, your drawing loop can make a before-hand bounds-check for your objects and test if they are completely outside the visible area. If so, there is no need to let them draw themselves.

Resources