title: Problem recreating shader on Phaser 3

text:
# Question
Title: Problem recreating shader on Phaser 3
I'm trying to recreate the following shader from shadertoy using Phaser 3: https://www.shadertoy.com/view/wdG3Rz

I managed to fix the errors I was getting but it just loads an empty black square when trying to load it on my scene. Here's a sample code:

```
const fragmentShader = `
#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 resolution;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;

varying vec2 fragCoord;

float avg(vec4 color) {
    return (color.r + color.g + color.b)/3.0;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Flow Speed, increase to make the water flow faster.
    float speed = 1.0;

    // Water Scale, scales the water, not the background.
    float scale = 0.8;

    // Water opacity, higher opacity means the water reflects more light.
    float opacity = 0.5;

    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = (fragCoord/resolution.xy);
    vec2 scaledUv = uv*scale;

    // Water layers, layered on top of eachother to produce the reflective effect
    // Add 0.1 to both uv vectors to avoid the layers stacking perfectly and creating a huge unnatural highlight
    vec4 water1 = texture2D(iChannel0, scaledUv + time*0.02*speed - 0.1);
    vec4 water2 = texture2D(iChannel0, scaledUv.xy + time*speed*vec2(-0.02, -0.02) + 0.1);

    // Water highlights
    vec4 highlights1 = texture2D(iChannel2, scaledUv.xy + time*speed / vec2(-10, 100));
    vec4 highlights2 = texture2D(iChannel2, scaledUv.xy + time*speed / vec2(10, 100));

    // Background image
    vec4 background = texture2D(iChannel1, vec2(uv) + avg(water1) * 0.05);

    // Average the colors of the water layers (convert from 1 channel to 4 channel
    water1.rgb = vec3(avg(water1));
    water2.rgb = vec3(avg(water2));

    // Average and smooth the colors of the highlight layers
    highlights1.rgb = vec3(avg(highlights1)/1.5);
    highlights2.rgb = vec3(avg(highlights2)/1.5);

    float alpha = opacity;

    if(avg(water1 + water2) > 0.3) {
        alpha = 0.0;
    }

    if(avg(water1 + water2 + highlights1 + highlights2) > 0.75) {
        alpha = 5.0 * opacity;
    }

    // Output to screen
    fragColor = (water1 + water2) * alpha + background;
}

void main(void)
{
    mainImage(gl_FragColor, fragCoord.xy);
    gl_FragColor.a = 1.0;
}
`;

class Example extends Phaser.Scene {
  constructor() {
    super("Example");
  }

  preload() {
    this.load.image("noise", "https://i.imgur.com/pZfKeRP.png");
    this.load.image("pic", "https://i.imgur.com/NQFMq6r.jpg");
    this.load.image("rocks", "https://i.imgur.com/fvHGrrU.png");
  }

  create() {
    const baseShader = new Phaser.Display.BaseShader(
      "BufferShader",
      fragmentShader
    );
    this.add
      .shader(baseShader, 0, 0, 800, 600, ["noise", "pic", "rocks"])
      .setOrigin(0, 0);
  }
}

const config = {
  type: Phaser.WEBGL,
  parent: "phaser-example",
  width: 800,
  height: 600,
  scene: Example
};

const game = new Phaser.Game(config);

```

Is there anything I'm doing wrong? Here's the same sample codepen so you can see the problem. https://codepen.io/javiervd/pen/ExMmeYY?editors=1011

Thanks.

# Answer
> 1 votes
Your code is ***correct***, but the problem has to do with the size of your Images.
You should use images with the **"power-of-two"** (as stated in the documentation). With other words, if you change the dimensions of your images, to be *(for example)* 64x64 pixel. The shader should be visible/displayed.

But I think your shader *(or the phaser config)* would need a bit more tweaking, to match the demo you mentioned.

**This is a screenshot of the working shader *(in phaser)*** \]

---
Tags: shaders, glsl, phaser
---


title: GLSL wrong data read from attribute

text:
# Question
Title: GLSL wrong data read from attribute
I'm developping an OpenGLes 3.0 app with Java and I started writing the shader code. For some reason, it seems to mix up the attributes data locations and I don't understand why. Here's the code :

Vertex shader:

```
#version 300 es
precision mediump float;

in vec3 position;
in vec2 uv;
in vec3 normal;

uniform mat4 transform;
uniform mat4 projection;

out f_norm;

void main(){
  //f_norm = normal;
  gl_Position = projection*transform*vec4(position,1.0);
}

```

Fragment Shader :

```
#version 300 es
precision mediump float;

in f_norm;

out vec4 Fragment;
void main(){
  Fragment = vec4(1.0);
}

```

I bind the VBOs using these lines :

```
GLES30.glBindAttribLocation(ProgramID,0,"position");
GLES30.glBindAttribLocation(ProgramID,1,"uv");
GLES30.glBindAttribLocation(ProgramID,2,"normal");

```

In the current form, the program works just fine, but if I uncomment this line : `f_norm = normal`, in the vertex shader, suddenly it uses uv coordinates as positions, even though they aren't used.

I know the data and the data mapping is fine : it works when I comment out the above line.

I know the binding is happening : it is very explicitly called, with the right values, when I check with the debugger.

I made sure that all the VBOs are properly enable and disable before and after the draw call.

I found an easy workaround ( specify `layout(location = <VBO>)` in front of the variables), but I'd like to know what's happening here, to get a more permanent fix.

# Answer
### Unreferenced variables are removed by compiler

What you are seeing is a kind of compilation optimisation (Though strictly speaking it is not considered an optimization).

When you declare inputs you need to use then or the compiler will remove them

Below all the variables are used and the code compiled looks like the source.

```
in vec3 A;
in vec3 B;
main () {
    gl_Position = A * B;
}

```

If you remove the reference to a declared variable the compiler seeing that it is not used will remove it completely.

Thus the following code that does not use `B`

```
in vec3 A;
in vec3 B;
main () {
    gl_Position = A;  // Not using B
}

```

Will be compiled as if the source looked like

```
in vec3 A;
// in vec3 B;  Compiler removed unreferenced variable B
main () {
    gl_Position = A;  // Not using B
}

```

When linking to a named variable the OpenGL implementation is not required to create an error if the name can not be found (it assumes that the index is pointing to an alias named "B" (the removed name)) .

What `GLES30.glBindAttribLocation(pId,1,"B")` does when the index is out of range is upto the OpenGL implementation and should be considered as undefined.

## Fix?

There is no simple fix that I know of!

You can try an just include a dummy reference, as some implementations will consider the variable as referenced just to see it.

```
in vec3 A;
in vec3 B;
main () {
    B;   // Cheap card and implementation might consider this a reference
    gl_Position = A;
}

```

However very few implementation will do this and it becomes difficult to trick the better implementation.
> 3 votes

---
Tags: java, glsl, opengl-es, vertex-attribute
---


title: AddExplosionForce in 2D

text:
# Question
Title: AddExplosionForce in 2D
Its a pretty simple question. I have a gun that shoots bullets, to make the game more fun i want the bullets to be used to navigate. For example shooting them below you would make the player jump up. I figured this would be a good use case for Rigidbody.AddExplosionForce, but I'm using a 2D Rigidbody, so how do I do it?

# Answer
> 1 votes
When there's not a built-in function that does what you want, just add your own:

```
public static class PhysicsExtensions {

    public static void AddExplosionForce(
      this Rigidbody2D body,
      float explosionForce,
      Vector2 explosionPosition,
      float explosionRadius,
      float upwardsModifier = 0f,
      ForceMode2D mode = ForceMode2D.Force) {

        var center = body.transform.TransformPoint(body.centerOfMass);
        var offset = center - explosionPosition;

        // You could make this slightly cheaper
        // by deferring the square root until after
        // the early out if you call this on
        // lots of out-of-range objects.
        float distance = offset.magnitude;

        if (distance >= explosionRadius)
            return;

        offset.y += upwardsModifier;

        var force = offset.normalized;

        // Scale force and attenuate to zero
        // at max radius.
        force *= explosionForce * (1f - distance/explosionRadius);

        body.AddForce(force, mode);
    }
}

```

Add this script to your project, and through the magic of extension methods, `Rigidbody2D.AddExplosionForce` is now available, using a syntax analogous to the 3D version.

I don't guarantee that this version gives exactly the same results as the 3D version, but since it's in user code, you can alter it as needed to produce whatever results you want.

---
Tags: unity, rigidbody
---


# Question
Title: What happens with global/singleton objects when using ECS?
As I've been learning about ECS one thing that gets me confused are things like input which in my case has usually been some singleton that gets polled or in one project was event based where code can listen to a key/action anyways with ECS do I just do

```
void SomeControllerSystem::update(ECS& ecs, float timestep) {
    for (auto& entity : ecs.queryEntitiesWith<PlayerComponent, TransformComponent>()) {
        PlayerComponent& player = ecs.getComponent<PlayerComponent>(entity);
        TransformComponent& transform = ecs.getComponent<TransformComponent>(entity);

        if (Input::IsKeyDown(SDLK_w)) {
            // Update transform component?
        }
    }
}

```

Or do I have to make some changes to integrate into ECS? A few things that I stumbled across are singleton entities/components which I think I originally heard from that overwatch gdc video, but I don't really understand what that means.

Also, unrelated, but can components have basic logic? For example

```
struct CameraComponent {
    // data ...
    void GetProjectionMatrix();
    void GetViewMatrix()
};

```

That doesn't really count as logic right?

# Answer
> 2 votes
The way I have solved "input" in an ECS is that I have a ComponentController that I stick to the Player entity (so I call it ComponentControllerPlayer). This component contains "what the input was" and there is a System that knows how to convert "what the input was" to "what the input means in terms of gameplay". This System will know a lot about how the entity is being composed (e.g. you control a car, then the system will assume one car body and four wheels, of which the 2 front wheels can steer and the 2 rear wheels cannot).

The Singleton that checks the input will update the ComponentControllerPlayer every frame, then this data will be consumed by the system.

This way you can either use an actual input scheme (like I describe above), or you can have your input dictated by another "System" like a robot/AI that is update upstream and reacts to the world.

---

That being said, and I'll repeat myself, there is no ECS police. Do the thing that works the best for your, then when you hit a snag, fix it *at that moment*, you'll know what the issue you're trying to fix is, and so that'll be the time to figure the best appropriate solution.

# Answer
> 1 votes
In ECS, Input handling typically isn't directly integrated into the core ECS architecture since it's considered external to the game world simulation. Instead, you would handle input separately using your existing input handling mechanism - be it a singleton, event-based, or another method.

---
Tags: c++, input, design-patterns, entity-component-system
---


