# Question
Title: Algorithm for distance based-activation of multiple actors
In our game we have many kind of actors that to activate certain behaviors can have one or more than one distance-based conditions. For instance a Rat Enemy could have

```
if(DistanceToPlayer < 50 && !_charging)
  charge_player();
else if(DistanceToPlayer > 100 && !_roaming)
  start_inoffensive_roaming();
else if(DistanceToFood < 10 && _hunger > 0.90f)
  eat_food();
else if(DistanceToFood < 30 && _hunger > 0.90f && !_moving_to_food)
  move_toward_food();
//and so on...

```

The same actor can be scripted to have interactions with many other elements of the game world, and being an "open world"-ish game I need to keep performance impact to a minimum.

My current approach is to refresh the distance checks if either of the 2 subjects has moved, even by a small amount: the rat "subscribes" itself to the position changes of the player (and of the rat itself), and to the position changes of all food items loaded in the world. If either of the three position changes, the rat will call its `UpdateConditions()` method on the next frame.

I might be over-optimizing it, but unless the rat is static, I'm doing 120 positional calculation per second due to the rat simply roaming around (60 `DistanceToPlayer`\+ 60 `DistanceToFood`). I'd love to reduce the refresh rate when the calculated positions are far from trigger points, and maintain precision when the positions are close to trigger points. Is there a common approach for this kind of problem?

# Answer
> 0 votes
The simplest approach is to not check every frame for an update. Both people and creatures have a reaction time to a change in stimuli, so it is totally reasonable to check for updates less frequently. Consider how far any given unit is traveling in 1 second. Are they ever traveling fast enough where they will miss a potential target? It will depend on your game but probably not. In your update function, simply increment a timer and check if the timer is above the set point. If it is, subtract the set point and perform the distance checks.

Faster units may need faster reaction times, but even if you set it to 0.25 seconds, you only have 4 checks per second instead of 60 while having little to no observable impact on gameplay.

From a more advanced perspective, games with larger numbers of units may use update scheduling. A central unit manager queues up a certain number of units to update each frame. This spreads the processing of all the units out over multiple frame updates and helps keep the processing load consistent instead of getting hit with big waves of processing when a bunch of unit update timers finish. If you have units of varying complexity, a processing time score can be assigned and used to decide how many units to update in the frame. Add units to the processing list for the current frame and add their scores together until a max processing score is reached, then process the selected units.

---
Tags: optimization, open-world
---


# Question
Title: Place effect when colliding player weapon with enemy
I've only been using Unity for a very short time and got stuck at one point. I explain.

It is a 2D platform game. I want that when hitting an enemy with a sword, right at the point where the collision has taken place, place a particle effect, but since I have never done it, I have many doubts. In the player I am using **Physics2D.OverlapCircleAll** which detects the collision with the enemy and inflicts damage, but I also want to place a contact effect (animation of contact with the particle system) right at that point of collision, although I wouldn't even know where or how to put it.

This is the method that registers the collision with an enemy:

```
void Hit()
     {
         Collider2D[] collided_objects = Physics2D.OverlapCircleAll(attack_controller.position, attack_radius, is_an_enemy);

  foreach (Collider2D collider in collided_objects)
         {

            collider.transform.GetComponent<Enemy>().enemy_damage(attack_damage, attack_power);

         }

  slash_weak_effect.Play();

     }

```

But the problem is that the effect always appears in the same place and it looks very ugly. My null knowledge does not manage to reach further. I have investigated on the net and I have not found anything, that's why I turn to you.

Where and how can I place this effect to make it realistic? In other words, I need something that places the particles at the exact point where the character's sword touches the enemy's collider.

Sorry if the question may be stupid for experts

# Answer
You can simply set the position of an object via Transform.position:

```
slash_weak_effect.transform.position = xxx;
slash_weak_effect.Play();

```

Given that multiple enemies are hit at once, playing the same `slash_weak_effect` may not work. Multiple `slash_weak_effect`s need to be played. We can create a clone of the gameObject by Object.Instantiate.

```
void Hit()
{
    Collider2D[] collided_objects = Physics2D.OverlapCircleAll(attack_controller.position, attack_radius, is_an_enemy);
    foreach (Collider2D collider in collided_objects)
    {
        collider.transform.GetComponent<Enemy>().enemy_damage(attack_damage, attack_power);
        var clone_of_slash_weak_effect = Instantiate(slash_weak_effect, collider.transform.position, Quaternion.identity);
        clone_of_slash_weak_effect.GetComponent<ParticleSystem>().Play();
    }
}

```

The second parameter of `Instantiate` specifies the position of the new object, and we can pass in the position of the hit collider.

And set `Stop Action` to `Destroy` in ParticleSystem component to have it self-destruct after playback is complete.

PS: While writing this answer I found another answer submitted which purported to show how to find exactly where the collision occurred. Maybe it's because of some ambiguity in the question itself, or maybe I'm reading it wrong. But I found that the original sample code did not set the position / create multiple effect clones. So I decided to leave this answer here.

> But the problem is that the effect always appears in **the same place** and it looks very ugly.

the same place on the enemy? the same place on the screen? I think it's the latter, the other answer thinks it's the former. Anyway, hope at least one of the two answers will help you. :D
> 1 votes

# Answer
You can't do that that easily with `Physics2D.OverlapCircle`, because it only tells you which colliders were found, but not where exactly the overlap happens.

If you want more information about collisions, then you need to use rigidbody collisions. These work very different from how you are doing collision detection right now.

1. The sword has to be a separate GameObject with a Rigidbody2D and a Collider2D. Note that this means that you *can* visualize the character and the sword as two separate sprites, but you don't have to. When you prefer to animate character and sword together as one sprite, then the sword can also be an invisible game-object with an animation that matches that of the sprite animation as good as possible.
2. The sword has to physically move to attack. I would recommend to do that with the animation system. When you don't know the animation system yet (you should really learn it - it's a very powerful and useful system that can be used for much more than just humanoids), you might need to animate it with code for now. Or, to get you going, you could provisorically just parent it statically to the player to act as a "lightsaber" that does damage when it touches stuff.
3. The enemies need to have Rigidbody2Ds as well, because otherwise you won't get any rigidbody collision events.
4. You need a script that is either on the sword or on the enemies and implements the method `OnCollisionEnter2D(Collision2D collision)`

This method gets executed whenever the object collides with another object with a rigidbody2D. The method has access to the `collision` object of type `Collision2D`. This class provides a lot of useful information about the collision event. Among that information is a method `GetContact(int)` that returns an object which contains a Vector2 of the exact point where the two colliders touched. Note that in some situations two colliders can collide at multiple points simultaneously, which is why this method requires an index. But you always have at least one contact point, so when you are not interested in handling this edge-case too accurately for now, you can just use `GetContact(0)`.

Here is an example script that assumes that the script is on the weapon and that anything that can be hit by it has a component "Enemy":

```
[RequireComponent(typeof(Rigidbody2D))]
class Hurtbox : MonoBehaviour {

    void OnCollisionEnter2D(Collision2D collisionInfo) {
        if (collisionInfo.gameObject.TryGetComponent<Enemy>(out Enemy enemy)) {
            Vector2 impactPoint = collisionInfo.GetContact(0).point;
            Debug.Log($"The { name } hit the { enemy.name } at { impactPoint }");
        }
    }
}

```
> 2 votes

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


# Question
Title: Software architecture advice for a Sokoban clone
I'm building a Sokoban clone, and I would like to try to get the architecture right for future extensions. Sokoban is a simple game, where the player has to move boxes around a grid and place them in target locations. The player can move in grid up, down, left or right. Boxes can be moved by pushing them (not by pulling) and only if they have an adjacent free cell where they can be moved.

I'm using the Godot game engine with C#, and I'm using a `TileMap` node to represent the grid, with various nodes for the player, boxes and targets.

The temptation is to create a big GameBoard script attached to the root node of the scene which contains everything for the full game logic, however I'm afraid it will degrade into spaghetti soon, and I would like to add more "special" features like blocking obstacles which are deactivated at some point and more.

What could be a more flexible architecture?

# Answer
This is a more general answer with no godot specific code but can be easily transfered to it.

First you have to decide for yourself how you want to have the logic done. Do you want to have one central manager/ gameboard script that handles all the logic or are the components itself responsible for logic?

If your components can have logic attached to them, adding new special features like key/ gate blocks, teleports or sliding grounds will be all handled by the component/ tile and their seperate logic.

If you have a central manager, you can still break it down into seperat components like `determinateWin`, `possibleMove`, `doMove`, `updateMap` etc. The more you think beforehand how to break it down, the easier it should be to add more features in the future.

Both approaches can lead to different problems. The big master script might be more prone to spagetti code. The component approach might have side effects when different components are interacting in unexpected ways (While this can be true as well for the master script, the master script should handle all the logic and the board is just used for display vs when the board/ the tiles on the board itself have power to decide what is happening).

One general tip is to just add a lot of commentary to your code that when you add new features in the future, you know for sure what a certain piece of code did or why you did it that way.
> 0 votes

---
Tags: architecture, godot
---


# Question
Title: Two methods of finding angle between vectors give different answers!
Ok, am I misunderstanding how Unity quaternions work, or is there a bad (about 2 degrees difference!) floating point error?

The TLDR is I use a quaternion r to rotate vector v and put the result in w. I then compute the angle between v and w (I looked at Unity's code for Vector3.Angle, and it looks correct to me, and the floating point error on the value of 180/pi is not enough to make more than a fraction of a degree difference) and I computed angle-axis of r itself (this time the code is internal and I can't see it). I expect the results to be the same, but they differ by a couple degrees.

What am I missing? I'd think if this is a bug, it'd be noticed and fixed by now!

Log output

> v = (1.00, 1.41, -1.50)
>
> r = (0.12768, 0.23930, 0.14488, 0.95155)
>
> w = (-0.20, 1.91, -1.26)
>
> angle = 33.43961
>
> angle = 35.81708
>
> axis = (0.42, 0.78, 0.47)

