# Question
Title: How do I make my character jump, with a curve, in C++?
```
#include "Game.h"
#include <iostream>

Game::Game(sf::RenderWindow& game_window)
  : window(game_window)
{
  srand(time(NULL));

  // Load the texture for the defender ship
  if (!defenderTexture.loadFromFile("Data/Images/kenney_animalpackredux/PNG/Round/bear.png")) {
    // Error handling: Unable to load defender texture
    std::cerr << "Failed to load defender texture!" << std::endl;
    // Optionally, you can handle this error further, like returning false from init() method.
  }

  if (!backgroundTexture.loadFromFile("Data/Images/lvl2.png")) {
    // Error handling: Unable to load defender texture
    std::cerr << "Failed to load defender texture!" << std::endl;
    // Optionally, you can handle this error further, like returning false from init() method.
  }

  if (!tileTexture1.loadFromFile("Data/Images/kenney_pixelplatformer/Tiles/tile_0091.png")) {
    // Error handling: Unable to load defender texture
    std::cerr << "Failed to load defender texture!" << std::endl;
    // Optionally, you can handle this error further, like returning false from init() method.
  }

  if (!tileTexture2.loadFromFile("Data/Images/kenney_pixelplatformer/Tiles/tile_0091.png")) {
    // Error handling: Unable to load defender texture
    std::cerr << "Failed to load defender texture!" << std::endl;
    // Optionally, you can handle this error further, like returning false from init() method.
  }

  if (!tileTexture3.loadFromFile("Data/Images/kenney_pixelplatformer/Tiles/tile_0091.png")) {
    // Error handling: Unable to load defender texture
    std::cerr << "Failed to load defender texture!" << std::endl;
    // Optionally, you can handle this error further, like returning false from init() method.
  }

  if (!tileTexture4.loadFromFile("Data/Images/kenney_pixelplatformer/Tiles/tile_0091.png")) {
    // Error handling: Unable to load defender texture
    std::cerr << "Failed to load defender texture!" << std::endl;
    // Optionally, you can handle this error further, like returning false from init() method.
  }

  // Set up the defender sprite
  defenderSprite.setTexture(defenderTexture);
  backgroundSprite.setTexture(backgroundTexture);
  tileSprite1.setTexture(tileTexture1);
  tileSprite2.setTexture(tileTexture2);
  tileSprite3.setTexture(tileTexture3);
  tileSprite4.setTexture(tileTexture4);

  // Set the initial position of the defender ship
  // You can adjust these coordinates according to your game layout
  defenderSprite.setPosition(window.getSize().x / 2.0f, window.getSize().y - 100.0f);
  tileSprite1.setPosition(100, 525);
  tileSprite2.setPosition(600, 425);
  tileSprite3.setPosition(100, 300);
  tileSprite4.setPosition(600, 225);

  defenderSprite.setScale(0.35f, 0.35f);
  backgroundSprite.setScale(0.8f, 0.8f);
  tileSprite1.setScale(18.0f, 3.0f);
  tileSprite2.setScale(18.0f, 3.0f);
  tileSprite3.setScale(18.0f, 3.0f);
  tileSprite4.setScale(18.0f, 3.0f);

}

Game::~Game()
{

}

bool Game::init()
{
  if(!font.loadFromFile("Data/Fonts/OpenSans-Bold.ttf"))
  {
    std::cout << "font did not load \n";
  }

  menu_text.setFont(font);
  menu_text.setString("Main Menu");
  menu_text.setCharacterSize(36);
  menu_text.setFillColor(sf::Color::White);
  menu_text.setPosition(450, 100);

  description.setFont(font);
  description.setString("Collect all the coins and avoid enemies to win!");
  description.setCharacterSize(18);
  description.setFillColor(sf::Color::Red);
  description.setPosition(350, 350);

  play_option.setFont(font);
  play_option.setString("Play");
  play_option.setCharacterSize(24);
  play_option.setFillColor(sf::Color::White);
  play_option.setPosition(400, 200);

  quit_option.setFont(font);
  quit_option.setString("Quit");
  quit_option.setCharacterSize(24);
  quit_option.setFillColor(sf::Color::White);
  quit_option.setPosition(650, 200);

  return true;
}

void Game::update(float dt)
{
  // Check for ship movement
  if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
    bearVelocity = -bearSpeed; // Move left
  } else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
    bearVelocity = bearSpeed; // Move right
  } else {
    bearVelocity = 0.0f; // Stop movement
  }

  // Calculate new ship position based on velocity
  float newBearX = defenderSprite.getPosition().x + (bearVelocity * dt);

  // Check bounds to prevent ship from going out of screen
  newBearX = std::max(0.0f, newBearX); // Clamp newShipX to be at least 0
  newBearX = std::min(newBearX, window.getSize().x - defenderSprite.getGlobalBounds().width); // Clamp newShipX to be at most window width - ship width

  defenderSprite.setPosition(newBearX, defenderSprite.getPosition().y);

}

void Game::render()
{
  if (in_menu)
  {
    // Render the menu
    window.draw(menu_text);
    window.draw(play_option);
    window.draw(quit_option);
    window.draw(description);
  }
  else
  {
    // Clear the window
    window.clear(sf::Color::Black);

    window.draw(backgroundSprite);

    // Render the defender ship sprite
    window.draw(defenderSprite);

    window.draw(tileSprite1);
    window.draw(tileSprite2);
    window.draw(tileSprite3);
    window.draw(tileSprite4);

  }

}

void Game::mouseClicked(sf::Event event)
{
  //get the click position
  sf::Vector2i click = sf::Mouse::getPosition(window);

}

void Game::keyPressed(sf::Event event)
{
  if (in_menu) {
    if (event.key.code == sf::Keyboard::Down) {std::cout << "Down" << std::endl;
      // Navigate up in the menu (e.g., move selection from "Play" to "Quit")
      if (play_selected) {
        play_selected = false;
        play_option.setFillColor(sf::Color::White);
        quit_option.setFillColor(sf::Color::Yellow);
      }
    } else if (event.key.code == sf::Keyboard::Up) {std::cout << "up" << std::endl;
      // Navigate down in the menu (e.g., move selection from "Quit" to "Play")
      if (!play_selected) {
        play_selected = true;
        quit_option.setFillColor(sf::Color::White);
        play_option.setFillColor(sf::Color::Yellow);
      }
    } else if (event.key.code == sf::Keyboard::Enter) {std::cout << "enter" << std::endl;
      // Select the currently highlighted menu option
      if (play_selected) {
        // Start the game
        in_menu = false;
      } else {
        // Quit the game
        window.close();
      }
    }
  }

}

```

So I want to make my character jump. this is my Game.cpp file with all my current functions. Currently, I've got my character and platforms rendered in (this is a platformer game). I want my character to jump and if the character is moving, for the character to continue to move during the jump.

# Answer
**Kinematic approach**

You could use the linear interpolation ("`lerp`") formula, along with some other function that create a curve (`3t^2 - 2t^3` for example). The problem with this is that being kinematic rather than physics-based, it does not respond well to dynamic circumstances such as collisions with other characters, or walls. So I would not use this approach here.

**Simple Physics-based approach**

```
vec2 characterPosition;
vec2 characterVelocity;

//(1) returns scalar speed as positive, negative or zero depending on walk control.
//(2) returns scalar speed as positive (jumping), negative (Falling), or zero depending on jump control.
characterVelocity.x = getScalarValueFromWalkInput(); //(1)
characterVelocity.y = getScalarValueFromJumpInput(); //(2)

//*apply equations of motion*
characterPosition = characterPosition + characterVelocity;

```

You could additionally use acceleration, in which case you would do something like:

```
vec2 characterPosition
vec2 characterVelocity;
vec2 characterAcceleration;

//(1) returns scalar acceleration as positive, negative or zero depending on walk control.
//(2) returns scalar acceleration as positive (jumping), negative (Falling), or zero depending on jump control.
characterAcceleration.x = getScalarValueFromWalkInput(); //(1)
characterAcceleration.y = getScalarValueFromJumpInput(); //(2)

//*apply equations of motion*
characterVelocity = characterVelocity + characterAcceleration;
characterPosition = characterPosition + characterVelocity;

```

...and then you would also need to careful control / limit maximum acceleration and velocity so that things don't move too quickly. Acceleration can give a more realistic / organic feel depending on your desired input controllers.

You will also have to understand how to do 2D collision detection and resolution in this case, which is a whole separate topic. For this reason, many people use libraries like Box2D, which handle the equations of motion for you, as well as collision detection and resolution.
> 0 votes

---
Tags: c++
---


# Question
Title: Correctly packing an RGBA color to a single float
I am trying to **render a colored quad** with LWJGL and OpenGL.

The vertices array is specified in interleaved format and look like this:

```
float[] vertices = {
    -0.5,0.5, MAGENTA_FLOAT,
    -0.5,-0.5, YELLOW_FLOAT,
    0.5,-0.5, RED_FLOAT,
    0.5,0.5, WHITE_FLOAT
};

```

I am trying to specify the colors as single float values. For this, I am packing each color using the following method:

```
public static float toFloatBits (int r, int g, int b, int a) {
    int color = (a << 24) | (b << 16) | (g << 8) | r;
    float floatColor = NumberUtils.intToFloatColor(color);
    return floatColor;
}

```

In my shader code, the attributes declarations look like this:

```
in vec2 a_position;
in vec4 a_color;

```

I expect the graphics driver to correctly interpret the float color value into 4 color components.

**Creating the VAO**

This is the snippet of creating the VAO:

```
vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);

int vbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
FloatBuffer interleavedBuffer = BufferUtils.createFloatBuffer(vertices.length);
interleavedBuffer.put(vertices).flip();
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, interleavedBuffer, GL15.GL_STATIC_DRAW);

int vertexSize = 2 * Float.BYTES + Integer.BYTES;
GL20.glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, vertexSize, 0);
GL20.glVertexAttribPointer(1, 1, GL11.GL_UNSIGNED_BYTE, true, vertexSize, Float.BYTES * 2);

GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);

```

I am not getting the expected result: the colors of the rendered quad are incorrect. (getting red where it should be green, getting all black, ignoring alpha even though blending enabled, etc.)

Can someone spot an error here?

# Answer
> 2 votes
You don't need to pack to a float for this to work.

You specify it as a 4-component byte array in your program code, with each component (of RGBA) in the range 0 to 255. Set up your vertex attrib pointer to use *size* 4, *type* GL\_UNSIGNED\_BYTE and *normalized* GL\_TRUE. Then set your shader code to read it as a vec4 and the conversion is automatic, nothing further required.

# Answer
> 0 votes
Ok, found where the problem was. Change the attribute length from 1 to 4:

incorrect:

```
GL20.glVertexAttribPointer(1, 1, GL11.GL_UNSIGNED_BYTE, true, vertexSize, Float.BYTES * 2);

```

correct:

```
GL20.glVertexAttribPointer(4, 1, GL11.GL_UNSIGNED_BYTE, true, vertexSize, Float.BYTES * 2);

```

---
Tags: opengl, rendering, lwjgl3
---


# Question
Title: How to structure my composite (player) object?
While learning about the Godot engine, I am trying to write a simple spaceships game.