title: What is a "controller"?

text:
# Question
Title: What is a "controller"?
I'm in the process of refactoring my camera code the goal is to try and simplify things using a struct instead of a class or at the very least try something new since I always jump straight to classes/OOP. The struct would just have data I know it could have logic, but that doesn't seem to be common so the problem becomes how do I control the camera. Originally I was gonna have free functions, but the word "controller" popped into my head I don't actually know what "controller" means, but based on the word it would be some object like `CameraController` which would use the data from the `Camera` struct and then have logic to control it.

I'd like to know if this is what "controller" means and if so would an approach like this be better then just doing OOP?

# Answer
In the case you're describing, yes, a CameraController is "something that controls the camera".

You can cut-down things like this:

**Camera**:

* has a frustum/projection matrix
* renders "what it sees" to "something" (on the screen, on a texture/buffer?) (to be honest, it could even be another type of object on its own: a view)

**Controller**:

* moves the camera around
* can be..
    + attached to a world object
    + controlled by user input (then how is it controlled, using a kind of "first person scheme"? "trackball/orbital camera"?)
    + a function that drives the camera on a "rail" based on other data
    + etc...

So depending on your needs, it could make sense to split the bare camera features from the way the camera is controlled.

---

Regarding the OOP-ness of this, I'm not sure there is a debate about whether you should or should not approach this with OOP.

OOP is an approach to programming offering encapsulation of data, etc. It's not opposed to separating the concerns when you need it.

At it's core, a camera is a projection matrix, a position matrix and a target to where to render it, while the controller is a way to convert "world coordinates" or "user input" to something to input to the position matrix of the camera. You can use OOP if it fits or design, or you can have free functions and global objects if it fits better.

After all, DOOM was release without being OOP.

If the game you're writing uses OOP, then it's fine, and if it doesn't and it uses a more data oriented approach, then it's fine too.

---

In an OOP setting, you could have Camera objects that determine how a scene is viewed, Controller objects which determine how cameras move, and View objects which determine onto what the camera is projected. And all those object instances could be interchangeable.

In a Data/function setting you would have a series of struct `Camera`, a series of `struct` CameraController, and a series of struct `View`, each having their own appropriate data, and a pointer to the other structs (or handle to them), with a bunch of function just using the data to render your game.
> 0 votes

---
Tags: c++, architecture, design-patterns, terminology
---


# Question
Title: What is the purpose of Uv_clipping in godot?
Can anyone tell me what is the purpose of uv\_clipping property of rendering section in tilemap in godot with example? I don't understand what's the use of this property

# Answer
> 1 votes
After looking at the source code, it seem that aside from passing the argument to virtual methods, it might set a `CANVAS_RECT_CLIP_UV` flag (source) which then translates to a `FLAGS_CLIP_RECT_UV` flag (source) which is checked in a shader (source) where it results in clapping the UV coordinates.

*In which situations this makes a difference is unclear to me. My best guess at a glance is that it is related to zooming and culling. Note: it is a 2D feature.*

Addendum: I found an documentation ticket relevant to this: CanvasItem.draw\_texture\_rect\_region parameter clip\_uv doesn't have explanation.

---
Tags: uv-mapping, godot-4
---


# Question
Title: How to pause or slow down/speed up Time.deltaTime when it is inside the Update() method?
My player is able to dive for a limited amount of seconds (let's say 10 seconds) while swimming. When he's not diving his breath gauge fills up again to a max of 10 seconds:

```
private bool isFreediving;
private float breath = 10f;

void Update()
{
    if (isFreediving)
    {
        if (breath > 0)
        {
            breath -= Time.deltaTime;
            Debug.Log(breath);
        }
        else
        {
            Debug.Log("Out of breath");
            breath = 0; // optional?
            isFreediving = false;
            // Do staff...
        }
    }
    else
    {
        if (breath == 0)
        {
            // TODO: Make the player stop moving for 1 second
            // TODO: Stop breath += Time.deltaTime for 3 seconds
        }
        else if (breath > 0 && breath < 10)
        {
            breath += Time.deltaTime; // TODO: Make breath fill up slower/faster
            Debug.Log(breath);
        }
    }
}

```

If the player runs out of breath completely, I want him to stop moving for a second and I also want the breath gauge to not start to fill up for 3 seconds. I tried with ***coroutines***, but my code is inside the `Update()` method, so it didn't work. I realize that the above `If`-`else` statements need to be rearranged properly.

Lastly, I want the breath gauge to be filled up at a different pace, for example:

```
breath += Time.deltaTime * 0.5f;

```

I wonder if there is a better way?

EDIT: After @Pow's solution:

```
float swimSpeed = 0.03f;
private bool isFreediving;
private float breath = 10f;
private bool canRefillBreath;

void Update()
{
    float swimAmount = Input.GetAxis("Vertical") * swimSpeed;
    transform.Translate(0, swimAmount, 0);

    if (isFreediving)
    {
        if (breath > 0) breath -= Time.deltaTime;
        else
        {
            breath = 0;
            isFreediving = false;
            // Do staff...
            canRefillBreath = false;
        }
    }
    else
    {
        if (breath == 0)
        {
            swimSpeed = 0;
            Invoke(nameof(EnableSwim), 1f);
            Invoke(nameof(EnableRefill), 3f);
        }
        if (canRefillBreath && breath < 10) breath += Time.deltaTime;
    }
}

private void EnableSwim() => swimSpeed = 0.03f;
private void EnableRefill() => canRefillBreath = true;

```

The only weird thing is that after 1 second the player starts moving at a slower rate until the 3 seconds `Invoke(nameof(EnableRefill), 3f);`, then he goes full speed.

# Answer
> 1 votes
A good way to make something happen only once/after a delay in the Update function is to use booleans, simple yet effective. You can use the `Invoke()` method to enable/disable booleans when needed.

Heres an example using your script:

```
private bool runOutOfBreath = false;
private bool canRefillBreath = false;
void Update()
{
    if (isFreediving)
    {
        if (breath > 0)
        {
            runOutOfBreath = false;
            breath -= Time.deltaTime;
            Debug.Log(breath);
        }
        else
        {
            runOutOfBreath = true;
            Debug.Log("Out of breath");
            breath = 0; // optional?
            isFreediving = false;
            // Do staff...
        }
    }
    else {
        if (runOutOfBreath) {
            // your function/coroutine.
            runOutOfBreath = false;
            canRefillBreath = false;
        }
        if (canRefillBreath && breath < 10) {
            breath += Time.deltaTime; // TODO: Make breath fill up slower/faster
            Debug.Log(breath);
        }
        if (breath == 0) {
            Invoke(nameof(EnableRefill), 3f);
        }
    }
}
private void EnableRefill() {
    canRefillBreath = true;
}

```

**NOTE:** you may want to move the if (runOutOfBreath) somewhere else depending on your use case. Right now it only checks if you've run out *and* your not diving. Hope this fixes your issue and let me know if you have any problems :)

---
Tags: unity, c#, timer, time, deltatime
---


# Question
Title: Way to check overlaps of a collider2d that's not set to "is trigger" in Unity
I have a system where physics2d objects are spawned and I need to know when they spawn outside of a region defined by a box collider set to "is Trigger".

Using onTriggerEnter and onTriggerExit to know if an object exits / re-enters the bounds (with some other conditions determining whether to kill the object when it exits the bounds). That stuff works fine.

However I can't detect when an object spawns outside of the collider (which I want to allow, but just know when it happens).

I tried the following in the Start method of the spawned object:

```
List<Collider2D> results = new List<Collider2D>();
_boundsCollider.OverlapCollider(new ContactFilter2D(), results);
bool spawned_outside = !results.Contains(_thisCollider);

```

However at the time that method runs, the booundsCollider doesn't register it. Subsequent frames it will, but that's too late.

OverlapCollder can't be run on the collider for the spawned object since it isn't set as a trigger.

Is there any way I can query the spawned object's own collider to determine if it is in contact with the bounds collider?

Thanks!

PS I can't trivially just reference the coords of the object and check if they're out of bounds because the bounds collider will move, and I want to know with precision wether just a corner is overlapping or whatever so I'd need something that amounts to my own simple collision system

# Answer
> 0 votes
You can use the "Awake()" behavior on the objects you want to detect spawning, and just implement the code you mentioned above:

```
List<Collider2D> results = new List<Collider2D>();
_boundsCollider.OverlapCollider(new ContactFilter2D(), results);
bool spawned_outside = !results.Contains(_thisCollider);

```

As you can see here that's called at the stage where the objects are actually initialized.

What behavior are you experiencing with calling it at "Start()" that's making it too late?

# Answer
> 0 votes
You could just get the bounds of the collider and check whether the objects are within the bounds, then you wouldn't have to check overlap at all.

Heres an example

```
public BoxCollider2D box;

void Start() {
    Bounds bounds = box.bounds
    if (transform.position.x < bounds.min.x)

```

Obviously you wouldn't just check whether its outside of the left bounds you would want other checks too however it may work for you.

Alternatively there is a Bounds.Contains() function but I'm not sure the implications of that.

---
Tags: unity, box2d
---


title: How to make UI specific to players?

text:
# Question
Title: How to make UI specific to players?
How can I implement a system in my application's user interface (UI) where certain UI elements are selectively visible to specific players, ensuring that each player, such as Player A, can exclusively view and interact with their own inventory, while preventing other players, like Player B, from accessing or seeing Player A's inventory?

# Answer
> 1 votes
Make sure the entity has authority before activating the UI :)

```
if is_multiplayer_authority()

```

---
Tags: multiplayer, gui, godot
---


# Question
Title: Moving "theme" file to a different folder - is it possible to update the resource paths within the "theme"?
Assume the following: One theme is created via the Godot Editor (version 3.5) and saved under `res://themes/my-theme.theme`. Due to changes in the project's file hierarchy, it is decided to move the theme to `res://gui/themes/my-theme.theme`. All the missing dependencies for the nodes are fixed, but when trying to start the game, it crashes with the error message that some resources specified in the `theme` (like fonts, textures etc.) could not be loaded. From the error message it becomes clear, that the `my-theme.theme` still contains the old absolute path to these resources and did not update to the new paths.

## Question:

Is there a way to update the resource paths in the `theme` file or does one have to create the complete theme from scratch?

# Answer
> 0 votes
The answer by @Theraot pointed me in the right direction.

However, at least the way I got my Godot 3.5 instance setup, my theme file is a binary, which means the external editor approach does not work, since the theme file is neither utf8 valid nor ISO compliant. This means there is no way to edit this file externally; it all has to be done within the Godot Editor.

