title: How to instantly break method call?

text:
# Question
Title: How to instantly break method call?
I'm making 2d Mobile game using JavaScript.

I have method that controls every character (Dumb AI) on battleground. It using recursion to call another action. I want to add debuff system and had little bit difficulty adding taunt (where close enemies are forced to attack specified enemy) and confuse (where enemy is attacking his ally). I want this to be instant. What I managed to do is make this happen after enemy finish his current action, but this behaviour is bad. I need somehow a way to break instantly current call, but I don't have idea how to do it as from my knowledge there isn't anything method that by reference can break JavaScript method, so I could start new one. I had some idea to use memory reference and kill it in memory, but that's where I was having some fun in my teenage years with cheat engine on some games, but this can raise other problem where the game would need access to memory and this would be bad for user and me.

What I can do achieve instant change of action?

Below my method that controls every character:

```
export const characterControl = async (characterData, closestEnemy, enemyCharacters, allies, characterControlId) => {
// my new attep to introduce a new variable called `characterControlId` where new method call would have new characterControlId and old one would be forced to stop.
   if(characterData.battleData.debuff && characterData.battleData.characterControlId !== characterControlId || isPaused || gamePause) {
       return;
   }

   if (checkIfBattleEnded(allies, enemyCharacters)) {
     /// code that stop all methods and game loop.
   }

   if (isBattleEnded) {
       return;
   }

   if (checkIfCharacterDied(closestEnemy)) {
          // code that find new enemy and start new action to move to him
   }
   let direction;

   switch (characterData.battleData.action) {
       case "attack":
// this handle logic to switch character Spine2d animation to attack and deal dmg to enemy
           return attackEnemy(characterData, closestEnemy, enemyCharacters, allies);
       case "move-ally":
           // testing new approach where this gonna switch Spine2d animation to run character towards his closest ally.

           return moveCharacter(characterData, closestEnemy, enemyCharacters, allies, direction, true);
       case "attack-ally":
// new approach where this logic gonna switch Spine2d animation to attack and inflict dmg to his ally.

           return attackEnemy(characterData, closestEnemy, enemyCharacters, allies, true);
       // case "taunted":
       //     return attackEnemy(characterData, closestEnemy, enemyCharacters, allies);
       case "move":
// default approach to switch character spine2d animation to run towards closest enemy
           return moveCharacter(characterData, closestEnemy, enemyCharacters, allies, direction);
       case "skill":
// when mana is above 100% it gonna switch character animation to his skill.
           return useSkillNew(characterData, closestEnemy, enemyCharacters, allies);
       default:
// when action of character is undefined it gonna look for possibilities what he should do next. If he should run or can has enemy in range and can attack him.
           return setCharacterAction(characterData, closestEnemy, enemyCharacters, allies);
   }
}

```

# Answer
> 1 votes
It appears that you are trying to implement AI in form of some form of "coroutine". An asynchronous function that runs in parallel to the game and handles the AI of an entity. The problem with a coroutine-based AI is that it is not automatically aware of what else is happening in the game. So when there is some interruption condition, the coroutine is responsible for detecting that condition itself.

However, there are other patterns available for game AI that are far more adaptable, like finite-state machines or behavior trees.

Usually those patterns involve having some form of update-function for each AI actor that gets called once per game tick for each actor and checks if, given the current state of the game and of the actor, there is anything to do *on this particular* tick.

This can look like this (in pseudocode)

```
IF i am currently performing an attack THEN
    IF the current attack target is valid
    AND i am in a state that allows me to attack THEN
        advance the attack animation by one tick
    ELSE
        abort the attack

IF i am not currently performing an attack
AND i am in a state that allows me to attack THEN
   find the most appropriate attack target that is valid
   IF i have an attack target THEN
      start a new attack

```

The function which check if an attack target is "valid" would take into account if the character is currently affected by "taunt" or "charm" and decide accordingly which attack targets are valid and which are invalid.

---
Tags: javascript, spine, pixi.js
---


# Question
Title: How to make laser made by line renderer get a effect of continuous damage?
I tried to implement a way of laser attacking. the character will shoot a laser implemented by the line renderer. the laser can detect an enemy using raycast hit, but it seems can only damage once. how to achieve continuous damage? The code to shoot laser

```
if (Input.GetMouseButton(0))
    {
        lr.enabled = true;
        for (int i = 0; i < segmentCount; i++)
        {

            currentPosition = transform.position;
            for (int j = 0; j < i; j++)
            {
                currentPosition += resultVectors[j] * blockLength;
            }

            RaycastHit hit;
            if (Physics.Raycast(currentPosition, resultVectors[i], out hit, blockLength))
            {
                hitPosition = currentPosition + resultVectors[i] * hit.distance;
                hitPosition = Vector3.MoveTowards(hitPosition, transform.position, moveHitToSource);
                if (hitEffect)
                {
                    hitEffect.transform.position = hitPosition;
                }

                dist = Vector3.Distance(hitPosition, transform.position);

                if (hit.transform.gameObject.tag == "Enemy")
                {
                    hit.transform.GetComponent<enemyHealth>().takeDamage(20);
                }

                break;
            }
        }
        globalProgress = 0f;
    }

```

# Answer
```
 if (hit.transform.gameObject.tag == "Enemy" && timer<0)
                {
                    hit.transform.GetComponent<enemyHealth>().takeDamage(20);
                    timer = 1.5f;
                }

```

Add these codes to control the frequency of damage.
> -1 votes

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


# Question
Title: I cannot see my whole substance painter in any window
I cant really say anything else about it, every time I launch the program now, regardless of how, my windows show up like so:

# Answer
> 0 votes
Seems like an issue with your graphic card/cards. Try disabling the motherboard one if you have a gaming laptop and see if that helps.

---
Tags: substance-engine
---


# Question
Title: Use Graphics Raycaster do implement pointer control VR
I am trying to figure out how to allow my players to put in a code to join a group room using photon. Unity seems to suggest using a graphics raycaster but in most sample code it uses mouse input for the input data like in this example :

```
//Create the PointerEventData with null for the EventSystem
PointerEventData ped = new PointerEventData(null);
//Set required parameters, in this case, mouse position
ped.position = Input.mousePosition;

```

I have been able to interact by putting a collider on the UI element and a collider on the OVR Player's hand but how would I create a pointer like in oculus home to interact with the GUI ?

# Answer
> 1 votes
Sounds like you are using Oculus OVR, so then you can use OVR Ray interactions (documentation here)

If you instead wanna use Unitys XR Interaction Toolkit, your can use the XR Interaction (documentation here)

There is also similar things for Microsofts MRTK (documentation here).

---
Tags: unity, gui, input, virtual-reality, oculus
---


title: How do I implement HP bar using OpenGL?

text:
# Question
Title: How do I implement HP bar using OpenGL?
I got simple hp bar container from open game art, rendered the texture and now I am wondering how to fill it and change the amount of filling.

I decided to render red rectangle over the container and change its size programmatically via matrix modification. However, I am not sure if this is the best way. What if I want something fancier than simple red color, what if I want to fill HP bar with some kind of texture?

Note that I can only use OpenGL.

# Answer
For complex hp bars, I recommend using two images.

* Empty hp bar.
* Filled hp bar.

And draw them partially in x or y direction.

* You can use two quads, adjusting the vertex coordinates and texture limits, one on the left and the other one on the right.
* Or you can use a shader, that receives an offset uniform variable and two textures and draw one of them depending on the texture coords (u,v).

Note: you can also mix both images in one texture atlas.

**ONE TEXTURE WITH TWO VERTICAL IMAGES (empty/filled)**

By default, your quad will display both images. x between 0.0-1.0 and y between 0.0 and 1.0. They are the standard coordinates to render an image inside a quad.

First we need to draw only half of the image. So we narrow the texture component from 0.0-1.0 to 0.0-0.5. Simply dividing by two (because there are two images).

```
vec2 texCoord = vec2(vTextureCoord.x / 2.0, vTextureCoord.y)

```

or

```
vec2 texCoord = vec2(vTextureCoord.x / 2.0 + 0.0, vTextureCoord.y)

```

That will show the left image. To show the right one (filled), we need texCoord x in the range 0.5-1.0. That can be achieved adding an offset to skip the left part (1.0/2.0). 1 image skipped of two.

```
vec2 texCoord = vec2(vTextureCoord.x / 2 + 0.5, vTextureCoord.y)

```

So just changing the offset from 0.0 to 0.5, we can draw the left (0.0 offset) or the right image (0.5 offset).

We need an external filled value, between 0.0 and 1.0, because the texture range goes from 0.0 to 1.0. If filled is not in the range \[0.0-1.0\] you need to do some maths to transform in the 0.0-1.0 range. For vertical image, we compare the texture.y coordinate with the filled value, if y is above the filled limit, then we show the left one (empty) if not, we show the right one (filled).

```
float offset = vTextureCoord.y > uFilled ? 0.0 : 0.5;

```

equivalent to

```
float offset;
if ( vTextureCoord.y > uFilled ) { offset = 0.0 }
else { offset = 0.5 }

```

***Fragment shader***

```
#version 330 core
out vec4 FragColor;

in vec2 vTextureCoord;

uniform float uFilled;          // between 0.0 and 1.0
uniform sampler2D uTexture;

void main() {
    // if vertical texture coord is greater than uFilled, use the empty one (left), otherwise the filled one (right)
    float offset = vTextureCoord.y > uFilled ? 0.0 : 0.5;
    vec2 texCoord = vec2(vTextureCoord.x / 2 + offset, vTextureCoord.y);
    FragColor = texture(uTexture, texCoord);
};

```

***Vertex shaders***

```
#version 330 core
layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec2 aTextureCoord;

out vec2 vTextureCoord;

void main() {
    gl_Position = vec4(aPosition, 1.0f);
    vTextureCoord = aTextureCoord;
};

```

**ONE TEXTURE WITH ADDITIONAL GRAY SCALE IMAGES**

Following the @Raildex recommendation in the comments. Example using gray scale additional images to fill the progress bar. Just an example of what can be done.

Left one using two images, right one using four images.
> 6 votes

---
Tags: opengl, sprites
---


title: Assimp - Error loading .obj files

text:
# Question
Title: Assimp - Error loading .obj files
I'm trying to load .obj files in my little game. I decided to use assimp as tool to import those models. But it seems that assimp does not import them correctly.

I looked for a simple cube mesh online and found this one: http://cs.wellesley.edu/~cs307/tw/objects/cube-textures.obj

But when importing the model the number of faces is only 11 instead of 12. I then tested to load the model in the model viewer provider by assimp. But the problem is the same, one face is missing.

Is there anything I'm missing? Here is my loading code:

```
const aiScene* AssimpScene = this->AssimpImporter.ReadFile("C:/cube.obj",  aiProcess_CalcTangentSpace);

```