A spaceship, as I have found out, can be defined as a scene of its own, with the following internal structure:

```
RigidBody2D            // the root of the scene
 |- Sprite2D           // the image representing the spaceship
 |- CollisionPolygon2D // the collision shape

```

Now, I can add this "Spaceship" scene into my main game scene, which then looks like this:

```
Node2D
 |- Spaceship             // instance of the above scene
     |- RemoteTransform2D // makes the camera follow the ship

```

In here, I have attached a C# script on the *Spaceship* node that does a simple check for input and calls methods like `AddConstantCentralForce` and `AddConstantTorque` n its `_Process` method to move the ship according to player input:

```
Node2D
 |- Spaceship + InputControl.cs
     |- RemoteTransform2D

```

So far, this works fine.

**Problem:** I also need (?) to attach a script to the root node of my *Spaceship* scene. That is because I want to dynamically add some additional nodes in there, depending on what is happening in the game, and I *think* the root object of the scene would be the appropriate place to handle this logic:

```
RigidBody2D + ManageShip.cs
 |- Sprite2D
 |- CollisionPolygon2D

```

But if I do this, it has no effect - the script on the root node of the *Spaceship* scene is *replaced* by the script on the *Spaceship* node in my main scene.

Possible alternatives:

* I do not want to integrate the input control script into the *Spaceship* scene, because only the player ship should be controlled like this, whereas I want to reuse the *Spaceship* scene also for enemy ships.
* I have tried to wrap the *Spaceship* node in a `Node2D` node in my main scene, but then I cannot attach my input control script because `Node2D` does not have the methods like `AddConstantCentralForce`:
```
Node2D
 |- Node2D + InputControl.cs
     |- Spaceship
         |- RemoteTransform2D

```
* I have tried to wrap the *Spaceship* node in a `RigidBody2D` node instead, but then, my input seems to have no effect because that `RigidBody2D` itself has no mass and/or shape (as is also pointed out by the Godot IDE with a warning symbol):
```
Node2D
 |- RigidBody2D + InputControl.cs
     |- Spaceship
         |- RemoteTransform2D

```

**What node type should I use instead? Is there a scene design guideline by Godot for this?**

Is the solution maybe to wrap *Spaceship* in just a `Node2D` and rewrite the input control script to find the nested `RigidBody2D` and call the methods on that instance?

But then, it seems that it would be my *Spaceship* scene flying around in this wrapping node rather than in the global space. That doesn't seem right. Or, looking at it differently, that would mean I could just as well handle input in a script on the main scene's root node (or anywhere else in the scene) and just notify the player object about the input. This will work, but is it the intended way to use Godot?

---

To elaborate on the workaround I suggested in the end, I have now implemented it like this:

Right below my main scene root, I have added a `Node2D` and attached `InputControl.cs` to it. On that node, I have added a metadata value named `PlayerNode` of type `NodePath` and assigned my *Spaceship* node from the same scene to it.

```
Node2D
 |- Spaceship + (whatever script is attached in the scene)
     |- RemoteTransform2D
 |- Node2D + InputControl.cs

```

The `InputControl` class now inherits from `Node2D` and has a `Player` property of type `RigidBody2D` that is used as the target of my calls to ship movement methods. I initialize the object as follows:

```
public override void _Ready()
{
    var player = GetNode(GetMeta("PlayerNode").AsNodePath()) as RigidBody2D;
    if (player == null)
    {
        throw new InvalidOperationException("Player object not found.");
    }

    Player = player;
}

```

This works, is easy to implement (once you know what API methods to use) and it's easy to understand, still - being a total beginner in Godot - I wonder **whether this is the way we're supposed to use Godot?**

# Answer
I have a very similar answer for the question What's the appropiate way to achieve composition in Godot?. *It is not accepted, so I can't vote to close this as duplicate. Please refer to it for a more elaborate use case. I'll focus on your use case for this answer.*

---

This is the gist: A node can manipulate its parent.

More precisely: Create a new script that handles input, and manipulate its parent based on said input. This new script is meant to attached to a node placed as child of your spaceship. So spaceships that do not have it, won't get input.

*You can think about it as adding a component to your spaceship.*

This approach has these advantages over the alternatives:

* If you want a different set of features you can have a different set of children component.
* The components are children, so they will naturally be moved with their parent when you are reorganizing the scene tree.
* In fact, components can be bundled in an scene with them. And you can take advantage of scene inheritance (open the context menu on your scene on the FileSystem dock, and select "New Inherited Scene").

---

If you really *really* don't want to do that, I have a couple alternatives for you:

* Yes, incorporating the input into your script would be the first idea to come to mind. I understand that you do not want to do that. A work-around would be to export `StringName` for the input actions, and if they are not set, do not run the input part of your code.

The drawback of this is that it makes your code more complex, and as you continue to add more optional features it will become harder to maintain.
* Alternatively you can resource to inheritance. Since Godot will be replacing the script you set in the scene with the one you set where you instance it... You can create a new class for it, which extends the one you use in the scene, and add whatever additional features you want.

On one hand you cannot toggle individual features during runtime. On the other, you need a new class for each combination of features you want.

Yet, right now you only have one optional feature, so these approaches are viable to you.

---

I'm aware that the Godot community has been saying to call down and signal up. I have repeated this advice myself. And yes, today I'm telling you to call up.

So, do not follow "call down and signal up" blindly. Understand it instead: If your nodes depend on other nodes that are not their children, when you are moving them in the scene tree, you might not notice if you place them such that they won't be able to find the nodes they need to work. And this will result in a runtime error much later.

Solutions to that problem include:

* Exporting a `Node`※ (Godot will keep it updated as you move nodes inside the scene).
* Using unique node names※ (Its relative position does not matter as long as it is in the same scene)
* Exporting a `NodePath` (Godot will keep it updated as you move nodes inside the scene).

※: These are a much more recent development than the "call down and signal up" advice.

Futhermore you can use a configuration warning (this requires a `@tool` script) to have your node tell you if it cannot find the nodes it need to work (this is similar to the `RigidBody2D` telling you that it does not have collision shapes, or a `PhysicalBone2D` telling you it is not a child of an `Skeleton2D`).

Note that exporting a `NodePath` is similar to what you are doing in your workaround, except you are using metadata for it instead of exporting a property (i.e. with `[Export]`).
> 0 votes

---
Tags: godot
---


# Question
Title: Unity WaitForSeconds without generating garbage
In Unity you can use:

```
    IEnumerator WaiterRoutine()
    {
        yield return new WaitForSeconds(<seconds as float>);
    }

```

To wait a number of seconds. But this generates garbage for the garbage collector. I have a routine that waits for a random number of seconds every time it runs. So it just continually creates garbage.

My question is: is there any reason not to wait like this instead:

```
    public static IEnumerator WaitForSeconds(float seconds)
    {
        float start = Time.time;
        while (Time.time < start + seconds)
        {
            yield return null;
        }
    }

```

and if not, then why the heck is this not part of Unity's libraries? Is new WaitForSeconds somehow optimized further? Like does it remove my routine from consideration rather than busy waiting?

Just trying to figure out an efficient way to handle waiting.

Here's the actual code in question:

```
    void OnEnable() => routine = StartCoroutine(SpiritCannon());
    void OnDisable() => StopCoroutine(routine);

    private IEnumerator SpiritCannon()
    {
        while (true)
        {
            yield return Helpers.WaitForSeconds(Random.Range(minWaitSecs, maxWaitSecs));
            animancer.Play(spiritAnimation[animationCycler.Next()]);
        }
    }

```

# Answer
> 2 votes
It sounds like the only way to use my code without consistently generating garbage is to code my example like this:

```
void OnEnable() => routine = StartCoroutine(SpiritCannon());
void OnDisable() => StopCoroutine(routine);

private IEnumerator SpiritCannon()
{
    while (true)
    {
        float seconds = Random.Range(minWaitSecs, maxWaitSecs);
        float start = Time.time;
        while (Time.time < start + seconds)
        {
            yield return null;
        }
        animancer.Play(spiritAnimation[animationCycler.Next()]);
    }
}

```

However, it should be possible to write a mutable custom yield instruction that doesn't generate garbage and can be modified/reused.

Here's unity's documentation.

And an example:

```
public class MutableWaitForSeconds : CustomYieldInstruction
{
    private float endTime;

    public MutableWaitForSeconds() : this(0f) { }
    public MutableWaitForSeconds(float seconds) => Reset(seconds);

    public void Reset(float seconds) => this.endTime = Time.time + seconds;

    public override bool keepWaiting => Time.time < endTime;
}

```

You would instantiate this custom yield instruction once, and then reuse it to avoid generating garbage.

# Answer
> 1 votes
Some time ago I actually found a solution for a garbage-free `WaitForSeconds`. Of course, as it was already mentioned, starting coroutines will always allocate memory. However, a certain fact about the WaitForSeconds class made it possible to simply reuse the same instance. The scheduler does not really store that `WaitForSeconds` instance internally. It just reads the wait time and forgets about the instance immediately. So all we have to do is change the internal float field of that instance.

This could be done with reflection, but since changing internal/private value type fields through reflection requires the value to be boxed, we're back to new garbage allocations. Though there's a solution. I made a small assembly over here that was simply written in IL and allowed me to manually call the constructor of the `WaitForSeconds` class again. This will not create a new instance, we just call the constructor which allows us to pass a new value and overwrite the current value.

So instead of:

```
yield return new WaitForSeconds(sec);

```

you can simply do:

```
yield return WaitForSecondsSingleton.Get(sec);

```

This will not allocate garbage as it uses a single `WaitForSeconds` instance. A bit hacky but works well.

Here's the compiled assembly and here's the IL source code.

# Answer
> 0 votes
With `WaitForSeconds` you directly queue the "resume" for its appropriate time. Haven't tested it but `WaitForSeconds` maybe is marginally faster (the longer the waiting period) because the checks/queuing is done "natively" by the engine and you don't do checks in addition to that it all the time. Using `WaitForSeconds` makes the code more straightforward to follow. When things get complex a lot of small readability issues quickly add up.

If your time is always the same you can avoid garbage by cashing `WaitForSeconds` as a `YeldInstruction` field and not generate a new one each time. BTW you can use the same cached one between multiple coroutines and that will not mess them up.

Your second example (while loop) advantage is that the time interval could change during wait. With `WaitForSeconds` once the wait begins you can not modify the wait time.

If you wait different amounts of time each time then the second example (with while loop) is probably better.

---
Tags: unity
---


# Question
Title: Abstracting the ability to attack using an ECS
As the title suggests, my question is how to abstract the concept of 'attacking' using an ECS (entity component system). The "game" I'm working on is a roguelike in real-time, where all enemies/NPCs/player is an Entity (just an Id) with components.

I read this link and it helped clarify some things about an attack system, but I'm still confused how to implement this with an ECS.

# Answer
> 1 votes
Whether your game uses an Entity-Component model, Inheritence Hierarchy, or some mixin of both strategies, it doesn't dictate what a combat system is within the scope of a game.

As Qqwy points out, we're discussing the notion of some damage modifier applied to health. The damage modifier can also affect the durability of the attacked entity's gear with time too, making it less useful with every attack made. You may need to factor in resistences, temporary stat modifiers too which could make an entity more powerful or more susceptable to damage.