```
using UnityEngine;

namespace Deplorable_Mountaineer.Core.Utils {
    public class VectorsAndRotations : MonoBehaviour {
        private void Start() {

            //make a vector
            Vector3 v = new Vector3(1, Mathf.Sqrt(2), -1.5f);
            Debug.Log($"v = {v}");

            //Make a rotation, first 20 degrees about z axis (roll), then
            //10 degrees about x axis (pitch), and then 30 degrees about
            //y axis (yaw).
            Quaternion r = Quaternion.Euler(10, 30, 20);
            Debug.Log($"r = {r}");

            //w is v rotated by the rotation r
            Vector3 w = r*v;
            Debug.Log($"w = {w}");

            //If v and w are vectors, what is the angle between them?
            //method 1
            float angle = Vector3.Angle(v, w);
            Debug.Log($"angle = {angle}");

            //method 2, since we know that w = r*v, find the angle of rotation encoded in r.
            //this way also gives the axis, perpendicular to the plane containing both vectors.
            Vector3 axis;
            r.ToAngleAxis(out angle, out axis);
            Debug.Log($"angle = {angle}");
            Debug.Log($"axis = {axis}");

            //why are they different?

        }
    }
}

```

# Answer
> 0 votes
The angle of a quaternion is measured in the plane perpendicular to its axis of rotation.

The angle between two vectors is measured in the plane containing those two vectors.

If those aren't the same plane, then you're measuring two different angles, and getting correct answers for both, just for different questions.

Think of it this way: a vector parallel to a quaternion's axis - like the north pole of the Earth acted on by the planet's spin - won't be changed at all when it's rotated by it. So measuring the angle between the before and after versions would give you a value of zero - a 100% error! As your input vector gets closer and closer to perpendicular to the axis of rotation - descending in latitude in the Earth example - it gets transformed more and more, so the angle you measure gradually increases. Until you reach the equator, fully perpendicular, where the vector is transformed by the quaternion by the maximum amount, and both angles are measured in the same plane.

In this case `Dot(v, axis) == Dot(w, axis) ≈ 0.814 != 0`, so your vectors are *not* perpendicular to the axis of rotation and do not experience the maximum angular change under this rotation.

tl;dr: a quaternion's angle is an *upper bound* for the angle you'll measure between vectors before & after rotation, and we should only expect them to be exactly equal when the vector is perpendicular to the axis of rotation.

---
Tags: unity, rotation, vector, geometry
---


# Question
Title: Tessellation shaders not working, no objects drawing on screen
Using this tutorial https://learnopengl.com/Guest-Articles/2021/Tessellation/Tessellation and this tutorial https://www.youtube.com/watch?v=21gfE-zUym8 I implemented tessellation shaders that I haven't been able to get working after debugging for 8 hours. The error message I get is

This is what my window is looking like

This is my tessellation control shader

```
#version 410 core

// specify control points per output per patch
// control size of input and output arrays
layout(vertices=3) out;
// input from vertex shader
in vec2 vert_coord[];
// output to evaluation shader
out vec2 vertex_coord[];

// for tessellation
uniform mat4 view;
uniform mat4 model;

void main()
{
    // pass attributes through
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
    vertex_coord[gl_InvocationID] = vert_coord[gl_InvocationID];

    // control tessellation
    if(gl_InvocationID==0)
    {
        /* dynamic tessellation */
        // first: define rendering constants to control tessellation
        const float MIN_TESS_LEVEL = 4;
        const float MAX_TESS_LEVEL = 64;
        const float MIN_DISTANCE = 20;
        const float MAX_DISTANCE = 800;
        // second: transform each vertex into each eye
        vec4 eye_space_pos_1 = view * model * gl_in[0].gl_Position;
        vec4 eye_space_pos_2 = view * model * gl_in[1].gl_Position;
        vec4 eye_space_pos_3 = view * model * gl_in[2].gl_Position;
        // third: distance from camera scaled between 0 and 1
        float distance_1 = clamp((abs(eye_space_pos_1.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        float distance_2 = clamp((abs(eye_space_pos_2.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        float distance_3 = clamp((abs(eye_space_pos_3.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        // fourth: interpolate edge tessellation level based on closer vertex
        float tess_level_1 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_3, distance_1));
        float tess_level_2 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_1, distance_2));
        float tess_level_3 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_2, distance_3));
        // fifth: set the corresponding outer tessellation levels
        gl_TessLevelOuter[0] = tess_level_1;
        gl_TessLevelOuter[1] = tess_level_2;
        gl_TessLevelOuter[2] = tess_level_3;
        // sixth: set the inner tessellation levels
        gl_TessLevelInner[0] = max(tess_level_1, tess_level_3);
        gl_TessLevelInner[1] = max(tess_level_1, tess_level_2);
    }
}

```

This is the tessellation evaluation shader

```
#version 410 core

// from control shader
layout(triangles, equal_spacing, ccw) in;

// input from control shader
in vec2 vertex_coord[];
// output vec
out vec2 vert;

// allows for object transformations and for movement
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    // patch coords
    float u = gl_TessCoord.x;
    float v = gl_TessCoord.y;
    float w = gl_TessCoord.z;

    // barycentric interpolation
    vec2 tex_coord = u * vertex_coord[0] + v * vertex_coord[1] + w * vertex_coord[2];

    // get control coords
    vec4 pos_1 = gl_in[0].gl_Position;
    vec4 pos_2 = gl_in[1].gl_Position;
    vec4 pos_3 = gl_in[2].gl_Position;

    // more barycentric interpolation
    vec4 pos = u * pos_1 + v * pos_2 + w * pos_3;

    // position
    gl_Position = model * view * projection * pos;
    vert = tex_coord;
}

```

This is the vertex shader

```
#version 410 core

// position of the object
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 vert;

out vec2 vert_coord;

void main()
{
    // position object
    gl_Position = vec4(pos, 1.0f);
    vert_coord = vert;
}

```

This is the fragment shader

```
#version 410 core

out vec4 color;

void main()
{
    color = vec4(0.86f, 0.74f, 0.09f, 1.0f);
}

```

This is the shader loader for the tessellation shaders

```
// tess control
tessellation_control_shader = glCreateShader(GL_TESS_CONTROL_SHADER);
glShaderSource(tessellation_control_shader, 1, &tessellation_control_shader_text, NULL);
glCompileShader(tessellation_control_shader);
glGetShaderiv(tessellation_control_shader, GL_COMPILE_STATUS, &success);
if(!success)
{
    glGetShaderInfoLog(tessellation_control_shader, 512, NULL, info_log);
    printf("Tessellation control shader failed: %s\n", info_log);
    perror(info_log);
}

// tess eval
tessellation_evaluation_shader = glCreateShader(GL_TESS_EVALUATION_SHADER);
glShaderSource(tessellation_evaluation_shader, 1, &tessellation_evaluation_shader_text, NULL);
glCompileShader(tessellation_evaluation_shader);
glGetShaderiv(tessellation_evaluation_shader, GL_COMPILE_STATUS, &success);
if(!success)
{
    glGetShaderInfoLog(tessellation_evaluation_shader, 512, NULL, info_log);
    printf("Tessellation evaluation shader failed: %s\n", info_log);
    perror(info_log);
}

```

This is the tessellation initialization, vertices, indices and, buffers

```
 #define NUM_PATCH_PTS 3
    // shader loading
    unsigned int shader_program = load_shaders("vert.glsl", "frag.glsl", "tes_ctrl.glsl", "tes_eval.glsl");

    // octahedron, vertices provided by https://gamedev.stackexchange.com/users/39518/dmgregory
    unsigned int draw_calls = 48;
    float vertices[] = {
        //top-north-east
         0.0,  1.0,  0.0,
         0.0,  0.0,  1.0,
         1.0,  0.0,  0.0,

        //top-north-west
         0.0,  1.0,  0.0,
        -1.0,  0.0,  0.0,
         0.0,  0.0,  1.0,

        //top-south-west
         0.0,  1.0,  0.0,
         0.0,  0.0, -1.0,
        -1.0,  0.0,  0.0,

        //top-south-east
         0.0,  1.0,  0.0,
         1.0,  0.0,  0.0,
         0.0,  0.0, -1.0,

        //bottom-north-east
         0.0, -1.0,  0.0,
         1.0,  0.0,  0.0,
         0.0,  0.0,  1.0,

        //bottom-north-west
         0.0, -1.0,  0.0,
         0.0,  0.0,  1.0,
        -1.0,  0.0,  0.0,

        //bottom-south-west
         0.0, -1.0,  0.0,
        -1.0,  0.0,  0.0,
         0.0,  0.0, -1.0,

        //bottom-south-east
         0.0, -1.0,  0.0,
         0.0,  0.0, -1.0,
         1.0,  0.0,  0.0,
};

    unsigned int indices[] = {
        // first triangle
        0, 1, 2,
        // second triangle
        3, 4, 5,
        // third triangle
        6, 7, 8,
        // fourth triangle
        9, 10, 11,
        // fifth triangle
        12, 13, 14,
        // sixth triangle
        15, 16, 17,
        // seventh triangle
        18, 19, 20,
        // eighth triangle
        21, 22, 23
    };
    unsigned int vbo, vao, ebo;
    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);
    glGenBuffers(1, &ebo);

    glBindVertexArray(vao);

    // upload vertex data to gpu
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) * sizeof(double), &vertices[0], GL_STATIC_DRAW);

    // upload index data to gpu
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices) * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // max tessellation points / patches
    glPatchParameteri(GL_PATCH_VERTICES, NUM_PATCH_PTS);

```

This is the draw call

```
    glBindVertexArray(vao);
    glDrawArrays(GL_PATCHES, 0, draw_calls*draw_calls*NUM_PATCH_PTS);

```

# Answer
Step one: go here https://learnopengl.com/Guest-Articles/2021/Tessellation/Tessellation

Step two: change code from quads to triangles, this includes vectors, matrices, other math things, etc. Example: `from layout (quads)` to `layout (triangles)`, `vec2 vertex_coords` to `vec3 vertex_coords` references: https://prideout.net/blog/old/blog/index.html@p=48.html https://www.khronos.org/opengl/wiki/Tessellationhttps://ogldev.org/www/tutorial30/tutorial30.html https://ogldev.org/www/tutorial30/tutorial30.html

Step three: This problem is solved, still a lot more but this one is done
> 0 votes

---
Tags: opengl, shaders, graphics-programming, debugging, tessellation
---


# Question
Title: Tricks to make the map feel bigger than it actually is
I am planning out a fantasy rpg. Based on its story and mechanics, it will span over multiple countries and continents. However, even at the highest possible funding and management, I may not be able to create a big enough map. My solution: Scale it way down.

Of course, this is not an original idea, dozens of games have done this. However, I am not really show how to without the players seeing that it's small.

What are ways that I could make the map be really small, but appear to be really huge?

For some details:

* The game is top-down, and in a style such as Stardew Valley or Chrono Trigger
* The design is a mix of Dark Souls and Skyrim, with a little GTA influence
* While there is of course a lot of walking, there is transportation, including dragon-riding, drivable wagons, and horses. Might include teleportation, but it will cost extra.