# Answer
> 0 votes
For the people still trying to figure this one out make sure that your .mtl file is also there. Just found out your OBJ is dependent on it

---
Tags: c++, directx9, assimp, obj
---


# Question
Title: How do I find the gradient of a noise value which has been re-evaluated on a curve
I have a function `Evaluate()`, which is used to remap a noise value based on a curve/spline to make the noise more interesting. There are 3 inputs: the noise value to be remapped, the gradient of the noise, and the curve/spline. What I need help with is finding the new gradient.

```
// "noise" is in the range [0,1], and is the value form a noise function,
// "gradient" is the gradient of the noise function,
// and "filter" has the heights of an animation curve in the interval [0,1]
private void Evaluate(ref float noise, ref float3 gradient, in UnsafeList<float> filter)
{
    int index = (int)(noise * (filter.Length - 1));

    float remap = filter[index]; // f(x)
    int h = index + 1 == filterResolution ? -1 : 1; // direction to evaluate the array
    float remaph = filter[index + h]; // f(x+h)
    gradient = (remaph - remap) / h * gradient; // curve derivative * noise derivative
    noise = remap;
}

```

# Answer
Chain rule says

$$\frac {d} {d x}f(g(x)) = f^\prime(g(x)) \cdot g^\prime(x) $$

In your case you have three functions to compose:

* Your filter function \\$f(i)\\$ that you approximate stepwise
(You may get better results if you use a piecewise linear or spline interpolation here, to avoid stairstep artifacts from the truncation. Below, we'll pretend it's a smooth function so the flat steps don't zero-out the gradient)
* Your range remapping function \\$r(i) = (\text{filter length} - 1)i\\$
* Your noise function \\$n(x, y, z)\\$

So we need to multiply three coefficients here:

$$\frac {\delta} {\delta x}f(r(n(x,y,z))) = f^\prime(r(n(x,y,z))) \cdot r^\prime(n(x, y, z)) \cdot \frac {\delta n(x,y,z)} {\delta x}$$

In code that could look like this:

```
private void Evaluate(ref float noise, ref float3 gradient, in UnsafeList<float> filter)
{
    int index = (int)(noise * (filter.Length - 1));

    float filtered = filter[index];

    int maxIndex = Mathf.Min(index + 1, filter.Length - 1);
    int minIndex = Mathf.Max(index - 1, 0);

    float approximateSlope = (filter[maxIndex] - filter[minIndex])
                             / (maxIndex - minIndex);

    //               f'                   r'                n'
    gradient = approximateSlope * (filter.Length - 1) * gradient;
    noise = filtered;
}

```
> 0 votes

---
Tags: mathematics, normal-mapping, curves, simplex-noise
---


# Question
Title: Would it be okay to try to reverse engineer Spore as an experiment and publish the results on-line?
Game in question is Spore. I'm fascinated by space and this game has been my favorite for years.

Now, I would try to reverse engineer as much as I can as an experiment because I am interested in generally how game works under the hood. On example what steganography algorithm is used to hide models in pictures or algorithm for generating planets and solar systems etc... I can think of a million different things.

But, some of my wishes are also to put this reverse engineered code public on my GitHub as my work. I don't know if this would be okay legally and if it wouldn't create some type of a problem because I put my work public.

Of course there is a rule that sometimes you cannot fully reverse engineer something, especially something like a game this big and code wouldn't be 100% equal as the source. But again, this is something to ask before even starting. It would be something really interesting, that's something I know for sure.

# Answer
> 2 votes
> From the user agreement it's mentioned that any service or product must not be reverse engineered or extracted data from.

Then no, it's not OK.

As luck would have it, this story just crossed my feed today: Revealing *Mortal Kombat II* Code Leak Pulled by Warner Bros.

It describes a situation where a user uploaded *Mortal Kombat II*'s source code to GitHub:

> The lawyers at Warner Bros. took exception to this by issuing a swift DMCA takedown notice that Github (sic) adhered to by disabling public access

So even a game significantly older than *Spore* still has the intellectual property rights to its source code protected by copyright law; that protection is actively enforced by corporate legal teams, and GitHub will cooperate with those measures.

Even if your reverse engineering efforts produce code that is not identical to the original source code, I'd wager that's not a fight you want to pick with a legal team the size of EA's.

---
Tags: software-engineering, legal
---


# Question
Title: Detecting whether sprite is outside the camera's view
I want to detect when the game object is not visible anymore.

I search for the size of the `SpriteRenderer`, and convert it to screen space. Then, I check if the position is below or above a certain `yMin` or `Ymax`, defined as:

```
yMin = - mySprite.y;
yMax = cam.pixelHeight + mySprite.y;

```

But it does not work at all!

Besides that, I attempted to print the size of the `SpriteRenderer`'s bounding rectangle, and it is too big for the actual sprite. See the image below.

The actual code to display the rectangle :

```
private void OnGUI()
{
    Vector3 position = cam.WorldToScreenPoint(transform.position);
    Vector2 bounds = cam.WorldToScreenPoint(mySprite.bounds.size);
    DrawQuad(new Rect(position.x, cam.pixelHeight - position.y, bounds.x, bounds.y), Color.green);
}

void DrawQuad(Rect position, Color color)
{
    Texture2D texture = new Texture2D(1, 1);
    texture.SetPixel(0, 0, color);
    texture.Apply();
    GUI.skin.box.normal.background = texture;
    GUI.Box(position, GUIContent.none);
}

```

When I print the size of the Sprite in the Log I get: `420.12, 280.22, 10.0`, but the size of the image is 446\*520.

I would like to understand the magic behind this.

# Answer
> 0 votes
This code is incorrect:

```
Vector2 bounds = cam.WorldToScreenPoint(mySprite.bounds.size);

```

As the function name says, it gives you a point: a specific location in space, not a dimension. To understand how this fails, imagine we pass the size (2, 5) before and after moving the camera: because the camera has shifted, the point (2, 5) will correspond to a different position on the screen before and after the move, and so we'll get two different values, even though the bounds we passed did not change.

Instead, you can compute the scaling factor of an orthographic camera (taking into account that `orthographicSize` is half the camera's world space height), and use that to convert world space bounds into screen space:

```
float pixelsPerUnit = cam.pixelHeight / (2f * cam.orthographicSize);
float screenSpaceSize = mySprite.bounds.size * pixelsPerUnit;

```

Though I think it would be even clearer to write your code something like this:

```
bool IsOffScreenVertically(SpriteRenderer sprite, Camera camera) {
    var bounds = sprite.bounds;

    var top = camera.WorldToViewportPoint(bounds.max);
    var bottom = camera.WorldToViewportPoint(bounds.min);

    return top.y < 0 || bottom.y > 1;
}

```

Here we're using viewport coordinates, where (0, 0) is the bottom-left corner of the camera's viewport and (1, 1) is the top-right, so there's no need for pixel conversions at all. And we're using points throughout, not lengths/sizes, so we don't need to go outside the available named functions.

---
Tags: unity, sprites, transformation
---


# Question
Title: After adding a new Assembly File the "Volume" class is no longer found
I added a new assembly file to a folder containing my Unity scripts. After setting the Assembly Definition References all Classes of other assemblies are found except `Volume`.

```
The type or namespace name 'Volume' could not be found (are you missing a using directive or an assembly reference?)

```

What assembly do I have to link to be able to use `Volume`?

# Answer
> 1 votes
The `Volume` class is part of the `UnityEngine.PostProcessing` namespace, so you will need to add a reference to the `UnityEngine.PostProcessing` assembly in order to use it.

---
Tags: unity, unity-urp, assembly
---


# Question
Title: How to share constant variables between Compute Shaders?
So, I have two compute shaders A and B (using unity and HLSL). Right now, before every dispatch, I send my mouse coordinates to both of them every update.

So, from my understanding, you can actually determine which register the mouse coordinates go to like so:

```
 float2 mxy :register(c1); // at the top of the shader

```

And by declaring this in both shaders, you can actually avoid sending the mouse coordinates twice.

The problem is, that this does not work! I've tried making cbuffers as well, but to no avail. (I don't actually know how to work with cbuffers on the CPU side that said)

**TLDR:** why can't I share variables between two compute shaders using float2 mxy :register(c1); ?

# Answer
I'm not very savvy with registers but, I do know that Unity has a built-in function to create variables that are shared between HLSL:

```
UnityEngine.Shader.SetGlobalFloat("shaderVariableName",c#VariableName);

```
> 0 votes

---
Tags: unity, c#, shaders, gpu
---


# Question
Title: Adding requestAnimationFrame in isometric Tile grid Code is not working
Hi There this is my first Post on gamedev, and i hope everyone understand what i want :)

First of all my Code is an very Personal Version from one Github Isometric Map.

I Tryd now 2 Days to Add the animation loop inside my Code. But if i add them on Draw() is Lags, Or The Place-Building Mouseover is not working. Outside of Draw() it works but only if i mouseover over the Iso Map.

An Overview of the Map

\[original\]https://github.com/demorose/isometric-map