My advice is design your combat system very high-level like. Consider what you want your combat system to involve and how it will behave. Once you have this guideline, you'll quickly notice what makes sense to be components.

One obvious idea would be to just create a CombatStatComponent that has all your stats. This could include the base stats an avatar can have, the extra stats they can acquire possibly from gear, resistence levels the avatar presently has. The combat system uses this components data to measure the damage possible between two entities when an attack is made. When the attack occurs, an event gets sent to the damaged entity with the damage done. It simply modifies it's health component's value.

But keep in mind, all the ECS does in this scenario is describe how you organize the code that makes up this combat system. But the internal steps the system must perform to apply some damage remains the same from a generalistic point of view regardless of how you manage entities as a whole.

# Answer
> 0 votes
I have an `Attack` component that has a boolean for the active status and a timestamp when I did swing the last time, like a swing timer.

The `AttackInputSystem` on the client will check that `Attack` component and if the corresponding key is pressed, it either sends a `StartAttackAction` or `StopAttackAction` depending on the active status of the `Attack` component.

The server has an `AttackActionSystem` that listens for those action events, and if the target is valid, updates the `Attack` component and confirms the action by sending an `EntityUpdateEvent` with the updated `Attack` component:

```
Entity player = operator.getPlayer();
Attack attack = player.getComponent(Attack.TYPE);
boolean wantsAttack = evt instanceof StartAttackAction;
if (attack.active() != wantsAttack) {
  if (!wantsAttack || validTarget(operator).isPresent()) {
    // update attack component
    attack = new Attack(wantsAttack, attack.timestamp());
    player.setComponent(attack);
    EventQueue eventQueue = operator.getEventQueue();
    eventQueue.publish(this, new EntityUpdateEvent(player.getId(), attack));
  }
}

```

The server also has an `AttackSystem` which will execute the attack by checking the conditions necessary to attack and sending an `AttackEvent`:

```
long now = System.currentTimeMillis();
Entity player = operator.getPlayer();
Attack attack = player.getComponent(Attack.TYPE);
if (attack.active()) {
  validTarget(operator).ifPresentOrElse(entity -> {
    if (now - attack.timestamp() > WEAPON_SPEED && inRange(player, entity) && isFacing(player, entity)) {
      eventQueue.publish(new AttackEvent(player.getId(), entity.getId()));
      player.setComponent(new Attack(true, now));
    }
  }, () -> {
    // toggle off auto attack
    Entity player = operator.getPlayer();
    eventQueue.publish(new EntityUpdateEvent(player.getId(), new Attack(false, now)));
  });
}

```

The `AnimationSystem` on the client takes the `Attack` component state to animate an 'ATTACK\_IDLE' animation and also plays the 'ATTACK' animation on `AttackEvent`.

The `DamageSystem` is responsible to react on the `AttackEvent` by updating the `Health` component, optionally creating the `DeathEvent`.

I'm not seeing yet how to transfer this into a more generic `AbilitySystem`. But it might give a good starting point.

---
Tags: entity-system
---


# Question
Title: How to mirror card placement over network
I'm not sure what logic I can use to place each card in the correct position. Example, I place in my middle drop zone (AllyDropZone (2)) and it appears the opposite way for my opponent (EnemyDropZone (2)). Right is (Host+client) and left is just a client.

Class `DropZone`:

```
public class DropZone : NetworkBehaviour, IDropHandler, IPointerEnterHandler, IPointerExitHandler
{
    public int row;
    public int col;

    public void OnPointerEnter(PointerEventData eventData)
    {
    }

    public void OnPointerExit(PointerEventData eventData)
    {
    }

    public void OnDrop(PointerEventData eventData)
    {
        Draggable d = eventData.pointerDrag.GetComponent<Draggable>();

        if (d != null)
        {

            if (CanDropCard(d))
            {
                d.parentToReturnTo = this.transform;
                Debug.Log(d.gameObject.name + " was dropped on " + gameObject.name);
            }
            else
            {
                Debug.Log("Cannot drop " + d.gameObject.name + " on " + gameObject.name + ". Incorrect placement.");
            }
        }
    }

    private bool CanDropCard(Draggable draggable)
    {
        // Checks to see if the card can be dropped on this spot
        if (gameObject.CompareTag("AllyDropZone") && draggable.isOwned)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

```

Class `PlayerManager`:

```
public class PlayerManager : NetworkBehaviour
{
    //Start of all network shared objects & variables//
    public GameManager GameManager;
    public GameObject PlayerCard;

    //All ally objects
    public GameObject AllyDropZone;
    public GameObject AllyDropZone1;
    public GameObject AllyDropZone2;
    public GameObject AllyDropZone3;
    public GameObject AllyDropZone4;
    public GameObject AllyHand;
    public GameObject AllyDeck;

    //All enemy object
    public GameObject EnemyDropZone;
    public GameObject EnemyDropZone1;
    public GameObject EnemyDropZone2;
    public GameObject EnemyDropZone3;
    public GameObject EnemyDropZone4;
    public GameObject EnemyHand;
    public GameObject EnemyDeck;

    //Lists that will hold ally and enemy drop zones resepctively
    public List<GameObject> AllyDropZones = new List<GameObject>();
    public List<GameObject> EnemyDropZones = new List<GameObject>();

    //Possible alternative Card List; same purpose but better way of getting it
    private List<GameObject> cards = new List<GameObject>();

    //Card list we are pulling from
    public static List<Card> cardList = new List<Card>();

    //Variable tracking current player
    public bool IsMyTurn = false;

    //Variables that are constantly kept synced across the network; Think seeing health all the time
    //Need to be used later combat system
    [SyncVar]
    int CardsPlayed = 0;
    int Health = 20;

    //End of declaration//

    //Start of actual code//

    //Runs the code below when Host+Client/Client button is selected
    public override void OnStartClient()
    {
        base.OnStartClient();

        GameManager = GameObject.Find("GameManager").GetComponent<GameManager>();

        //Connects hand and deck of both players to a variable by looking for objects with listed name
        AllyHand = GameObject.Find("AllyHand");
        AllyDeck = GameObject.Find("AllyDeck");
        EnemyHand = GameObject.Find("EnemyHand");
        EnemyDeck = GameObject.Find("EnemyDeck");

        //Connects each ally drop zones to each variable by looking for objects with listed name
        AllyDropZone = GameObject.Find("AllyDropZone");
        AllyDropZone1 = GameObject.Find("AllyDropZone (1)");
        AllyDropZone2 = GameObject.Find("AllyDropZone (2)");
        AllyDropZone3 = GameObject.Find("AllyDropZone (3)");
        AllyDropZone4 = GameObject.Find("AllyDropZone (4)");

        //Connects each enemy drop zones to each variable by looking for objects with listed name
        EnemyDropZone = GameObject.Find("EnemyDropZone");
        EnemyDropZone1 = GameObject.Find("EnemyDropZone (1)");
        EnemyDropZone2 = GameObject.Find("EnemyDropZone (2)");
        EnemyDropZone3 = GameObject.Find("EnemyDropZone (3)");
        EnemyDropZone4 = GameObject.Find("EnemyDropZone (4)");

        //Fills Ally list with ally drop zones
        AllyDropZones.Add(AllyDropZone);
        AllyDropZones.Add(AllyDropZone1);
        AllyDropZones.Add(AllyDropZone2);
        AllyDropZones.Add(AllyDropZone3);
        AllyDropZones.Add(AllyDropZone4);

        //Fills Enemy list will enemy drop zones
        EnemyDropZones.Add(EnemyDropZone);
        EnemyDropZones.Add(EnemyDropZone1);
        EnemyDropZones.Add(EnemyDropZone2);
        EnemyDropZones.Add(EnemyDropZone3);
        EnemyDropZones.Add(EnemyDropZone4);

        //Determines which player goes first; Whoever presses "Client" button goes first
        if (isClientOnly)
        {
            IsMyTurn = true;
        }

        //Message to show that client is running; appears in console tab
        Debug.Log("OnStartClient was activated");
    }

    //Starts server (Host + Client)
    [Server]
    public override void OnStartServer()
    {
        base.OnStartServer();

        //Adds a card to current card list
        cardList.Add(new Card(0, "Jester", 1, 1, 2, "+1 power for every other Jester card on the board", Resources.Load<Sprite>("placeHolder")));

        //Should output current card list to console
        Debug.Log(cardList);

        //Tells us that the server is running
        Debug.Log("OnStartServer was activated");
    }

    //Command that adds cards to players hands and grants authority
    [Command]
    public void CmdDealCards()
    {
        //Fills player's hand with a card and repeats 3 times
        for (int i = 0; i < 3; i++)
        {
            GameObject card = Instantiate(PlayerCard, new Vector2(0, 0), Quaternion.identity);
            NetworkServer.Spawn(card, connectionToClient);

            //Tells which card has been drawn
            Debug.Log("Drawing card" + i);

            //Sets current status of the card to "Dealt" which makes it appear in hand for the Server
            RpcShowCard(card, "Dealt");
        }

        //Changes game manager current state
        RpcGMChangeState("Compile");
    }

    //Calls upon CmdPlayCard
    public void PlayCard(GameObject card)
    {
        CmdPlayCard(card);
    }

    //Calls upon RocShowCard
    [Command]
    void CmdPlayCard(GameObject card)
    {
        RpcShowCard(card, "Played"); //Sets current status of the card to "Played" which makes it appear in a drop zone for the Server
    }

    //Actual function that moves the recently added card to hand and/or drop zone
    [ClientRpc]
    void RpcShowCard(GameObject card, string type)
    {
        if(type == "Dealt") // "Dealt" cards are placed into player's hand and checking ownership allows for it mirror
        {
            if (isOwned)
            {
                card.transform.SetParent(AllyHand.transform, false);
            }
            else
            {
                card.transform.SetParent(EnemyHand.transform, false);
            }
        }
        else if(type == "Played") // "Played" cards are placed into a player's drop zone and check mirror condition
        {
            if (isOwned)
            {
                //card.transform.SetParent(AllyDropZone.transform, false);
            }
            else
            {
                //card.transform.SetParent(EnemyDropZone.transform, false);
            }
        }
    }

    [ClientRpc]
    void RpcGMChangeState(string stateRequest)
    {
        GameManager.ChangeGameState(stateRequest);
    }
}

```

# Answer
This is a rather simple solution for 2 players, but can be used for any number of players with a small tweak.

Alice and Bob are playing. The game logic states: Alice got a card. This card arrives with that information at both clients. When we check that on Alice client, we know it is our card and place it on AllyHand, AllyDeck, AllyDropZone, etc. On Bobs client, have the same information but since Bob knows it is Alice card, his PlayerManager places it on the corresponding EnemyDrop location.

If you have more players, just use numbers for the location. Assign yourself the number 1 (or whichever number is in front of you). The server is providing a list of all players and in which order they are going. Find yourself on that list. Your player manager assigns the number 2 to the player after you in that list. Location 3 the player after. Continue until all locations are done. Now when the server sents information like: Player 3 gets a card, you make a lookup in your list which location you assigned to Player 3. Since that happens on each client, everyone can have the place in front of them for themself and the cards are placed visually correct in play order.