# Answer
## Cutscenes and travel minigames

You mention Chrono Trigger: do you recall the racing minigame in 2300 AD? That made the location feel much bigger.

Instead of covering distance on screen, take up the player's time: during wagon riding (I imagine a caravan), make random events play out. Give the player something to do. Add night maps around the campfire. Then you don't need to show that 100km have been traversed; it suffices to have a couple of day and night events in succession.

## World map

World maps help to convey size without requiring to model each square kilometer in detail:

Secret of Mana, for example, had these fast travel trampoline thingies that would show you launch and landing, which helped to show distances and the layout of the land. This series employs travel by sea and air eventually so you'd traverse the world map, but it's mostly set dressing as you go from landing spot to landing spot.

That's different from the Final Fantasy games for SNES which allow to move on the world map iself, including random battles.

The idea is to provide detail maps + a zoomed out world map that's interactible, i.e. goes beyond a mere map screen showing one's location.

## Many detail maps

Chained Echoes instead uses tons of large detail maps to convey distances. That's similar to esp. ""Secret of Mana 2"" (Seiken Densetsu 3) where you'd have all these beautiful locations when you travel on foot prior to unlocking air travel.

String together smaller detail maps, vary the tileset, and fade through black during transitions to convey "time has passed" and players might be able to imagine something happened during map transitions whenever the map-stitching is imperfect.

That takes the most map-making time, but I'm personally not convinced this actually improves the game. I'd favor caravan rides any day of the week :)
> 1 votes

# Answer
* Don't let the player see too much of the world at once. In top-down, this can be accomplished by having the camera closer to the player-character. In 1st or 3rd person, it can be accomplished by having a lot of buildings, walls, mountains and other objects that break lines of sight in the world. The result is that the player needs more time to fully explore the world, which makes it seem a lot larger.
* Don't let the player traverse too quickly. The faster the player can move through the game world, the smaller it seems.
* Don't let the player go everywhere too early. You can prevent that via gating. Gating means that you place a lot of obstacles that prevent the player from entering certain areas which then get subsequently unlocked as the story and/or the players ability progress. This prevents the player from exploring the game world too quickly, while still letting the player know that there is lots of content they haven't seen yet.
* Make good use of the locations you have by making sure the player wants to spend as much time in them as possible. You can do that by encouraging the player to explore each location very thoroughly by placing a lot of hidden collectibles and resources for the player to find. Or encourage the player to fight through the same dungeon multiple times. This can be done by optional sidequests which prompt the player to revisit a location they already cleared. Or you can give the player an intrinsic motivation to revisit locations by changing them slightly as the game progresses and thus promising a new experience. For example by adding stronger enemies, but also better rewards to old areas. Or by giving the player new abilities that allow them to interact with old areas in new ways.
> 1 votes

---
Tags: maps, rpg, level-design, open-world, top-down
---


title: Align two meshes given 2 faces

text:
# Question
Title: Align two meshes given 2 faces
I have two meshes (A and B) and I know that a triangle in A has the same size and same angles as a triangle in B.

For simplicity, suppose A is an octahedron and B is a tetrahedron. And suppose the triangle in A is the first one and the triangle in B is the first one.

I want to find a way (a matrix) to move B such that the triangle is coincident with the triangle in A.

I'd like to move the blue mesh such as the green triangle touches the green triangle in the orange mesh.

I'd like to move the mesh such so that its triangle's normal will point opposite to that of the stationary mesh's face (so the octahedron and tetrahedron "dock" along the shared face, like pressing two dice together)

I'm using javascript with thee.js, but I'm not tied to any framework or language.

# Answer
This is a bit easier if you have a quaternion "look rotation" method handy, but I don't see one in the library you're using, so I'll describe the algorithm in high level pseudocode and you can translate it as needed. That can include implementing your own `lookRotation(forward, up)`, which returns a quaternion that rotates (0, 0, 1) to point along `forward` and (0, 1, 0) to point as close as possible to `up` using the remaining degree of freedom.

So, we have object 1 with a triangular face ABC and object 2 with a triangular face PQR, each defined in the objects' own local coordinates. We want to move object 2 so that P meets A, Q meets C, and R meets B.

First we'll compute the normal to each face, the centroid of each face, and a vector from the centroid to the vertex we want to match up on each face:

```
n1 = cross(B - A, C - A)
n2 = cross(Q - P, R - P)

c1 = (A + B + C)/3
c2 = (P + Q + R)/3

v1 = A - c1
v2 = P - c2

```

We'll use that to compute an orientation of each face within its object's local coordinate space:

```
q1 = lookRotation(-n1, v1)
q2 = lookRotation(n2, v2)

```

We negate `n1` to flip the face, so we dock object 2 to the outside of the face, not the inside.

Now ABC's orientation in world space is:

```
worldSpaceOrientation = object1.rotation * q1

```

And we can undo the effects of PQR's local orientation by inverting it, to get...

```
object2.rotation = worldSpaceOrientation * q2.inverse

```

Now we've rotated the second object so PRQ is in the right orientation to match ABC, but it's still probably in the wrong position. All we have to do now is get the vector between the two centroids, and translate object 2 by that vector:

```
c1World = object1.matrix * c1
c2World = object2.matrix * c2

object2.position += c2World - c1World

```

Make sure you do this after rotating object 2, otherwise the rotation can change the translation you need, twisting them out of alignment again.
> 1 votes

---
Tags: rotation, matrix, geometry, webgl, linear-algebra
---


# Question
Title: After keying value in animation track, property becomes locked and can't be changed
I am trying to rotate a sword hitbox around the player depending on which animation is currently playing.

I have the following node setup:

```
Scene
|---AnimationPlayer
|---Marker2D
.....|---Area2D
..........|---CollisionShape2D

```

The CollisionShape2D is for the shape of the hitbox. The Marker 2D is centred on the player, and I want to use its rotation property to rotate the hitbox around the player.

So I go to my AnimationPlayer node, select an animation and key the rotation property at the start of the animation.

The issue is that once I have keyed rotation to the first animation, the rotation property becomes "locked" and I cannot change its value anymore.

Is this intended behaviour and I am missing something obvious? Or is this a bug?

I am using Godot version 4.0.beta16

# Answer
This is caused by having an `AnimationTree` set to *Active*. Deactivate the tree and the issue disappears.

Alternatively, change the `update mode` of the animation track to *discreet* (from *continuous*) then this issue also disappears.

See: https://github.com/godotengine/godot/issues/74006
> 1 votes

---
Tags: animation, godot
---


# Question
Title: How do I find two points on opposite sides of a circle where the angle of the first point's position is a percent of the whole circle?
I am trying to simulate sunrise/sunset with a linear gradient. I want the gradient to rotate around a circle whose diameter is the width of the screen with the center point being the very bottom middle of the screen.

I found this this answer on a different thread with a similar question, but I am still left confused.

The following is my current attempt:

```
      double width = MediaQuery.of(context).size.width;
      double height = MediaQuery.of(context).size.height;
      // Circle is intended to be screen width
      // Radius then is half the width of the screen
      double radius = width / 2;

      // Center of the circle.
      // Intended to be the very bottom center of the screen
      double centerX = radius;
      double centerY = height;

      // Using x = r * sin(a) and y = r * cos(a) to get the coordinates of the start and end points
      // The angle is elapsed percent of 360 degrees
      double beginVectorX = radius * sin(360 * _percentOfDayElapsed);
      double beginVectorY = radius * cos(360 * _percentOfDayElapsed);

      // The end coordinates need to always be on the opposite end of the circle
      // The angle is the same as the start coordinates but shifted 180 degrees
      double endVectorX = radius * sin((360 * _percentOfDayElapsed) + 180);
      double endVectorY = radius * cos((360 * _percentOfDayElapsed) + 180);

      // The coordinates then need to be added to the center to get the points relative to the position of the circle
      double beginX = centerX + beginVectorX;
      double beginY = centerY + beginVectorY;
      double endX = centerX + endVectorX;
      double endY = centerY + endVectorY;

      // The coordinates then need to be converted from absolute X, Y to relative alignment
      // Relative alignment means: (-1, -1) is top left, (0, 0) is center, and (1, 1) is bottom right
      // Conversion forumli: (2 * x - w) / w and (2 * y - h) / h
      begin = Alignment(
          (2 * beginX - width) / width, (2 * beginY - height) / height);
      end = Alignment(
          (2 * endX - width) / width, (2 * endY - height) / height)

```

The following is a quote from the answer that I used (p0 is the center of the circle, p1 and p2 are the two points on opposite ends, a is the rotation of p1, and the orange vector is the radius of the circle):

> Basic trigonometry says that to get the x value of the orange vector (p0 to p1), we can do r * sin(a) and for its y, do r * cos(a). Hence to find p1, add the orange vector to p0. For p2, subtract the orange vector from p0. You can then use p1 and p2 to draw your gradient.

What I don't understand is what it means by adding and subtracting the vector from the center point. I believe I'm doing that here:

```
      // The coordinates then need to be added to the center to get the points relative to the position of the circle
      double beginX = centerX + beginVectorX;
      double beginY = centerY + beginVectorY;
      double endX = centerX + endVectorX;
      double endY = centerY + endVectorY;

```

but I'm not really sure.

The problem is that while the gradient does rotate around the right spot, a full rotation is about 25 minutes instead of 24 hours.

Also, keep in mind that the origin of the screen is at the top left, and moving downward is an increase in Y and moving right is an increase in X. That is why I'm still adding the vector to the center for the point at the other end, even though the answer said to subtract.

I don't think \_percentOfDayElapsed is affecting anything adversely, but just in case, it is defined as follows:

```
Timer.periodic(const Duration(milliseconds: 100), (timer) {
  final now = DateTime.now();

  setState(() {
    _percentOfDayElapsed =
        ((now.hour * 3600) + (now.minute * 60) + now.second) / 86400;
  });
});

```

# Answer
It turns out that the cos and sin functions required radians instead of degrees.

The solution is to replace 360 degrees with 2pi and 180 degrees with pi.
> 1 votes

---
Tags: mathematics, animation, trigonometry
---


# Question
Title: Signal is not recognized as being declared in the current scope in Godot 3.5
I'm learning to use the Godot Engine (v3.5) along with the GDScript. I'm following the official tutorial for the same.

In the step-by-step tutorial for the "Dodge the Creeps" game, there is a section on using a signal to identify a hit.

Based on the above I have the following code:

```
extends Area2D

signal hit

export var speed = 400 # How fast the player will move (pixels/sec).
var screen_size # Size of the game window.

func _ready():
    screen_size = get_viewport_rect().size
    hide()

func _process(delta):
    var velocity = Vector2.ZERO
    if Input.is_action_pressed("move_right"):
        velocity.x += 1
    if Input.is_action_pressed("move_left"):
        velocity.x -= 1
    if Input.is_action_pressed("move_down"):
        velocity.y += 1
    if Input.is_action_pressed("move_up"):
        velocity.y -= 1

    if velocity.length() > 0:
        velocity = velocity.normalized() * speed
        $AnimatedSprite.play()
    else:
        $AnimatedSprite.stop()

    position += velocity * delta
    position.x = clamp(position.x, 0, screen_size.x)
    position.y = clamp(position.y, 0, screen_size.y)

    if velocity.x != 0:
        $AnimatedSprite.animation = "walk"
        $AnimatedSprite.flip_v = false
        $AnimatedSprite.flip_h = velocity.x < 0
    elif velocity.y != 0:
        $AnimatedSprite.animation = "up"
        $AnimatedSprite.flip_v = velocity.y > 0

func _on_Player_body_entered(body):
    hide() # Player disappears after being hit.
    hit.emit()
    $CollisionShape2D.set_deferred("disabled", true)

func start(pos):
    position = pos
    show()
    $CollisionShape2D.disabled = false

```

This code gives me the following error:

```
error(45,1): The identifier "hit" isn't declared in the current scope.

```

This is what the signals in the "Node" tab look like.

\]

I can't seem to call hit.emit() despite it being declared.

# Answer
> 2 votes
This line:

```
hit.emit()

```

Is correct in GDScript 2.0 (Godot 4). Which might have just sneaked on you as it was released hours earlier at the time of writing.

In Godot 3.x you do this:

```
emit_signal("hit")

```

---

You can see which version of the documentation at the bottom left. For example here I'm looking at the current stable:

If you click there it will expand to a menu where you can pick the version you want:

As you can see, you can choose language (in this case it is in English) and version (in this case it is "stable", which, again, it is 4.0 at the time of writing). Since you are working on 3.5 you would pick that.

*By the way, you can see "3.6" there, it is work in progress documentation for the next version of the 3.x branch. Similarly the option that says "latest" is the work in progress documentation for the next version of the master branch… which should be 4.1.*

---
Tags: godot, gdscript
---


# Question
Title: What to do when my game is rejected by CrazyGames?
Every time I try to upload a scratch game to CrazyGames, it won't let me upload it.

I start the upload and I wait 30 minutes to 2 hours and it just says "rejected" — I don't know why.

If anybody has tips for what I should do to fix this, please tell me.

This is the current version of the game. I have tried to change my title. Is there something else I should change to avoid rejection?

# Answer
> 13 votes
From the CrazyGames Developer FAQ, under the heading **Uploading my games**:

> **Can I submit a rejected game again?**
> Only if you have improved your game and it follows our quality guidelines.

One thing that is almost immediately obvious on your Itch.io implementation:

* There's no guidance on how to play & the player has about five seconds to figure out the controls before they lose.

That seems to be in conflict with the CrazyGame's quality guidelines under the heading *"Is your game easy to play? Are the rules and objectives clear?"*

Your current version shows a very brief splashscreen with your developer name / logo when the game is launched. As first step toward communicating the game controls to the user, I suggest following your logo screen with one or two screenshots that attempt to explain the controls to the user. This seems like a relatively low effort fix as you would be recycling something you've already developed to solve the problem.

I also experienced very erratic player movement in the game. On Itch.Io that you have the game marked as `Status In development`. It's understandable that a game is likely to have errors while it is in development. However, the guidelines on CrazyGames state that their expectation is that "errors don't hinder the experience". You should correct any obvious bugs before attempting to resubmit.

In general, when publishing to *any* platform, you should read and adhere to their guidelines.

As mentioned in the comments, ultimately CrazyGames determines which game are accepted and which are rejected & if you want to know the specifics regarding your situation, you need to ask them.

# Answer
> 5 votes
I just saw your game, and no offense, but it looks like it is subpar quality compared to the other apps on the site.

Off the top of my head, I can list several points that may be fundamentally wrong with your game causing rejection:

* Graphics: The characters have no animation, enemies have no animation, UI are simple colored shapes.
* Feedback: Your game doesn't have any feedback or particle effects on impact when you kill a zombie.
* Audio: Only simple music, no sound effects for shooting, impact, or zombies.
* Gameplay: It is just too simple. No progression, no rewards, no store, only a score kept for shooting zombies.
* Game Over: After the player dies, there is no way to restart the game. It just stays frozen at that screen. This alone would get your app rejected on any platform.

These are just the basic things that are wrong with the game in my opinion. In short, the project looks like a new high school programming project. All the apps on CrazyGames are production-ready, fully-fleshed out games. I suggest you maybe get some experience doing game jams, getting feedback from other game devs, and get better at making games in general. Hope you can improve and get better at game dev and eventually get a good project published!

---
Tags: html5, scratch
---


title: Creating Asset Bundle in Unity 2021

text:
# Question
Title: Creating Asset Bundle in Unity 2021
I am using this code snippet in unity 2021.3.16 to create Asset bundles:

```
using System.IO;
using UnityEditor;
using UnityEngine;
using System.Security.Cryptography;
public class ABEncryption
{

    [MenuItem("ABD/Build AssetBundles")]
    static void ABCreate()
    {
        string _assetNameForAB = "Assets/Prefab/Cube.prefab";
        string _ABName = "MyAB";

        AssetBundleBuild[] assetBundleBuilds = new AssetBundleBuild[1];
        assetBundleBuilds[0].assetBundleName = _ABName;
        assetBundleBuilds[0].assetBundleVariant = "";
        assetBundleBuilds[0].assetNames = new string[] { _assetNameForAB };

        BuildAssetBundleOptions buildAssetBundleOptions = BuildAssetBundleOptions.None;
        buildAssetBundleOptions |= BuildAssetBundleOptions.DeterministicAssetBundle;
        buildAssetBundleOptions |= BuildAssetBundleOptions.ChunkBasedCompression;

        string outputPath = Application.streamingAssetsPath  + "/EncryptedAB/";

        BuildPipeline.BuildAssetBundles(outputPath,
                                        assetBundleBuilds,
                                        BuildAssetBundleOptions.None,
                                        BuildTarget.StandaloneWindows64);

    }

}

```

Something very strange is happening. Compile time is perfectly fine but when I run this I get several errors:

> Assets\ABEncryption.cs(27,36): error CS0103: The name 'BuildAssetBundleOptions' does not exist in the current context
>
> Assets\ABEncryption.cs(38,9): error CS0103: The name 'BuildPipeline' does not exist in the current context
>
> Assets\ABEncryption.cs(40,41): error CS0103: The name 'BuildAssetBundleOptions' does not exist in the current context
>
> Assets\ABEncryption.cs(41,41): error CS0103: The name 'BuildTarget' does not exist in the current context
>
> Assets\ABEncryption.cs(54,9): error CS0103: The name 'BuildPipeline' does not exist in the current context
>
> Assets\ABEncryption.cs(55,41): error CS0103: The name 'BuildAssetBundleOptions' does not exist in the current context
>
> Assets\ABEncryption.cs(56,41): error CS0103: The name 'BuildTarget' does not exist in the current context
>
> Error building Player because scripts had compiler errors

I am running this method in the editor (on context menu). Here is the complete details

# Answer
> 2 votes
From the screenshot, `ABEncryption` seems to be a `MonoBehaviour` you attach to a `GameObject`, which means it is runtime code. Runtime code cannot contain references to Editor code.

A quick fix is wrapping all the editor code that is placed in runtime classes between `#if UNITY_EDITOR` and `#endif` compiler directives. This instructs compiler to only compile them in the editor, and not for runtime.

A better way would be to extract that Editor code completely to a separate Editor-only class and make that class a part of either an `Editor` folder or an Editor-only assembly definition.

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


title: Sliding scale for secondary stats

text:
# Question
Title: Sliding scale for secondary stats
So, I’m designing a game where Crit Chance is based on a Prowess Stat but want it to have a sliding scale with diminishing returns and for some reason the math is escaping me. The max value for Crit Chance would be 40%. The min value of Prowess would be 1 but there is no ceiling.

# Answer
> 3 votes
You can adapt basically any function with a horizontal asymptote. Here are a few options:

```
// hyperbolic
critChance = maxChance * (1 - 1/(rate * prowess + 1))

// arc tangent
critChance = maxChance * atan(rate * prowess) * 2/PI

// exponential
critChance = maxChance * (1 - exp(-rate * prowess))

```

These behave similarly, and all reach toward a max of `maxChance` as `prowess` increases toward infinity - they just differ in how steeply they rise initially, and how gradually they brake as they approach that cap.

`rate` in all three is a parameter you can use to control the steepness of the early part of the curve / how quickly it starts to plateau. In this chart, I've plotted the three versions with `rate` tuned so they all pass through the point (15, 25%) to get an apples-to-apples look at how they compare:

If you want to tune the `rate` so the curve passes through a given `(prowess, critChance)` pair, the formulas for that are:

```
// hyperbolic
rate = (1/(1 - critChance/maxChance) - 1) / prowess

// arc tangent
rate = tan(critChance * PI / (2 * maxChance)) / prowess

// exponential
rate = ln(1 - critChance/maxChance) / prowess

```

I've shared a version of these formulas as a Google Sheets workbook you can play with here \- see the "Diminishing Returns" tab. You can set the Min Output to zero if you want zero stat to map to zero chance, as shown above.

---
Tags: mathematics
---


# Question
Title: Play Games for Unity achievement is broken
There was a huge issue a few months ago while integrating with Firebase. The authentication always failed, and all the features were broken.

Somehow I fixed the authentication by adding an app signing certificate in Google Cloud OAuth, but the achievement system is still broken and not coming back.

There are two types of this issue. The first issue is just not working at all. I added achievement in the last update, and it's already been two months, but no man who achieved it. Many of my players already satisfied the condition, but no one achieved it in my Google Play Console.

The second issue is that they consistently watch the same unlocking achievement popup every time they play it. Afaik, if the user already achieved the achievement, it should be just ignored. It was, but after the firebase incident, it's broken.

Whether it's the first or the second case, the new achievement has not been cleared at all, so it's clear that it's completely broken in my case.

I already added my app signing and uploading SHA-1 in my Google Cloud project. Authentication and Saved Games are works, but achievement isn't. What am I missing?