```
    var canvas  = document.getElementById('canBG');
    var context = canvas.getContext('2d');
    context.oncontextmenu = function () {return false; };

    var c = document.getElementById('can');
    var ctx = c.getContext('2d');
    c.oncontextmenu = function () {return false; };

    var buildset = false;
    var lastSelected = new Tile();
    var tileSet = new Image();
    var tileWidth = 100;
    var tileHeight = 70;
    var visualHeight = 50;

    var tilesetOffset = 1;
    tileSet.src = 'images/baumap/tileset.png';

    var buildings = new Image();
    var buildingHeight = 150;
    buildings.src = 'images/baumap/building.png';

    // test
    var buildings1 = new Image();
    buildings1.src = 'images/baumap/10.png';

    var offsetX = window.innerWidth/2;
    var offsetY = window.innerHeight/6;
    var map = [];
    var showgrid = 0;

    window.addEventListener('resize', resizeCanvas, false);

    function Tile() {
        this.x=0;
        this.y=0;
        this.z=0;
        this.type='';
        this.selected = false;
        this.isConstructible = true;
        this.building = 0;
        this.level = 0;
        this.buildset = false;

        if (typeof(Tile.initialized) == 'undefined') {
            Tile.prototype.toScreen = function () {
                var screen = [];
                screen.x = offsetX - (this.y * tileWidth / 2) + (this.x * tileWidth / 2) - (tileWidth / 2);
                screen.y = offsetY + (this.y * visualHeight / 2) + (this.x * visualHeight / 2);
                return screen;
            };
            Tile.prototype.print = function (context) {
                var j;
                if(showgrid !== 0){
                        context.drawImage(tileSet, tileWidth * 0, 0 * tileHeight, tileWidth, tileHeight, this.toScreen().x, ((this.toScreen().y) - this.z), tileWidth, tileHeight);
                }
               if (this.selected) {

                    if (!this.isConstructible){
                        if(this.buildset == true){
                            context.drawImage(buildings, tileWidth * this.building, 1 * buildingHeight, tileWidth, buildingHeight, this.toScreen().x, this.toScreen().y - (buildingHeight - visualHeight) - this.z, tileWidth, buildingHeight);
                        }
                        context.drawImage(tileSet, tileWidth * 1, 0 * tileHeight, tileWidth, tileHeight, this.toScreen().x, ((this.toScreen().y) - this.z), tileWidth, tileHeight);
                    } else {
                        if(this.buildset == true){
                            context.drawImage(buildings, tileWidth * this.building, 1 * buildingHeight, tileWidth, buildingHeight, this.toScreen().x, this.toScreen().y - (buildingHeight - visualHeight) - this.z, tileWidth, buildingHeight);
                        }else{
                            if(showgrid == 1){
                                context.drawImage(tileSet, tileWidth * 3, 0 * tileHeight, tileWidth, tileHeight, this.toScreen().x, ((this.toScreen().y) - this.z), tileWidth, tileHeight);
                            }else{
                                context.drawImage(tileSet, tileWidth * 0, 0 * tileHeight, tileWidth, tileHeight, this.toScreen().x, ((this.toScreen().y) - this.z), tileWidth, tileHeight);
                            }
                        }

                    }
                    j = 1;
                }
                else {
                    j = 0;
                }

                if (this.building !== 0 && this.building !== 2 && this.building < 2) {

                    context.drawImage(buildings, tileWidth * 1, j * buildingHeight, tileWidth, buildingHeight, this.toScreen().x, this.toScreen().y - (buildingHeight - visualHeight) - this.z, tileWidth, buildingHeight);

                }else if(this.building == 2){
                    context.drawImage(buildings, tileWidth * 2, j * buildingHeight, tileWidth, buildingHeight, this.toScreen().x, this.toScreen().y - (buildingHeight - visualHeight) - this.z, tileWidth, buildingHeight);

                }else if(this.building > 2){
                    context.drawImage(buildings, tileWidth * this.building, j * buildingHeight, tileWidth, buildingHeight, this.toScreen().x, this.toScreen().y - (buildingHeight - visualHeight) - this.z, tileWidth, buildingHeight);

                }

            };
        }
    }

var lastset = 0;
    c.addEventListener('mousemove', function (evt) {
        var mousepos = getMousePos(c, evt);
        if (typeof(map[mousepos.x]) !== 'undefined') {
            if (typeof(map[mousepos.x][mousepos.y]) !== 'undefined') {
                if (map[mousepos.x][mousepos.y].selected !== true) {
                    lastSelected.selected = false;
                    map[mousepos.x][mousepos.y].selected = true;

                    if(buildset == true){
                        map[mousepos.x][mousepos.y].buildset = true;
                        buildset = true;
                        if(map[mousepos.x][mousepos.y].building == 0){
                            map[mousepos.x][mousepos.y].building = building1;
                            lastset = map[mousepos.x][mousepos.y];
                        }

                    }else{
                        map[mousepos.x][mousepos.y].buildset = false;
                        buildset = false;
                        lastset = 0;

                    }
                    lastSelected = map[mousepos.x][mousepos.y];
                    draw();
                    if(lastset !== 0){
                    map[lastset.x][lastset.y].building = 0;
                    }
                }
            } else {
                if (lastSelected.selected) {
                    lastSelected.selected = false;
                    draw();

                }
            }

        } else {
            if (lastSelected.selected) {
                lastSelected.selected = false;
                draw();
            }
        }

    });

    c.addEventListener('mousedown', function (evt) {
        switch (evt.button) {
        case 0:
            leftClick(evt);
            break;
        case 1:
            middleClick(evt);
            break;
        case 2:
            rightClick(evt);
            break;
        }
    });

    function draw() {
        c.width = window.innerWidth;
        c.height = window.innerHeight;
        var rect = c.getBoundingClientRect();

        var topLeft = (((toMapCoord(c, 0-rect.left-offsetX, 0-rect.top-offsetY).x) >= 0) ? toMapCoord(c, 0-rect.left-offsetX, 0-rect.top-offsetY).x: 0);
        var bottomRight = (((toMapCoord(c, c.width-rect.left-offsetX, c.height-rect.top-offsetY).x) >= 0) ? toMapCoord(c, c.width-rect.left-offsetX, c.height-rect.top-offsetY).x: 0);

        var topRight = (((toMapCoord(c, c.width-rect.left-offsetX, -rect.top-offsetY).y) >= 0) ? toMapCoord(c, c.width-rect.left-offsetX, -rect.top-offsetY).y: 0);
        var bottomLeft = (((toMapCoord(c, -rect.left-offsetX, c.height-rect.top-offsetY).y) >= 0) ? toMapCoord(c, -rect.left-offsetX, c.height-rect.top-offsetY).y: 0);

        for(var i=topLeft; i< bottomRight; i++){
            if(typeof(map[i]) != 'undefined'){
                for(var j=topRight; j<bottomLeft; j++){
                    if(typeof(map[i][j]) != 'undefined'){
                        map[i][j].print(ctx);

                    }
                }
            }
        }

    }
    requestAnimationFrame(draw);
    function toscreen() {
        var screen = [];
        screen.x = offsetX - (tileWidth / 2) + (tileWidth / 2) - (tileWidth / 2);
        screen.y = offsetY + (visualHeight / 2) + ( visualHeight / 2);
        return screen;
    };
    var background = new Image();
    background.src = 'images/baumap/bg.png';

    function drawBG() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        var rect = canvas.getBoundingClientRect();
        context.drawImage(background, toscreen().x - 800, toscreen().y - 150,);
    }

    function resizeCanvas() {
        draw();
        drawBG();
    }

    function toMapCoord(canvas, x, y){
        var i = Math.floor((y + x/2)/visualHeight);
        var j = Math.floor((y - x/2)/visualHeight);

        return{
            x:i,
            y:j
        };
    }

    function getMousePos(canvas, e) {
        var rect = canvas.getBoundingClientRect();
        var x = e.clientX - rect.left-offsetX;
        var y = e.clientY-rect.top-offsetY;

        return toMapCoord(canvas, x, y);
    }
var building1 = 0;
function getbinfo (id){
            $.ajax({
            method: "POST",
            url: "../ajax.php?a=binfo",
            data: { building: id }
            }).done(function( data ) {
                $('.gebinfo').remove();
                $('.geb2info').remove();
                if(data.allowedtobuild === true){
                    var button = '<button class="bau">Bauen</button>';
                }else{
                    var button = 'Nicht genug Resourcen';
                }

                $('.start').append('<div class="gebinfo"><h3>'+data.name+'</h3><p>'+data.beschreibung+'</p><br><br><span><b>Kosten:</b><br>Eisen: '+data.keisen+'<br>Kristall: '+data.kkristall+'<br>Trinium: '+data.ktrinium+'<br><br>Bauzeit: '+data.bauzeit+'</span><br>'+button+'<button class="schliessen">Schließen</button></div>');
$(".gebinfo").find(".bau").click(function () {
        building1 = id;buildset = true;
        return false;
});
$(".gebinfo").find(".schliessen").click(function () {
$('.gebinfo').remove();
building1 = 0;buildset  = false;
        return false;
});
});

}

$('#bi_2').on('click',function(){ getbinfo (2); });
$('#bi_3').on('click',function(){ getbinfo (3); });

function getbinfo2 (id, x, y){
            $.ajax({
            method: "POST",
            url: "../ajax.php?a=binfo",
            data: { building: id, x: x, y: y }
            }).done(function( data ) {
                $('.geb2info').remove();
                $('.gebinfo').remove();

                if(data.allowedtobuild === true){
                    var button = '<button class="ausbau">Ausbau auf Level 2</button>';
                }else{
                    var button = 'Nicht genug Resourcen';
                }

                $('.start').append('\
                    <div class="geb2info">\
                        <div style="float:right;top:0px;font-weight:bold;">Level 1</div>\
                        <h3>'+data.name+'</h3>\
                        <p>'+data.beschreibung+'</p>\
                        <br><br><span><b>Kosten:</b><br>Eisen: '+data.keisen+'<br>Kristall: '+data.kkristall+'<br>Trinium: '+data.ktrinium+'<br><br>Bauzeit: '+data.bauzeit+'</span><br>'+button+'<button class="schliessen">Schließen</button></div>');

$(".geb2info").find(".schliessen").click(function () {
$('.geb2info').remove();
        return false;
});
});

}

    function leftClick(evt) {
        var mousepos = getMousePos(c,evt);
        if(typeof(map[mousepos.x]) !== 'undefined'){
            if(typeof(map[mousepos.x][mousepos.y]) !== 'undefined'){
                if(map[mousepos.x][mousepos.y].isConstructible){
                    if(building1 !== 0){
                        map[mousepos.x][mousepos.y].isConstructible = false;
                        map[mousepos.x][mousepos.y].building = building1;

                        $.ajax({
                            method: "POST",
                            url: "../ajax.php?a=baue",
                            data: { x: mousepos.x, y: mousepos.y, building: building1 }
                        });

                        draw();
                    building1 = 0;
                    map[mousepos.x][mousepos.y].buildset = false;
                    buildset = false;
                    }
                } else {
                    getbinfo2(map[mousepos.x][mousepos.y].building, mousepos.x, mousepos.y);
                    console.log(map[mousepos.x][mousepos.y]);
                    map[mousepos.x][mousepos.y].buildset = false;
                    buildset = false;

                }

            }
        }
        return false;
    }

    function rightClick(evt) {
        var mousepos = getMousePos(c,evt);
        if(typeof(map[mousepos.x]) !== 'undefined'){
            if(typeof(map[mousepos.x][mousepos.y]) !== 'undefined'){
                if(map[mousepos.x][mousepos.y].building !== 0) {
                    map[mousepos.x][mousepos.y].isConstructible = true;
                    map[mousepos.x][mousepos.y].building = 0;
                        $.ajax({
                            method: "POST",
                            url: "../ajax.php?a=bauweg",
                            data: { x: mousepos.x, y: mousepos.y }
                        });

                }
                    building1 = 0;
                    map[mousepos.x][mousepos.y].buildset = false;
                    buildset = false;
                draw();
            }
        }
        return false;
    }

    var startX;
    var startY;
    function middleClick(evt) {
        var elementToChange = document.getElementsByTagName("body")[0];
        elementToChange.style.cursor = "url('images/baumap/deplace.png'), auto";
        startX = evt.clientX;
        startY = evt.clientY;
        c.addEventListener('mousemove', dragMap, false);
        c.addEventListener('mouseup', function(){
        c.removeEventListener('mousemove', dragMap, false);
        var elementToChange = document.getElementsByTagName("body")[0];
        elementToChange.style.cursor = "url('images/baumap/cursor.png'), auto";
        });
    }

    function dragMap(evt){
        if(evt.offsetX){
            offsetX += evt.clientX-startX;
            offsetY += evt.clientY-startY;
            startX = evt.clientX;
            startY = evt.clientY;
        }
        draw();
        drawBG();
    }

      $('#gridcheckbox').change(function(){
          if(showgrid == 1){
              showgrid = 0;
                      draw();
        drawBG();
          }else{
            showgrid = 1;
                    draw();
        drawBG();
          }
            //console.log(showgrid);

        });

    for (var a = 0; a <= 15; a++) {

        if (map[a] === void 0){
            map[a] = [];
        }
        for (var b=0;b<=15;b++){
            var tile = new Tile();
            tile.type = 3;
            //tile.type = Math.floor((Math.random()*4)+1);
            <?php
                $buildings = new Buildings;

                echo "var test = ".json_encode($buildings->get_buildings($user->get_lastplanet())).";";
            ?>
            $.each(test, function(i, v) {
            if (v.x == a && v.y == b) {
                tile.building = v.building;
                tile.level = v.level;
                tile.isConstructible = false;
                return;
            }
            });
            if(tile.type === 1){
                tile.isConstructible = false;
            }
            tile.x = a;
            tile.y = b;
            map[a][b] = tile;
        }
    }

        tileSet.onload = resizeCanvas();

        background.onload = function() {
    drawBG();
    draw();
};
drawBG();

```