Since I also had some custom fonts loaded, I also had to manually edit the font resource files to contain the correct paths. So the workflow was in the end:

1. Select the theme resource under `FileSystem` Tab of the Godot Editor
2. Right click and select the `Edit Dependencies...` Menu Option
3. Edit all the relevant resource paths; make especially sure that all the custom font resource paths are correct
4. Select the custom font resource under `FileSystem` Tab of the Godot Editor
5. Correct the font path.
6. Repeat Step 4 and Step 5 until all the custom font resource files contain the correct paths
7. Restart the Godot Editor to load the changes
8. Select a `Node` in the `Scene` Tab that uses the theme.
9. In the `Inspector` Tab, under `Theme`, press on the Downarrow Symbol and select `Load`
10. Select the theme and click `Open`
11. Repeat Step 8 to Step 10 for all Nodes which use the theme

Steps 8 to Step 11 were necessary for me because a simple Godot Editor restart did not apply the theme changes. If one is using `Theme Overrides`, especially with the custom font resource, one also has to go through them one by one or otherwise the changes will not be applied.

# Answer
> 0 votes
Outside of Godot: you should be able to open the theme file with a regular text editor, and there you should be able to fix the path via search and replace.

Inside of Godot: in the context menu of the resource file in FileSystem you should find the option "Edit Dependencies..." which should open a window showing which dependencies are broken. There you can either replace them one by one, or use the "Fix Broken" option that will try to search for all the missing the files, which should work since they are just in a different path.

---
Tags: file-format, godot-3, asset-workflow, filesystem
---


# Question
Title: Dark spot glitch in normal mapping shader - WebGPU
I'm implementing a normal mapping PBR shader using WebGPU, but I'm getting a strange dark spot and visual glitches. My scene consists of a cube with a brick texture which has a normal map, as well as a point light.

At certain angles, there is a cone-shaped specular highlight visible:

Here's a video of me moving around the camera.

Here's the full shader code I'm using. Critical parts: Calculation of TBN matrix in vertex shader:

```
    out.t = normalize((model_transform * vec4(in.tangent.xyz, 0.0)).xyz);
    out.n = normalize((model_transform * vec4(in.normal, 0.0)).xyz);
    let bitangent = cross(in.normal, in.tangent.xyz) * in.tangent.w;
    out.b = normalize((model_transform * vec4(bitangent, 0.0)).xyz);

```

Transformation of normals in fragment shader:

```
    let tbn = mat3x3<f32>(in.t, in.b, in.n);
    var normal = textureSample(t_normal, s_normal, in.tex_coords).rgb * 2.0;
    normal = normal - vec3(1.0);
    normal = normalize(tbn * normal);

```

This is what the output looks like when I just return the `normal` variable at the end of the fragment shader instead of the color:

I already tried several approaches (transforming everything to tangent space, just transforming the normals to tangent space, etc.) including approaches requiring you to invert the model matrix to no avail. What could be the reason for the glitches I'm experiencing? I suspect something's wrong with my TBN matrix.

# Answer
> 1 votes
The first thing that jumps out at me is that you aren't normalizing your pixel shader inputs that represent quantities that you're expecting to be normalized. This is necessary because the interpolation that happens on those values will change their length.

However, in the case of a cube, you might get away without doing that, because all of the vertices on one face share the same normal. I think it's still worth doing though, even if it doesn't fix anything in this specific case.

Looking at the video, I saw a dark spot in the middle of the screen. It might be worth investigating what's going on there. I'd recommend using a GPU Debugger like Renderdoc.

---
Tags: normals, normal-mapping, webgpu, wgsl
---


# Question
Title: Strange Marker2D behavior in Godot with barebones code
I'm new to programming in Godot but I've been playing around with things I've learned in various tutorials. That is, until I ran into the following issue which I can't seem to debug. I attached a video to show what's happening.

When I first run it, the child bullets work really well with the position at the Gun's Marker2D, direction and rotation according to the code. Once I move the player though, the global\_position of the Marker2D seems to translate in the same Vector as the player movement but greatly increased. So rotation and direction still work fine, but the starting position is way off. It's even possible to move back to the original pos and then the bullets start at the right place again.

Code at player.gd:

```
extends CharacterBody2D

const SPEED = 400

var bullet_scene: PackedScene = preload("res://projectile.tscn")

func _process(_delta):
    var direction := Input.get_vector("move_left", "move_right", "move_up", "move_down")
    velocity = direction * SPEED
    move_and_slide()

    if Input.is_action_just_pressed("primary_shot"):
        var weapon_rotation = (get_global_mouse_position() - position).normalized()
        var shot_pos = $Gun/Marker2D.global_position
        var other_rotation = get_angle_to($Gun/Marker2D.global_position)
        #print("shot_pos:", shot_pos, "weapon_rot:", weapon_rotation)

        var bullet = bullet_scene.instantiate()
        get_node("Projectiles").add_child(bullet)
        bullet.position = shot_pos
        bullet.direction = weapon_rotation
        bullet.rotation = other_rotation

```

For some reason, if I emit a signal from the player with all the same variables to my main.gd, and run everything verbatim from var bullet onwards in its signal function, it works just fine. My concern is that I literally have another project I made a couple of days earlier where I run everything in player.gd and it works perfect there, but not now, and I want to know what I'm doing wrong.

https://www.youtube.com/watch?v=0la6s\_OSDfM

# Answer
> 0 votes
You are mixing coordinates spaces.

---

Here is the issue at hand:

```
var shot_pos = $Gun/Marker2D.global_position
# (...)
bullet.position = shot_pos

```

The variable `shot_pos` is in global coordinates, but you set `position` which is relative to the parent (of the bullet in this case, i.e. `get_node("Projectiles")`). Set `global_position` instead.

*You might be interested in: Why isnt my spike shooters child showing up in the scene in godot?*

---

I believe the direction is not presenting any issues because you are not rotating the player character. Yet, it is also mixing coordinate spaces:

```
var weapon_rotation = (get_global_mouse_position() - position).normalized()

```

As the name suggest `get_global_mouse_position()` is in global coordinates. Meanwhile `position` is not, instead it is relative to the parent (of the character body in this case). Use `global_position`.

---

An slightly different issue can happen with the rotation. Because `get_angle_to` takes global coordinates and converts them internally, the rotation is correct... for the character body where you are calling it.

If there is any rotation introduced between the character body and `get_node("Projectiles")` it would not behave correctly.

A solution could be to take the rotation at `get_node("Projectiles")` which is where you are adding the children:

```
var other_rotation = get_node("Projectiles").get_angle_to($Gun/Marker2D.global_position)

```

---
Tags: godot, godot-4
---


# Question
Title: LibGDX websockets GWT html app cant find source to WebSocket class
I'm using this library to connect to websocket server: https://github.com/czyzby/gdx-lml/tree/master/websocket

It's working on android/desktop applications, but when compiling to html gwt app with **html:dist** command it returns many errors for websocket classes, this is one of them:

```
[ERROR] Line 25: No source code is available for type com.github.czyzby.websocket.WebSocket; did you forget to inherit a required module?

```

I added all required libraries:

```
project(":core") {
   implementation "com.github.czyzby:gdx-websocket:1.9.1.9.6"
}

project(":html") {
   implementation "com.github.czyzby:gdx-websocket-gwt:1.9.1.9.6"
   implementation "com.github.czyzby:gdx-websocket-gwt:1.9.1.9.6:sources"
}

```

And in GdxDefinition.gwt.xml I added:

```
<inherits name='com.github.czyzby.websocket.GdxWebSocketGwt' />

```

But i don't know why I'm still getting this error with no source code available. Anyone knows how to resolve this issue?

**Solution:** I downgraded websocket gwt library version in html module to

```
api 'com.github.czyzby:gdx-websocket-gwt:1.8.1.9.4'
api 'com.github.czyzby:gdx-websocket-gwt:1.8.1.9.4:sources'

```

And now it sees the source code for all websocket classes.

# Answer
**Solution:** I downgraded websocket gwt library version in html module to

```
api 'com.github.czyzby:gdx-websocket-gwt:1.8.1.9.4'
api 'com.github.czyzby:gdx-websocket-gwt:1.8.1.9.4:sources'

```

And now it sees the source code for all websocket classes.
> 1 votes

---
Tags: libgdx, websocket, gradle
---


# Question
Title: Why the following code does not smoothly resets my orientation in Unity?
Hi I have the following code snippet in Unity and I am trying to smoothly reset my orientation. However the code below snaps my object in default orientation. Any suggestions why this would be happening?

using System.Collections.Generic;
using UnityEngine;

public class Cube : MonoBehaviour
{
    public bool aligning = false;

    public Quaternion TargetQuaternion;
    public float animationTime;
    public float animationDuration = 2.0f;
    public float t = .0f;
    private bool set = false;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        float rotspeed = 3.0f;
        float movespeed = 10.0f;
        if(Input.GetKey(KeyCode.UpArrow))
        {
            transform.position += transform.forward * movespeed * Time.deltaTime;
        }
        if (Input.GetKey(KeyCode.DownArrow))
        {
            transform.position -= transform.forward * movespeed * Time.deltaTime;
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            Quaternion q = Quaternion.identity;
            q.SetAxisAngle(new Vector3(0, 1, 0), rotspeed * Time.deltaTime);
            transform.rotation *= q;
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            Quaternion q = Quaternion.identity;
            q.SetAxisAngle(new Vector3(0, 1, 0), -rotspeed* Time.deltaTime);
            transform.rotation *= q;
        }

        if (aligning)
        {
            t = animationTime / animationDuration;
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), t);
            animationTime += Time.deltaTime;
            if (animationTime >= animationDuration)
            {
                aligning = false;
                animationTime = 0.0f;
            }
        }
    }
}
```
</code></pre>

# Answer
This is probably something you would want to do with Coroutines. Coroutines are like functions, however, unlike functions, they can span over more than one frame. Coroutines are good for time based changes. For example fading one colour into another colour. Heres an example of a coroutine that would reset the players orientation.

```
// A coroutine is defined by an IEnumerator
private IEnumerator ResetOrientation(float duration) {
    // these will only be called once when the coroutine starts
    float elapsed = 0f;
    Vector3 originalRotation = transform.eulerAngles;
    Vector3 targetRotation = (0, 0, 0);

    // The while will iterate every frame until the specified duration is met
    while (elapsed < duration) {
        // Increase the elapsed time by deltaTime
        elapsed += Time.deltaTime;
        // Lerp linearly interpolates between two values
        transform.eulerAngles = Vector3.Lerp(originalRotation, targetRotation, elapsed / duration)
        // Return null and wait for the next frame
        yield return null;
    }
}