Using Unity 2019.4.31f and Play Games for Unity 0.10.14.

# Answer
Solved by adding a new credential in Google Play Console that exists in Google Cloud Project.
> 0 votes

---
Tags: unity, google-play, google-play-services
---


# Question
Title: How do I distort a 2D texture based on the movement of a point that starts at the center?
So there's this point that starts in the center. If the user drags it up towards the top of the texture, the top squishes and the bottom stretches. If the user drags it down, the top stretches on the bottom squishes. The same goes for left and right. How do I do this?

# Answer
okay i figured it out

```
shader_type canvas_item;

const vec2 center_original = vec2(0.5, 0.5);
uniform vec2 center_actual = vec2(0.5, 0.5);

void fragment() {
    vec2 adjusted_uv = vec2(0.0, 0.0);
    if (UV.x < center_actual.x){
        adjusted_uv.x = UV.x * center_original.x / center_actual.x;
    } else {
        adjusted_uv.x = UV.x * (1.0 - center_original.x) / (1.0 - center_actual.x) + 1.0 - (1.0 - center_original.x) / (1.0 - center_actual.x);
    }
    if (UV.y < center_actual.y){
        adjusted_uv.y = UV.y * center_original.y / center_actual.y;
    } else {
        adjusted_uv.y = UV.y * (1.0 - center_original.y) / (1.0 - center_actual.y) + 1.0 - (1.0 - center_original.y) / (1.0 - center_actual.y);
    }
    COLOR = texture(TEXTURE, adjusted_uv);
}

```
> 1 votes

---
Tags: shaders, glsl, fragment-shader
---


# Question
Title: Is it better to cut floor polygons where they're hidden under objects?
I have a floor that's interrupted by several objects sitting on top:

Would it be better for performance to let the floor polygons extend straight through the footprints of these objects? Or should I cut the floor polygons around any permanent objects that will cover up part of it?

# Answer
There are costs both ways.

If you leave an occluded polygon present, you may pay some fill rate / overdraw cost for it (time spent drawing floor pixels that will later be drawn-over by pixels of closer objects anyway). It might take up space in a lightmap that will never be seen, and could have been used to give better lightmap resolution to other parts of your scene.

If you cut it out, now you have more vertices and triangles to render. The cost for those isn't extreme, unless you're vertex bound, but it's not nothing. In particular, small, skinny triangles can add to your fill rate costs because you end up shading 2x2 blocks of pixels all along their edges for very few interior pixels that you actually keep.

Cutting also comes with development costs: each time you want to move objects around on the floor, you have to re-do your cuts, or you have to invest in some auto-cutting tech to do it for you, both of which are time spent not working on other features.

Which of these costs dominates can be situational, so the best way to get an answer to any performance question is to build a test and profile it, to measure which way performs better in your actual situation.

If you asked me to make a bet, I'd say the situation you've shown is not worth worrying about. There's only a tiny bit of overdraw you'd save, and it would come at the cost of adding a lot more triangles to the floor. I wouldn't worry about it until your profiling tells you that you're fill rate bound and ending up with a lot of unnecessary overdraw.
> 2 votes

---
Tags: rendering, performance, lighting, 3d-modeling
---


# Question
Title: Best file format for short audio clips in a video game
I am writing a video game to teach kids how to read, and as part of that I have to play short audio clips that make basic sounds. For example, the /t/ sound (the first sound in "Tiger").

I will also play longer syllable sounds, like "strong" and "est". And finally I will play full word sounds, like "brontosaurus" (a little over 1 second in length).

I've read that latency can be an issue with shorter sounds, so it's best to use a non-compressed file format like .wav for short files. The files will be larger, but the impact on disk storage won't be so much since the audio files are short.

For longer sounds like "brontosaurus", I would be inclined to keep using the same file format (.wav) just for consistency of sound assets. But I will have over 5000 words being said in my program, and so disk space may become an issue. If so, I could use a compressed format and perhaps preload it.

I have spoken dialogue in the game as well, but plan to just use mp3 for that. A small delay there would be fine.

Does it make sense to use .wav for all shorter sounds? Is there a number of seconds at which it makes sense to switch to a compressed audio format?

# Answer
It is ultimately your call. One notable consideration is where and how you will deploy it.

It should not be hard to extrapolate the size of wav files based on their duration and bit rate since they are not compressed. And use that information to make your decision.

A quick back of the envelope computation tells me that all the audio should be less than a couple gigas in storage. Which might be acceptable, or might not. You decide.

---

Yet, I have something to add: consider ogg. The codec is free, gratis, libre. And it gives you good quality for its compression, which you can take advantage of to have less playback latency than mp3 of similar quality.

*At the same bit rate the ogg might actually be larger, but sound better to the human ear, than the mp3. So might be able to go for a lower bit rate, and it will have less playback latency chiefly by being lighter. Tweaking and testing required.*

---

> Does it make sense to use .wav for all shorter sounds?

Sure.

---

> Is there a number of seconds at which it makes sense to switch to a compressed audio format?

Nope.

Instead, for music you usually don't worry about playback latency… Unless you need to sync the game with music (i.e. rhythm games). *A workaround being having the music compressed so it takes less storage, but when you need a song, you delaying the gameplay until you uncompress the music in memory and get it ready for playback.*

But for a sound effects - in particular in action heavy games - you do care that they have low playback latency (e.g. you want to hear an impact when you see it on the screen, similarly you don't want to hear an in game gun shot late).

Thus, it is first a matter of use case. Not of length of the audio.

---

Your game might not be an action heavy one. Thus, it could be that timing does not matter as much for your game. In which case, you can go ahead and use audio compression.

Or it might be that audio quality does not matter as much… If it is all uniform clear speech without much noise, you might get some good compression while still having an acceptable quality. Again, tweaking and testing required.

Similarly, if you need to deploy to a platform that is sensible to storage (e.g. mobile) you might have to compress the audio to an acceptable size despite the latency and drop in quality.
> 1 votes

# Answer
It's not too difficult to decompress an audio file at load time. There's obviously some CPU cost, but for short files that shouldn't be significant.

I'd therefore suggest:

1. Record all the audio as uncompressed wav files. That way you can play with compression settings to trade off file size vs. quality later on.
2. Start with the simple option of compressing all of the audio using something like Ogg Vorbis or mp3.
3. For any cases where you have performance/latency issues, consider:
    * Loading latency sensitive audio files into memory in advance instead of streaming them from disc. The file I/O will probably add more latency than the decompression.
    * If need be decompress them at load time too. Playing uncompressed audio also helps with the CPU cost.
    * If loading takes too long, then consider storing them decompressed, or loading them on a background thread.

One thing to note with latency is that a typical game rendering process will have some latency, which can easily add up to 50ms or more at 60 FPS, so having a little bit of audio latency can actually mean that you're better synchronized with the graphics!
> 1 votes

---
Tags: audio
---


# Question
Title: How to make object movable only by the player?
I'm trying to let the player of my PhaserJS game (with MatterJS physics) **move a (static?) object** around. That is: the player is allowed to move the object, but otherwise it should be `static` to the world of MatterJS. Here's a minimal scenario reproducing my situation:

```
class MyScene extends Phaser.Scene {
  create() {
    this.matter.add.rectangle(60, 120, 100, 10).isStatic = true;
    this.matter.add.pointerConstraint({ /* solve it here?! */ });
  }

  dropBall() {
    this.matter.add.circle(150, 20, 10);
  }
}

const game = new Phaser.Game({
  banner: false,
  width: 300,
  height: 150,
  physics: {
    default: 'matter',
    matter: { debug: true, setBounds: true },
  },
  scene: [MyScene]
});

document.addEventListener("DOMContentLoaded", () => {
  document.getElementById("start").addEventListener("click", () => {
    game.scene.getScenes(false)[0]?.dropBall();
  });
});
```

```
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/3.55.2/phaser.min.js"></script>
<div>1. Move platform to middle. 2. Then <button id="start">Drop a ball!</button></div>
```

I want the player to *only* be able to move the `static` rectangle around with the mouse. Technically the ball-dropping feature in my example is not needed for the question, but I'd hope it gives some context. Plus it shows that the `pointerConstraint` does *something* because you now *can* move the balls around (which shouldn't be possible).

# Answer
> 2 votes
If you want to use the builtin phaser functions, you just need to create a *phaser-matter-gameboject*, like an image (link to the documentation), and that you configer it to be draggable.

1. create matter-image
2. make image interactive `setInteractive`
3. make image draggable `this.input.setDraggable(...)`
4. in the `drag` Event update the position of the image

**Here a short demo, showcasing this:**
*(based on your codesnippet)*

```
class MyScene extends Phaser.Scene {
  create() {
    // START - just creating an image for the demo
    let graphics  = this.make.graphics();
    graphics.fillStyle(0xffffff);
    graphics.fillRect(0, 0, 100, 10);
    graphics.generateTexture('paddle', 100, 10);
    // END - just creating an image for the demo

    let paddle = this.matter.add.image(60, 120, 'paddle').setStatic(true);

    paddle.setInteractive();
    this.input.setDraggable(paddle);

    this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
        paddle.x = dragX;
        paddle.y = dragY;
    });
  }

  dropBall() {
    this.matter.add.circle(150, 20, 10);
  }
}

const game = new Phaser.Game({
  banner: false,
  width: 300,
  height: 150,
  physics: {
    default: 'matter',
    matter: { debug: true, setBounds: true },
  },
  scene: [MyScene]
});

document.addEventListener("DOMContentLoaded", () => {
  document.getElementById("start").addEventListener("click", () => {
    game.scene.getScenes(false)[0]?.dropBall();
  });
});
```

```
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/3.55.2/phaser.min.js"></script>
<div>1. Move platform to middle. 2. Then <button id="start">Drop a ball!</button></div>
```

---
Tags: phaser
---


# Question
Title: Creating custom types that extend certain objects
Really new to C# scripting. I'm trying to extend a `TileBase` type object to be able to hold custom methods and variables.

I want to create a pathfinding script and I need to store certain information for each tile. Something like this:

```
TileBase startPoint = tilemap.GetTile (tilemap.WorldToCell (transform.position));

startPoint.customVariable = 5;

```

Is there a way to extend TileBase into a new type and create custom methods inside it? How can I achieve this in Unity?

# Answer
Tiles are Scriptable Objects in Unity. See official manual: https://docs.unity3d.com/Manual/Tilemap-ScriptableTiles.html

So yes, you can extend either TileBase or Tile. The manual has an example: https://docs.unity3d.com/Manual/Tilemap-ScriptableTiles-Example.html