I tryd to add few animate Functions and call them from the Draw function and from outside. I think my Problem is with my Loops for the Drag Map and the Tiles. But im not sure. :)

# Answer
Every call of `requestAnimationFrame(draw);` results in the draw function being called exactly *once*, not contiguous on every following frame.

When you want a contiguous drawing loop, then the draw-function needs to reschedule itself by calling `requestAnimationFrame` for itself:

```
function draw() {
    /*               *
     *  drawing code *
     *               */

    requestAnimationFrame(draw);
}

requestAnimationFrame(draw);

```

You can then remove all other calls to the draw function, because the canvas gets permanently repainted while the browser tab is visible. You in fact **must** get rid of them, because otherwise you are going to create multiple parallel drawing loops which will tank your framerate. If you still think you have situations where you need to call the draw-function once without creating a loop (I doubt it, though), then you can structure your drawing-code like this:

```
function draw() {
    /*               *
     *  drawing code *
     *               */
}

function drawLoop() {
    draw()
    requestAnimationFrame(drawLoop);
}

requestAnimationFrame(drawLoop);

```

That means you have a function `drawLoop` which reschedules itself while the original `draw` function can still be called individually.
> 0 votes

---
Tags: javascript, html-canvas, isometric
---


# Question
Title: Idiomatic Way to Create Card Instances in Unity
I'm extremely new to Unity, and I'm trying to figure out if this design makes sense. I'm creating a card game in which multiple instances of the same card will exist. I'm trying to determine if the "idiomatic" way to do this is as follows:

* Create a Scriptable Object to contain card metadata.
* Then create specific Scriptable Objects for each card.
* Then at runtime, whenever I need a specific card, I create a gameObject add the (simple for example purposes) `IsCard` MonoBehavior and associate `IsCard` with whatever `ScriptableObject` corresponds to the specific card in question to extract/assign metadata.

Does this make sense or is there a more performant/idiomatic way to do this?

This is my current implementation of the above solution.

```
using UnityEngine;
using UnityEngine.UI;

[CreateAssetMenu(fileName = "CardSO", menuName = "ScriptableObjects/Card")]
public class CardSO : ScriptableObject
{
    public string cardName;
    public Image cardImage;
    // There could be more specific SOs for creatures, spells, etc.
}

```

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

[RequireComponent(typeof(Image))]
public class IsCard : MonoBehaviour
{

    public CardSO cardSO;

    // Start is called before the first frame update
    void Start()
    {
        if (cardSO == null)
        {
            return;
        }

        Image image = GetComponent<Image>();
        image.sprite = cardSO.cardImage.sprite;
        //Reference/Utilize other properties when applicable.
        //If this were a creature, perhaps we could have a mono behavior that stores power/toughness, etc.
        //public int power;
        //power = creatureCardSO.power;
    }
}
```

# Answer
Yes, this is a perfectly viable approach.

But another approach you could consider is to represent card types not as ScriptableObjects but as prefabs. The advantage is that prefab instances can be changed. So when you want to have mechanics in the game which modify individual cards that are already on the table, then you can change the data of the card instance directly without changing the data for all other instances of the card. When you are working with scriptable objects, then you would need a rather complicated system on the cards for managing instant-specific modifiers to the card attributes inherited from the scriptable object.
> 2 votes

---
Tags: unity, card-game
---


# Question
Title: In C#, is there any performance reason to implement ECS?
The formal ECS specification was developed to address gaming in a JavaScript environment.

In any C# translation, this implies all of the classes' members must be public.

My concern is that too many JavaScript developers are transitioning to C# without a full understanding of classes, interfaces, interfaces and inheritance(and capitalization), and the speed drawbacks to that approach, when compared to execution times of properly written classes and interfaces.

So my question is: could the ECS be implemented in a way that fully utilizes C# without sacrificing speed and FPS?

# Answer
> 5 votes
Performance will always depend on implementation. It's definitely possible to make well-performing non-ECS games, or poorly-performing ECS games, but there are certain performance tricks that ECS lends itself well to: particularly data-oriented design (DOD).

To have something to contrast against, let's imagine another component-based game written in a more idiomatic **Object-Oriented Programming** style (arguably naïve, but it helps for the sake of example):

* Class `GameObject` contains a list of component instances attached to it.
    + `Component` is an abstract class (or an `IComponent` interface) with a virtual `Update()` method.
    + We implement different derived classes descending from `Component` (or implementing `IComponent`) for each different behaviour we want.
* A scene contains a list of active `GameObject` instances.
    + Each frame, we iterate over each object in the scene, and each component on that object, calling `Component.Update()` which has been overridden for each behaviour we need.

In contrast to this, we'll implement our **DOD-focused ECS version** so that components are `struct` types, and we'll store them in contiguous arrays of the same type. Game objects with particular mixes of components will be just an index within a set of parallel component arrays commonly called an archetype. Systems will implement update functions that iterate over all archetypes with a specific component signature.

So we've added quite a bit of complexity and given up some flexibility. Now adding/removing a component from a game object isn't just a matter of calling `List.Add()`/`RemoveAt()`, instead we need to extract it from one archetype's buffers and append it to another, possibly creating a new bespoke archetype for this combination of components - certainly messy!

But here's what we can gain from this:

* **Good data locality**: each cache line you pull in contains not just the component you want to act on now, but also the next component in the buffer, so it's already waiting for us when we want it. The linear access pattern allows the CPU to predict and pre-fetch the next cache line we'll want, letting us make full use of the available CPU and minimizing waiting on the slow memory bus.

This also works if a single system needs to access/modify multiple component types - using a Structure of Arrays layout, we can race down multiple of these packed buffers in parallel.

In contrast, our OOP example has strewn the `GameObject` and `Component` instances more or less randomly around the heap - taking whatever slot was available each time we called `new Foo()`. When we want to know what component to access next, we have to look up a pointer from the list, check that it's valid, then try to read the memory at that location. That memory is very likely not already in cache, so we incur a cache miss - burning hundreds of CPU cycles just waiting for the component data to be fetched from main memory - that's time when our CPU could have been doing useful work!
* **Good *code* locality**: because we have one system executing again and again on a big batch of data, the code we need to run is *also* continually in cache. We might even be able to write our update functions so they update batches of components at the same time - or the processor might be able to rearrange our code on the fly to interleave multiple loop iterations, so the fast parts get done while we're still waiting on the slow parts (it's *scary* what these chips can do these days!)

But for our naïve OOP example, we don't know which component class's `Update()` we want to call until we call it. That means chasing a pointer to the component instance, chasing a pointer to its VTable, and chasing a pointer to the function code to run it just once. Then for the next component we come to, we have to do it all again, since it's very likely a different component type than the previous one. Since we haven't used this new component's code lately, it's been evicted from the instruction cache and we need to burn hundreds of cycles again waiting to read it back in.

In practice, **this data-oriented approach can yield *large* performance wins**. I routinely hear from Unity developers who have observed **10x speedups** when migrating code from conventional `MonoBehaviour` scripts (which act similar to the naïve OOP example) into Unity's Job System (which acts similar to the DOD ECS example).

Granted, that's not entirely a fair comparison because Unity's Burst compiler and multithreading give extra advantages to the Job version. But it's also true that it's the clear structure and dependency relationships of the ECS model that *allow* them to implement those optimizations.

What about `public` and `private`?

It's true that a system needs some means to change the internal state of the components, and the simplest way to do that is to make components Plain Old Data Structures with all members public. ECS purists may say this is the only way and that you should never have any code in a component.

But you don't get points for how "pure" your ECS is - what matters is how much you like working with it.

So you could implement private members in a component type, and setter or mutating methods on it that help it maintain some invariants without that responsibility leaking into the corresponding systems (or worse, needing to be shared or *duplicated* across multiple systems). If these methods are small, they might well get inlined into the system update methods anyway.

The "no code" guideline is mainly to help you step out of the "one update at a time" mentality that member methods encourage, and start to see opportunities for "batch update" approaches when you think of components as a stream of data. But we can bend that rule when it helps us develop more flexibly, avoid bugs, etc.

---

So... does all this mean we should always implement ECS, and never use convenient OOP features like inheritance, interfaces, etc?

**Heck no!**

* The advantages described above assume you have **big lists of components** \- enough to outweigh any overhead you're paying to get them into and manage those lists in the first place. In a game that has just a handful of objects of each type, you're not going to see big wins. Such a game will probably run just fine in the classic OOP style.

Where ECS shines is in games with huge numbers of similar objects. Think physics simulations with hundreds of dynamic bodies, crowd sims with hundreds of agents, endless procedural worlds that need to generate content over the horizon as fast as you can race towards it. If you're not making the kind of game that needs to cram all that in, you can prioritize ease of development instead. Because...
* DOD ECS is kind of a pain. There's **a lot of up-front complexity** to set up, and conceptually simple things like adding/removing/disabling/re-enabling a component suddenly require non-trivial engineering. References between objects are also tricky to manage in this scheme.

All this makes iterating on a game in development much more complicated, and you might need larger refactoring to implement a design change, compared to how easily you can swap out and experiment with new component behaviours in OOP. So if you're not sure if you need ECS speed, or your game concept is still in flux, it may pay to prioritize development speed over processing speed - at least early in the project. Then once you have the core gameplay needs solidified, you can evaluate whether your performance is adequate, and whether a migration to ECS would be worthwhile.
* We can take half-steps toward fixing the worst time sinks, without completely abandoning the OOP convenience. Re-using objects from a pool initialized at start-up helps improve data locality. Iterating your components in order by type rather than by what object they're attached to helps improve code locality. Using concrete types when practical saves the overhead of virtual method calls. You can probably think of dozens of other ways the simplistic OOP approach above could be improved, without paying the full engineering cost of the ECS style.

A good tweet I just saw helps put this in perspective:

> **Juan Linietsky**
> @reduzio
>
> This is how I see abstraction/optimization balance in sw design:
>
> Code executed less often is the large majority of the codebase and can benefit from more abstraction. Code executed more often needs better algorithms, and critical code (small minority) needs to be data oriented.

The abstraction we get from C# class inheritance, interfaces, virtual function calls, references, etc. helps a lot with stuff in the middle and left of that chart. And for many games, that's all you need. But some games have features at the right side of the graph, that demand the kind of high data throughput where these indirections are too costly, and the limitations/complexity of data-oriented approaches are a worthwhile trade for the speed we can get.

---
Tags: c#, performance, entity-component-system
---


# Question
Title: Dealing with block corners in a grid-based raycaster
I'm trying to build a simple grid-based raycaster, but I'm having trouble with rendering block corners.

First of all, I want to change the color of all the y-axis walls. But a block's corner belongs to both the y and x axis, so it's never clear whether it should be recolored or not. Because of this, when I place several blocks in a row, I end up with a wall with a bunch of vertical stripes on it.

The second issue is that when two blocks are placed in such a way that only their corners "touch", a ray can pass between them and hit something behind them, allowing the camera to see things it should not be able to.

Here is my current implementation of a raycaster that showcases these issues, written in Rust with Raylib:

```
use raylib::prelude::*;