```

You can call the coroutine anywhere simply using `StartCoroutine(ResetOrientation(2f))` and passing a duration in seconds as an argument, in this case it would do it over 2 seconds. Hope this fixes your issue.

**EDIT**: Also, *never* use `transform.position -= transform.forward * movespeed * Time.deltaTime;` setting an objects position is a very bad way to move things, as it completely ignores physics and collisions. Typically this can lead to wall clipping and stuttery movement, I highly recommend you search for a different way to move that suits your needs.
> 0 votes

---
Tags: unity
---


# Question
Title: Unity VR using OpenXR, how to spawn object when you grab a static object
I am trying to create a simple VR card game in Unity using OpenXR, just to learn Unity and also some VR stuff. I made a deck of cards object and a card object. I put both in a scene. The card is Kinematic and can be grabbed and thereby picked up. The deck is static on the table. I put the card on top of the deck and I can pick it up (see https://drive.google.com/file/d/1gi4RAUDzS-r862I6ur3eb\_YZPQRXjMMA/view?usp=sharing). However I want to spawn a new card on top of the deck to grab. First I wanted to spawn the card, first when the user makes the grab action, touching the pile, but I could not find any information how to do that and actually attach the card (instead of the deck) to the hand. How can I detect the grab of my playing card, and spawn a new card on top of the deck instead of the one just taken by a player? I am an experienced software developer, but I am a total noob when it comes to Unity. I tried to find some answers online, but I think I lack some basic understanding of how Unity works. I hope someone can point me in the right direction.

# Answer
I don't know OpenXR, but I do know unity. You can just duplicate the card using Instantiate, like this:

```
private void PickedUpCard() {
    Instantiate(cardObject, deckPosition.position, Quaternion.idenitity);
}

```
> 1 votes

# Answer
With the help of "Pow" I have found a solution.

I created a property on my Card object:

```
public GameObject deckPrefab;

```

Then dragged the deck object from the scene onto this property to assign the deck object ot the deckPrefab property.

Next when the card is grabbed. I instanciate a new card on top of the deck:

```
GameObject newCard = Instantiate(cardPrefab, new Vector3(deckPrefab.transform.position.x, deckPrefab.transform.position.y + 0.01f, deckPrefab.transform.position.z), Quaternion.identity);

```

The card has a property, which card it is (taken from a list of all cards remaining in the deck). And the face of the card is replaced with a new texture:

```
var renderer = newCard.GetComponentInChildren<Renderer>();
for (int i=0; i<renderer.materials.Length; i++)
{
    var material = renderer.materials[i];
    if (material.name.StartsWith("CardFace"))
    {
        int idx = GetCardIndex(newCard.textureIndex);
        material.SetTexture("_BaseMap", cardFaces[idx]);
        break;
    }
}

```

cardFaces is an array of Texture2D objects with all the PNG images of the card faces. I used this guide on YouTube for inspiration, but modified to use 3D objects instead of sprites: https://www.youtube.com/playlist?list=PLuq\_iMEtykn8XiZb6453f61U7HC7u8KiC
> 0 votes

---
Tags: unity, virtual-reality, openxr
---


# Question
Title: Setting up perspective projection in OpenGL
I'm trying to set up perspective projection in OpenGL but it doesn't work

```
void Camera::setViewportSize(float left, float right, float bottom, float top)
{
    constexpr float fov = glm::radians(45.0f);
    m_projectionMatrix = glm::perspective(fov, (right - left) / (top - bottom), 0.1f, 10.0f);
    recalculateViewMatrix();
}

void Camera::recalculateViewMatrix()
{
    glm::mat4 translate = glm::translate(glm::mat4(1.0f), glm::vec3(m_position, 0.0f));
    glm::mat4 rotate = glm::rotate(glm::mat4(1.0f), m_rotation, glm::vec3(0.0f, 0.0f, 1.0f));
    glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(m_scale, m_scale, 1.0f));

    m_viewMatrix = translate * rotate * scale;
    m_viewMatrix = glm::inverse(m_viewMatrix);

    m_viewProjectionMatrix = m_projectionMatrix * m_viewMatrix;
}

```

I upload viewProjectionMatrix to shader and use it like this:

```
gl_Position = u_viewProjectionMatrix * vec4(a_position, 1.0);

```

It just doesn't show anything. I double checked if I pass good left, right, bottom, top values and it should be all good. Playing with zNear and zFar didn't change anything. Note - When I use ortho, it works like a charm:

```
    m_projectionMatrix = glm::ortho(left, right, bottom, top, 1.0f, -1.0f);

```

**Update** I did add model matrix and I translated it -2 units on z axis. I can see the lines:  But they are disorted.

They should be at positions:

```
line1: (0.0f, 0.0f), (100.0, 100.0)
line2: (0.0f, 0.0f), (600.0f, 800.0f)

```

It seem like the centre of screen is at (0, 0)???

# Answer
> 0 votes
Check camera settings, viewport dimensions, OpenGL errors, object positions, and shader code for perspective projection in OpenGL.

---
Tags: opengl, c++, graphics-programming, perspective, projection-matrix
---


# Question
Title: How to develop a game on a 2015 MacBook Pro without learning Metal?
I'm on Mac and OpenGL and Vulcan are not supported. Even worse, I'm on a 2015 MBP 13". Yeah, can't do much with that.

I spent a full year learning C++ and I have no patience to try and learn Metal which they force on Mac users (with its limited scope — Mac& iOS games only).

I wanted to learn something very useful, practical and cross platform. I've been following the SFML Game Dev book tutorial, but the errors are many. And yes, I went to their GitHub and got the updated code. I still get errors.

SFML does a lot of handholding and I feel like I would find difficulties trying to use something complex.I really want to understand the ins and outs of talking to the system directly. Following a set library feels like I'm just memorizing steps and not understanding what's happening. It would be ok if I didn't get errors trying to do things the "easy way"

Is there a way I can work around this? I want to develop a game using my c++ knowledge.

# Answer
If you just want to be able to use Vulkan there's MoltenVK, which is a wrapper on top of Metal.
> 1 votes

---
Tags: c++, sfml, macos
---


# Question
Title: Recreating The Lighting In Paper Mario: TTYD In Unity
**Goal:**

* I would like to recreate the lighting in Paper Mario: The Thousand Year Door.
* Currently, I am only using a directional light.
* I am also using URP.

---

**Comparison**:

Here is an example of how it looks in game:

And this is how it looks when imported into Unity:

---

**Issue:**

Currently, just using a directional light causes a very different appearance. The colors seem much less vibrant and they look washed out, almost similar to when you overlay a color many times.

---

If anyone has any insight as to how I can achieve the same lighting style it would be very much appreciated!

# Answer
> 1 votes
Some basic tips:

* Reduce the intensity of the directional light a bit. If the scene gets too dark, increase the ambient light level.
* Try using Linear color instead of Gamma color
* Use flat shading instead of smooth shading on the building walls (this may require making edits to the building meshes in a 3D model editor such as Blender).

# Answer
> 0 votes
The lighting in paper mario TTYD (as well as many other games in that era) utilizes vertex colors to color textures and create artificial lighting. Adding vertex colors to your models can be done in the 3d modelling software you're using (such as autodesk maya, blender, etc).

---
Tags: unity, lighting
---


title: How to structure this concept in ECS?

text:
# Question
Title: How to structure this concept in ECS?
##### High level

At a high level, I'm looking to create a galaxy exploration-style game.

A number of points of interest will be selectable on the map (I'd like to aim for several hundred, but flexible and needs testing).

A POI can be something story-related or a source of one of 4 resources.

Players start with a ship, head to a resource node, harvest resources and can move on.

So far so good, I've got a small number of resources, so can just group them together as a single `ResourceStockpile` component and hide empty resources in the UI.

The POI that produce resources will have a service that increments their stockpile over time, and ships will have a "cargo bay" of `ResourceStockpile`.

The player can use \[some resources\] to create factories at a POI.

Factories convert resources to goods (both finished products and components/parts).

##### Complexity

I want to be able to ship goods. Unlike resources, I'm expecting to have several dozen types of finished good (and many more intermediate parts and components), with an eye to expanding over time.

Storing a few zeroes for resources seemed like a small overhead to maintain a consistent `ResourceStockpile` I could reuse.

As the number of items/fields grows, the design feels less and less desirable.

To make things more interesting, I'd ideally like to be able to ship pretty much anything (including the factories, if the ship is large enough).

Do I switch to a `HasX` component for every possible resource/good? If so, it seems like I'm going to spend an *awful* lot of time swapping between archetypes.

It also seems like a lot of duplicated code, unless there's some way to treat it as a generic `Has<X>` instead, but I believe that's quite complex to implement, and may negate some of the memory management benefits of ECS (?)

Or do I create a `ResourceStockpile` with -say- 100 integers, one per possible resource/good and just swallow the overhead?

What's the right™ way to break this down?

# Answer
> 1 votes
What you might be looking for is a DynamicBufferComponent. It's the go-to solution when an entity doesn't have one value but `n` values with variable values of `n` depending on the entity.

I would create a component like this:

```
[InternalBufferCapacity(2)]
public struct ResourceStack : IBufferElementData
{
    public ResourceType type;
    public int amount;
}