Essentially:

```
using UnityEngine;
using UnityEngine.Tilemaps;

public class MyTile : Tile {
   [SerializeField] private int movementCost { get; }

   [...the rest...]
}

```
> 0 votes

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


# Question
Title: "Graphics device is null" error on a Linux dedicated server build
In my project I am trying to build a dedicated server build to deploy to Multiplay hosting services.

Build target is Linux OS,build settings are default, scripting backend set to IL2CPP.

When `Addressables.InstantiateAsync()` is being called for the first time, or when `Resources.Load()` gets called, a "Graphics device is null" error is fired and the server crashes. Here are the logs: When using `Addressables.InstantiateAsync().WaitForCompletion()` :

```
Graphics device is null.
UnityEngine.ResourceManagement.ResourceProviders.AssetBundleResource:GetAssetBundle()
UnityEngine.ResourceManagement.ResourceProviders.AssetBundleResource:WaitForCompletionHandler()
UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1:WaitForCompletion()
UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle:WaitForCompletion()
UnityEngine.ResourceManagement.AsyncOperations.GroupOperation:InvokeWaitForCompletion()
UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1:WaitForCompletion()
UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1:WaitForCompletion()
UnityEngine.ResourceManagement.AsyncOperations.ProviderOperation`1:InvokeWaitForCompletion()
UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1:WaitForCompletion()
UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1:WaitForCompletion()
UnityEngine.ResourceManagement.InstanceOperation:InvokeWaitForCompletion()
UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1:WaitForCompletion()
UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1:WaitForCompletion()
<OnAllocate>d__5:MoveNext()
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Runtime.CompilerServices.MoveNextRunner:Run()
System.Threading.Tasks.AwaitTaskContinuation:RunOrScheduleAction(Action, Boolean, Task&)
System.Threading.Tasks.Task:FinishContinuations()
System.Threading.Tasks.Task`1:TrySetResult(TResult)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:SetResult(TResult)
Unity.Services.Multiplay.Internal.<GetPayloadAllocationAsPlainText>d__9:MoveNext()
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Runtime.CompilerServices.MoveNextRunner:Run()
System.Threading.Tasks.AwaitTaskContinuation:RunOrScheduleAction(Action, Boolean, Task&)
System.Threading.Tasks.Task:FinishContinuations()
System.Threading.Tasks.Task`1:TrySetResult(TResult)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:SetResult(TResult)
Unity.Services.Multiplay.Apis.Payload.<PayloadAllocationAsync>d__7:MoveNext()
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Runtime.CompilerServices.MoveNextRunner:Run()
System.Threading.Tasks.AwaitTaskContinuation:RunOrScheduleAction(Action, Boolean, Task&)
System.Threading.Tasks.Task:FinishContinuations()
System.Threading.Tasks.Task`1:TrySetResult(TResult)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:SetResult(TResult)
Unity.Services.Multiplay.Http.<MakeRequestAsync>d__1:MoveNext()
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Runtime.CompilerServices.MoveNextRunner:Run()
System.Threading.Tasks.AwaitTaskContinuation:RunOrScheduleAction(Action, Boolean, Task&)
System.Threading.Tasks.Task:FinishContinuations()
System.Threading.Tasks.Task`1:TrySetResult(TResult)
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:SetResult(TResult)
Unity.Services.Multiplay.Http.<CreateWebRequestAsync>d__3:MoveNext()
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Runtime.CompilerServices.MoveNextRunner:Run()
System.Threading.ThreadPoolWorkQueue:Dispatch()

[ line 729763672]

```

Then I was able to solve this by replacing the `WaitForCompletion()` with awaiting the Task (`await taskName.Task`), but encounter this error when starting up a session in Photon Fusion:

```
   Graphics device is null.