struct Map {
    scale: i32,
    data: Vec<Vec<i32>>,
}

impl Map {
    fn get_tile(&self, mut x: i32, mut y: i32) -> i32 {
        (x, y) = (x / self.scale, y / self.scale);
        let (max_y, max_x) = (self.data.len(), self.data[0].len());
        if y >= 0 && x >= 0 && y < max_y as i32 && x < max_x as i32 {
            return self.data[y as usize][x as usize];
        }

        return 0;
    }
}

struct Camera {
    fov: i32,
    range: i32,
    h: i32,
    w: i32,
}

impl Camera {
    fn draw(&self, player: &Player, map: &Map, display: &mut RaylibDrawHandle) {
        display.draw_rectangle(0, 0, self.w, self.h / 2, Color::BLACK);
        display.draw_rectangle(0, self.h / 2, self.w, self.h / 2, Color::GRAY);

        for i in (-self.fov / 2)..(self.fov / 2) {
            let (mut rx, mut ry);
            let ra = player.direction + (i as f32).to_radians();

            // slow but simple
            for step in 1..self.range {
                rx = (player.x.round() + step as f32 * ra.cos()).round() as i32;
                ry = (player.y.round() + step as f32 * ra.sin()).round() as i32;

                // only recolors one side, but showcases issue well
                let mut color = Color::WHITE;
                if rx % map.scale == 0 {
                    color = Color::LIGHTGRAY;
                }

                if map.get_tile(rx, ry) > 0 {
                    let dist = (
                        step as f32 * (player.direction - ra).cos()
                    ).round() as i32;
                    let line_height = (map.scale * self.h / dist).clamp(0, self.h);
                    let line_width = self.w / self.fov;
                    display.draw_rectangle(
                        self.w / 2 + i * line_width,
                        self.h / 2 - line_height / 2,
                        line_width,
                        line_height,
                        color
                    );
                    break;
                }
            }
        }
    }
}

struct Player {
    speed: f32,
    rotation_speed: f32,
    direction: f32,
    x: f32,
    y: f32,
}

impl Player {
    fn move_relative(&mut self, side: f32, fwd: f32, delta: f32, map: &Map) {
        let normalized = Vector2::new(side, fwd).normalized();

        let speed = self.speed * delta;
        let mut nx = self.x + speed * normalized.y * self.direction.cos();
        let mut ny = self.y + speed * normalized.y * self.direction.sin();

        let side_direction = self.direction + 90_f32.to_radians();
        nx = nx + speed * normalized.x * side_direction.cos();
        ny = ny + speed * normalized.x * side_direction.sin();

        if map.get_tile(nx.round() as i32, ny.round() as i32) == 0 {
            (self.x, self.y) = (nx, ny);
        } else if map.get_tile(nx.round() as i32, self.y.round() as i32) == 0 {
            self.x = nx;
        } else if map.get_tile(self.x.round() as i32, ny.round() as i32) == 0 {
            self.y = ny;
        }
    }

    fn rotate(&mut self, r: f32, d: f32) {
        self.direction += r * self.rotation_speed * d;
    }
}

fn main() {
    let (mut rl, thread) = raylib::init()
        .size(800, 450)
        .resizable()
        .title("rustcast")
        .build();

    rl.set_window_min_size(64, 64);
    //rl.set_target_fps(60);

    let map = Map {
        scale: 40,
        data: vec![
            vec![1,1,1,1,1,1,1,1,1],
            vec![1,0,0,0,0,0,0,0,1],
            vec![1,0,0,0,0,0,0,0,1],
            vec![1,0,0,0,0,0,0,0,1],
            vec![1,0,0,0,0,0,0,0,1],
            vec![1,0,0,0,0,0,0,0,1],
            vec![1,0,0,0,1,0,0,0,1],
            vec![1,0,0,0,0,1,0,0,1],
            vec![1,0,0,0,0,0,0,0,1],
            vec![1,1,1,1,1,1,1,1,1],
        ]
    };
    let camera = Camera {
        fov: 80,
        range: 600,
        w: 800,
        h: 450
    };
    let mut player = Player {
        speed: 50.0,
        rotation_speed: 10.0,
        direction: 0.0,
        x: 100.0,
        y: 100.0,
    };

    while !rl.window_should_close() {
        let delta_time = rl.get_frame_time();

        let (mut move_h, mut move_v, mut rotate) = (0, 0, 0);
        if rl.is_key_down(KeyboardKey::KEY_A) { move_h -= 1 };
        if rl.is_key_down(KeyboardKey::KEY_D) { move_h += 1 };
        if rl.is_key_down(KeyboardKey::KEY_W) { move_v += 1 };
        if rl.is_key_down(KeyboardKey::KEY_S) { move_v -= 1 };
        if rl.is_key_down(KeyboardKey::KEY_Q) { rotate -= 1 };
        if rl.is_key_down(KeyboardKey::KEY_E) { rotate += 1 };
        player.rotate(rotate as f32, delta_time);
        player.move_relative(move_h as f32, move_v as f32, delta_time, &map);

        let mut dis = rl.begin_drawing(&thread);

        dis.clear_background(Color::BLACK);
        camera.draw(&player, &map, &mut dis);
        dis.draw_fps(0, 0);
    }
}

```

What can I do to fix these issues? And is it possible to do that without adding a lot of complexity?

# Answer
> 1 votes
Since you have a grid, you know something important: the ray is passing through *a series of adjacent grid cells.* You can fix both of your problem cases by making your code obey this rule.

Right now you're sampling along a fixed step size, which can skip over corners. A way to patch this algorithm to succeed would be to notice whenever the *previous* grid cell and the *current* grid cell are diagonally adjacent, and pretend the ray hit the one of the two diagonal cells in the mean time, thus making each individual step cross a specific, single *face* of a grid cell.

```
bad       patched
\ ##      \ ##
 \##  ->   `\#
##\       ##|
## \      ## \

```

Then, while you're doing this adjacency analysis, you can also determine which face of a grid cell is being entered (= which coordinate is changing and whether it is incrementing or decrementing). Then, you can choose colors according to that face and the cell coordinates, rather than only using the cell coordinates. If you do this, you will *never* see vertical stripes.

---

However, there is a better algorithm which not only inherently doesn't have this problem, but is also more efficient and precise because it takes exactly one step per grid cell examined (rather than taking steps smaller than cells). It is the algorithm presented in "A Fast Voxel Traversal Algorithm for Ray Tracing" by John Amanatides and Andrew Woo, 1987, and which I wrote up a practical example of in this answer, and later wrote a Rust version (though that is complicated with additional requirements, so it may not be the clearest sample).

While this algorithm as described is for 3D, you can make it 2D by just deleting the “Z” branch from the comparisons.

---
Tags: rendering, raycasting
---


# Question
Title: Y in transform.position has different value in inspector than in code
I've got very simple code:

```
private void StepButtonClicked(int stepIndex) {
    _scenarioManager.SetActiceStepIndex(stepIndex);
    var position = _steps[stepIndex].transform.localPosition;
    var difference = _stepsPointer.transform.position - position;

    Debug.Log(differencePosition.x);

    _stepsPointer.transform.position = new Vector3(
        x: position.x,
        y: 1f,
        z: 0);
}