You should as well not use GameObject.Find("XYZ") for all those locations, since your GameObjects are already public, just assign them in the editor.
> 1 votes

---
Tags: unity, mirror-networking
---


# Question
Title: How do you get the world position from the screen position in a URP shader graph used in a ScriptableRenderPass?
I'm using a shader graph in the Universal Shader Pipeline (URP) to do some post-processing in a ScriptableRenderPass. How do I get the world coordinates of the screen position?

I have tried using the View Direction node, set to World:

And I have tried the Screen Position node, with either a Transform node or Transformation Matrix node:

Neither seems to be working because the colors change as I move the camera around, but I would expect the color to stay the same since the world position of the GameObject in the view is not changing. Any suggestions?

# Answer
Here's how I've done it in the past:
> 0 votes

# Answer
I'm not 100% sure what you are after from your description, but this appears to do it:

Here is a project demonstrating a colour effect that stays on the horizon as the camera rotates: https://github.com/paulsinnett/PostProcessFullScreenURP
> 0 votes

---
Tags: unity, unity-shader-graph
---


# Question
Title: How can I get all DontDestroyOnLoad GameObjects?
I need to Destroy all `DontDestroyOnLoad` GameObjects. But in order to do this, I first need to find them all. I would prefer to automate this, opposed to having to manually reference each one.

`DontDestroyOnLoad` GameObjects seem to all be in the shared scene, `"DontDestroyOnLoad"`. So I tried collecting all root GameObjects from this Scene, but it says it is an invalid scene.

```
private void DestroyDontDestroyOnLoadGameObjects()
{
    var dontDestoyOnLoadScene = SceneManager.GetSceneByName("DontDestroyOnLoad");
    var dontDestroyOnLoadGameObjects = dontDestoyOnLoadScene.GetRootGameObjects();
    foreach (var dontdestroyGameObject in dontDestroyOnLoadGameObjects)
    {
        Destroy(gameObject);
    }
}

```

How can I Destroy all of the GameObjects that have `DontDestroyOnLoad` called on them?

# Answer
> 12 votes
Here's a cheeky little hackish method that **works only in the Editor**. We can't find the DontDestroyOnLoad scene by name, but every DontDestroyOnLoad'ed GameObject holds a reference to it. So, if we have a reference to just one such object (or create such an object) then we can get to all of them:

```
public void DestroyAllDontDestroyOnLoadObjects() {

   var go = new GameObject("Sacrificial Lamb");
   DontDestroyOnLoad(go);

   foreach(var root in go.scene.GetRootGameObjects())
       Destroy(root);

}

```

You can avoid creating a sacrificial object every time you need to operate on this list of objects by referencing one such object you know you'll always have in existence (say, the manager object that this script itself resides on), or by performing the ritual sacrifice once early in the run and caching a reference to the scene to use from then on (in my tests, it remains valid even after all its objects have been destroyed and new objects are marked DDOL)

Note that according to the docs this trick won't work in a a built game:

> You do not have access to the DontDestroyOnLoad scene and it is not available at runtime.

Trying to access this scene will throw an exception complaining that the scene is invalid.

---