UnityEngine.Resources:Load(String)
Fusion.<>c:<Reload>b__6_0()
System.Lazy`1:ViaFactory(LazyThreadSafetyMode)
System.Lazy`1:CreateValue()
Fusion.NetworkProjectConfig:get_Global()
Fusion.NetworkRunner:StartGame(StartGameArgs)
ServerLauncher:StartSimulation(NetworkRunner, Int32, String, String, String, String, Dictionary`2, Int32)
<OnAllocate>d__5:MoveNext()
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Runtime.CompilerServices.MoveNextRunner:Run()
System.Threading.ThreadPoolWorkQueue:Dispatch()

```

The server runs in a batchMode, meaning the Launch Parameters are `-nographics -batchmode`.

It sounds like a very standard scenario, but I couldn't find any solution anywhere, including approaching the Multiplay support team.

Can someone shed some light on this?

# Answer
> 1 votes
Apparently, the issue was caused by not instantiating the assets from the main thread.

I made a custom implementation for forcing the method to run in the main thread, and it is now solved.

This is the class that I created to force a method to run in the main thread:

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

public class UnityMainThreadDispatcher : MonoBehaviour
{
public static UnityMainThreadDispatcher _instance;
private static Queue<System.Action> _actionQueue = new
   Queue<System.Action>();

private void Awake()
{
    if (!Application.isBatchMode)
    {
        Destroy(this.gameObject);
    }

    if (_instance != null)
    {
        Destroy(gameObject);
    }
    else
    {
        _instance = this;
        DontDestroyOnLoad(gameObject);
    }
}

void Update()
{
    lock (_actionQueue)
    {
        while (_actionQueue.Count > 0)
        {
            _actionQueue.Dequeue().Invoke();
        }
    }
}

public void ExecuteOnMainThread(System.Action action)
{
    lock (_actionQueue)
    {
        _actionQueue.Enqueue(action);
    }
}
}

```

Then, for all the code that I want to force to the main thread, I use this:

```
        UnityMainThreadDispatcher._instance.ExecuteOnMainThread(async () =>
    {
       // Enter code here
    });

```

---
Tags: unity, multiplayer, assetbundle, addressable
---


# Question
Title: Force Feedback on joystick device using SharpDX DirectInput API
# The Goal (for context)

Get input from a USB joystick device in the Unity Game Engine and activate Force Feedback functionality on the joystick from Unity.

# The Method

I am using the SharpDX.DirectInput managed library to access DirectX. Using Direct Input was listed as the only USB solution the device currently supports according to the response I got from the company who makes the device. (The device was initially developed for use with specific simulator applications, not generic use. I did not make the decision of using this device with the simulation we are developing).

From all my research, SharpDX seems to be the best option as it's the most recently supported managed wrapper for DirectX and it was recommended by the the device's support team.

# Where I'm At

After a week of struggling I have been able to successfully get input from the device via SharpDX. It's been an uphill battle against limited documentation and my own inexperience in this area but I was able to finally decipher examples to get that working. I have also been able to confirm, via SharpDX, that the device has force feedback capabilities.

However, I can't find even a single code example for sending force feedback commands via SharpDX even though it is supposedly possible (there are various structs, enums, classes, and methods that all seem to be related to it within the SharpDX API).

The only code sample I found was using the DirectX 9.0 for managed code API. I was not able to translate it to SharpDX. (The answer also included a link to two other supposedly useful examples, one here, and one resurrected from the Internet Archive here both of which appear to be using the DirectX 9.0 API).

I have every reason to believe that it is possible but haven't been able to figure it out of my own accord. Any input, advice, or directions would be very much appreciated. Thanks in advance!

# Answer
I have succeeded in my efforts and wanted to share my code incase anyone else is ever doing this again.

To recap, I am scripting in C# using the SharpDX.DirectInput library. Additionally, for context, the device I am interfacing with is a Brunner CLS-E MK II Rudder with Toe Brakes which has been put in DirectX Mode. The 'rudderDeviceName' in this case is thus "CLSE MK II Rudder DirectX".

This script is placed on a GameObject in the Unity Game Engine.

Please note that I'm still working through the exact units which the effect parameters need to be sent in and this only includes and example of the periodic force effect. That being said, this should go a long way to getting someone started with what they are trying to do.

using System;
using System.Linq;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using SharpDX.DirectInput;

public class PedalManager : MonoBehaviour
{
    [SerializeField] string rudderDeviceName;
    [SerializeField] TextMeshProUGUI steerText;
    [SerializeField] TextMeshProUGUI leftBrakeText;
    [SerializeField] TextMeshProUGUI rightBrakeText;

    Joystick rudder;
    Effect effect;
    EffectParameters effectParams;
    PeriodicForce periodicForce;
    Envelope envelope;

    int[] actuators;
    int[] dirVector;

    [SerializeField] float duration = 5;
    [SerializeField] float fadeIn = .2f;
    [SerializeField] float fadeOut = .2f;
    [SerializeField] int direction = 0;
    [SerializeField] float gain = 50;
    [SerializeField] float amplitude = 50;
    [SerializeField] float frequency = 10; //hz
    [SerializeField] float phase = 0;
    [SerializeField] float offset = 0;

    int AttackTime => (int)(duration / 2 * fadeIn * 10000);
    int ReleaseTime => (int)(duration / 2 * fadeOut * 10000);
    int Direction => (direction + 180) * 100;
    int Gain => (int)(gain * 100);
    int Duration => (int)(duration * 1000000); //seconds -> microseconds
    int Amplitude => (int)(amplitude * 100);
    int Period => (int)(1.0 / frequency * 1000000);
    int PeriodicOffset => (int)(offset * 100);
    int Phase => (int)(phase * 100);

    bool isAcquired = false;

    private void Start()
    {
        SetupDevice();
        AcquireDevice();
        InitTestEffect();
    }
    private void OnEnable()
    {
        AcquireDevice();
    }
    private void Update()
    {
        if(rudder != null && isAcquired)
        {
            JoystickState joyState = rudder.GetCurrentState();
            steerText.text = joyState.X.ToString();
            leftBrakeText.text = joyState.RotationX.ToString();
            rightBrakeText.text = joyState.RotationY.ToString();
        }
    }
    private void OnDisable()
    {
        StopEffect();
        ReleaseDevice();
    }

    void SetupDevice()
    {
        DirectInput directInput = new DirectInput();

        Debug.Log(string.Format("Searching for {0}...", rudderDeviceName));
        DeviceInstance rudderInstance = directInput
            .GetDevices(SharpDX.DirectInput.DeviceType.Joystick, DeviceEnumerationFlags.AllDevices)!
            .First(d => d.InstanceName == rudderDeviceName);

        if (rudderInstance == null)
        {
            Debug.Log("Rudder device not found, cannot continue.");
            return;
        }
        Debug.Log(string.Format("Found device \"{0}\"", rudderInstance.InstanceName));

        rudder = new Joystick(directInput, rudderInstance.InstanceGuid);

        rudder.Properties.AxisMode = DeviceAxisMode.Absolute;
        rudder.SetCooperativeLevel(GetActiveWindow(), CooperativeLevel.Exclusive | CooperativeLevel.Background);
        rudder.Properties.BufferSize = 128;
    }
    void AcquireDevice()
    {
        if(rudder != null && !isAcquired)
        {
            rudder.Acquire();
            isAcquired = true;
            Debug.Log("Device acquired.");
        }
    }
    void ReleaseDevice()
    {
        if (rudder != null && isAcquired)
        {
            rudder.Unacquire();
            isAcquired = false;
            Debug.Log("Device Released.");
        }
    }

    void InitTestEffect()
    {
        effectParams = new EffectParameters();
        periodicForce = new PeriodicForce();
        envelope = new Envelope();
        CreateTestEffect();
    }
    void CreateTestEffect()
    {
        if (!isAcquired)
            return;
        if (effect != null)
        {
            effect.Stop();
            effect.Unload();
            effect.Dispose();
        }
        var deviceObjs = rudder.GetObjects().ToList().Select(o => o.ObjectId).ToList();
        List<int> intList = deviceObjs
            .FindAll(o => o.Flags.HasFlag(DeviceObjectTypeFlags.ForceFeedbackActuator))
            .Select(o => (int)o).ToList();
        actuators = intList.ToArray();
        dirVector = Enumerable.Repeat(Direction, intList.Count).ToArray();

        envelope.AttackLevel = 0;
        envelope.FadeLevel = 0;
        envelope.AttackTime = AttackTime;
        envelope.FadeTime = ReleaseTime;

        effectParams.Flags = EffectFlags.Polar | EffectFlags.ObjectIds;
        effectParams.Duration = Duration;
        effectParams.Gain = Gain;
        effectParams.SetAxes(actuators, dirVector);
        effectParams.SamplePeriod = 0;
        effectParams.StartDelay = 0;
        effectParams.TriggerButton = -1;
        effectParams.TriggerRepeatInterval = 0;
        effectParams.Envelope = envelope;

        periodicForce.Magnitude = Amplitude;
        periodicForce.Offset = PeriodicOffset;
        periodicForce.Phase = Phase;
        periodicForce.Period = Period;

        effectParams.Parameters = periodicForce;

        Guid guid = EffectGuid.Sine;

        effect = new Effect(rudder, guid, effectParams);
        Debug.Log("Periodic effect created.");
    }

    [ContextMenu("Play FFB Effect")]
    public void PlayEffect()
    {
        Debug.Log("Starting FFB effect");
        CreateTestEffect();
        effect.Start(1);
    }
    [ContextMenu("Stop FFB Effect")]
    public void StopEffect()
    {
        Debug.Log("Stopping FFB effect");
        if (effect != null)
            effect.Stop();
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();
}

```

> 1 votes

---
Tags: input, sharpdx, joystick, directinput, force-feedback
---


# Question
Title: What's the difference between FindObjectsByType and FindObjectsOfType?
FindObjectsOfType and FindObjectsByType look very similar, both in name and in usage. The only difference I noticed is that `FindObjectsByType` takes a `sortMode` parameter that says:

> Whether and how to sort the returned array. Not sorting the array makes this function run significantly faster.

The documentation for `FindObjectsOfType` recommends using `FindObjectsByType` instead:

> **Note:** This function is very slow. It is not recommended to use this function every frame. In most cases you can use the singleton pattern instead.
>
> It is recommended to use `Object.FindObjectsByType` instead. This replacement allows you to specify whether to sort the resulting array. `FindObjectsOfType()` always sorts by `InstanceID`, so calling `FindObjectsByType(FindObjectsSortMode.InstanceID)` produces identical results. If you specify not to sort the array, the function runs significantly faster, however, the order of the results can change between calls.

What are the advantages of one vs the other?

# Answer
When you want to know the rationale for a particular addition to the API, a good place to start is the release notes for the relevant update. I found this just by searching "unity findobjectsbytype":

> Scripting: Added: New `Object.FindObjectsByType()` function added as a potentially faster alternative to `Object.FindObjectsOfType()`. This new function gives users the choice whether or not to perform the expensive sorting by `InstanceID` on the returned collection of objects rather than having it always performed, wasting time when unnecessary. See the scripting documentation for `Object.FindObjectsByType()` and `Object.FindObjectsOfType()` for more details.

This is similar to the rationale for adding FindFirstObjectByType and FindAnyObjectByType, which were introduced in the same update (2021.3.18).

I'd suspect these additions indicate that under the hood, Unity changed the way that the game objects in open scenes and their components are stored in memory, or the acceleration structures for searching them, in such a way that made it significantly faster to get them in an unordered fashion, but slower to get them in a stable/consistent order. Since for many common use cases we don't care about order, this lets the developer take the fast path when suitable.

They couldn't just change the behaviour of the existing functions though, because that could be a breaking change for old code that relied on the fact that the old methods returned objects in a stable order — wreaking havoc on projects in development that try to update their version, or on who knows how many third-party assets and plug-ins on the Asset Store or tutorials that are not being actively maintained. So they kept the old functions behaving as-is and made a new more explicit API for new code.

I wouldn't be surprised if, in future Unity versions, the old `FindObjectOfType`/`FindObjectsOfType` APIs are deprecated, and either automatically upgraded to the equivalent new versions, or made to generate compiler warnings - that way a developer is prompted to examine each call site to determine whether stable ordering is needed for that case, letting them explicitly opt into the fast or slow paths as needed (or refactor their approach if necessary to enable taking the fast path). The team might be giving some time to battle-test the new APIs or stabilize other parts of the engine before taking this step, or giving asset developers time to update voluntarily, so as to minimize the warning spam and disruption when the old API is eventually deprecated. That's just my guess, though.

**tl;dr:** there's *no reason* to continue to use the old `FindObjectsOfType` API. New code should use the more explicit `FindObjectsByType` API exclusively, making use of the faster `FindObjectsSortMode.None` option whenever possible.

In rare cases where you *do* need a stable ordering, passing `FindObjectsSortMode.InstanceID` makes that requirement explicit, so it's clear you're not taking the slow path by accident, as was possible with `FindObjectsOfType`.
> 10 votes

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


# Question
Title: Is it necessary to unsubscribe from C# events when the event owner has already been destroyed?
The following code throws a null reference exception when I stop the project because `touchInterfaceController` has already been destroyed.

```
private void OnDestroy()
{
    touchInterfaceController.Pitch.OnInput -= OnTouchPitchInput;
    touchInterfaceController.Thrust.OnThrustInput -= OnTouchThrustInput;
}

```

Is it safe to simply check for null and in that case not bother to unsubscribe? i.e.

```
if (touchInterfaceController == null) return;

```

Both `touchInterfaceController` and the script which contains this code will be destroyed, and usually will be re-instantiated in the next scene.

# Answer
> 3 votes
Expanding on the answer I gave here, we can test this by using a script that holds references to both a publisher and subscriber "gently" and then checks whether they've been successfully claimed by the garbage collector after destruction.

```
using System.Collections;
using UnityEngine;

public class SubscriptionTest : MonoBehaviour
{

    public bool killPublisherFirst;

    System.WeakReference publisherRef;
    System.WeakReference subscriberRef;

    void Start()
    {
        var publisher = new GameObject("Publisher").AddComponent<Publisher>();
        var subscriber = new GameObject("Subscriber").AddComponent<Subscriber>();

        publisherRef = new (publisher, false);
        subscriberRef = new (subscriber, false);

        publisher.MyEvent += subscriber.DoThing;

        StartCoroutine(Monitor());
    }

    IEnumerator Monitor() {

        if (killPublisherFirst) {
            yield return KillAndReport(publisherRef);
            yield return KillAndReport(subscriberRef);
        } else {
            yield return KillAndReport(subscriberRef);
            yield return KillAndReport(publisherRef);
        }
    }

    IEnumerator KillAndReport(System.WeakReference toKill) {
        yield return new WaitForSeconds(0.5f);

        {
            var victim = (Component)toKill.Target;
            Debug.Log($"Killing {victim.name}");
            Destroy(victim.gameObject);
        }

        yield return new WaitForSeconds(0.5f);

        Debug.Log($"After destroy, publisher is alive: {publisherRef.IsAlive} / subscriber: {subscriberRef.IsAlive}");

        System.GC.Collect();

        Debug.Log($"After collect, publisher is alive: {publisherRef.IsAlive} / subscriber: {subscriberRef.IsAlive}");

        yield return new WaitForSeconds(0.5f);

        Debug.Log($"After delay, publisher is alive: {publisherRef.IsAlive} / subscriber: {subscriberRef.IsAlive}");
    }
}

public class Subscriber : MonoBehaviour {

    public void DoThing() {
        Debug.Log("Did the thing.");
    }
}

public class Publisher : MonoBehaviour {
    public event System.Action MyEvent;
}

```

The upshot, if we don't explicitly unsubscribe:

* When destroying the object with the event (the publisher), that object can be claimed by the garbage collector immediately.
* When destroying the object subscribing to the event (the subscriber), that object cannot be claimed until the publisher is also destroyed.
* After both objects have been destroyed, the garbage collector can successfully claim them both, regardless of the order in which they were destroyed.

So:

* It's good to unsubscribe if the subscriber is the first to be destroyed. (This keeps the subscriber's ghost from lingering in memory until the publisher is also destroyed - which might take until the scene is unloaded, or when the game is shut down, whichever happens first).
* If the publisher was the first to die (`== null`), it's safe to skip unsubscribing. No lingering references remain to be cleaned up.

The same goes for `UnityEvent`, so they don't behave materially differently from standard C# events in this regard.

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


# Question
Title: Data structure for storing / looking up type objects representing different item types
I'm still learning C++ and am no way an expert so I could be conceptualizing this wrong.