```

But I don't understand why the value of `position.y` shows as -662 in the inspector instead of 1 as set in code.

Can you tell me why is this happening? X position is working fine.

# Answer
> 3 votes
The inspector does not show you `transform.position` (the object's location in world space).

It shows you `transform.localPosition` (the object's position in its parent object's coordinate system).

For objects at the root level of the hierarchy, with no parent object, these are equivalent, so you might have gotten used to thinking of them interchangeably.

Here `StepsViewPointer` is a child of `Viewport`, so when you set `transform.position`, Unity works out what `localPosition` the object would need to have relative to `Viewport` in order to sit at the given position in world space.

If you want to set the location relative to the parent, set `localPosition` directly, rather than asking Unity to convert from a world space position to parent space automatically. Or for a `RectTransform` in a UI canvas, it often helps to work with `anchoredPosition`.

You should also make sure not to combine/subtract positions in different coordinate spaces, like where you're computing `difference` as a local position minus a world position. This is not geometrically meaningful, and will give you nonsense values unrelated to what you're trying to accomplish.

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


# Question
Title: How do you approach resolution independence in raster based graphics content?
Those games that are not fortunate enough to run on a locked platform spec, like handhelds, need to run across various resolution formats and aspect ratios.

In a 3D game you might have a HUD or menu GUI based on raster graphics, and in a 2D game you might have a bunch of quads which are vessels for sprites.

So my question is, how do you approach designing and operating content across various resolutions and aspect ratio? Let's assume you have a sprite character that is 300x400 pixels sprite and surrounded by a level made of tiles. On different resolutions/aspect ratios you'd see a different FOV altogether. Or if you have a HUD or a GUI menu, you'd want to keep some stuff at same positions and of same size relative to the screen. Yet, graphics source is raster bitmaps, not vector.

Obviously, problem has been addressed numerous times. I'm interested to hear abut various approaches that worked for you so far. Do you keep an arbitrary dimension agnostic 'pixel' unit that you magically transform into needed dimensions via formula based on res and aspect ratio or other approaches?

**edit:**

So, conclusion is to enumerate your aspect ratios. Lowest combination of aspect:resolution is the one you design important stuff into. A safe area if you will. Same aspect ratios, but higher resolutions are simple scaling issues. Art content is designed for highest resolution. Larger aspect ratios simply show more of level/FOV with information presented which is not critical as is the one in safe area. Something like in this image I made.

# Answer
> 7 votes
If your resolutions are similar to each other, you can just use the same art across all of them with maybe some downscaling at runtime for the smaller screens. If they differ by more than say a factor of 2x, you're going to need to author (or at least have an artist tweak) separate assets for the different resolutions.

With 2D, resolution has a huge affect on how you design images. A sprite that looks richly detailed and realistic at high-res will be muddy and indecipherable scaled down. Likewise, a sprite that's clean and sharp looking at low-res will look cheap and overly-simple at high-res.

# Answer
> 4 votes
One way is to make the image assets in a vectorial format (SVG, Illustrator, etc) and convert them into raster images as needed by the different versions of the game.

# Answer
> 4 votes
When maintaining fullscreen across different resolutions, if you want pixel-perfection (i.e. "As the artist produced it"), then the problem is that there is no *fully* automated way to scale sprites up OR down (or to rotate them) that doesn't require human approval. Ultimately that's because the placement of pixels is a subjective thing. The rendering algorithm performs some scaling, or rotation, and has to use some approximation techniques to do this, eg. bilinear filtering. If you still want hard edges on the pixels in order to have that "pixel perfection" (i.e. not using AA or BF), then you are going to have to accept that scaling by some non-power-of-2 degree is *going* to produce some undesirable artifacting.

An interesting approach to a similar problem is found in RotSprite, an application/algorithm designed to perform "automatic" rotations of sprites. By that, I mean it produces a number of possibly desirable end results after intensive processing, for the human operator to pick from. The hand-picked sprites then end up going into the game, meaning this is a content creation step, and not a runtime one.

One possible answer to your "arbitrary magical dimension agnostic pixel" question: OpenGL (which you may well be intending to use if you're going cross-platform) works in a totally different way from a software raster renderer. It considers the width and height of the display in floating-point range 0.0-\>1.0, and maps pixels accordingly on the GPU. Of course this can itself result in artifacting, unless eg. BF is turned on for textures (which is what your sprites are in OpenGL).

# Answer
> 0 votes
GPUs already have a way to draw lines that's been worked on for decades : geometry.

If you make a triangle, it'll always be drawn perectly according to camera distance, angle, etc. Same for 3D objects

---
Tags: 2d, sprites, gui
---


# Question
Title: How to generate all possible lang fields for a modded Minecraft pack?
I want to translate a modpack Tekkit2 in Minecraft. According to Minecraft wiki one has to create a resource pack and map identifier-translation pairs to a json file. However in order for the translation to be whole, I would have to know the identifiers of modded items, which I couldn't find on any site. Is it possible to generate a list of keys and their default values?

# Answer
> 0 votes
*Some* mods provide their identifiers in their .jar file so the best course is to make a script that goes trough the mods and find the appropriate lang file and extract the keys.

---
Tags: minecraft-modding
---


# Question
Title: Modify ballistic code to not rotate projectile
I am currently using this formula to fire a projectile in my game.

Credit to Stephan-B for this wonderful formula: https://forum.unity.com/threads/throw-an-object-along-a-parabola.158855/

```
private IEnumerator FireProjectile()
{

    // Move projectile to the position of throwing object + add some offset if needed.
    Projectile.position = transform.position + new Vector3(0, 0.0f, 0);

    // Calculate distance to target
    float target_Distance = Vector3.Distance(Projectile.position, Target.position);

    // Calculate the velocity needed to throw the object to the target at specified angle.
    float projectile_Velocity = target_Distance / (Mathf.Sin(2 * FiringAngle * Mathf.Deg2Rad) / Gravity);

    // Extract the X  Y componenent of the velocity
    float Vx = Mathf.Sqrt(projectile_Velocity) * Mathf.Cos(FiringAngle * Mathf.Deg2Rad);
    float Vy = Mathf.Sqrt(projectile_Velocity) * Mathf.Sin(FiringAngle * Mathf.Deg2Rad);

    // Calculate flight time.
    float flightDuration = target_Distance / Vx;

    // Rotate projectile to face the target.
    Projectile.rotation = Quaternion.LookRotation(Target.position - Projectile.position);

    float elapse_time = 0;

    while (elapse_time < flightDuration)
    {
        Projectile.Translate(0, (Vy - (Gravity * elapse_time)) * Time.deltaTime, Vx * Time.deltaTime);

        elapse_time += Time.deltaTime;

        yield return null;
    }
}

```

This works great, however, I don't want the projectile to rotate it's transform. I'd like it to keep it's rotation while it travels. I thought it would be as simple as commenting out this line:

```
// Rotate projectile to face the target.
    Projectile.rotation = Quaternion.LookRotation(Target.position - Projectile.position);

```

But, doing this ruins the code and causes the projectile to go in the wrong direction. I also tried keeping the code the same and adding a billboard to the projectile, but doing so also causes the projectile to move in the wrong direction.

It appears that this formula relies on the projectile rotating to hit its target correctly. I like this formula because it let's me easily change the projectile's angle and the gravity affecting it, but I really need the projectile to keep its rotation throughout. Is anyone able to please assist me with this? Thanks so much!

# Answer
The problem is here:

```
Projectile.Translate(0, (Vy - (Gravity * elapse_time)) * Time.deltaTime, Vx * Time.deltaTime);

```

Checking the docs on `Transform.Translate`, we see that by default, this translates in the object's local coordinate system. So if the object is rotated the wrong way to begin with,

This code is otherwise written assuming world space, so we should add `Space.World` to the end of the line:

```
Projectile.Translate(0,
                     Vy - (Gravity * elapse_time) * Time.deltaTime,
                     Vx * Time.deltaTime,
                     Space.World);

```

That will work out of the box if the game is in 2D, so `Vx` is along the x axis (though you may need a flip if the target is to the left: `if (Target.position.x < Projectile.position.x) Vx *= -1;`).

In 3D, you'd want to make a unit vector pointing toward the target along the ground plane, and advance your "x" velocity along that rotated axis:

```
// Before the while loop.
var horizontal  = Target.position - Projectile.position;
horizontal.y = 0;
horizontal = horizontal.normalized * Vx;

while (elapsed_time < flightDuration)
{
    Vector3 velocity = horizontal;
    velocity.y = (Vy - Gravity * elapsed_time);

    Projectile.Translate(velocity * Time.deltaTime, Space.World);

    elapsed_time += Time.deltaTime;

    yield return null;
}

```
> 0 votes

---
Tags: unity, c#, mathematics, projectile-physics
---


# Question
Title: What am I doing wrong with this BC7 reading?
I need to import a BCn image without any existing libraries. Thus, I have to write my own reader. This has gone fairly well so far for BCs 1-5 (don't need BC6), but now BC7 is causing a problem.

As testing, I have a BC7 image that I know to have an entirely empty blue channel, and the very first 4x4 block is all solid red (rgba 255,0,0,255). This is the data of that block, as read directly from the file:

```
as hex: 30FF0300 C0FFAFAA AAAA4A92 24499224
as bin: 00110000111111110000001100000000110000001111111110101111101010101010101010101010010010101001001000100100010010011001001000100100

```

According to the standard, this is a mode 2 block (starts with 001), which means this is the decoding pattern:

This lays out how the endpoints are stored in the order all reds, all greens, all blues. Simple compared to most other modes. But when I lay out the bits like this, I get this structure:

```
mode:         001
partition ID: 100001
reds:         11111 11000 00011 00000 00011 00000
greens:       01111 11111 01011 11101 01010 10101
blues:        01010 10101 00100 10101 00100 10001
indexes:      0 01 00 0 10 01 00 11 00 10 01 00 01 00 10 0