If the ritual sacrifice turns your stomach (with fair cause, I'd say) or **if you need this at runtime in a built game**, a more conventional approach would be to introduce a DontDestroyOnLoadManager like this:

```
public static class DontDestroyOnLoadManager
{
    static List<GameObject> _ddolObjects = new List<GameObject>();

    public static void DontDestroyOnLoad(this GameObject go) {
       UnityEngine.Object.DontDestroyOnLoad(go);
       _ddolObjects.Add(go);
    }

    public static void DestroyAll() {
        foreach(var go in _ddolObjects)
            if(go != null)
                UnityEngine.Object.Destroy(go);

        _ddolObjects.Clear();
    }
}

```

Then you can replace any instance of `DontDestroyOnLoad(someObject)` elsewhere in your codebase with `someObject.DontDestroyOnLoad()` (here I'm using an extension method to keep it concise, but you can also call it through your manager class explicitly). This wraps the native DontDestroyOnLoad and also performs the necessary bookkeeping to find all those objects later. The downside is if you have additional 3rd-party scripts & plugins that call DontDestroyOnLoad, you'd need to modify them to be tracked by this system.

# Answer
> 0 votes

public class DeleteDontDestroyOnLoad : MonoBehaviour
{
    void Start()
    {
        // Get all root GameObjects in the scene
        GameObject[] rootObjects = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects();

        // Loop through each root GameObject
        foreach (GameObject rootObject in rootObjects)
        {
            // Check if the GameObject is marked as DontDestroyOnLoad
            if (IsDontDestroyOnLoad(rootObject))
            {
                // Destroy the GameObject
                Destroy(rootObject);
            }
        }
    }

    bool IsDontDestroyOnLoad(GameObject obj)
    {
        // Check if the GameObject has DontDestroyOnLoad flag
        return obj.scene.name == null;
    }
}
```

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


# Question
Title: Having a problem with tangent/bitangent calculation for my meshes
Hy Guys, I have a very specific problem according to normal mapping. I am writing a very simple 3D engine just for fun, following the tutorials at "LearnOpenGL.com". So far, it is working well. I am now trying to implement normal mapping to the engine, following the tutorial found here: "LearnOpenGL/Advanced Lighting/Normal mapping". I have a very simple shader with a point light:

Vertex shader:

```
#version 460 core
layout (location = 0) in vec3 vertexPosition_modelspace;
layout (location = 1) in vec3 vertexNormal;
layout (location = 2) in vec2 texture_coord;
layout (location = 4) in vec3 aTangent;
layout (location = 5) in vec3 aBitangent;

struct pointLight{
   vec3 position;
   float constant;
   float linear;
   float quadratic;
   vec3 ambient;
   vec3 diffuse;
   vec3 specular;
   bool present;
};

uniform mat4 model;
uniform mat4 view;
uniform vec3 viewPos;
uniform mat4 projection;
uniform pointLight light;

out VS_OUT{
   vec3 normal;
   vec3 FragPos;
   vec3 vColor;
   vec2 texCoord;
   vec3 TangentLightPos;
   vec3 TangentViewPos;
   vec3 TangentFragPos;
} vs_out;
void main()
{
   vs_out.vColor = vec3(1.0);
   vs_out.FragPos = vec3(model * vec4(vertexPosition_modelspace, 1.0));

   mat3 normalMatrix = transpose(inverse(mat3(model)));
   vec3 T = normalize(normalMatrix * aTangent);
   vec3 N = normalize(normalMatrix * vertexNormal);
   T = normalize(T - dot(T, N) * N);
   vec3 B = cross(N, T);

   mat3 TBN = transpose(mat3(T, B, N));
   vs_out.TangentLightPos = TBN * light.position;
   vs_out.TangentViewPos  = TBN * viewPos;
   vs_out.TangentFragPos  = TBN * vs_out.FragPos;

   vs_out.normal = vec3(vec4(normalMatrix * vertexNormal, 0.0));
   vs_out.texCoord = texture_coord;
   gl_Position = projection * view * vec4(vs_out.FragPos, 1.0);
}

```

Fragment shader:

```
#version 460 core
struct Material{
   float roughness;
   float shininess;
   float alpha;
   vec3 ambient;
   vec3 diffuse;
   vec3 specular;
   sampler2D texture_diffuse1;
   sampler2D texture_specular1;
   sampler2D texture_normal1;
};

struct pointLight{
    vec3 position;

    float constant;
    float linear;
    float quadratic;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    bool present;
};

//input data
in VS_OUT{
    vec3 normal;
    vec3 FragPos;
    vec3 vColor;
    vec2 texCoord;
    vec3 TangentLightPos;
    vec3 TangentViewPos;
    vec3 TangentFragPos;
} fs_in;

// Values that stay constant for the whole mesh.
uniform vec3 viewPos;
uniform pointLight point_light;
uniform Material material;

// output data
out vec4 FragColor ;

vec3 CalcPointLight(pointLight light, vec3 normal, vec3 viewDir, vec3 material_tex, vec3 material_tex_specular);

void main()
{
    vec3 material_tex = texture(material.texture_diffuse1, fs_in.texCoord).rgb;
    vec3 material_tex_specular = texture(material.texture_specular1, fs_in.texCoord).rgb;

    // obtain normal from normal map in range [0,1]
    vec3 norm = texture(material.texture_normal1, fs_in.texCoord).rgb;
    // transform normal vector to range [-1,1]
    norm = normalize(norm * 2.0 - 1.0);  // this normal is in tangent space

    vec3 result_light = CalcPointLight(point_light, norm, normalize(fs_in.TangentViewPos - fs_in.TangentFragPos), material_tex, material_tex_specular);
    FragColor = vec4(result_light.rgb, material.alpha);
}

vec3 CalcPointLight(pointLight light, vec3 normal, vec3 viewDir, vec3 material_tex, vec3 material_tex_specular){
    // ambient
    vec3 ambient = light.ambient * material_tex;

    // diffuse
    vec3 lightDir = normalize(fs_in.TangentLightPos - fs_in.TangentFragPos);
    float diff = max(dot(lightDir, normal), 0.0);
    vec3 diffuse = light.diffuse * diff * material_tex;

    //specular blinn shading:
    vec3 halfwayDir = normalize(lightDir + viewDir);
    float spec = pow(max(dot(normal, halfwayDir), 0.0), material.shininess);

    vec3 specular = light.specular * spec * material_tex_specular;

    // attenuation
    float dist    = length(light.position - fs_in.FragPos);
    float attenuation = 1.0 / (light.constant + light.linear * dist + light.quadratic * (dist * dist));

    ambient  *= attenuation;
    diffuse   *= attenuation;
    specular *= attenuation;

    if(material.shininess <= 0.0){
        return (ambient + diffuse);
    }else{
        return (ambient + diffuse + specular);
    }
}

```

With a mesh imported with the assimp importer library (github.com/assimp/assimp), this shader works really well - no issues at all. But in this case the tangent and bitangent are calculated by the assimp importer lib.

However, when it comes to my own meshes it is a different story. For my own meshes I have to generate the tangent and bitangent myself. Therefore I used the algorithm shown at LearnOpenGL/Normalmapping and extended it to be able to go over several triangles in a mesh (btw: my meshes are all index vertex arrays). This looks like this:

```
void my3DEngineVertexObject::calculateTangentsIndexed(vertex* vertex_array, size_t nr_vertices, GLuint* indices, size_t nr_indices) {
    //iterate the indices array
    for(size_t i = 0; i < nr_indices; i+=3){ //we need to handle 3 vertices --> one triangle
        //calculate indices
        unsigned int i1 = indices[i];
        unsigned int i2 = indices[i + 1];
        unsigned int i3 = indices[i + 2];

        glm::vec3 edge1 = glm::vec3(vertex_array[i2].pos.x, vertex_array[i2].pos.y, vertex_array[i2].pos.z) - glm::vec3(vertex_array[i1].pos.x, vertex_array[i1].pos.y, vertex_array[i1].pos.z);
        glm::vec3 edge2 = glm::vec3(vertex_array[i3].pos.x, vertex_array[i3].pos.y, vertex_array[i3].pos.z) - glm::vec3(vertex_array[i1].pos.x, vertex_array[i1].pos.y, vertex_array[i1].pos.z);
        glm::vec2 deltaUV1 = glm::vec2(vertex_array[i2].texCoord.u, vertex_array[i2].texCoord.v) - glm::vec2(vertex_array[i1].texCoord.u, vertex_array[i1].texCoord.v);
        glm::vec2 deltaUV2 = glm::vec2(vertex_array[i3].texCoord.u, vertex_array[i3].texCoord.v) - glm::vec2(vertex_array[i1].texCoord.u, vertex_array[i1].texCoord.v);

        // calculate tangent.
        float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
        glm::vec3 tangent = f * (deltaUV2.y * edge1 - deltaUV1.y * edge2);

        // calculate bitangent.
        glm::vec3 bitangent = f * (-deltaUV2.x * edge1 + deltaUV1.x * edge2);

        vertex_array[i1].tangent = tangent;
        vertex_array[i2].tangent = tangent;
        vertex_array[i3].tangent = tangent;

        vertex_array[i1].bitangent = bitangent;
        vertex_array[i2].bitangent = bitangent;
        vertex_array[i3].bitangent = bitangent;
    }
}

```

Since it worked for the tutorial, I thought I can extrapolate this to my vertex arrays and it should work these to - but it didn't, as you can see in the pictures below. My own plane (500x500 vertices) lit by a single point light and using this normal map, it looks quite off:

It seems that the normal mapping is "ok" for one half of the plane, the other half looks like it lays in darkness.

Similar problem for the cube with the brick wall (using this normal map):

I am not sure if it matters, but these are the vertices used for the cube:

```
static vertex cube_vertices[] = {
    // positions             // normals             // TexCoord    // color
    // back (red)
    {{-0.5f, -0.5f, -0.5f},  { 0.0f,  0.0f, -1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f, -0.5f, -0.5f},  { 0.0f,  0.0f, -1.0f}, {1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f,  0.5f, -0.5f},  { 0.0f,  0.0f, -1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{-0.5f,  0.5f, -0.5f},  { 0.0f,  0.0f, -1.0f}, {0.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    // front (green)
    {{-0.5f, -0.5f,  0.5f},  { 0.0f,  0.0f,  1.0f}, {0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f, -0.5f,  0.5f},  { 0.0f,  0.0f,  1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f,  0.5f,  0.5f},  { 0.0f,  0.0f,  1.0f}, {1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{-0.5f,  0.5f,  0.5f},  { 0.0f,  0.0f,  1.0f}, {0.0f, 1.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    // left (blue)
    {{-0.5f, -0.5f, -0.5f},  {-1.0f,  0.0f,  0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{-0.5f, -0.5f,  0.5f},  {-1.0f,  0.0f,  0.0f}, {1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{-0.5f,  0.5f,  0.5f},  {-1.0f,  0.0f,  0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{-0.5f,  0.5f, -0.5f},  {-1.0f,  0.0f,  0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    // right (yellow)
    {{ 0.5f, -0.5f, -0.5f},  { 1.0f,  0.0f,  0.0f}, {0.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f, -0.5f,  0.5f},  { 1.0f,  0.0f,  0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f,  0.5f,  0.5f},  { 1.0f,  0.0f,  0.0f}, {1.0f, 1.0f}, {1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f,  0.5f, -0.5f},  { 1.0f,  0.0f,  0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    // underside (magenta)
    {{-0.5f, -0.5f, -0.5f},  { 0.0f, -1.0f,  0.0f}, {0.0f, 0.0f}, {1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f, -0.5f, -0.5f},  { 0.0f, -1.0f,  0.0f}, {1.0f, 0.0f}, {1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f, -0.5f,  0.5f},  { 0.0f, -1.0f,  0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{-0.5f, -0.5f,  0.5f},  { 0.0f, -1.0f,  0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    // upperside (cyan)
    {{-0.5f,  0.5f, -0.5f},  { 0.0f,  1.0f,  0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f,  0.5f, -0.5f},  { 0.0f,  1.0f,  0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{ 0.5f,  0.5f,  0.5f},  { 0.0f,  1.0f,  0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
    {{-0.5f,  0.5f,  0.5f},  { 0.0f,  1.0f,  0.0f}, {0.0f, 1.0f}, {0.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}
};

```

And this is my algorithm to generate the plane:

```
my3DEngineObjectPlane::my3DEngineObjectPlane(GLuint xRes, GLuint yRes) {
    if (xRes > 1 && yRes > 1) {
        vertex* vertices = new vertex[xRes * yRes]; //memory for vertices

        unsigned int index = 0;

        // create vertices
        for (unsigned int y = 0; y < yRes; y++) {
            for (unsigned int x = 0; x < xRes; x++) {

                vertices[index].pos.x = ((GLfloat)x / (GLfloat)(xRes - 1)) - 0.5f; // -0.5 for centering the origin of the plane in the center of the plane
                vertices[index].pos.y = 0.0f;
                vertices[index].pos.z = ((GLfloat)y / (GLfloat)(yRes - 1)) - 0.5f;

                vertices[index].color = glm::vec3(1.0f, 0.0f, 1.0f);

                vertices[index].texCoord.u = ((GLfloat)x / (GLfloat)(xRes-1));
                vertices[index].texCoord.v = ((GLfloat)y / (GLfloat)(yRes-1));

                vertices[index].normal = glm::vec3(0.0f, 1.0f, 0.0f);

                vertices[index].tangent = glm::vec3(0.0f, 0.0f, 0.0f);
                vertices[index].bitangent = glm::vec3(0.0f, 0.0f, 0.0f);
                index++;
            }
        }

        // create indices for GL_TRIANGLES
        GLuint* indices = new GLuint[(yRes - 1) * (xRes - 1) * 2 * 3]; // memory for indices - 2 triangles per square, 3 indices per triangle
        index = 0;
        for (unsigned int y = 0; y < yRes - 1; y++) {
            for (unsigned int x = 0; x < xRes - 1; x++) {
                indices[index++] = yRes * y + x;
                indices[index++] = yRes * y + x + xRes;
                indices[index++] = yRes * y + x + xRes + 1;

                indices[index++] = yRes * y + x;
                indices[index++] = yRes * y + x + xRes + 1;
                indices[index++] = yRes * y + x + 1;
            }
        }

        size_t vertex_size = (size_t)xRes * (size_t)yRes * sizeof(vertex);
        size_t index_size = (size_t)((xRes - 1) * (yRes - 1) * 2 * 3) * sizeof(GLuint);

        calculateTangentsIndexed(vertices, (size_t)(xRes*yRes), indices, (size_t)((yRes - 1) * (xRes - 1) * 2 * 3));

        addVertexDataIndexed((GLfloat*)vertices, indices, vertex_size, index_size, GL_TRIANGLES, true, true, true, true);

        if (vertices != nullptr) delete[] vertices;
        if (indices != nullptr) delete[] indices;
    }
}

```

I desperatly need some help from far more seasoned people then me here. It seems I am close, but missing some crucial detail. I first thought, that my base normals are off, but as you can see at the cube, the yellow normals seem alright for me. However, for the plane the normals seem to be off:

When I visualize the tangent from the sahder it looks like this:

TangentViewPos - changes with the camera movement:

TangentFragPos - something seems off here:

TangentLightPos - something is definitly off here:

# Answer
> 0 votes
I have found all my problems in the code:

The first issue with normal mapping not working at all was that my vertex array was organized differently to what I told openGL. Therefore openGL interpreted my vertex normals as color and vice versa.

The second issue with the cube, was that the light position was not updated correctly resulting that the light was inside the cube and the cube was not lit correctly. I only noticed the bug when I started to try to move the light and nothing in the scene changed according to lighting.

---
Tags: opengl, normal-mapping
---


# Question
Title: How can I calculate vertex positions for a rectangle outline using a unit square, vertex normals, model matrix and outline thickness?
I'm trying to draw a hollow rectangle (i.e. the border of a rectangle without the middle) using a unit square plus normals. The actual positions are being calculated in my vertex shader.

For example, without worrying about the outline for a moment, the unit square positions multiplied by my model matrix gives:

```
0,0 ___ 1,0           10,10 ___ 60,10
   |   |     becomes       |   |
   |   |                   |   |
0,1 --- 1,1           10,60 --- 60,60

```

I think multiplying a normalised position by the scale to get the real size is reasonably well understood. The problem I am having is how to apply this same principle to producing an outline made of 8 triangles.

Assuming that the outline increases the size of the shape, I can find the inside points using the above approach. But the outer points are problematic and I can't quite figure out how to calculate them with the information I have available.

The formula without using a transformation matrix is relatively straightforward:

```
((vertex_position * scale + vertex_normal * outline_thickness) * rotation) + translation

```

I've made quite a few attempts at this, and I thought I could simply add the `vertex_normal * thickness` calculation to the scale components of the model matrix:

```
let ty = r_pc.info.x;
let thickness = r_pc.info.y;
let is_fill = select(false, true, ty >= 0.5 && ty < 1.5);
let is_outline = select(false, true, ty >= 1.5 && ty < 2.5);

var model = r_pc.model;
var position = vec4(vertex.position, 0.0, 1.0);
if is_outline {
    // Add thickness to model's scale components.
    var width = vertex.normal * thickness;
    model[0][0] += width.x;
    model[1][1] += width.y;
}
position = r_camera.view_proj * model * position;

let color = r_pc.color;
let uv = vertex.uv;

return VsOut(position, color, uv);

```

But that left me missing the top-left half of the outline!

I understand why that would be - it's a multiplication by 0. I think combining the transformations in the way I have done is not quite accurate. I believe I need to scale the point first, then add the translation along the normal, before applying the rotation and translation.

I don't know how to construct such a matrix when the only information I have available is:

* vertex position (normalised)
* vertex normal (or mitre joint)
* model matrix describing the rectangle (not the outline extent)
* outline thickness (not normalised)

Given this information, is it possible to calculate the position of the outer vertices and how? If not, what additional information do I need and how?

# Answer
I have updated my Unity project which I think does what you want: https://github.com/paulsinnett/RectangleOutlineShader

As long as you stick to integer coordinates, scales, and widths, I think it should be solid.

Here is the new code to generate the geometry:

```
using UnityEngine;

public class OutlineBox : MonoBehaviour
{
    void Start()
    {
        MeshFilter meshFilter = GetComponent<MeshFilter>();
        Mesh mesh = new Mesh
        {
            name = "OutlineBox"
        };
        meshFilter.mesh = mesh;

        mesh.vertices = new Vector3[]
        {
            new Vector3(0.0f, 1.0f, 0f),
            new Vector3(1.0f, 1.0f, 0f),
            new Vector3(1.0f, 0.0f, 0f),
            new Vector3(0.0f, 0.0f, 0f),
            new Vector3(0.0f, 1.0f, 0f),
            new Vector3(1.0f, 1.0f, 0f),
            new Vector3(1.0f, 0.0f, 0f),
            new Vector3(0.0f, 0.0f, 0f)
        };

        mesh.uv = new Vector2[]
        {
            // note: in clip space y is upside down
            new Vector2(-1.0f, -1.0f),
            new Vector2(1.0f, -1.0f),
            new Vector2(1.0f, 1.0f),
            new Vector2(-1.0f, 1.0f),
            new Vector2(0.0f, 0.0f),
            new Vector2(0.0f, 0.0f),
            new Vector2(0.0f, 0.0f),
            new Vector2(0.0f, 0.0f)
        };

        mesh.triangles = new int[]
        {
            0, 1, 5,
            0, 5, 4,
            1, 2, 6,
            1, 6, 5,
            2, 3, 7,
            2, 7, 6,
            3, 0, 4,
            3, 4, 7
        };
    }
}

```

Notes: I've switched to passing the mitre data into the uv channel because I think the normal data might get corrupted by vertex compression if its not length 1 data. Also the y directions are reversed as in Unity, the clip space is the other way up.

Here is the modified shader code:

```
Shader "Unlit/OutlineBoxShader"
{
    Properties
    {
        _Width ("Outline Width", Range(0, 10)) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

            float _Width;

            v2f vert (appdata v)
            {
                v2f o;
                float4 clip = UnityObjectToClipPos(v.vertex);
                // in Unity clip space is -1 to 1 so pixels are twice the size
                float2 pixelSize = 2 * (_ScreenParams.zw - float2(1, 1));
                clip.xy += v.uv * _Width * pixelSize;
                o.vertex = clip;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return fixed4(1, 1, 1, 1);
            }
            ENDCG
        }
    }
}

```

Notes: the \\$\times 2\\$ is needed to calculate the pixel size in Unity because in clip space the screen is -1 to 1, whereas the screen space it is 0 to 1.
> 1 votes

---
Tags: matrix, transformation, geometry, vertex
---


# Question
Title: Broken graphics in a compiled Android application
Why is it that when I compile this application in Unity for Android, the graphics completely break (camera image output). Maybe I need to set something special in the Player settings? I'm using the SLAM-ARLab library on GitHub.

# Answer
> 1 votes
It was a Unity bug with getting `WebCamTexture`, I changed the resolution (height and width) to 640x480, and everything worked.

---
Tags: unity, android, architecture, augmented-reality
---


# Question
Title: Xcode Build Failure: Unity Framework Error -> Undefined Symbol (IL2CPP Related)
I've been building Unity iOS projects to iOS devices for years and I've rarely had issues with errors in Xcode. This is probably because I rarely change anything in the Xcode project and just use whatever Unity generates out of the build process. However, after I downloaded Unity 2021.3.36 I am now unable to deploy my builds due to errors:

As you can see the errors are all IL2CPP related. I don't know how to resolve these, I've looked online but I cannot find anything that works. The errors are occurring with builds generated by Unity 2021.3.36f1 and 2020.3.46. Both are using the IL2CPP scripting backend.

Please could someone help me resolve these errors? I am stuck right now and cannot make any progress. Help would be greatly appreciated.

**The error messages are as follows:**

* Undefined symbol: il2cpp codegen get\_virtual call\_ method pointer (Methodinfo const\*)
* Undefined symbol: il2cpp codegen get generic\_virtual\_ method\_internal (Methodinfo const\*, Methodinfo const\*, VirtualInvokeData\*)
* Linker command failed with exit code 1 (use - to see invocation)

I was using Unity 2020.3.46f1 for about 3 years, no issues. I then installed 2022.3.21 and was able to deploy builds, no issues. I then uninstalled 2022.3.21 and installed 2021.3.36. This is when the issues started. I now get these errors whenever I try to deploy a build in 2021.3.36 and 2020.3.46, so I am completely stuck.

I use a very simple build process with minimal customization:

* I open Unity -\> File -\> Build Settings -\> Build.
* I then open the Xcode project that this generates, and simply deploy that to my device.

That's literally it, I don't have any custom processes or anything like that.

# Answer
I finally found a fix for this. It needs to be done in Xcode as follows:

Xcode \> Product \> Clean Build Folder

The errors will then clear and the build will deploy as expected.
> 3 votes

---
Tags: unity, ios, xcode, il2cpp
---


# Question
Title: In Godot, how do I reposition the center of my mesh?
When importing a Unity package to Godot via Unidot importer, I noticed that a few imported models have their child rotations and transformations off-center from their expected points.

For example, here is a model of a toilet seat. In Unity, if I adjust the `x` rotation of the lid, it rotates at the hinge to appear closed.

But in Godot, it rotates like this:

How do I resolve this? Apologizes if this is obvious, I am not experienced in 3D modeling.

# Answer
I figured out the answer. When it imported the model, it added some values in its transform (which I reverted in the picture), I just needed to add the inverse of that transform in the mesh renderer.
> 0 votes

---
Tags: rotation, godot, mesh, godot-4
---


# Question
Title: 400 errors for half my tiles in Map Tiles API
I have this error below for about half of my tiles (see screenshot). What can be wrong. It used to work just fine. I haven't made any edit related to the API to my scene. From my understanding, the issue happened overnight. Why does it happen and how may I fix it?

```
[2024-03-17 19:57:20.055] [error]
[TilesetJsonLoader.cpp:889] Received status code 400 for tile content
https://tile.googleapis.com/v1/3dtiles/datasets/CgA/files/UlRPVEYubm9kZWRhdGEucGxhbmV0b2lkPWVhcnRoLG5vZGVfZGF0YV9lcG9jaD04ODAscGF0aD0yMTYwNDE1MjUyNTE0MjcxNDQyLGNhY2hlX3ZlcnNpb249NixhbGlnbm1lbnRfdmVyc2lvbj1ST0NLVFJFRV85NjlfR09PR0xFX0RBVFVNXzIwMjMxMjA1VDA3NTNaX2dlbmVyYXRlZF9hdF8yMDI0MDIyMVQxMzA5Wg.glb?session=CLrnutPxmpqeahDDvdyvBg&key=xxx

```

I am using Unity version control, maybe something went wrong there?

# Answer
> 2 votes
400 is the Bad Request status code due to something that is perceived to be a client error - in other words, it's not proceeding due to something it believes is an error from your end.

If you go to the URL in your error message (as linked here), it states:

```
[{
  "error": {
    "code": 400,
    "message": "API key not valid. Please pass a valid API key.",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "API_KEY_INVALID",
        "domain": "googleapis.com",
        "metadata": {
          "service": "tile.googleapis.com"
        }
      }
    ]
  }
}
]

```

This part: `"message": "API key not valid. Please pass a valid API key."`, seems self explanatory - it doesn't like your API key. It may be that your key expired or that an error was introduced in your source somehow. Regardless of how it got that way, it appears like your API key is the problem.

# Answer
> 0 votes
It can happen if your internet connection is bad or interrupted.

---
Tags: unity, maps, augmented-reality
---


title: Pin object to the end of a rope

text:
# Question
Title: Pin object to the end of a rope
I'm trying to make a cool simulation where a rope swings with an object attached to its end. I've set up the rope using Verlet integration and used Hooke's law to attach the object. But here's the catch: the object's movement is all over the place!

I thought about just sticking the object to the end of the rope by setting its position to the rope last point's position, but this method won't account for the forces acting on the object, such as gravity.

Here's the code I'm using:

```
extends Node3D

class VerletRope:

    class Point:
        var locked: bool = false
        var pos: Vector3 = Vector3()
        var last_pos: Vector3 = Vector3()

        func _init(pos: Vector3, locked: bool = false):
            self.pos = pos
            self.last_pos = pos
            self.locked = locked

    class Stick:
        var point_a: Point
        var point_b: Point
        var length: float

        func _init(point_a: Point, point_b: Point, length: float):
            self.point_a = point_a
            self.point_b = point_b
            self.length = length

    var points: Array[Point] = []
    var sticks: Array[Stick] = []
    var gravity = 100.0
    var num_iterations = 30

    func _init(from: Vector3, to: Vector3, segment_distance: float, num_iterations: int = 30, gravity: float = 100.0) -> void:
        self.gravity = gravity
        self.num_iterations = num_iterations

        var rope_length = from.distance_to(to)
        var dir = from.direction_to(to)
        var segment_count = int(rope_length / segment_distance)
        var last_point = null

        for i in range(segment_count + 1):
            var pos = from + dir * (i * segment_distance)
            var point = Point.new(pos)
            self.points.append(point)

            if last_point:
                var length = last_point.pos.distance_to(point.pos)
                var stick = Stick.new(last_point, point, length)
                self.sticks.append(stick)

            last_point = point

    func simulate(delta: float) -> void:
        for point in points:
            if not point.locked:
                var last_pos = point.pos
                point.pos += point.pos - point.last_pos
                point.pos += Vector3.DOWN * gravity * delta * delta
                point.last_pos = point.pos

        for i in range(num_iterations):
            for stick in sticks:
                var center = (stick.point_a.pos + stick.point_b.pos) / 2.0
                var dir = (stick.point_a.pos - stick.point_b.pos).normalized()

                if not stick.point_a.locked:
                    stick.point_a.pos = center + dir * stick.length / 2.0

                if not stick.point_b.locked:
                    stick.point_b.pos = center - dir * stick.length / 2.0

@onready var ball = get_node("Ball")
@onready var verlet = VerletRope.new($Pole.position + Vector3(0, 2.0, 0), ball.position, 0.5)

var gravity = 9.81
var mass = 1.0
var velocity = Vector3()

var spheres = []

func _ready():
    verlet.points[0].locked = true
    verlet.points[-1].locked = true

    for point in verlet.points:
        var sphere = CSGSphere3D.new()
        sphere.radius = 0.1
        add_child(sphere)
        sphere.position = point.pos
        spheres.append(sphere)

func _physics_process(delta):
    verlet.points[-1].pos = ball.position
    verlet.simulate(delta)

    for i in range(verlet.points.size()):
        spheres[i].position = verlet.points[i].pos

    var net_force = Vector3()

    var tension = calculate_tension(ball.position, verlet.points[-2].pos)
    net_force.y -= mass * gravity
    net_force += tension

    var acceleration = net_force/ mass
    velocity += acceleration * delta
    ball.position += velocity * delta

func calculate_tension(start: Vector3, end: Vector3):
    var displacement = end - start

    var spring_constant = 100.0
    var force = displacement * spring_constant

    return force

```

You can check out the source along with the project files here too. My goal is to get that smooth, natural movement between the rope and the object, just like in the pictures.

Any tips or ideas would be appreciated, thanks in advance for the help!

# Answer
So, after some trial and error was able to reproduce something not that terrible!!! Ended up ditching verlet and dealing only with spring instead. Here's the result:

Here's the working source code if you need: https://github.com/SmiteIsTrashBro/RopePhysics/blob/master/spring\_rope\_test\_3d.gd

```
extends Node3D

@onready var sphere_1 = $Sphere1
@onready var sphere_2 = $Sphere2

var spring_constant = 100.0
var gravity = 9.80
var damping_rate = 1.0
var velocity = Vector3()
var density = 1.0

class Point:
    var pos: Vector3 = Vector3()
    var force: Vector3 = Vector3()
    var velocity: Vector3 = Vector3()
    var rest_length: float = 0.0
    var mass: float = 0.0

    func _init(pos: Vector3):
        self.pos = pos

var points = []
var spheres = []

func _ready():
    var initial_pos = sphere_1.position
    var final_pos = sphere_2.position
    var segment_interval = 0.5
    var distance = initial_pos.distance_to(final_pos)
    var dir = initial_pos.direction_to(final_pos)
    var segment_count = ceil(distance / segment_interval)
    var corrected_interval = distance / segment_count
    var segment_mass = density * distance / segment_count

    for i in range(segment_count + 1):
        var pos = initial_pos + dir * (corrected_interval * i)
        var point = Point.new(pos)
        point.rest_length = corrected_interval
        point.mass = segment_mass
        points.append(point)

        var sphere = CSGSphere3D.new()
        add_child(sphere)
        sphere.radius = 0.05
        spheres.append(sphere)

func _physics_process(delta):
    if Input.is_action_pressed("ui_right"):
        points[0].pos.x += 5.0 * delta
    if Input.is_action_pressed("ui_left"):
        points[0].pos.x -= 5.0 * delta

    for i in range(1, points.size() - 1):
        var prev_point = points[i - 1]
        var point = points[i]
        var next_point = points[i + 1]

        var f_spring0 = calculate_spring_force(point, prev_point)
        var f_spring1 = calculate_spring_force(next_point, point)
        point.force = f_spring0 - f_spring1

    points[-1].force = calculate_spring_force(points[-1], points[-2])

    for i in range(1, points.size()):
        var point = points[i]
        var f_gravity = Vector3(0, -point.mass * gravity, 0)
        var f_damping = -point.velocity * damping_rate
        var acceleration = (point.force + f_gravity + f_damping) / point.mass
        point.velocity += acceleration * delta
        point.pos += point.velocity * delta

    for i in range(points.size()):
        spheres[i].position = points[i].pos

    sphere_1.position = points[0].pos
    sphere_2.position = points[-1].pos

func calculate_spring_force(from: Point, to: Point):
    var displacement = from.pos - to.pos
    var x = displacement.length() - from.rest_length
    var f_spring = -spring_constant * x * displacement.normalized()

    return f_spring

```

Some resources I stumbled uppon during my research:
> 2 votes

---
Tags: physics, 3d, godot, rope-physics
---


# Question
Title: Why does everything I've made in Unity begin to vanish when I get close to it?
I've attempted looking into this via. the Unity Manual, and even posts on the Unity forum, although I've found nothing. I have already tried checking Occlusion Culling and general Object Culling.

I've skimmed through the settings as well, and found nothing I figured was related to why my camera is behaving like this. (near the bottom, where it abruptly cuts off.)

# Answer
In Unity 2021.3, you can adjust the clipping planes for the Scene view like this:

1. In the Scene view, click the Camera button
2. Deselect "Dynamic Clipping"
3. Edit the Near and Far clipping planes as needed (in your case, reduce the Near plane).

The procedure may vary in other versions of Unity.
> 3 votes

# Answer
Just change the cameras clipping planes:

if you decrease the near plane, parts close to the camera will be rendered, its mostly there so that if for example, you put the camera inside the head of a player, the model doesnt block the view.
> 1 votes

---
Tags: unity, 3d, camera, frustum-culling
---


title: Shader compilation error

text:
# Question
Title: Shader compilation error
This is the begin of my vertex shader code:

```
#version 430

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTextCoord;

layout(location = 0) out float Fog_Val;

```

When compiling a project in Visual Studio 2019, it gives the following error:

error(#106) Version number not supported by GL2

How to remove the error and compile the project? Could this be due to outdated drivers for my video card?

Updated.

I use

```
glewInit();

```

to initializing OpenGL. My video card is ATI Radeon HD 4650. Before I used ATI Radeon HD 5470 and all works fine. I readed in Wiki video cards AMD/ATi Radeon HD 5000/6000/7000/8000 supports OpenGL 4.4. May be my videocard is outdated. Is there solution?

# Answer
> 2 votes
This error indicates you are trying to use OpenGL 4.3 but your graphics card doesnt support it.

From the web

> The Radeon HD 4650 cards come with OpenGL 2.0 support, allowing them to handle graphics rendering efficiently.

Since you are trying to use OpenGL 4.3, this wont work.

The most simple solution is to use a lower OpenGL version, or get a better graphics card, the HD 4650 is almost 20 years old. A used graphics card can be pretty cheap if your looking for a budget option, my GTX 1050 Ti isnt the best of the best, but it was £60 and goes up to OpenGL 4.6.

---
Tags: c++, opengl
---


# Question
Title: How to Develop Card Combat System/Manager
I'm looking for some guidance on how to develop a card combat system similar to Legends of RuneTerra auto combat. I'm a bit lost on how to get the proper card info from each drop zone (5 each player) and how to compare them.

I'm trying to run a combat function when both players have pressed their End Turn button again during the Execute phase. Currently, pressing the button just disconnects a player (there was a Red jester card across from the Blue one).

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

public class CombatManager : NetworkBehaviour
{
    // Reference to the GameManager
    public GameManager gameManager;

    // Reference to the PlayerManager
    public PlayerManager playerManager;

    // Start is called before the first frame update
    void Start()
    {
        // Find references to GameManager and PlayerManager
        gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
        playerManager = GameObject.Find("PlayerManager").GetComponent<PlayerManager>();
    }

    // Method to compare power and health values of cards in the first drop zones of both players
    public void CompareCards()
    {
        // Get the card GameObjects from the first drop zones of both players
        GameObject allyCardObject = playerManager.AllyDropZone1?.transform?.GetChild(0)?.gameObject;
        GameObject enemyCardObject = playerManager.EnemyDropZone1?.transform?.GetChild(0)?.gameObject;

        // Check for null references
        if (allyCardObject == null || enemyCardObject == null)
        {
            Debug.LogError("One or both card GameObjects are null.");
            return; // Exit the method to prevent further execution
        }

        // Get the Card components attached to the card GameObjects
        Card allyCard = allyCardObject.GetComponent<Card>();
        Card enemyCard = enemyCardObject.GetComponent<Card>();

        // Check for null Card components
        if (allyCard == null || enemyCard == null)
        {
            Debug.LogError("One or both Card components are null.");
            return; // Exit the method to prevent further execution
        }

        // Display the initial health values before combat
        Debug.Log("Ally Card Initial Health: " + allyCard.health);
        Debug.Log("Enemy Card Initial Health: " + enemyCard.health);

        // Subtract the power of the enemy card from the health of the ally card
        allyCard.health -= enemyCard.power;

        // Display the updated health values after combat
        Debug.Log("Ally Card Updated Health: " + allyCard.health);
        Debug.Log("Enemy Card Health: " + enemyCard.health);

        // Check if the ally card's health is less than or equal to 0
        if (allyCard.health <= 0)
        {
            // Destroy the ally card GameObject if its health is <= 0
            NetworkServer.Destroy(allyCardObject);
        }

        // Notify clients to update the displayed cards after combat
        RpcUpdateCombatResult(allyCardObject, allyCard.health);
    }

    // Method to notify clients to update the displayed cards after combat
    [ClientRpc]
    private void RpcUpdateCombatResult(GameObject cardObject, int newHealth)
    {
        // Update the health of the card on the client side
        Card card = cardObject.GetComponent<Card>();
        card.health = newHealth;

        // Implement logic to update the UI or perform other actions based on the combat result
    }
}

```

```
public class PlayerManager : NetworkBehaviour
{
    //Start of all network shared objects & variables//
    public GameManager GameManager;
    public GameObject PlayerCard;
    public CombatManager CombatManager;

    //All ally objects
    public int AllyHealth;
    public GameObject AllyDropZone1;
    public GameObject AllyDropZone2;
    public GameObject AllyDropZone3;
    public GameObject AllyDropZone4;
    public GameObject AllyDropZone5;
    public GameObject AllyHand;
    public GameObject AllyDeck;

    //All enemy object
    public int EnemyHealth;
    public GameObject EnemyDropZone1;
    public GameObject EnemyDropZone2;
    public GameObject EnemyDropZone3;
    public GameObject EnemyDropZone4;
    public GameObject EnemyDropZone5;
    public GameObject EnemyHand;
    public GameObject EnemyDeck;

    //Lists that will hold ally and enemy drop zones resepctively
    public List<GameObject> AllyDropZones = new List<GameObject>();
    public List<GameObject> EnemyDropZones = new List<GameObject>();

    //Card list we are pulling from
    public static List<Card> cardList = new List<Card>();

    //Variable tracking current player
    public int CardsPlayed = 0;
    [SyncVar]
    public int TurnsEnded = 0;

    public bool IsMyTurn = false;

    //Possible alternative Card List; same purpose but better way of getting it
    private List<GameObject> cards = new List<GameObject>();

    //Runs the code below when Host+Client/Client button is selected
    public override void OnStartClient()
    {
        base.OnStartClient();

        //Connect to GameManager
        GameManager = GameObject.Find("GameManager").GetComponent<GameManager>();

        //Connects hand and deck of both players to a variable by looking for objects with listed name
        AllyHand = GameObject.Find("AllyHand");
        AllyDeck = GameObject.Find("AllyDeck");
        EnemyHand = GameObject.Find("EnemyHand");
        EnemyDeck = GameObject.Find("EnemyDeck");

        //Connects each ally drop zones to each variable by looking for objects with listed name
        AllyDropZone1 = GameObject.Find("AllyDropZone");
        AllyDropZone2 = GameObject.Find("AllyDropZone (1)");
        AllyDropZone3 = GameObject.Find("AllyDropZone (2)");
        AllyDropZone4 = GameObject.Find("AllyDropZone (3)");
        AllyDropZone5 = GameObject.Find("AllyDropZone (4)");

        //Connects each enemy drop zones to each variable by looking for objects with listed name
        EnemyDropZone1 = GameObject.Find("EnemyDropZone");
        EnemyDropZone2 = GameObject.Find("EnemyDropZone (1)");
        EnemyDropZone3 = GameObject.Find("EnemyDropZone (2)");
        EnemyDropZone4 = GameObject.Find("EnemyDropZone (3)");
        EnemyDropZone5 = GameObject.Find("EnemyDropZone (4)");

        //Fills Ally list with ally drop zones
        AllyDropZones.Add(AllyDropZone1);
        AllyDropZones.Add(AllyDropZone2);
        AllyDropZones.Add(AllyDropZone3);
        AllyDropZones.Add(AllyDropZone4);
        AllyDropZones.Add(AllyDropZone5);

        //Fills Enemy list will enemy drop zones
        EnemyDropZones.Add(EnemyDropZone1);
        EnemyDropZones.Add(EnemyDropZone2);
        EnemyDropZones.Add(EnemyDropZone3);
        EnemyDropZones.Add(EnemyDropZone4);
        EnemyDropZones.Add(EnemyDropZone5);

        //Determines which player goes first; Whoever presses "Client" button goes first
        if (isClientOnly)
        {
            IsMyTurn = true;
        }

        //Message to show that client is running; appears in console tab
        Debug.Log("OnStartClient was activated");
    }

    //Starts server (Host + Client)
    [Server]
    public override void OnStartServer()
    {
        base.OnStartServer();

        //Tells us that the server is running
        Debug.Log("OnStartServer was activated");
    }

    //Command that adds cards to players hands and grants authority
    [Command]
    public void CmdDealCards()
    {
        //Fills player's hand with a card and repeats 3 times
        for (int i = 0; i < 3; i++)
        {
            GameObject card = Instantiate(PlayerCard, new Vector2(0, 0), Quaternion.identity);
            NetworkServer.Spawn(card, connectionToClient);

            //Sets current status of the card to "Dealt" which makes it appear in hand for the Server
            RpcShowCard(card, "Dealt");
        }

        //Changes game manager current state
        RpcGMChangeState("Compile {}");
    }

    //Calls upon CmdPlayCard
    public void PlayCard(GameObject card)
    {
        CmdPlayCard(card);
        Debug.Log("Cards Played counter: " + CardsPlayed);
    }

    //Calls upon RocShowCard
    [Command]
    void CmdPlayCard(GameObject card)
    {
        RpcShowCard(card, "Played"); //Sets current status of the card to "Played" which makes it appear in a drop zone for the Server
    }

    //Command to call function that checks if player ends their turn
    [Command]
    public void CmdEndTurn()
    {
        Debug.Log("TurnsEnded = " + TurnsEnded);
        RpcEndTurn();

        if (TurnsEnded == 1)
        {
            //Changes game manager current state
            RpcGMChangeState("Execute {}");
        }
        Debug.Log("TurnsEnded = " + TurnsEnded);
    }

    [ClientRpc]
    public void RpcEndTurn()
    {
        PlayerManager pm = NetworkClient.connection.identity.GetComponent<PlayerManager>();
        pm.IsMyTurn = !pm.IsMyTurn;
        Debug.Log("Ran RpcEndTurn");
    }

    //Command that initializes combat system
    [Command]
    public void CmdCombatSystem()
    {
        CombatManager.CompareCards();
    }

    //Actual function that moves the recently added card to hand and/or drop zone
    [ClientRpc]
    void RpcShowCard(GameObject card, string type)
    {
        if(type == "Dealt") // "Dealt" cards are placed into player's hand and checking ownership allows for it mirror
        {
            if (isOwned)
            {
                card.transform.SetParent(AllyHand.transform, false);
            }
            else
            {
                card.transform.SetParent(EnemyHand.transform, false);
            }
        }
        else if(type == "Played") // "Played" cards are placed into a player's drop zone and check mirror condition
        {
            if (CardsPlayed == 5)
            {
                CardsPlayed = 5;
            }

            if (isOwned)
            {
                //card.transform.SetParent(AllyDropZones[CardsPlayed].transform, false);
                card.transform.SetParent(AllyDropZones[CardsPlayed].transform, false);
            }
            else if (!isOwned)
            {
                card.transform.SetParent(EnemyDropZones[CardsPlayed].transform, false);
            }

            //Increases card counter
            CardsPlayed++;
            Debug.Log("Card ID: " + card.name);
        }
    }

    //Changes GameState by passing Game State name and calling function
    //Check Gamemanger to see function def. (TLDR: ReadyClicks var +1)
    [ClientRpc]
    void RpcGMChangeState(string stateRequest)
    {
        GameManager.ChangeGameState(stateRequest);
        if (stateRequest == "Compile {}")
        {
            GameManager.ChangeReadyClicks();
        }

        if(stateRequest == "Execute {}")
        {
            GameManager.ChangeReadyClicks();
        }
    }

}

```

# Answer
> 0 votes
If you are a beginner in networking, forget about Host mode. Host mode allows you to make easy mistakes that are hard to figure out if you do not fully understand what information the server and client has and how the communication between them is. It can introduce bugs that are working on one client but fail on the second one.

Instead of Host mode + client I would advise to start one Server + 2x client. It makes the setup harder but your coding easier in the long run.

**Server code/ logic**
A server does not care who is Ally or Enemy. It does not care about the visual representation or physical location for cards, draw stacks, graveyard, drop zones or whatever your game uses (this is different for different types of games). From the servers point of view, everyone is a player. It holds the logic for your game, knows the state of the game, how cards are interacting, how a round works. Your combatmanager looks like it should be server code. But you should have no need for code like `AllyDropZone1?.transform?.GetChild(0)?.gameObject` on the server. It knows which card is first in hand or first on board. You could write the whole game in the server logic first without a single visual representation. There is no secret information on the server. Your draw cards are probably stored in a list. Hand cards in an array or another list. Board? Array. Graveyard? Array or list.

**Client**
One error that you will notice `if (isClientOnly)` will be true for every player. Never trust the client with any game important decision making. They can choose to do an action, but the server in the end performs that action. In this case the server decides who goes first and informs that client. Or all clients which the name of which client goes first. If that name is your client, you can play your turn. All other clients can display the currents player turn or handle however you choose to do if it is offturn. Hitting end turn button? Just sending that flag to the server. You would evaluate there if it is 1) the current players turn who hit it 2) what happens next.

**Communication**
The server would not care, where the card is located (transform) of it. Nor should it care that you said: I played the first card in my hand. The client would sent the identification of the card to the server along with the action (which is usually only one possible option). Hand cards can usually be played. If it is important to be able to place them on specific locations, you would include the location index, not coordinates (different players usually have different resolutions, maybe even custom layouts - server does not care). Playing the energy card from hand that goes to the land stack on the board? Telling server I played energy. Playing monster X and it should go in the middle of the board? Telling the server played monster X at 5. Now the servers job is to check that you have that card in hand and that the location is valid. Maybe you played a monster already. Maybe you can't pay the cost. Maybe the location is blocked. When the move is valid, the server informs all players about the new state of the game and each client handles that information accordingly. If player 1 played monster X, that will look visually different location vise for player 2.

---
Tags: unity, card-game, mirror-networking
---


# Question
Title: Skill Class design : How to deal with multiple criteria
I'm planning to make a Class for RPG game's character skill. But the problem is that the skills need to be classified by multiple criteria. Below are the criteria for skills.

> 1. Independent / dependent

Some skills are usuable by itself. Howver some skills are only used (automatically) in situations where certain skills are used. For example 'Additinal FireBall' skill are only used after 'FireBall' skill.

> 2. Attack / Buff

Attack skills deal damage to enemy. On the contrary buff skills do some useful effects like increasing character's movement speed.

```
abstract class Skill {
    String skillId;

    abstract void use(Character character, Enemy enemy);
}

abstract class IndepentdentSkill {
}

abstract class DependentSkill {
    List<String> conditionSkills; //DependentSkill are automatically used after one of conditionSkills are used
}

interface AttackSkill {
    void doDamage(Enemy enemy);
}

interface BuffSkill {
    void applyBuff(Character character);
}

class IndependentAttackSkill extends IndepentdentSkill implements AttackSkill {
    @Override
    void use(Character character, Enemy enemy) {
        doDamage(enemey);
    }

    @Override
    void doDamage(Enemy enemy) {
        enemy.takeDamage(this.damage);
    }
}

class IndependentBuffSkill extends IndepentdentSkill implements BuffSkill {
    List<BuffEffects> BuffEffects;

    @Override
    void use(Character character, Enemy enemy) {
        doDamage(enemey);
    }

    @Override
    void applyBuff(Character character) {
        character.applyBuff(this.BuffEffects);
    }
}

//class DependentAttackSkill { ... }
//class DependentBuffSkill { ... }

```

I tried to make class like below but there were several problems.

1. In this example, there will be four(2 * 2) class in total(IndependentAttackSkill, ..., DependentBuffSkill). If I need one more criteria and it would be 2 * 2 * 2 = 8. Moreover, if I have to add 'Defense' classification there would be a lot of work.
2. method Skill.use(Character, Enemy) are taking parameter more than necessary. As you can see in the concrete Class, Skill.use() only use one of them.

**If you know a class design that can complement these two issues, I would really appreciate it if you could let me know**

# Answer
> 1 votes
When I made a Tactical RPG a couple years ago, I had a class for `Actions`s that can be used in combat as a one-time action and `StatusEffect`s that remain on a `Combatant`* and do... something.

A `Skill` can enable a combatant to use an `Action` (which the player would consider an "active skill") and/or bestow a permanent `StatusEffect` on them (which the player would consider a "passive skill"). Using an `Action` usually does damage, but can also result in bestowing temporary `StatusEffect`s on one or more combatants (which the player would call a "buff"/"debuff") or do something entirely different.

The `Action` class is pretty straight-forward: It has various properties that say on what kind of targets it can be used (allies, enemies, tiles or perhaps no specific target at all), in what range, with what area of effect and at what cost it can be used. And then it gets a `use(Combatant user, List<Combatant> targets)` method that can be overridden by derived classes to contain custom code that actually does stuff. Like inflict damage or bestow status effects.

The `StatusEffect` class is basically an event handler. A class inheriting from `StatusEffect` can subscribe to various events while active. When such an event happens (combatant stats are recalculated, combatant turn begins, combatant uses an Action, combatant receives damage...), the game checks if any active status effects subscribed to these events and then calls their handler method, which then get an opportunity to influence the results.

<sub>* I usually don't like having separate classes for `Character` and `Enemy`. I usually have one class `Combatant` that represents any participants in a combat and has a property that says which team it is fighting for.</sub>

---
Tags: java, rpg, design-patterns
---


title: Set Textures DX12

text:
# Question
Title: Set Textures DX12
```
    for (int j = 0; j < MeshNums; j++)
    {
        CD3DX12_CPU_DESCRIPTOR_HANDLE hDescriptor = CD3DX12_CPU_DESCRIPTOR_HANDLE(m_SrvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
        hDescriptor.Offset(j, m_CbvSrvUavDescriptorSize);

        m_CommandList->SetGraphicsRootDescriptorTable(0, hDescriptor);

        m_CommandList->IASetVertexBuffers(0, 1, &m_Scene[j]->VertexBufferView());

        m_CommandList->DrawInstanced(
            m_Scene[j]->DrawArgs.VertexCount, 1, 0, 0);
    }

```

C++ DX12 project. I'm trying to draw several meshes in a row on the screen, and apply a texture to each subsequent mesh. But I get a compilation error on the line:

```
m_CommandList->SetGraphicsRootDescriptorTable(0, hDescriptor);

```

How to solve a problem?

# Answer
> 1 votes
```
for (int j = 0; j < MeshNums; j++)
    {
        CD3DX12_GPU_DESCRIPTOR_HANDLE hDescriptor(m_SrvDescriptorHeap->GetGPUDescriptorHandleForHeapStart());
        hDescriptor.Offset(j, m_CbvSrvUavDescriptorSize);

        m_CommandList->SetGraphicsRootDescriptorTable(0, hDescriptor);

        m_CommandList->IASetVertexBuffers(0, 1, &m_Scene[j]->VertexBufferView());

        m_CommandList->DrawInstanced(
            m_Scene[j]->DrawArgs.VertexCount, 1, 0, 0);
    }

```

There was a syntax error in the code. Necessary:

GetGPUDescriptorHandleForHeapStart()

Was:

GetСPUDescriptorHandleForHeapStart()

---
Tags: c++, directx12
---