```

The `2` in `[InternalBufferCapacity(2)]` here is just a guess of how many key-value pairs of resources the average resource-stockpiling entity will have in your game (one input resource and one output resource). If that's not the typical number of resources in your game, you should adjust it accordingly. It's not a hard limit on how many you can have; it's an optimization hint for the Entities framework regarding how much memory it should initially allocate per entity with this buffer component.

`ResourceType` would be an ID type, probably an `enum`.

---
Tags: unity, architecture, entity-system, entity-component-system
---


# Question
Title: Calculate damage when attacker has bonus but defender has resist
Let's say an archer does base damage of `50`. But their equipment provides `+30% bow damage` to make the damage `65`.

The archer is attacking a creature with `20% bow damage resistance`.

Is the damage now **52** `50 * 1.3 * 0.8`

Or is the damage now **55** `50+10%` because the `%30 bonus - 20% resist = 10% bonus`.

# Answer
It would be more logical for the damage to be 52. The damage resistance would apply to whatever damage is dealt to the creature, no mather what bonus the damage has, since the damage resistance bonus of the creature is logically independant of the damage bonus of the player.

In the end, it remains a personal choice.
> 1 votes

# Answer
I noticed you prefixed the archer's bonus with a `+`, whereas you didn't when stating the creature's resistance. This made me think those two numbers mean different things and shouldn't interact directly (i.e. adding them up).

I can support this claim by considering the edge case of *invincibility* in your original problem.

Let's assume the target creature had a `100% bow damage resistance` buff. (It could be a single-use item effect, for example.) In this case, I would expect the final damage to be zero.

The first equation you proposed yields such expected result:

$$\begin{eqnarray} DMG\_{tot} &=& DMG\_{bow}\cdot(1+BONUS\_{bow})\cdot(1-RESIST\_{bow})\\ &=& 50\cdot(1+0.3)\cdot(1-1)\\ &=& 0 \end{eqnarray}$$

The second one, however, does not:

$$\begin{eqnarray} DMG\_{tot} &=& DMG\_{bow}\cdot(1+BONUS\_{bow}-RESIST\_{bow})\\ &=& 50\cdot(1+0.3-1)\\ &=& 15 \end{eqnarray}$$

I would be disappointed if I read "`100% resistance`" on an armour my avatar is wearing, only to discover it didn't prevent me from taking damage.

Moreover, while the first equation describes how a defender **absorbs part of the attacker's damage**, the second equation implies that the defender actually **affects the attack before the blow lands** on them. I would consider the latter as a different game mechanic, such as *debuff statuses* on characters. Here's an example:

> An archer attacks with `50 base bow damage`. Their equipment provides a `+30% bow damage` bonus. The target creature has `15% bow damage resistance`. The creature is also covered in mud, which hampers the arrows' piercing ability: `+5% bow resistance`. On the contrary, the archer is sleep-deprived from continuously fighting. This affects their ability to shoot arrows, causing a `-10% bow damage` malus.

In this scenario, we could merge the two original equations to compute the archer's total damage against the creature:

$$\begin{eqnarray} DMG\_{tot} &=& DMG\_{bow}\cdot(1+BONUS\_{bow}-MALUS\_{bow})\cdot(1-(RESIST\_{bow}+BONUS\_{resist}))\\ &=& 50\cdot(1+0.3-0.1)\cdot(1-0.15-0.05)\\ &=& 48 \end{eqnarray}$$
> 0 votes

---
Tags: mathematics
---


# Question
Title: I'm trying to find a way to iterate through a list of game objects to find furthest object in the list. Then re iterate if path is blocked
I've got the first part of the code working. It iterates and does a check through the gameobjects to find the furthest nav point to hit. Then it calculates path to see if its valid or not. Now I'm stuck. I want it to re iterate by omitting that value from the list of gameobjects and pick a new value and check it again to see if it is valid. Here is the code in question.

```
if (navMeshAgent.remainingDistance <= navMeshAgent.stoppingDistance)
                {

                    furthestObject = FindFurthestObject(navPoints);
                    bool isPathValid =CheckForValidPath(furthestObject.transform.position);

                    if (isPathValid)
                    {
                        navMeshAgent.Warp(furthestObject.transform.position);
                        runFromLight = false;
                    }
                    else
                    {
                        GameObject navPoint = FindRandomSpawnPoint(navPoints);
                        runFromLight = false;
                        GameObject telePortParts = Instantiate(teleportParticleSystem, transform.position, transform.rotation);
                        navMeshAgent.Warp(navpoints[0].transform.position);
                    }
                }

```

And the code for iterating through the gameobject lists is here.

```
public GameObject FindFurthestObject(List <GameObject> gameObjects)
{
    float furthestDistance = 0;
    GameObject furthestObject = null;

    foreach(GameObject Object in gameObjects)
    {
        float objectDistance = Vector3.Distance(transform.position, Object.transform.position);

        if(objectDistance > furthestDistance)
        {
            furthestObject = Object;
            furthestDistance = objectDistance;
        }
    }

    return furthestObject;
}

```

# Answer
> 0 votes
create a list of game objects called something like `gameObjectsCheck`. and make it a copy of your `navPoints` list, replace

```
furthestObject = FindFurthestObject(navPoints);

```

with

```
furthestObject = FindFurthestObject(gameObjectsCheck);