```

**Why does the blue channel have no endpoints equal to 0?** The image has no blue whatsoever. And this block doesn't have any green either, yet its endpoints are also all nonzero. If I swap the reading from RRRRRRGGGGGGBBBBBB to RRGGBBRRGGBBRRGGBB, that would at least get a zero endpoint in each channel, but this wouldn't solve the problem because the non-zero endpoints are still being used at least once (by the definition of mode 2). And furthermore, there are only 3 strings of 5+ zeroes in the entire input, all of which are in the red zone, so it's not like I'm only a bit or two off or something. I can't see any possible way to read this data that makes logical sense while still remaining true to the stated standard.

I haven't needed to do any messing about with endians or such bit/byte-order-changing for the other BCn readers, so I shouldn't need to for this.

EDIT: I have done some messing about with editing the image binary directly and seeing what this affects when opened in Visual Studio or XNViewMP. And apparently, editing the bits that are supposed to be the red endpoints instead affects the alpha of the block. Mode 2 is supposed to be opaque, and in none of the modes does alpha come before colour - maybe it gets swapped with a colour, but the alpha is apparently also immediately followed by the red, so it cannot be a swap. So I'm now suspicious that this can't be a BC7 image at all, despite all the exiting programs labelling it as such.

# Answer
> 1 votes
Looking at the Khronos docs linked in the comment, I think you've got the mode wrong:

> Each block can contain data in one of eight modes. The mode is identified by the lowest bits of the lowest byte. It is encoded as zero or more zeros followed by a one. For example, using ‘x’ to indicate a bit not included in the mode number, mode 0 is encoded as xxxxxxx1 in the low byte in binary, mode 5 is xx100000, and mode 7 is 10000000. Encoding the low byte as zero is reserved and should not be used when encoding a BPTC texture; hardware decoders processing a texel block with a low byte of 0 should return 0 for all channels of all texels.

Your first byte is `0x30` or `00110000b` which looks to me like it decodes as mode 4 according to those instructions, because it ends with four zeros in binary.

Obviously that means that you also need to change the way that you've looked at the rest of the data in the block.

---
Tags: directx11, dds
---


# Question
Title: Trying to make a procedural generated map like the game "Unrailed!"
I am trying to make a procedural map similar to a game called "Unrailed!"

I used perlin noise based on Sebastian Lague's video, as you can see below, the water would always be generated surrounding the rock because based on how perlin noise works, which is not what I wanted.

Is there any other method to generate the map like Unrailed? Or am I using perlin noise wrongly?

# Answer
> 3 votes
A common method is to layer multiple instances of a noise pattern.

For example, you can generate the water by sampling the noise starting at offset `a:b` and then as a next step generate the rocks by sampling the noise starting at `c:d`, where a, b, c and d are all pseudorandom numbers.

If I had to guess what they did in the screenshot above, I would guess that they did that for different terrain features in this order:

1. water
2. trees
3. rocks

This technique also allows you to use different frequencies for different terrain features or even experiment with using different noise algorithms for different features.

---
Tags: unity, procedural-generation, maps
---


# Question
Title: Why does Radiosity Normal Mapping use 3 directional components and not 5?
I have read the HL2 Paper and Presentation for Radiosity Normal Mapping. I am currently trying to implement it myself. I already managed to generate a single radiosity lightmap by drawing a hemicube and downsample it to a single pixel.

For Radiosity Normal Mapping like HL2 I need 3 different Radiosity Lightmaps, one for each Directional Component, But why only 3 and not 5? If we take a flat plane as our destination polygon, shouldn't I generate 5 different radiosities, one for the Normal, One For the Tangent, One for the Bitangent, one for the Inverted Tangent and one for the Inverted Bitangent?

# Answer
You can see this explained in this figure from Valve's slide presentation on the topic at GDC 2004:

They don't measure the lighting along 5 basis vectors \\$(\pm 1, \pm1, 0), (0, 0, 1)\\$, where only one is locally perpendicular to the surface and the rest look along the horizon (and so only half their domain is capturing light that's likely to illuminate this surface)

Instead they use three perpendicular basis vectors, arranged to all make the same angle with the horizon (about 54.7°):

* \\$\left( \sqrt{\frac 2 3}, 0, \frac 1 {\sqrt 3} \right)\\$
* \\$\left( -\frac 1 {\sqrt 6}, \frac 1 {\sqrt 2}, \frac 1 {\sqrt 3} \right)\\$
* \\$ \left( -\frac 1 {\sqrt 6}, -\frac 1 {\sqrt 2}, \frac 1 {\sqrt 3} \right)\\$

This makes the three basis vectors more uniformly distributed above the surface, rather than having one "special" vector that's dead-on and the rest squeezed to the outer limit where they'd be more prone to might leak light from over the horizon. Each one is now pulling about equal weight in terms of how often a bump will use its contribution.

This of course also gives an optimization: it's 40% cheaper to store, sample, and do math on 3 maps instead of 5!
> 2 votes

---
Tags: graphics, graphics-programming, normal-mapping, radiosity
---


title: Unity detect drag to a game object

text:
# Question
Title: Unity detect drag to a game object
I want to detect when a UI object it dragged and released on top of a game object. The drags starts on a sprite on the canvas outside of the game object. I tried using `OnMouseUp()` but it only work if the `MouseDown` event happens on the same game object. How can I detect `MouseUp` events that started outside of my object and ended inside the object.

# Answer
> 1 votes
I solved this problem by checking if the mouse is currently over the game object and checking if the mouse button is released inside the function

```
 void OnMouseOver()
    {
        Debug.Log("OnMouseOver on GameObject");
        if (Input.GetMouseButtonUp(0))
        {
            Debug.Log("MouseButtonUp");
        }
    }

```

---
Tags: unity, mouse
---


title: Fire Projectile In Ballistic Motion

text:
# Question
Title: Fire Projectile In Ballistic Motion
I am using the following to calculate velocity: https://gamedev.stackexchange.com/a/114547/39518

```
private void CalculateVelocity()
{
    Vector3 toTarget = Target.position - StartingPoint.position;

    // Set up the terms we need to solve the quadratic equations.
    float gSquared = Physics.gravity.sqrMagnitude;
    float b = Speed * Speed + Vector3.Dot(toTarget, Physics.gravity);
    float discriminant = b * b - gSquared * toTarget.sqrMagnitude;

    // Check whether the target is reachable at max speed or less.
    if (discriminant < 0)
    {
        // Target is too far away to hit at this speed.
        // Abort, or fire at max speed in its general direction?
    }

    float discRoot = Mathf.Sqrt(discriminant);

    // Highest shot with the given max speed:
    float T = Mathf.Sqrt((b + discRoot) * 2f / gSquared);

    // Convert from time-to-hit to a launch velocity:
    Velocity = toTarget / T - Physics.gravity * T / 2f;
}

```

I'd now like to take the calculated velocity and move the projectile using the following: https://gamedev.stackexchange.com/a/119636/39518

I came up with the following: "T" & "Velocity" are variables calculated in the first method.

```
private IEnumerator MoveProjectileToTarget()
{

    while(Projectile.position != Target.position)
    {
        // Standard ballistic motion:
        Vector3 point = StartingPoint.position
                      + T * Velocity
                      + 0.5f * T * T * (Vector3)(Physics.gravity);

        Projectile.position = point;

        yield return null;
    }

}

```

The current problem I have is the projectile is warping to it's target. I believe the issue lies in the while loop I created. Any help would be greatly appreciated. Thanks!

# Answer
You're currently calculating just the position at the END of the arc (time `T` is the total time it takes to finish the whole flight). Did you mean to gradually step a `t` value from 0 up to `T`?

```
private IEnumerator MoveProjectileToTarget()
{
    for (float t = 0; t < T; t += Time.deltaTime) {
        Projectile.position = StartingPoint.position
                            + t * Velocity
                            + 0.5f * t * t * Physics.gravity;

        yield return null;
    }
}

```
> 0 votes

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


# Question
Title: "An ID3D12Resource object is referenced by GPU operations in-flight on Command Queue": When Should I Create my Buffers?
When trying to re-create my vertex buffers, my app crashes and I get this error:

> D3D12 ERROR: ID3D12Resource2::: CORRUPTION: An ID3D12Resource object (0x000001DDEBA98FC0:'Vertex Buffer Default Resource Heap') is referenced by GPU operations in-flight on Command Queue (0x000001DDEB80E3A0:'Unnamed ID3D12CommandQueue Object'). It is not safe to final-release objects that may have GPU operations pending. This can result in application instability. \[ EXECUTION ERROR #921: OBJECT\_DELETED\_WHILE\_STILL\_IN\_USE\]

Here is my function called `create_vertex_buffers()`:

```
// a triangle
Vertex verts[] = {
    Vertex(0.0f, 0.5f, 0.5f),
    Vertex(0.5f, -0.5f, 0.5f),
    Vertex(-0.5f, -0.5f, 0.5f),
};

const UINT verts_size = sizeof(verts);

// create default heap
auto buffer = CD3DX12_RESOURCE_DESC::Buffer(verts_size);
auto heap_properties1 = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
device->CreateCommittedResource(
    &heap_properties1, // a default heap
    D3D12_HEAP_FLAG_NONE, // no flags
    &buffer, // resource description for a buffer
    D3D12_RESOURCE_STATE_COPY_DEST,
    nullptr,
    IID_PPV_ARGS(&vertex_buffer));

// create upload heap
// upload heaps are used to upload data to the GPU. CPU can write to it, GPU can read from it
// We will upload the vertex buffer using this heap to the default heap
auto heap_properties2 = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD);
auto buffer2 = CD3DX12_RESOURCE_DESC::Buffer(verts_size);
device->CreateCommittedResource(
    &heap_properties2, // upload heap
    D3D12_HEAP_FLAG_NONE, // no flags
    &buffer2, // resource description for a buffer
    D3D12_RESOURCE_STATE_GENERIC_READ,
    nullptr,
    IID_PPV_ARGS(&vertex_buffer_upload));

D3D12_SUBRESOURCE_DATA vertex_data = {};
vertex_data.pData = reinterpret_cast<BYTE*>(verts); // pointer to our vertex array
vertex_data.RowPitch = verts_size; // size of all our triangle vertex data
vertex_data.SlicePitch = verts_size; // also the size of our triangle vertex data

UpdateSubresources(command_list.Get(), vertex_buffer.Get(), vertex_buffer_upload.Get(), 0, 0, 1, &vertex_data);