I'm having trouble getting the right data structure for items in my game. I don't need actual object instance data (x, y, z locations etc. There's an "item" object that just gets filled with the data from the item table when an instance is created)

The type of system I want is similar to Bethesda's creation engine, where I could basically start an array from 0 and increment it as an item is added to the game. Then I could just make each item in the array a struct holding all the item's variables. The reason I'm doing it this way is it makes it simple to get an item variable: `item[56].size` returns that item's `size` variable. (Meaning its gameplay dimensions, not its memory footprint)

The issue I'm having is different types of items require different variables. So for weapons there would need to be a damage variable that wouldn't exist for say a healing potion, or a gun requires different variables than a chair. So my current solution is to have many different arrays of structs, each array containing its own struct base that has only the relevant variables for that type. This leads to an unconnected series of arrays that get called like item\_weapon\[22\].damage. I can't do a multi-dimensional array because it requires each type to have the same amount of items which they won't.

It'd be more ideal to just have 1 unified data structure holding all the items' data. (I would think, I'm still new to programming). So my idea would be to use an enum to increment the different types, then each enum holds an array of all the items of that type and each item in the arrays is a struct that only has variables similar to those in the same enum number. However my instinct is that doing this would still require each array to be the same length, but I'm not sure.

I can't find much on enum of arrays of structs. Is there a better solution? Is this maybe too complicated or not a good idea? Any help would be appreciated!

# Answer
> 1 votes
**Disclaimer:** I'm not fluent in C++ myself, so I'm going to describe high-level strategies, but I'd welcome edits or alternative answers from C++ experts regarding exact implementation considerations and syntax.

---

If your item types are similar in total memory footprint, you might want to try making your array of item type data hold entries of type `std::variant<Weapon, Potion, etc...>`, which is effectively a type-safe tagged union of multiple types.

It has a memory footprint equal to the largest of its constituent types, plus an index to identify which type it's storing currently, plus padding for alignment if necessary. So it's not such a great choice if some items need 100 variables but most others need 0 — you end up leaving "empty slots" for those extra variables in every array index that's storing a smaller item type. But if you have fewer than a thousand item types or the biggest item type is still smaller than a kilobyte then even that might be an acceptable trade-off for the simplicity and convenience it offers.

---

If you *require* **dense storage** (because you have many thousands of item types, or some item types need megabytes of memory, or you're targeting a very memory-constrained environment like a retro console, or these items are iterated in a hot path where using full cache lines is critical to performance), then like many things in programming, it can be solved by adding another layer of indirection.

Each entry in the item types array stores a pair of two values: an enum value identifying the item's "meta-type" (eg. Weapon, Potion...), and an index identifying the item type's position in a separate array specific to that meta-type. It can also store any variables that are common to *all* item meta-types (eg. localized name, icon, sale value, quest item flags, weight), or those can be stored in parallel array(s) for an SoA approach.

To look up the weapon damage value of "BroadSword" = item type #56, you confirm/assert that `itemTypes[56].metaTypeId == Weapon`, then look up `WeaponTypes[itemTypes[56].subIndex]` to get the `WeaponTypeData` associated with that type. This allows you to have densely packed arrays of each meta-type, of potentially different lengths, while still addressing them all uniquely from one primary item type enumeration as a lookup key.

This indirection has a cost, but a modest one. Because you have dense storage, non-random access patterns (you'll likely hit the weapon and armour tables repeatedly when evaluating combat, without needing to load the gemstone, crafting ingredient, or quest item meta-type tables into cache), and no hashing/probing/searching, I'd wager this will outperform other classic approaches like a hashmap.

---

Another thing you may want to consider is **composition**: "has-a" relationships rather than "is-a". So an item that can be used as a melee weapon "isn't" itself a `MeleeWeapon` type, it "has" a `MeleeDamage` component. Each item type is then a collection of components (could be a vector of pointers/references to those component instances, or similar to the above, it could be an index or reference to an "Archetype" containing parallel arrays of a specific subset of component types, plus an index into that collection).

This style is commonly used in Entity Component System approaches in games, and makes it easier to support "hybrid" items, like a spiked shield with both defensive and offensive stats, a gunblade or bayonet with both ranged and melee attacks, or a potion you can both drink and throw as a grenade, without needing to make hard-coded specialized types for each of these combinations. This encourages code re-use, and can enable remixing by designers/modders/players to craft novel items without writing new code.

But if you only need a closed set of a few item meta-types with little to no overlap in behaviours, then that's probably over-engineering for your needs.

---
Tags: c++, data-structure
---


# Question
Title: MissingReferenceException: The object of type 'CapsuleCollider' has been destroyed but you are still trying to access it
i use this code , but when the health is below to 0 and destroy the gameobject , unity show the error "MissingReferenceException: The object of type 'CapsuleCollider' has been destroyed but you are still trying to access it."

```
void OnTriggerEnter(Collider other)
    {
        if (canAttack && other.CompareTag("Player"))
        {
            canAttack = false;
            if(other != null)
            {
                StartCoroutine(AttackPlayer(other));
            }
        }
    }
    IEnumerator AttackPlayer(Collider playerCollider)
    {
        while (true)
        {
            playerCollider.GetComponent<Player>().TakeDamage(damageAmount);
            yield return new WaitForSeconds(0.1f);
        }
    }

```

and i alreally check the colider is null before.

here is the player script

```
public void TakeDamage(float damage)
    {
        Health -= damage;
        if (Health < 0)
        {
            Die();
        }
    }

    private void Die()
    {
        Destroy(gameObject);
    }

```

i try to check is null still no work, no debug log

IEnumerator AttackPlayer(Collider playerCollider)
    {

        while (true)
        {
            if (playerCollider.gameObject == null)
            {
                Debug.Log("111");
                yield break;
            }
            playerCollider.GetComponent<Player>().TakeDamage(damageAmount);
                yield return new WaitForSeconds(AttackSpeed);
        }
    }
```
</code></pre>

# Answer
If the player has been destroyed (eg. by taking lethal damage), then every component attached to the player will be treated as null, including the player collider.

Once the collider is being treated as null, trying to use the dot operator to access *anything* about the collider will throw an exception. That includes:

* `playerCollider.GetComponent<Player>()` \- if `playerCollider` is `null`, then this is `null.GetComponent`, and `null` does not have a `getComponent` method --\> exception!
* `playerCollider.gameObject == null` \- if `playerCollider` is `null`, then this is `null.gameObject`, and `null` does not have a `gameObject` member --\> exception!

So if you think something could have been destroyed, don't use the dot operator! Check it for null first!

A better version of this code would look like this:

```
void OnTriggerEnter(Collider other)
{
    // You know players have the Player component, so check for that, not a tag.
    if (canAttack && other.TryGetComponent(out Player player))
    {
        canAttack = false;
        // Now we can pass the player component itself to the attack function.
        StartCoroutine(AttackPlayer(player));
    }
}

IEnumerator AttackPlayer(Player player)
{
    // If the player is killed, STOP LOOPING.
    while (player != null)
    {
        // No more GetComponent() search in the middle of the loop.
        player.TakeDamage(damageAmount);

        // You could construct the wait once and cache it.
        yield return new WaitForSeconds(0.1f);
    }

    // My target is dead, I can try to attack a different target now.
    canAttack = true;
}

```
> 1 votes

---
Tags: unity
---


# Question
Title: ProBuilder objects ignores draw order overrides
I have a shader which has the `ZTest` property set to always which allows me to draw an object on top of every other object. This works perfectly with all objects except ones created with ProBuilder.

Why does that happen and how do I go about fixing it?

UPDATE: i'm using a Universal render pipeline

# Answer
> 1 votes
Depth Testing is not the same as draw order.

Changing the depth testing mode does not change when this item draws. It just says, when it *does* draw, how should it behave with respect to content that was already drawn to the depth buffer before it?

So Depth Test: Always means "always draw over everything that was drawn before me".

It says nothing about content that gets drawn *after*.

You could block any content from drawing after - by setting the Depth Write to output a depth at the camera near plane, so everything else will get depth culled, or by using a stencil value / stencil test on all your other content.

Or you could arrange things so that this item draws *last*, after anything that could potentially occlude it.

In the old built-in render pipeline, when writing shaders as text code, this was done using the "Queue" tag in ShaderLab or material.renderQueue. The various implementations of graph shaders each have their own ways of controlling draw order, so we'll need a bit more detail in your question to be able to suggest the right one for the shader graph you're authoring.

---
Tags: unity, shaders
---


# Question
Title: Notification function doesn't work as intended in Godot
I have a situation where `_notificaion` doesn't work as intended.

I have three scenes: game scene (named `Puzzle`), main menu scene (`MainMenu`) and `Victory` scene.

When player on android phone presses back key on Puzzle, he/she gets back to MainMenu.

I use this code inside `_notification` and it works fine.

```
if what == MainLoop.NOTIFICATION_WM_GO_BACK_REQUEST:
   get_tree().change_scene("res://scenes/MainMenu.tscn")

```

When puzzle is solved, I add Victory scene to the root node by using `get_tree().root.call_deferred('add_child', victoryScene)` while puzzle screen is the current scene. Then, after victoryScene finishes its `start_animation`, I remove puzzle from root by `queue_free` using a signal called '`finished`' that is emitted when start\_animation is completed.

The issue I encounter is that I am using the same code of going back to `MainMenu` inside `_notification` function of `victoryScene`, but it doesn't work.

I tried using the following code inside `_notification` of Puzzle and Victory, and it worked fine while testing scenes individually using play scene button.

```
if get_tree().current_scene.name == "Puzzle":
    get_tree().change_scene("res://scenes/MainMenu.tscn")

```

However, I get an error saying that `get_tree().current_scene` is `null` when I use play project button.

# Answer
> 2 votes
You have described that you got rid of the current scene:

> When puzzle is solved, I add Victory scene to the root node by using `get_tree().root.call_deferred('add_child', victoryScene)` while **puzzle screen is the current scene**. Then, after victoryScene finishes its `start_animation`, I **remove puzzle from root by `queue_free`** using a signal called '`finished`' that is emitted when start\_animation is completed.

*Emphasis mine.*

Since you freed the current scene, `get_tree().current_scene` becomes invalid.

---

You could, for example, tell Godot that the `victoryScene` is the current scene when you call `queue_free` on the puzzle scene:

```
get_tree().current_scene = victoryScene

```

---

About the back button, you could have a field in the `victoryScene` that stores where to go back to. For example:

```
var back_button_scene:String

```

So you can do this:

```
if back_button_scene != "":
    get_tree().change_scene(back_button_scene)

```

And have the puzzle scene set it:

```
victoryScene.back_button_scene = "res://scenes/MainMenu.tscn"

```

And you would do something similar everywhere you need the `victoryScene`.

---

I submit to your consideration to have an autoload (singleton) handle all this logic, in such way that nothing access `get_tree().current_scene` and related methods except said the autoload.

*So, either the other scenes call the autoload, or the autoload handles the notifications directly. So you don't have to replicate this logic for every scene.*

*Since the autoload would be handling changes between scene, it could also implement loading screens and transitions (fades, et.al.).*

---
Tags: android, godot, gdscript
---