```

then, in your first code block, you should surround the entire thing after the initial if statement in a while loop using `!isValidPath` as it's break condition. this way you will keeping checking new objects until a valid path is found. you will need to create the `isValidPath` bool outside of the while loop, and set it to false as well, in order to start the while loop.

```
if (navMeshAgent.remainingDistance <= navMeshAgent.stoppingDistance)
{
    bool isPathValid = false;
    while ( !isValidPath )
    {
        furthestObject = FindFurthestObject(gameObjectsCheck);
        isPathValid=CheckForValidPath(furthestObject.transform.position);

...

```

lastly, when you check if a path is valid, in the `else` statement, as in when a valid path *is not* found, remove `furthestObject` from `gameObjectsCheck`.

in total, this will loop through the code checking whether the current furthest object has a valid path to it or not, and if it doesn't, it is removed from the list of objects you are checking using `FindFurthestObject`, which will then find the *next* furthest object, and check again with that object, repeating this process until a valid path is found.

---
Tags: unity, c#, algorithm, path-finding, navmesh
---


title: Audio Cue for Accuracy game

text:
# Question
Title: Audio Cue for Accuracy game
I'm really not sure if this is the appropriate community to ask in. I want to use some sort of audio cue that provides feedback for a player's accuracy in a task. They perform some action in real time - which they have to maintain - that gives an output on a linear scale. There is a target they are trying to reach and maintain on that scale. I want some sort of auditory feedback to assist the player in reaching the target. I thought about a pure tone that has increasing noise the further away they are from the target, but this doesn't give a sense of whether they are above or below on that linear scale. Any suggestions?

# Answer
I would experiment with trying to add two different disturbing "you are wrong" sound effect in addition to the pleasant "you are right" sound effect. One high-pitched "screeching" one that signals that the player is too high and one low-pitched "growling" one that signals that the player is too low.

Another option would be to use stereo sound and have the "you are wrong" effect stereo-pan to the left when the player is too low and to the right when the player is too high.
> 2 votes

# Answer
One approach is to play a continuous tone at a fixed frequency at all times, and then play another continuous tone whose frequency depends on the output on the linear scale. The two tones will then sound out of tune whenever the player isn't accurate, and as long as the player has at least an average sense of relative pitch, they'll know if they're too high or too low.

Those tones shouldn't be pure sine waves, but they should be relatively simple, maybe like a string or woodwind instrument, or a classic analog synth patch. If you don't need absolute 100% accuracy from the player, you should also have a "dead zone" where the variable tone is set to exactly the same pitch as the fixed tone - this is to avoid beating.

You'll need to play around with what kinds of pitch ratios you'll get at various points on the scale, to avoid making something off the mark sound better than something closer to the mark. For example, if the variable tone is 20% higher than the fixed tone, you get a minor third, which sounds very pleasant compared to the ratios you get with pitches that are closer together. Generally, keeping the pitches within about 10% of each other should avoid that issue. On a similar note, you should experiment with non-linear mappings between the player's accuracy output and the variable tone's pitch.

Finally, to reinforce the sweet spot, you could add a third tone that increases in intensity as long as the player maintains their accuracy. You need something with no harmonic relation to the other tones - for example, white noise rising in pitch, or a drum beat that increases in volume or tempo. If the player has to stay in the sweet spot for some X number of seconds to get the reward, and this happens more than once in the game, this third tone communicates the remaining time by giving players something familiar that they can anticipate - like how power up music functions in Mario.
> 2 votes

---
Tags: game-design, audio
---


title: Curved Grid Layout Group

text:
# Question
Title: Curved Grid Layout Group
I can't find a quick answer anywhere, besides adding a 100 line script that I'm pretty sure is outdated. As the title suggests, I am trying to curve a grid layout group. I also want the children of the object with the grid component to rotate according to where it is. Thanks in advance. I'm trying to do this in 2D, in UI, if that helps. I'm also in the latest version of unity.

I want the objects to be on the line (without the actual line) with rotating depending on where it is.

(if you're wondering I did try the script and I'm pretty sure it's unity-script)

# Answer
> 0 votes
You can use UI Extensions -\> RadialLayout script: https://github.com/Unity-UI-Extensions/com.unity.uiextensions

And there is the video how to use it: https://www.youtube.com/watch?v=iUlk0d2RDMs&t=138s

---
Tags: unity, c#, 2d
---


# Question
Title: Checking if I am looking through a window using angles
I am developing a mod for a game with a Lua api.

I am trying to detect if I am looking through from behind a window when I shoot an enemy. For context, when I shoot through this window I apply a special buff effect.

Characters lie on a map which is an xy coordinate system with 4 quadrants. 0, 0 lies at the center of the map.

I am doing a top-down view. I can get the xy position of my character, the xy position of the enemy character, and the 2 xy positions of the boundaries of the window.

I got the angle of the character relative to the angle of the window edges, and I got the angle of the character relative to the angle of the enemy.

here is an example:

```
player position -149.55355834961 -54.274295806885
target position -147.99998474121 -67.999992370605
left position -151.8394317627 -56.843517303467
right position -147.86442565918 -56.397045135498
angle target 96.457664489746
angle left 48.340045928955
angle right 128.51026916504

```

this is how I am calculating the angles (the game uses xz as the horizontal plane):

```
function getAngleBetween(object1, object2)
    -- y is height here
    local x1, y1, z1 = GetWorldPosition(object1)
    local x2, y2, z2 = GetWorldPosition(object2)
    local zDiff = z1 - z2
    local xDiff = x1 - x2
    local phi = math.atan2(zDiff, xDiff)
    if phi < 0 then
        phi = phi + (2 * math.pi)
    end
    local degrees = phi * (180/math.pi)
    return degrees
end

```

I used this code to check if the angle with the enemy was between the two sides of the window, but it gives inconsistent results. I think it has to do with how I am calculating the angles, and the coordinate system. For example, If I am facing north, it works. But if I am facing south, it doesn't.

```
    function isAngleBetweenDeg(leftAngle, rightAngle, checkAngle)

        leftAngle = math.mod(leftAngle,360)
        rightAngle =  math.mod(rightAngle,360)
        checkAngle =  math.mod(checkAngle,360)

        if leftAngle > rightAngle then
            return checkAngle >= leftAngle or checkAngle <= rightAngle
        end
        return checkAngle > leftAngle and checkAngle < rightAngle
    end

```

How do I check if I am behind the window? as far as the game's API, you only need to know GetWorldPosition give me the coordinates.

# Answer
I wouldn't set this up with angles but rather with line segments. One line segment goes from your position to the enemy's position. The other line segment goes from the right to the left position of the window. If these two line segments cross each other, you see the enemy through the window.

Note that the two lines formed by the two players and the window will always intersect (unless they are parallel) so you can just compute the intersection point of the lines and then check whether the intersection is in-between the two players and in-between the sides of the window.
> 0 votes

---
Tags: mathematics, geometry, coordinates, lua, trigonometry
---


# Question
Title: How to delete unnecessary points given a jointed path
I'm writing code for client-side pathfinding, the player can setup more than one point and then pathfinding in segments finally get a concatenated path.(actually it's for the long distance pathfinding, you can setup some halfway points and the final dest, to travel the further position)

Here's the pathsmoothing code so far and it's in lua:

```
    local c = path.nextWork
while c + 1 < table.getn(path.finishedPath) do

    -- Points to test
    local p0 = coordToPoint(path.startPos, path.finishedPath[c-1])
    local p1 = coordToPoint(path.startPos, path.finishedPath[c+1])

    -- Has LOS
    if TheWorld.Pathfinder:IsClear  (
                                        p0.x, p0.y, p0.z,
                                        p1.x, p1.y, p1.z,
                                        path.pathcaps
                                    )
    then
        table.remove(path.finishedPath, c)

    -- No LOS
    else
        c = c + 1
    end

```

And the problem is that i found if i do path smooth for the concatenated path, (especially when some detours in the path),the result still exists some unnecessary point, the path smoothing code doesn't work well as expected.

For example, if i set a segment assisted point C like this and get a path that walk around a square obstacle, the expected smoothing result should be A--\>E, but the code actual not remove the B and D. Note C point was marked by player and not required to be exactly on the final path.What i want is the code that make the jointed path without any redundant steps

Here's the similar situations in game(DontStarveTogether):

My expected path result:

# Answer
You can define an "unnecessary" criterion which relies on how collinear a triplet of points are. I'll use your `B`,`C`,`D` as an example. You can use this to iterate over points starting from the first point until you have no further points.

To determine if `C` would be "unnecessary" you need to do some vector math.

```
local vecBD = {  x= D.x - B.x, y = D.y - B.y }
local lenBD = math.sqrt(vecBD.x^2 + vecBD.y^2)

local vecBC = { x = C.x - B.x, y = C.y - B.y }

```

You can then measure "how far off" `C` is from the line `BD` by projecting the `BC` vector component perpendicular to the line `BD`

```
local offBC = {
   x = vecBC.x - vecBC.x*vecBD.x/lenBD,
   y = vecBC.y - vecBC.y*vecBD.y/lenBD
}

local lenOffBC = math.sqrt(offBC.x^2 + offBC.y^2)

```

`lenOffBC` here is the distance `C` is off from the line `BD`. You can discriminate on this value or on a value relative to the length of another distance, e.g. `BD` as `lenOffBC/lenBD`

If `C` is determined to be too close you remove it, and then repeat for `BDE`. If `BDE` is "good" you move on and do the hypothetical `DEF` until you don't have three points anymore.
> 0 votes

---
Tags: path-finding
---


# Question
Title: Checking if a node is of a given type in Godot 4
I want to check if the player is near a door.

In practice, this means that I want to check if the `Area2D` of the player node overlaps a door node (an `Area2D` with an attached `door.gd` script). This is working in Godot 3:

`player.gd`

```
# ...

var door_type = preload("res://objects/door.gd")

# ...

for area in $Area2D.get_overlapping_areas():
    if area is door_type:
        # ...

```

`door.gd`

```
extends Area2D

# ...

```

However, in Godot 4 (v4.1.2) I have the following error:

> "door\_type" is a variable but does not contain a type.

I tried an Internet search for this error, but I did not find any result.

How can I achieve this behavior in Godot 4?

# Answer
> 3 votes
Preload the script into a constant:

```
const door_type = preload("res://objects/door.gd")

```

Then `is` should work.

---
Tags: godot, godot-4
---


# Question
Title: How to add gameTime to movement with acceleration and diagonal normalization?
I recently started rewriting my engine from scratch, because the old one was my first attempt and the structure was very messy. Everything has been going great, but now I'm being held back by some stuff related to character movement and collision detection.

So, I wanted to remake the character movement with acceleration and deceleration physics. I got it working fine, but I didn't use `gameTime.ElapsedGameTime.TotalSeconds`. Now it would seem to be complicated and messy to add it to all the places where I use `velocity`, `Acceleration`, and `Deceleration`

What I'm wondering is that, is it worth it to even use `gameTime` at all? I think I've read in many posts and tutorials that using `gameTime` is best practice because then movement isn't coupled to frame rate. And if it is worth using it, how would you implement it in such a system along with acceleration and normalizing for diagonal movement?

I wouldn't mind restructuring the code at all, but I just don't know where to start from. I've been thinking about and trying to solve this issue for so long and I don't know what to do. It's draining all my motivation :( If you notice any other improvements here, feel free to mention. Thanks.

Here is the movement code:

```
    private void UpdateMovement(List<GameObject> objects) {

        if (velocity != Vector2.Zero){

            if (SimpleCollisionCheck(objects, out GameObject obj) == true) {
                    DirectionalCollisionCheck(obj);
            }

        }

        position += velocity;

        if (velocity.X > 0) { // Decrease X velocity over time
            if (velocity.X - Deceleration > 0) { velocity.X -= Deceleration; } else { velocity.X = 0; }
        } else if (velocity.X < 0) {
            if (velocity.X + Deceleration < 0) { velocity.X += Deceleration; } else { velocity.X = 0; }
        }

        if (velocity.Y > 0) { // Decrease Y velocity over time
            if (velocity.Y - Deceleration > 0) { velocity.Y -= Deceleration; } else { velocity.Y = 0; }
        } else if (velocity.Y < 0) {
            if (velocity.Y + Deceleration < 0) { velocity.Y += Deceleration; } else { velocity.Y = 0; }
        }

    }

    protected void MoveLeft() {
        if (velocity.X - Acceleration > -VelocityMaximum) { velocity.X -= Acceleration + Deceleration; }
        direction.X = -1;
    }

    protected void MoveRight() {
        if (velocity.X + Acceleration < VelocityMaximum) { velocity.X += Acceleration + Deceleration; }
        direction.X = 1;
    }

    protected void MoveUp() {
        if (velocity.Y - Acceleration > -VelocityMaximum) { velocity.Y -= Acceleration + Deceleration; }
        direction.Y = -1;
    }

    protected void MoveDown() {
        if (velocity.Y + Acceleration < VelocityMaximum) { velocity.Y += Acceleration + Deceleration; }
        direction.Y = 1;
    }

```

Here is the collision code:

    protected bool SimpleCollisionCheck(List<GameObject> objects, out GameObject obj) {

        Rectangle futureCollision = Collision;

        if (Velocity.X != 0) {
            if (Velocity.X > 0) { futureCollision.X += (int)VelocityMaximum; } else { futureCollision.X -= (int)VelocityMaximum; }
        }

        if (Velocity.Y != 0) {
            if (Velocity.Y > 0) { futureCollision.Y += (int)VelocityMaximum; } else { futureCollision.Y -= (int)VelocityMaximum; }
        }

        foreach (GameObject o in objects) {
            if (o != this && o.Active == true && o.CollisionEnabled == true && o.CollisionCheck(futureCollision) == true) {
                obj = o;
                return true;
            }
        }

        obj = null;
        return false;

    }

    private bool CollisionLeft(GameObject o) {
        return ((Collision.Left - VelocityMaximum) < o.Collision.Right) &&
            (Collision.Right >= o.Collision.Right) &&
            (Collision.Top < o.Collision.Bottom) &&
            (Collision.Bottom > o.Collision.Top);
    }

    private bool CollisionRight(GameObject o) {
        return ((Collision.Right + VelocityMaximum) > o.Collision.Left) &&
            (Collision.Left <= o.Collision.Left) &&
            (Collision.Top < o.Collision.Bottom) &&
            (Collision.Bottom > o.Collision.Top);
    }

    private bool CollisionUp(GameObject o) {
        return ((Collision.Top - VelocityMaximum) < o.Collision.Bottom) &&
            (Collision.Bottom >= o.Collision.Bottom) &&
            (Collision.Left < o.Collision.Right) &&
            (Collision.Right > o.Collision.Left);
    }

    private bool CollisionDown(GameObject o) {
        return ((Collision.Bottom + VelocityMaximum) > o.Collision.Top) &&
            (Collision.Top <= o.Collision.Top) &&
            (Collision.Left < o.Collision.Right) &&
            (Collision.Right > o.Collision.Left);
    }

    private void DirectionalCollisionCheck(GameObject o) {

        if (velocity.X < 0.0f && CollisionLeft(o)) {

            if (CollisionNudgeEnabled && o.CollisionNudgeEnabled) {

                if ((PositionCentered.Y /*- CollisionThickness*/) < (o.Collision.Top - collisionNudgeOffset)) {
                    velocity.Y = velocity.X;
                } else if ((PositionCentered.Y /*+ CollisionThickness*/) > (o.Collision.Bottom + collisionNudgeOffset)) {
                    velocity.Y = -velocity.X;
                }
            }

            velocity.X = 0.0f;

        } else if (velocity.X > 0.0f && CollisionRight(o)) {

            if (CollisionNudgeEnabled && o.CollisionNudgeEnabled) {

                if ((PositionCentered.Y /*- CollisionThickness*/) < (o.Collision.Top - collisionNudgeOffset)) {
                    velocity.Y = -velocity.X;
                } else if ((PositionCentered.Y /*+ CollisionThickness*/) > (o.Collision.Bottom + collisionNudgeOffset)) {
                        velocity.Y = velocity.X;
                }
            }

            velocity.X = 0.0f;
        }

        if (velocity.Y < 0.0f && CollisionUp(o)) {

            if (CollisionNudgeEnabled && o.CollisionNudgeEnabled) {

                if (PositionCentered.X < (o.Collision.Left - collisionNudgeOffset)) {
                    velocity.X = velocity.Y;
                } else if (PositionCentered.X > (o.Collision.Right + collisionNudgeOffset)) {
                    velocity.X = -velocity.Y;
                }
            }

            velocity.Y = 0.0f;

        } else if (velocity.Y > 0.0f && CollisionDown(o)) {

            if (CollisionNudgeEnabled && o.CollisionNudgeEnabled) {

                if (PositionCentered.X < (o.Collision.Left - collisionNudgeOffset)) {
                    velocity.X = -velocity.Y;
                } else if (PositionCentered.X > (o.Collision.Right + collisionNudgeOffset)) {
                    velocity.X = velocity.Y;
                }
            }

            velocity.Y = 0.0f;
            }
        }
```
</code></pre>

# Answer
So, I broke out some old physics formula books and had some sort of a revelation. I added `updateTime = (float)gameTime.ElapsedGameTime.TotalSeconds;` into the main update function of the character and changed the following code and now it seems to work (?):

<pre><code>    private float accelDistance = 20f;
    private float decelDistance = 60f;
    public float velocityMaximum = 180f;
    private float updateTime;

    public float Acceleration { protected get { return accelDistance * updateTime; } set { accelDistance = value; } }
    public float Deceleration { protected get { return decelDistance * updateTime; } set { decelDistance = value; } }
    public float VelocityMaximum { protected get { return velocityMaximum * updateTime; } set { velocityMaximum = value; } }
```

> 0 votes

---
Tags: c#, collision-detection, movement, monogame
---


# Question
Title: Why does this movement script prevent you from jumping if you're running forward (but running in other directions does allows jumping)?
This is a rigidbody-based movement script. I notice that it doesn't let you jump while you're running. This problem persists whether you are using new Input System or not (I tested both ways).

Notably, the jump only doesn't work while running **if you are running forward** (straight forward, left-forward, or right-forward). If you try jumping while running backwards, left, or right, the jump will work. In case it matters, jump is Space and run is Shift.

What might be the reason for this happening?

    using System;
    using System.Collections.Generic;
    using UnityEngine;

    public class HumanoidLandController: MonoBehaviour {
        public Transform CameraFollow;

        [SerializeField] HumanoidLandInput _input;
        [SerializeField] CameraController _cameraController;
        [SerializeField] GameObject _playerObject; // Added for animations

        Vector3 _playerObjectOriginalLocalPosition = Vector3.zero; // Added for animations

        Rigidbody _rigidbody = null;
        CapsuleCollider _capsuleCollider = null;

        [SerializeField] Vector3 _playerMoveInput = Vector3.zero;

        Vector3 _playerLookInput = Vector3.zero;
        Vector3 _previousPlayerLookInput = Vector3.zero;
        [SerializeField] float _cameraPitch = 0.0 f;
        [SerializeField] float _playerLookInputLerpTime = 0.35 f;

        [Header("Movement")]
        [SerializeField] float _movementMultiplier = 30.0 f;
        [SerializeField] float _notGroundedMovementMultiplier = 1.25 f;
        [SerializeField] float _rotationSpeedMultiplier = 180.0 f;
        [SerializeField] float _pitchSpeedMultiplier = 180.0 f;
        [SerializeField] float _crouchSpeedMultiplier = 0.5 f;
        [SerializeField] float _runMultiplier = 2.5 f;

        [Header("Ground Check")]
        [SerializeField][Range(0.0 f, 1.8 f)] float _groundCheckRadiusMultiplier = 0.9 f;
        [SerializeField][Range(-0.95 f, 1.05 f)] float _groundCheckDistanceTolerance = 0.05 f;
        [SerializeField] float _playerCenterToGroundDistance = 0.0 f;
        public bool _playerIsGrounded {
                get;
                private set;
        } = true; // Modified for animations

        RaycastHit _groundCheckHit = new RaycastHit();

        [Header("Gravity")]
        [SerializeField] float _gravityFallCurrent = 0.0 f;
        [SerializeField] float _gravityFallMin = 0.0 f;
        [SerializeField] float _gravityFallIncrementTime = 0.05 f;
        [SerializeField] float _playerFallTimer = 0.0 f;
        [SerializeField] float _gravityGrounded = -1.0 f;
        [SerializeField] float _maxSlopeAngle = 47.5 f;

        [Header("Jumping")]
        [SerializeField] float _initialJumpForceMultiplier = 750.0 f;
        [SerializeField] float _continualJumpForceMultiplier = 0.1 f;
        [SerializeField] float _jumpTime = 0.175 f;
        [SerializeField] float _jumpTimeCounter = 0.0 f;
        [SerializeField] float _coyoteTime = 0.15 f;
        [SerializeField] float _coyoteTimeCounter = 0.0 f;
        [SerializeField] float _jumpBufferTime = 0.2 f;
        [SerializeField] float _jumpBufferTimeCounter = 0.0 f;
        [SerializeField] bool _jumpWasPressedLastFrame = false;
        public bool _playerIsJumping {
                get;
                private set;
        } = false; // Modified for animations

        private void Awake() {
                _rigidbody = GetComponent < Rigidbody > ();
                _capsuleCollider = GetComponent < CapsuleCollider > ();

                _maxAscendRayDistance = _maxStepHeight / Mathf.Cos(_maximumAngleOfApproachToAscend * Mathf.Deg2Rad);
                _maxDescendRayDistance = _maxStepHeight / Mathf.Cos(80.0 f * Mathf.Deg2Rad);

                _numberOfStepDetectRays = Mathf.RoundToInt(((_maxStepHeight * 100.0 f) * 0.5 f) + 1.0 f);
                _rayIncrementAmount = _maxStepHeight / _numberOfStepDetectRays;

                _playerFullHeight = _capsuleCollider.height;
                _playerCrouchedHeight = _playerFullHeight - _crouchAmount;

                _playerObjectOriginalLocalPosition = _playerObject.transform.localPosition; // Added for animations
        }

        private void FixedUpdate() {
                if (!_cameraController.UsingOrbitalCamera) {
                        _playerLookInput = GetLookInput();
                        PlayerLook();
                        PitchCamera();
                }

                _playerMoveInput = GetMoveInput();
                PlayerVariables();
                _playerIsGrounded = PlayerGroundCheck();

                _playerMoveInput = PlayerMove();
                _playerMoveInput = PlayerRun();

                PlayerInfoCapture();

                _playerMoveInput.y = PlayerFallGravity();
                _playerMoveInput.y = PlayerJump();

                Debug.DrawRay(_playerCenterPoint, _rigidbody.transform.TransformDirection(_playerMoveInput), Color.red, 0.5 f);
                _playerMoveInput *= _rigidbody.mass; // NOTE: For dev purposes.

                _rigidbody.AddRelativeForce(_playerMoveInput, ForceMode.Force);
                Debug.Log(_playerMoveInput.x);
        }

        private Vector3 GetLookInput() {
                _previousPlayerLookInput = _playerLookInput;
                _playerLookInput = new Vector3(_input.LookInput.x, (_input.InvertMouseY ? -_input.LookInput.y : _input.LookInput.y), 0.0 f);
                return Vector3.Lerp(_previousPlayerLookInput, _playerLookInput * Time.deltaTime, _playerLookInputLerpTime);
        }

        private void PlayerLook() {
                _rigidbody.rotation = Quaternion.Euler(0.0 f, _rigidbody.rotation.eulerAngles.y + (_playerLookInput.x * _rotationSpeedMultiplier), 0.0 f);
        }

        private void PitchCamera() {
                _cameraPitch += _playerLookInput.y * _pitchSpeedMultiplier;
                _cameraPitch = Mathf.Clamp(_cameraPitch, -89.9 f, 89.9 f);

                CameraFollow.rotation = Quaternion.Euler(_cameraPitch, CameraFollow.rotation.eulerAngles.y, CameraFollow.rotation.eulerAngles.z);
        }

        private Vector3 GetMoveInput() {
                return new Vector3(_input.MoveInput.x, 0.0 f, _input.MoveInput.y);
        }

        private void PlayerVariables() {
                _playerCenterPoint = _rigidbody.position + _capsuleCollider.center;
        }

        private Vector3 PlayerMove() {
                return ((_playerIsGrounded) ? (_playerMoveInput * _movementMultiplier) : (_playerMoveInput * _movementMultiplier * _notGroundedMovementMultiplier));
        }

        private bool PlayerGroundCheck() {
                float sphereCastRadius = _capsuleCollider.radius * _groundCheckRadiusMultiplier;
                Physics.SphereCast(_playerCenterPoint, sphereCastRadius, Vector3.down, out _groundCheckHit);
                _playerCenterToGroundDistance = _groundCheckHit.distance + sphereCastRadius;
                return ((_playerCenterToGroundDistance >= _capsuleCollider.bounds.extents.y - _groundCheckDistanceTolerance) &&
                        (_playerCenterToGroundDistance <= _capsuleCollider.bounds.extents.y + _groundCheckDistanceTolerance));
        }

        private Vector3 PlayerRun() {
                Vector3 calculatedPlayerRunSpeed = _playerMoveInput;
                if (_input.MoveIsPressed && _input.RunIsPressed && !_playerIsCrouching) {
                        calculatedPlayerRunSpeed *= _runMultiplier;
                }
                return calculatedPlayerRunSpeed;
        }

        private void PlayerInfoCapture() {
                if (_playerIsGrounded && _groundCheckHit.collider) {
                        _lastGroundCheckHit = _groundCheckHit;
                        _playerMoveInputAtLastGroundCheckHit = _playerMoveInput;
                }
        }

        private float PlayerFallGravity() {
                float gravity = _playerMoveInput.y;
                if (_playerIsGrounded || _playerIsAscendingStairs || _playerIsDescendingStairs) {
                        _gravityFallCurrent = _gravityFallMin; // Reset
                } else {
                        _playerFallTimer -= Time.fixedDeltaTime;
                        if (_playerFallTimer < 0.0 f) {
                                float gravityFallMax = _movementMultiplier * _runMultiplier * 5.0 f;
                                float gravityFallIncrementAmount = (gravityFallMax - _gravityFallMin) * 0.1 f;
                                if (_gravityFallCurrent < gravityFallMax) {
                                        _gravityFallCurrent += gravityFallIncrementAmount;
                                }
                                _playerFallTimer = _gravityFallIncrementTime;
                        }
                        gravity = -_gravityFallCurrent;
                }
                return gravity;
        }

        private float PlayerJump() {
                float calculatedJumpInput = _playerMoveInput.y;

                SetJumpTimeCounter();
                SetCoyoteTimeCounter();
                SetJumpBufferTimeCounter();

                if (_jumpBufferTimeCounter > 0.0 f && !_playerIsJumping && _coyoteTimeCounter > 0.0 f) {
                        //if (Vector3.Angle(_rigidbody.transform.up, _groundCheckHit.normal) < _maxSlopeAngle)
                        //{
                        calculatedJumpInput = _initialJumpForceMultiplier;
                        _playerIsJumping = true;
                        _jumpBufferTimeCounter = 0.0 f;
                        _coyoteTimeCounter = 0.0 f;
                        //}
                } else if (_input.JumpIsPressed && _playerIsJumping && !_playerIsGrounded && _jumpTimeCounter > 0.0 f) {
                        calculatedJumpInput = _initialJumpForceMultiplier * _continualJumpForceMultiplier;
                } else if (_playerIsJumping && _playerIsGrounded) {
                        _playerIsJumping = false;
                }
                return calculatedJumpInput;
        }

        private void SetJumpTimeCounter() {
                if (_playerIsJumping && !_playerIsGrounded) {
                        _jumpTimeCounter -= Time.fixedDeltaTime;
                } else {
                        _jumpTimeCounter = _jumpTime;
                }
        }

        private void SetCoyoteTimeCounter() {
                if (_playerIsGrounded) {
                        _coyoteTimeCounter = _coyoteTime;
                } else {
                        _coyoteTimeCounter -= Time.fixedDeltaTime;
                }
        }

        private void SetJumpBufferTimeCounter() {
                if (!_jumpWasPressedLastFrame && _input.JumpIsPressed) {
                        _jumpBufferTimeCounter = _jumpBufferTime;
                } else if (_jumpBufferTimeCounter > 0.0 f) {
                        _jumpBufferTimeCounter -= Time.fixedDeltaTime;
                }
                _jumpWasPressedLastFrame = _input.JumpIsPressed;
        }

    }
```

# Answer
> 2 votes
The code was irrelevant; it's just keyboard ghosting that causes it. `Shift`+`W`+`Space` doesn't work with certain keyboards

---
Tags: unity, c#
---


# Question
Title: In a tile based game, with units that can move a specific amount per turn, how do i make my pathfinding avoid damage unless it is the only valid path?
i am making a 3d tactics game, visually similar to something like final fantasy tactics. it's tile based, with units able to move up and down the level onto buildings and up staircases and what have you.

im using dijkstra's algorithm to score every tile on the map that is within a units movement stat, then i highlight all of the tiles that are within our characters movement, then when you select one of those tiles, the unit follows the shortest path to that tile.

this all works fine, but i have one issue i don't know how to resolve. if a unit jumps from a certain height, it takes damage. this is fine, and i want to let the player/ai do this in order to take shortcuts at the cost of some hp if they want to. the problem is i will sometimes run into a case where there is a safer route to take, that while actually a longer path, is still within the units movement. for example:

in this case, the unit is able to move 3 spaces in one turn, and it wants to move from the red space to the blue space, the green tiles are the spaces it can reach this turn. since this unit can move 3 spaces, we can avoid jumping from this height by going down the descending tiles and using all 3 of our moves to reach the blue space safely. since it is a turn based game, it doesn't matter that we move a few extra tiles, as long as we don't move more than 3 tiles in a turn. so i would want the pathfinding to favor not taking damage when it can.

if it can't avoid damage, like in this case:

the only way the unit can reach that tile is by using all of its movement, so taking the fall damage is unavoidable, and we let the player make the choice to take the fall damage or not.

# Answer
It sounds like your game is turn-based, so there will be a movement phase where you get to use up a certain number of movement points or move a certain number of tiles. And it sounds like for the movement phase you don't care how many "movement points" or such can be used, just whether you can get there or not.

A different case would be if you had something like 'action points' where you might want to spend some on movement and retain some to perform an action like attacking. That would make it more complicated.

So what you want is a list of all available tiles you can go to and the least damage you can take while getting there. I think each tile in your path then needs an array of objects with distance and damage, and you can't simply mark a tile as 'visited', but check if the new way you get there gives you less distance, or less distance for a given damage value. Both paths should be evaluated.

So when you are checking `tilesTo` and the tile doesn't exist, add it. If it already exists, add path to an array of from paths along with the distance. An example, say you are on tile B trying to get to E, with the numbers representing the heights, and you take 10 points of damage for each level dropped above the first, and tiles are joined horizontally and vertically:

```
ABCDE
FGHIJ
KLMNO
PQRST

```

Height map:

```
24100
23200
12100
01000

```

You begin with a starting node:

```
{ tile: B, from: START, distance: 0, damage: 0 }

```

Then you look at the tiles you can get to and add paths to them, queueing for processing:

```
{ tile: A, from: B, distance: 1, damage: 10 }
{ tile: C, from: B, distance: 1, damage: 20 }
{ tile: G, from: B, distance: 1, damage: 0 }

```

The tile A node above generates only one new path to F if you can't climb back to B, carrying along the 10 damage from the previous record, which is added to your list and queued:

```
{ tile: F, from: A, distance: 2, damage: 10 }

```

The tile C node when you process it generates two new records (assuming you can't climb back to B) based on the distance 1 and damage 20, adding 1 more distance but no more damage. These are added to your results and queued for processing.

```
{ tile: D, from: C, distance: 2, damage: 20 }
{ tile: H, from: C, distance: 2, damage: 20 }

```

Then you add the 4 paths you can get to from G. But here you can check the existing nodes and either replace them or ignore your current path if it is worse/equal in both distance and damage:

```
{ tile: B, from: G, distance: 2, damage: 0 } // ignored
{ tile: F, from: G, distance: 2, damage: 0 } // replaces and queues
{ tile: H, from: G, distance: 2, damage: 0 } // replaces and queues
{ tile: L, from: G, distance: 2, damage: 0 } // adds and queues

```

So for new nodes you generate, check existing nodes for that tile:

1. If an node already exists for the same tile where the damage and distance are both \<= the new node's damage and distance, ignore the new node - STOP
2. Remove existing nodes for the same tile that have \>= both damage and \>= distance of the new node. Because we ignored the new node and stopped at step 1 if they were both equal, either distance or damage will be greater than our new node and the other value be greater or equal, so the new node is better in some way and at least as good in the other.
3. Add the new node and queue it for further processing

When adding the node to tile B, we see that there is an existing node with damage 0 and distance 0. Since there is an existing node with the same or lower damage and the same or lower distance, we ignore our new node, we don't add it and don't queue it for processing.

When adding the node for tile F, we see an existing node with the same or higher distance and more damage, so we remove that existing node, then add our new node and queue the new node for more processing.

When adding the node for tile H, there is an existing node from C with distance 2 and damage 20, so we replace it with our new one because it has lower damage and queue the new node.

When adding the node for tile L, there is no existing node for tile L so we add it and queue the new node. Our list now looks like this (comments on queued nodes)

```
{ tile: B, from: start, distance: 0, damage: 0 }
{ tile: A, from: B, distance: 1, damage: 10 }
{ tile: C, from: B, distance: 1, damage: 20 }
{ tile: G, from: B, distance: 1, damage: 0 }
{ tile: D, from: C, distance: 2, damage: 20 }// in queue
{ tile: F, from: G, distance: 2, damage: 0 } // in queue
{ tile: H, from: G, distance: 2, damage: 0 } // in queue
{ tile: L, from: G, distance: 2, damage: 0 } // in queue

```

That was the first difference, we can replace existing nodes only distance or damage is less than any existing nodes for that tile and the other value is the same or less than the existing tile. But you can have multiple nodes for tiles as well if one value is higher but the other is lower. In the queue we will generate a new node for C from H that will have a higher distance than the existing node, but a lower damage. So we will queue it and keep *both*.

```
{ tile: C, from: H, distance: 3, damage: 0 }

```

Both of those nodes will generate nodes for tile D by carrying over the damage and adding 1 to the distance:

```
{ tile: D, from: C, distance: 2, damage: 20 }
{ tile: D, from: C, distance: 4, damage: 0 }

```

Say you have a maximum movement of 4, so in this case you would not queue up the last node because the distance is already 4, but the first node would be in the queue and allow you to move on to tile E:

```
{ tile: E, from: D, distance: 3, damage: 20 }

```

If you were using action points, you might want to present both options for moving to tile D to your player. Either they can move there using 2 points and taking 20 damage but have 2 action points remaining, or use all 4 action points to move there and take no damage.

In your game I think you would want to condense the list to have only one entry per tile with the minimum damage, so you would keep the tile D node with distance 4 and damage 0. It seems like for your display you would just show it as green or something since you won't be taking damage, but the E tile will show as red because the only way to get that far is to take damage.
> 2 votes

# Answer
I think the easiest way to do this is to do two passes of pathfinding. First, treat any path that would cause damage as being impassable. Try to solve the path, and if you exhaust your set before reaching the goal, then try again but allow the damaging path to be passable.

This will always prefer to take a non damaging route when possible but not prevent it entirely.
> 2 votes

# Answer
If you want to be able to distinguish not only no damage/ some damage but also find the lowest total damage possible then I think you need to add weights to the paths between neighboring tiles. So if you can pass directly from a tile to its neighbor without taking damage the weight of this passage is 1. If you can pass directly between the two tiles but take damage the weight is 100 times the amount of damage. If it is impossible to pass between the two tiles you can either put no path or a weight of 10000.

Next you apply a weighted pass finding algorithm that tries to find the path with the smallest total weight. If it is possible to find a path with no damage then this path will always have lower total weight than a pass with damage. If only paths with damage exist then if the individual damaging passages are weighted according to damage this will find the paths with the smallest amount of damage. Finally you need a check that if the total weight of the path is bigger than 10000 than you can't go there so you don't show that tile as reachable.

In response to comments: This algorithm makes indirect use of the fact that the maximal total number of steps a unit can make is limited, in OPs example to 3. You also need a hard check that only paths with at most 3 steps total are evaluated (or considered at the end). If you do this, this algorithm works as intended.

If you want to go from the red tile to the green tile at the bottom right next to it, the algorithm finds two possible paths using at most 3 moves. First the direct jump with cost 100 and 1 move and second taking the stairs with cost 3 and 3 moves total. Taking the stairs has lower total weight so this path will be picked.

If on the other hand you want to go from the red tile to the blue tile, there is only path using at most 3 moves, namely taking the jump with total weight 102, so this path will be picked. There is another path taking the stairs but that path takes 5 total moves, so it is not considered because of the hard 3 moves constraint.
> 2 votes

# Answer
If the only damage concern (or the primary) is fall damage from a height, adding that Av (vertical axis) to the calculation with an exponential component can help.

For instance, let's say your normal movements have a weight from 1-3 (maybe depending on terrain). If you set any vertical movement to Xv (spaces vertical) squared * 10, you get an increasingly non-preferred path. So one vertical is 1^2 * 10 = 10. A two vertical unit drop is 2^2 * 10 = 40 - a significantly larger impact to the path budget. A three vertical unit drop is 3^2 * 10 = 90. By using an exponentially increasing value, it will still prefer LESS damaging paths.

That exponent can be made larger if the budget is increased because the movement space is large. For instance, you don't want the NPC to take the damaging path that includes 3 vertical unit drop because there's a walkable path that is more units, but still preferred. In that instance, perhaps you use Xv^3 or even Xv^4 and play around with your base movement cost and your overall budget until it "fits".
> 0 votes

---
Tags: algorithm, path-finding, turn-based, gdscript
---