auto transition = CD3DX12_RESOURCE_BARRIER::Transition(vertex_buffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
command_list->ResourceBarrier(1, &transition);

vertex_buffer_view.BufferLocation = vertex_buffer->GetGPUVirtualAddress();
vertex_buffer_view.StrideInBytes = sizeof(Vertex);
vertex_buffer_view.SizeInBytes = verts_size;

```

It is my function for creating the vertex upload and default buffers. I implement it into my command queue like this:

```
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(render_targets[frame_index].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
command_list->ResourceBarrier(1, &barrier);

// -------------------------+
create_vertex_buffers(); // | <== This is where I'm calling it!!
// -------------------------+

CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle(rtv_descriptor_heap->GetCPUDescriptorHandleForHeapStart(), frame_index, rtv_descriptor_size);
CD3DX12_CPU_DESCRIPTOR_HANDLE dsv_handle(depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart());

command_list->OMSetRenderTargets(1, &rtv_handle, FALSE, &dsv_handle);

command_list->ClearRenderTargetView(rtv_handle, color, 0, nullptr);
command_list->ClearDepthStencilView(depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);

command_list->SetPipelineState(pipeline_state_object.Get());
command_list->SetGraphicsRootSignature(root_signature.Get()); // set the root signature
command_list->RSSetViewports(1, &viewport); // set the viewports
command_list->RSSetScissorRects(1, &scissor_rect); // set the scissor rects
command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // set the primitive topology
command_list->IASetVertexBuffers(0, 1, &vertex_buffer_view); // set the vertex buffer (using the vertex buffer view)
command_list->DrawInstanced(3, 1, 0, 0); // finally draw 3 vertices (draw the triangle)

barrier = CD3DX12_RESOURCE_BARRIER::Transition(render_targets[frame_index].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
command_list->ResourceBarrier(1, &barrier);

```

I have tried adding a fence after creating the resources and waiting for that fence before calling `DrawInstanced()`, in case it's still making them once it's started drawing. I tried moving where I call `create_vertex_buffers()`.

I'm unsure of when I should be creating these buffers. I'm planning on later only creating them when necessary, which will be every so often, not every frame.

# Answer
> 0 votes
You seem to be recreating the vertex buffer resources in every render frame. You should be calling `create_vertex_buffers()` only once, for example immediately after you have created your device, swapchain, PSOs and root signatures.

---
Tags: directx, resource-management, vertex-buffer, directx12
---


# Question
Title: How do I change the gravity for just one object
I'm making a 2D game in Unity and I have a player character who needs to walk on the four walls of a room, so I gave them a Rigidbody so I can change the gravity. But my game has enemies too and when the player changes the gravity, the enemy is affected too (I just want them to move up/down in a pattern).

How do I change the gravity to one specific object (the player character) without affecting others (the enemies)?

# Answer
> 1 votes
You can change the gravityScale of a single Rigidbody2D, but that would only work for up/down. For any direction, the simplest way would be to just implement gravity yourself, and either set the gravity in the physics settings to 0,0 or set the gravityScale of the player's rigidbody to 0 if you want the enemies to use the default gravity system.

Something like this should work:

```
public Vector2 gravityDirection; // new Vector2(0, -9.81f) could be the default
private Rigidbody2D _rb;
void Awake() {
    _rb = GetComponent<Rigidbody2D>(); // cache reference since GetComponent is expensive
}

void FixedUpdate(){  // use FixedUpdate for physics stuff
    _rb.AddForce(gravityDirection);
}

```

You can leave the ForceMode as the default, impulse is meant for instantaneous things like collisions (see here).

# Answer
> 2 votes
You can set the `gravityScale` parameter on your `Rigidbody2D` component to zero to ignore the built-in gravity. Then you can add a `ConstantForce2D` component to the object, and set the `force` parameter to simulate a gravity force of any magnitude, in any direction. This lets you simulate gravity differently for each object you put this component onto.

Here's a YouTube tutorial that shows how to do something similar in 3D instead of 2D.

---
Tags: unity, 2d, physics, rigidbody
---


# Question
Title: Changing GameObject Position with the new InputSystem Unity 2D
I am making a little top-down 2D RPG right now and I'm struggling with the range of my attacks. The problem is that my range is stuck on the right side of my player. This is of course really annoying, because you can't attack to the left.

I want to make a script that makes the range transform, based on where you are facing. I'm just not experienced enough to know how.

Maybe creating a script that changes the whole movement of the player, wouldn't be a bad idea. It would of course be nicer to just add a few things to fix the problem, but I would also be ok with changing the overall movement as a solution, I guess.

Here is the `Movement + PlayerAttack` script:

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

public class Move : MonoBehaviour
{

public int damage;
private float timeBtwAttack;
public float startTimeBtwAttack;

public float attackCooldown;
float _lastAttackTime;

public Transform attackPos;
public LayerMask whatIsEnemies;
public float attackRangeX;
public float attackRangeY;
public float ValueIsGiven;

//Move Start
[SerializeField] private Rigidbody2D rb2D;
[SerializeField] private float speed;
private Vector2 moveInputValue;

private void OnMove(InputValue value)
{
    moveInputValue = value.Get<Vector2>();
    if(ValueIsGiven >= 1){
    Debug.Log(moveInputValue);
    }
}
private void MoveLogicMethod()
{
    Vector2 result = moveInputValue * speed * Time.fixedDeltaTime;
    rb2D.velocity = result;
}
    private void FixedUpdate()
    {
        MoveLogicMethod();
    }
//Move End

//Attack Start

public void OnPlayerAttacking()
{
// If attacking too close to previous attack, ignore this input.
if (Time.time - _lastAttackTime < attackCooldown) return;

var enemiesToDamage = Physics2D.OverlapBoxAll(
           attackPos.position,
           new Vector2(attackRangeX, attackRangeY),
           0,
           whatIsEnemies
);

foreach (var enemy in enemiesToDamage) {
     enemy.GetComponent<Enemy>().TakeDamage(damage);
}

_lastAttackTime = Time.time;
}
void OnDrawGizmosSelected(){

        Gizmos.color = Color.black;
        Gizmos.DrawWireCube(attackPos.position, new Vector3(attackRangeX, attackRangeY, 1));
}
//Attack End
}

```

I don't use any rotation in my movement script.

Here is a screenshot of my scene with the range:

The most important thing right now is to get it to work, the visuals are second.

Also the `AttackRangePos` is currently defined by an empty game object named "attackPos". (You can also see it in the screenshot I took). I think some people could get confused that the Sword is the attack position, but the Sword is only for visuals. Would still be essential for the sword to move too.

I also developed an idea, which could maybe deal with this problem:  The idea is basically that the attackPos gets the MoveValue, so it knows where the player is currently moving and then uses this information to move to the side of the player which is facing the direction of where the player is going. Since the attackPos is parented in the Player, the attackPos only needs to be moved by 1-2 units at max, so it shouldnt be to performance consuming, i hope.

I also want the attackPos to stay at its current position, even when you are not currently moving anymore. I would really apppreciate it, if you could help me fixing the problem that I have. To whoever this reads: Have a nice day!

@Maganta Hi, Maganta thnak you so much for you answer, I really appreciate it, but Im not sure if I used this infos right. Also I couldnt fit this in the comment section. My code is a total mess and Im kinda confused, especially because I dont get any errors, eventhough its not working. This ofc is because of me being unexpirienced and I have to admit I have no idea what I should do. Heres the code:

```
public class Move : MonoBehaviour
{

public int damage;
private float timeBtwAttack;
public float startTimeBtwAttack;

public float attackRange;
public Vector2 moveInputValue;
public Vector2 attackDir = Vector2.right; // independent direction of attack

public float attackCooldown;
float _lastAttackTime;

public Transform Player;
public Transform attackPos;
public LayerMask whatIsEnemies;
public float attackRangeX;
public float attackRangeY;
public float ValueIsGiven;

//Move Start
[SerializeField] private Rigidbody2D rb2D;
[SerializeField] private float speed;

private void OnMove(InputValue value)
{
    var attackPos = (Vector2)transform.position + attackDir*attackRange;   //Get the world coordinates of attackPos
    moveInputValue = value.Get<Vector2>();
    if(moveInputValue != Vector2.zero){
    attackDir = moveInputValue.normalized; //When the player stops moving, use the last movement direction as the attack direction
    }
    if(ValueIsGiven >= 1){
    Debug.Log(moveInputValue);
    }
    }

public float Angle(Vector2 vector2)
{
return 360 - (Mathf.Atan2(vector2.x, vector2.y) * Mathf.Rad2Deg *    Mathf.Sign(vector2.x));
}
private void MoveLogicMethod()
{
    // Vector2 result = moveInputValue * speed * Time.fixedDeltaTime;
    Vector2 result = moveInputValue.normalized * speed; //fixedDeltaTime is not needed here
    rb2D.velocity = result;

}
    private void FixedUpdate()
    {
        MoveLogicMethod();
    }
//Move End

//Attack Start

public void OnPlayerAttacking()
{
// If attacking too close to previous attack, ignore this input.
if (Time.time - _lastAttackTime < attackCooldown) return;

var enemiesToDamage = Physics2D.OverlapBoxAll(
        attackPos.position,
        new Vector2(attackRangeX, attackRangeY),
        0,
        whatIsEnemies
);

foreach (var enemy in enemiesToDamage) {
     enemy.GetComponent<Enemy>().TakeDamage(damage);
}

_lastAttackTime = Time.time;
 }
 void OnDrawGizmosSelected(){

        Gizmos.color = Color.black;
        Gizmos.DrawWireCube(attackPos.position, new Vector2(attackRangeX, attackRangeY));
}
//Attack End
}

```

I also havent used any if statements yet, since I think it would even further confuse me. Im kind of ashamed asking you for help again, especially after you gave me such a long and good answer.

# Answer
> 1 votes
I'm not sure I understand your question 100%, but for the target of attacking left, you can simply treat the `Player` as a whole and flip it horizontally. In 2D games we often use scale(-1,1) to do this:

```
public Transform player;
...
private void OnMove(InputValue value)
{
    moveInputValue = value.Get<Vector2>();
    player.localScale = new Vector2((moveInputValue.x > 0?1:-1),1);
}

```

edit:

After some limited observations, I finally understand what you want. Now let's make a list of what has been achieved and what would like to be achieved.

Achieved：

1. Player moving.
2. Damage Dealing.
3. Attacking cool down.

To be achieved:

1. The attack direction is determined by the movement direction(360°). This includes the position of the attack point and the rotation of the shape used for detection.

To achieve the player-centered rotation of the attack point, the value that the developer needs to set is no longer a fixed point(`attackPos`), but a fixed distance(`attackRange`).

```
// public Transform attackPos;
public float attackRange; // replace attackPos with attackRange

```

The calculation of the specific position follows the formula:

> attackPos = playerPos + normalized(attackDirection)\*attackRange

`normalized` means keep the direction of the vector and change its length to 1.

vector`*`number means keep the direction of the vector and multiply its length.

`normalized(attackDirection)*attackRange` means a vector with a length of attackRange in the attackDirection, this is a relative value, so we need to add the position vector of the player itself.

So now we can do this:

```
    var attackPos = (Vector2)transform.position + attackDir*attackRange; //Get the world coordinates of attackPos

    var enemiesToDamage = Physics2D.OverlapBoxAll(
            attackPos,
            new Vector2(attackRangeX, attackRangeY),
            0,
            whatIsEnemies
    );

```

**You can use the built-in member variable `transform` to get the transform of the gameobject where the current script is located.*

How can we get `attackDir`? It essentially depends on the direction of movement, so just use the normalized value of `moveInputValue`. But when the movement stops, the value of `moveInputValue` is `Vector2.zero`, which prevents the attack from executing correctly. When the player stops moving, we need to get the last moving direction as the attack direction. We can set a non-zero initial value for `attackDir`, and only when `moveInputValue` is not 0, overwrite `attackDir` with its normalized value.

```
private Vector2 moveInputValue;
private Vector2 attackDir = Vector2.right; // independent direction of attack

private void OnMove(InputValue value)
{
    moveInputValue = value.Get<Vector2>();
    if(moveInputValue != Vector2.zero){
        attackDir = moveInputValue.normalized; //When the player stops moving, use the last movement direction as the attack direction
    }
}

```

Now let's look at rotation. We can use Vector2.Angle and Vector2.SignedAngle to get the angle between two vectors. So we can calculate the angle between a vector and *a vector with an angle of 0* to get the angle value of this vector:

```
var angle = Vector2.SignedAngle(Vector2.up,attackDir); //Cast Vector2 to angle[-180,180], it's used in OverlapBoxAll

```

Or you can use trigonometric functions to figure out the angle of a vector:

```
public float Angle(Vector2 vector2)
{
    return 360 - (Mathf.Atan2(vector2.x, vector2.y) * Mathf.Rad2Deg * Mathf.Sign(vector2.x));
}

```

Finally, we need a visual debugging method. Unity does not have an api for `DrawBox` with a rotation angle. You can debug it by whatever you like, such as calculating the coordinates of the 4 points of the rectangle and drawing 4 line segments, or using a sprite object as a debugger.

BTW, When you calculate the velocity and apply it to the rigid body, you don't need `Time.fixedDeltaTime`, This part of the calculation is handled by the physics phase of the engine itself.

```
private void MoveLogicMethod()
{
    // Vector2 result = moveInputValue * speed * Time.fixedDeltaTime;
    Vector2 result = moveInputValue.normalized * speed; //fixedDeltaTime is not needed here
    rb2D.velocity = result;
}

```

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