# Question
Title: How can I implement UI in Unity using Chromium?
I'm looking for an alternative to UI Builder.

Ideally I'd like to have basically a Chromium instance atop Unity3D which would have its JS calls somehow land in the C# (maybe in the "Update" loop it listens to a constant stream of potential calls and the parameters will correspond to function names in my Unity code, I don't know)

here's what I found which doesn't quite live up to my expectations:

This Unity forum thread may be relevant. Chromium Embedded Framework was a tool used by some assets on the asset store to create chromium UI but it has been removed.

If not using these assets, how can I implement my idea of using Chromium as my UI layer?

# Answer
> 4 votes
I'm the developer of 3D WebView, and I just wanted to clarify that it doesn't have the limitations you thought:

---
Tags: unity, gui, chrome
---


# Question
Title: How to find vector representing altitude of a triangle?
I'm trying to find this green vector and I've got three points A, B, C. How can I find that vector in Unity code-wise?

# Answer
> 1 votes
Given the input vectors

```
   Vector3 AB =  Vector3(Bx, By, Bz) - Vector3(Ax, Ay, Az);
   Vector3 Caxis = Vector3(Cx, Cy, Cz) - Vector3(Ax, Ay, Az); // This is the vector from A to C

```

The direction of the result vector `C` we seek is the same direction as (`AB` cross `Caxis`) cross `AB`

```
   Vector3 Cdir = Vector3.Cross(Vector3.Cross(AB, Caxis), AB).Normalize();

```

Finding the magnitude is more involved. We know that starting at the point `Cz` and going in the direction `Cdir` must intersect along `AB`

```
   Caxis - alpha * Cdir == beta * AB

```

and we need to find unknowns `alpha` and `beta`. We can find a vector perpendicular to `Caxis`  by projecting `AB` onto the plane to which `Caxis` is normal

```
   Vector3 Cperp = Vector3.ProjectOnPlane(Caxis, AB).Normalize();

```

so our equation with `alpha` and `beta` can be reduced to one unknown

```
  - alpha * (Cdir . Cperp)/(AB . Cperp) == beta

```

So solving for `alpha` (which is in fact the magnitude of our final vector `C`)

```
   Caxis == alpha * (Cdir - AB* (Cdir . Cperp)/(AB . Cperp) )

```

This is a vector equation, but we can solve for `alpha` by taking the dot product with `Caxis` on both sides. Writing code again this is

```
   float num = Caxis.magnitude*Caxis.magnitude;
   float denom1 = Vector3.Dot(Cdir, Caxis);
   float denom2 = Vector3.Dot(AB, Caxis) * Vector3.Dot(Cdir, Cperp) / Vector3.Dot(AB, Cperp);

   float Cmag = num/(denom1 - denom2);

```

`C` is then, using the sign convention from your diagram,

```
   Vector3 C = Cmag*Cdir;

```

I'm leaving it without checks for cases where you get a divide by zero, such as when points `B` and `C` are identical.

# Answer
> 3 votes
You can do this more simply. This vector in green is just AC with the portion parallel to AB removed.

So:

```
Vector3 AC = C - A;
Vector3 AB = B - A;

return AC - Vector3.Project(AC, AB);

```

---
Tags: unity, vector, linear-algebra
---


# Question
Title: Isometric ordering issue with moving entities taller than one block
I'm having a lot of trouble sorting it in such a way that it works with a moving entity that is "taller" than a "block" size in this map. I've recorded my problem here: https://www.youtube.com/watch?v=Zlo07gTZf9M

(and here it is in a choppy gif for easier access):

The numbers on the blocks/tiles represent their draw order. Basically, currently, it's incremented one after an entity has been passed, so that after that everything is drawn on top.

The draw order is per row, then per column, then per level (height). This allows the levels, created in Tiled, to basically be imported directly into Godot and the order of insertion is the initial render order (so no need for ZIndexing).

Currently, the sorting code is this:

```
int index = 0;
for (int level = 0; level < _stacksGrid.GetLength(2); ++level)
{
    for (int y = 0; y < _stacksGrid.GetLength(1); ++y)
    {
        for (int x = 0; x < _stacksGrid.GetLength(0); ++x)
        {
            // Check if there's a tile here
            Tile tile = _orderableTiles[x, y, level];
            if (null != tile)
            {
                tile.SetZ(index);
            }

            // Then check if there's an orderable here
            IIsometricOrderable orderable = _orderablesGrid[x, y, level];
            if (null != orderable)
            {
                // Move them all up from now on
                orderable.SetZ(index++);
            }
        }
    }
}

```

I've tried "stacking" tiles that are orderable. Basically making them into a single object, and only the grounded position is used for ordering. However, this unfortunately brings with it a bunch of new issues.

I'm *hoping* this is solvable without splitting the enity (the player in this case) in multiple parts.

If somebody has a good tutorial, book, example, open source project (I've looked at OpenRCT but it's a different rendering method), or just straight up answer.. I'm all ears. I've been breaking my head over this for way too long.

# Answer
Usually we would sort objects by their ground position. In fact, we can argue there are two orders:

* Sort objects by their ground position, back to front.
* Sort object by their elevation, bottom to top. *This is sorting by level.*

And the first one should take priority. For example, here:

The character should be in front of the whole stack that is behind, because of its GROUND SCREEN position. This is done by sorting by the SCREEN y position. For what I understand the block exist in a xy grid, but those aren't the screen position, so I'm not talking about that y position. Also keep in mind that different levels will result in a different screen y position. We want the lowest level. This is why I call it GROUND position. *To be fair, I'm calling it screen y, it can be without scaling (zoom) and translating (pan).*

Of course, on the stack, you should draw what is higher on top. This is sorting by level.

I remind you that you need to follow the same rule to position the character.

---

I guess you would want to put that on a single integer z-index. If you know the range of high for the stacks we can do that easily: You will use multiples of the maximum stack size for the first order, and then units for the second.

Something like this:

```
zIndex = ScreenY * MaxStackSize + Level

```

If you view a range of levels (for example, if you slice the stacks for visibility), you could do it like this:

```
zIndex = ScreenY * (MaxLevel - MinLevel) + (Level - MinLevel)

```

---

You could consider the characters to be on a level higher than the floor it is standing on.

Alternatively, you could consider the character to be on the same level, but make the block take even values for z-index (the computation above but multiplied by two), and the characters take the odd values (the computation above but multiplied by two and plus one). So characters and the blocks do not compete for a slot.

---

If you are doing this with `Sprite`s in Godot you can accomplish this by using the `YSort` node. Except your stacked blocks should all have the same position (so the `YSort` do not sort them), which you can accomplish with the `offset` property of the `Sprite`. And you would still be responsible for sorting the stack.

In fact, I would make all the blocks of the stack child of a single node… So that `YSort` sorts those parent nodes, and you only need to sort the children.

And since you need to follow the same rule for the character, you would use `offset` on the character sprite to change the level.

*And you would have to compensate for that when positioning with the mouse. if the mouse pointer is on a top face of a block you can put the character there, otherwise, you would have to put the character on one of the stacks that are in front, and the character might have to be floating in the air to match the mouse pointer position.*
> 3 votes

---
Tags: tiles, godot, isometric, voxels, sorting
---


# Question
Title: Efficiently find all points within a circle
I am writing code that requires me to find all points within circle on certain parts of the screen hundreds of times per frame. I wrote a quadtree for this and have 1 method called query\_circle that looks like this:

```
def query_circle(self, center, radius, lis=None):
    '''
    Uses given bounds of center and radius and
    creates AABB to search all quadtrees that intersect that region for
    the in that region
    '''
    bounds = [center[0] - radius, center[1] - radius, radius * 2, radius * 2]
    x1, y1 = (bounds[0], bounds[1])
    x2, y2 = (bounds[0] + bounds[2], bounds[1] + bounds[3])
    if lis == None:
        lis = []

    if self.nodes:
        if y1 <= self.center[1]:
            if x1 <= self.center[0]:
                self.nodes[0].query_circle(center, radius, lis)
            if x2 > self.center[0]:
                self.nodes[1].query_circle(center, radius, lis)
        if y2 > self.center[1]:
            if x1 <= self.center[0]:
                self.nodes[2].query_circle(center, radius, lis)
            if x2 > self.center[0]:
                self.nodes[3].query_circle(center, radius, lis)

    for point in self.points:
        if (point.x - center[0]) ** 2 + (point.y - center[1]) ** 2 <= radius**2:
            lis.append(point)
    return lis

```

What is happening is I create an AABB for the circle and then find all the QuadTrees that are intersecting with the AABB and using those QuadTrees to check if the points inside of them are within the circle. Unfortunately, the animation was running at less than 3 frames per second and the root cause was this method. I profiled the method and found this:  As you can seet the last 4 lines of code where I check if the point is inside the circle and append it to a list are what are slowing down the method the most. Is there any technique I can use to considerably speed up that process?

# Answer
> 4 votes
**About this algorithm:**

You don't have to check whether every object is inside the circle. If a node square is **completely** inside or outside the circle, you can use all objects in it directly without distance check. If not, subdivide it until it can't be.In this way, the objects that need to be judged by distance are only a few objects near the ring. For example, the blue area in the figure does not need to be checked object by object:

----\>

You can use the outer square of the circle to exclude the area completely outside the circle.(you have done so). And use the inscribed square of the circle to exclude the area completely inside the circle. **Or** you can use the circumcircle of the node square, and the target circle to judge, which will lead to somehow more accurate results. **Or** You can check that the node square is completely within or not within the target circle directly. I don't know which one is faster, it depends on your data characteristics.

This leads to an exponential performance boost when the map is very large and the target circle is also very large. Again, it depends on your data characteristics.

**About code style:**

As @Vaillancourt said in the comments, you are doing a lot of repeated calculations in the loop. Try putting them outside the loop or the function. Here are some of my suggested modifications:

1. `query_circle` should not be a member function, but a static utility function.
2. For each query, there is no need to repeatedly calculate the variables related to the target circle, use the closure to store them, create a method object and call it.
3. Use `*` to replace `**2`.
4. For each point, use AABB check first.

Disclaimer: I don't currently have a python environment and the (fake)code is untested:

```
def query_circle(center, radius):
    bounds = [center[0] - radius, center[1] - radius, radius * 2, radius * 2]
    x1, y1 = (bounds[0], bounds[1])
    x2, y2 = (bounds[0] + bounds[2], bounds[1] + bounds[3])
    r_square = radius*radius

    def query_circle_closure(node,lis):
        nCenter = node.center
        nNodes = node.nodes

        if nNodes:
            if y1 <= nCenter[1]:
                if x1 <= nCenter[0]:
                    query_circle_closure(nNodes[0], lis)
                if x2 > nCenter[0]:
                    query_circle_closure(nNodes[1], lis)
            if y2 > nCenter[1]:
                if x1 <= nCenter[0]:
                    query_circle_closure(nNodes[2], lis)
                if x2 > nCenter[0]:
                    query_circle_closure(nNodes[3], lis)
        else:
            for point in node.points:
                if x1<point.x<x2 and y1<point.y<y2:
                    if (point.x - center[0]) *(point.x - center[0]) + (point.y - center[1]) *(point.y - center[1]) <= r_square:
                        lis.append(point)
        return lis
    return query_circle_closure

lis = []
queryFunc = query_circle(center, radius)
queryFunc(your_root_node,lis)

```

Hope it helps.

---
Tags: collision-detection, performance, python, geometry, optimization
---


# Question
Title: Pygame moving only once when key pressed integrated into player class
I'm having an issue when I have created a player class and want to move my sprite in between three lanes. I was able to get the sprite to move when I used `pygame.get_pressed()`, however, I only want the sprite to move in single large steps between three lanes, therefore one key press == moving say 50 pixels up and then no further movement.

Therefore I swapped the `get_pressed` code for a `for event in pygame.event.get()` so I could use the "KEYDOWN" method. I have got this to work in a separate project file by including it in the main while loop. However I believe this should be able to be included in the Player class and currently nothing happens.

# Setup

```
import pygame
import get_image, player_class
from sys import exit
pygame.init()
screen = pygame.display.set_mode((960,480))
pygame.display.set_caption('Platform Test')
background_surface = pygame.image.load('assets/graphics/green.png').convert_alpha()
final_background = pygame.transform.scale(background_surface, (960,480))
background_rect = final_background.get_rect(topleft = (0,0))
clock = pygame.time.Clock()
sprite_sheet_image = pygame.image.load('assets/graphics/player.png').convert_alpha()
sprite_sheet = get_image.SpriteSheet(sprite_sheet_image)
GREEN_SCREEN_BACKGROUND = (32, 156, 0)
FPS = 60

```

# Player Class

```
class Player(pygame.sprite.Sprite):
    global x_position, y_position
    x_position = 50
    y_position = 400
    def __init__(self):
        super().__init__()

        player_walk_1 = sprite_sheet.get_image(0, 24, 34, 3, GREEN_SCREEN_BACKGROUND)
        player_walk_2 = sprite_sheet.get_image(1, 24, 34, 3, GREEN_SCREEN_BACKGROUND)
        player_walk_3 = sprite_sheet.get_image(2, 24, 34, 3, GREEN_SCREEN_BACKGROUND)
        player_walk = [player_walk_1, player_walk_2, player_walk_3]
        player_walk_index = 0

        self.image = player_walk_2
        self.rect = self.image.get_rect(bottomleft = (x_position,y_position))

    def player_input(self):
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                    self.rect.y -= 20
    def update(self):
        self.player_input()

```

# Body

```
player = pygame.sprite.GroupSingle()
player.add(Player())

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

    player.update()
    screen.blit(final_background,background_rect)
    player.draw(screen)
    pygame.display.update()
    clock.tick(FPS)

```

# Answer
> 1 votes
The main issue is that you process all the events in two places (the first is in the main loop and the second is in the player), the first one ignores the `KEYDOWN` event, and the second one misses it because the first one discarded it. The code `for event in pygame.event.get():` is responsible for this.

The first way you can patch this is by checking for the `KEYDOWN` event in the main loop and pass a flag to the `Player.update()` function:

(All code is untested.)

In Body:

```
while True:
    player_moves_up = False
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

        if event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
            player_moves_up = True

    player.update(player_moves_up)
    screen.blit(final_background,background_rect)
    player.draw(screen)
    pygame.display.update()
    clock.tick(FPS)

```

In Player:

```
    # This function is no longer needed.
    # def player_input(self, player_moves_up):
    #     for event in pygame.event.get():
    #         if event.type == pygame.KEYDOWN:
    #             if event.key == pygame.K_UP:
    #                 self.rect.y -= 20

    def update(self, player_moves_up):
        if player_moves_up:
            self.rect.y -= 20

```

Alternatively you can have you player class monitor for key value changes ("rising edge"), and act upon it.

In Player:

```
class Player(pygame.sprite.Sprite):
    global x_position, y_position
    x_position = 50
    y_position = 400

    def __init__(self):
        super().__init__()

        player_walk_1 = sprite_sheet.get_image(0, 24, 34, 3, GREEN_SCREEN_BACKGROUND)
        player_walk_2 = sprite_sheet.get_image(1, 24, 34, 3, GREEN_SCREEN_BACKGROUND)
        player_walk_3 = sprite_sheet.get_image(2, 24, 34, 3, GREEN_SCREEN_BACKGROUND)
        player_walk = [player_walk_1, player_walk_2, player_walk_3]
        player_walk_index = 0

        self.image = player_walk_2
        self.rect = self.image.get_rect(bottomleft = (x_position,y_position))

        # This will track from frame to frame the state of the key
        self.keyboard_state_move_up_pressed = False

        # This will allow you to check that the key has just been pressed this frame
        self.keyboard_state_move_up_just_pressed = False

    def player_input(self):
        # Reset the flag
        self.keyboard_state_move_up_just_pressed = False

        # Check if the key has just been pressed
        new_keyboard_state_move_up_pressed = pygame.key.get_pressed()[pygame.K_UP]
        if not self.keyboard_state_move_up_pressed and new_keyboard_state_move_up_pressed:
            self.keyboard_state_move_up_just_pressed = True

        # Store the key state for the next frame
        self.keyboard_state_move_up_pressed = new_keyboard_state_move_up_pressed

    def update(self):
        self.player_input()

        # You can now react to it based on the updated input.
        if self.keyboard_state_move_up_just_pressed:
            self.rect.y -= 20

```

The first "patch" approach has the advantage that you know which keys are used and you don't have to track the state yourself, and it can make your class easier to test because you "inject" the values to it, instead of having it rely on singletons, while the "second" approach has the handling more localized where you need it and "pollutes" less of the rest of the code.

---
Tags: movement, pygame
---


# Question
Title: Unity - How to stop the slide on slopes?
struggling with a wee issue where if my character walks up a slope he slides back down when at rest, and bounces down when running down the slope. I've followed a few videos but none seem to address the issue. I've posted my movement code so far and I'm not opposed to fundamentally changing this, however with the other aspects of my game, the rigid body and collider setup seems to be working quite well. Any ideas?

```
 //inputs
    if (Input.GetKey(buttonKey["Left"]))
    {
        inputHorizontal = -1;
    }
    else if (Input.GetKey(buttonKey["Right"]))
    {
        inputHorizontal = 1;
    }
    else
    {
        inputHorizontal = 0;
    }

    //jump
    if (Input.GetKey(buttonKey["Jump"]) && isgrounded.Grounded && canJump)
    {
        jump();
        jumpTimerCurrent = 0;
        canJump = false;
    }

    if (jumpTimerCurrent <= jumpTimerReset)
    {
        jumpTimerCurrent += Time.fixedDeltaTime;
    }
    else
    {
        canJump = true;
    }

 void FixedUpdate()
{
    rb.velocity = new Vector2(inputHorizontal * Time.fixedDeltaTime * runSpeed, rb.velocity.y);
}

    void jump()
{
    rb.velocity = new Vector2(rb.velocity.x, 0.0f);
    rb.AddForce(Vector2.up * jumpForce, ForceMode.Force);
}

```

# Answer
> 0 votes
Have you tried playing around with Physics Materials before. If you add a roughed up Physics Material it might prevent it from sliding back down when not moving. Another trick you could do is just set freeze position and rotation bools of rb when in rest mode. Also by freeze rotation of rb there's a good chance the bouncing might stop. The bouncing might dissappear if you use a smooth phsyics material when coming down. But its weird I can't see why your object would be sliding back down when you clearly are zeroing out the rb.velocity, which should do the trick unless your rb.velocity.y needs to be zeroed out as well which is possible.

# Answer
> 0 votes
I don't know why it would slide back down, but the reason it's bouncing down slopes is most likely the fact you're setting its y velocity to 0 when grounded. Try something in the negatives, like -2.

---
Tags: unity, character-controller
---


# Question
Title: Changing Coordinate Origin [From Coord System A -> Coord System B]
I'd really appreciate some help on this one.

Given 2 coordinate systems A and B where

1. xA is an initial Vector3 position, rA is an initial Quaternion rotation
2. xB is an initial Vector3 position, rB is an initial Quaternion rotation

How can I then transform a random (position, rotation) from A into B?

I can understand how I would go about if I only had position. If I had randomA, it would be *randomB = xB + (randomA - xA)* to shift from **A to B**. I'm kind of stuck on where should I incorporate the quaternions / their inverse.

# Answer
> 1 votes
I believe something like this should work:

```
random_position_world = (Quat_A * random_position_A) + xA_world
random_position_B = inverse(Quat_B) * (random_position_world - xB_world)

random_rotation_world = Quat_A * random_rotation_A
random_rotation_B = inverse(Quat_B) * random_rotation_world

```

The suffix `_world` here is to denote that the value is expressed in world space. If you want a bit more insight into this sort of thing you should read about transformation matrices.

---
Tags: 2d, rotation, coordinates, position
---


# Question
Title: Creating object in front of player, with some distance
I want to create objects in front of player with some distance, so that prevents hit with player immediately. So first, I get the global player position and direction vector which player towards:

```
var player_position = player.transform.origin
var player_forward_vector = player.global_transform.basis.z

```

And then give additional distance:

```
var spawn_position = player_position
spawn_position.z -= player_forward_vector.z + 100

```

And then set the position:

```
var asteroid_instance = asteroid_scene.instance()
asteroid_instance.transform.origin = spawn_position

```

When I run the game, first it seems work, however when I rotated the player, still object spawned same position, not in front of where I'm looking at.

Here's the video to demonstrate: https://youtu.be/zvMU9ad33SA

Why object doesn't created in front of player, instead keep spawns in same location? Any advice will very appreciate it.

Here's the full code of spawning object. Note that asteroid is just Rigidbody object with collision shape as child.

```
# AsteroidSpawner.gd
extends Node

onready var player: Player = get_tree().get_root().find_node("Player", true, false)
var asteroid_scene: PackedScene = preload("res://Asteroid/Asteroid.tscn")

func _ready():
    spawn_asteroids()

func spawn_asteroids():
    while true:
        spawn_asteroid()
        yield(get_tree().create_timer(2), "timeout")

func spawn_asteroid():
    var spawn_position: Vector3 = get_spawn_position()

    var asteroid_instance = asteroid_scene.instance()
    asteroid_instance.global_transform.origin = spawn_position

    # Push towards player
    var direction_to_player: Vector3 = player.transform.origin - spawn_position
    var speed = min(rand_range(5, 10), 10)
    asteroid_instance.add_force(direction_to_player * speed, Vector3())

    add_child(asteroid_instance)

func get_spawn_position() -> Vector3:
    var player_position = player.global_transform.origin
    var player_forward_vector = player.global_transform.basis.z
    var spawn_position = player_position
    spawn_position.z -= player_forward_vector.z + 100

    return spawn_position

```

# Answer
There isn't enough information to say for sure, but you're mixing local and global transforms. If you're basing the spawned object location on the players *global* transform, you should set `asteroid.global_tranform.origin`. Otherwise the resulting position will be affected by the parent's transform.
> 0 votes

# Answer
1. Define the `offset` between player and spawn location as a `Vector3`.
2. Get the rotation of the player as a quaternion, using `var rotation = player.global_transform.basis.get_rotation_quat( )`
3. Rotate the spawn offset vector by that quaternion, using the xform method. Like this: `var rotated_offset = rotation.xform( offset )`
4. Add the player position and the rotated offset together: `var spawn_point = player.global_transform.origin + rotated_offset`

By the way, you can skip the quaternion and just do `var rotated_offset = player.global_transform.basis.xform( offset )`. But then the scale factor of the player will affect the distance of the spawn point.
> 0 votes

---
Tags: transformation, godot
---


# Question
Title: Why does the setPosition function in SFML require the x and y arguments both floating-point numbers, not integers?
Why do the coordinates x and y in the 2D game both floating-point numbers, not integers? For example, the SFML `setPosition` function requires two floating-point values as arguments. However, the setup screen mode or video mode requires two integers. The left hand didn't talk to the right hand?

# Answer
> 2 votes
Integers are used for initializing the screen because that's how the hardware (screen) treats them. Even if you're doing something like subpixel rendering, fundamentally either you have a pixel or you don't.

World space positioning models real life positioning. Things can exist at non integer locations. Floating point numbers aren't a perfect representation, (because they are an approximation of real numbers), but they work reasonably well for this.

Eventually things in world space get rendered & rasterized to screen space:

(image source)

But prematurely casting your coordinates to integers would result in a loss of precision & introduce rendering errors. And again, the high level API (you your case SFML) is using what the lower level API (OpenGL) and hardware (video card) supports - floating point.

You *can* treat world space & screen space as the same. Some 2D games do that in part because it simplifies some of the math & reduces what you have to keep track of. But that simplification isn't necessarily true in general for all games or how things are modelled in general.

The SFML tutorial on Using sf::View touches on the differences between using two different coordinate systems & how to use `mapPixelToCoords(…)` and `mapCoordsToPixel(…)` to convert between them.

# Answer
> 1 votes
Because our game loop is 60 fps or even higher, it would be nice if we could make a sprite moving a little bit, a fraction of pixels for each frame rate. A fraction of the pixels, a floating-point value, that we could add or subtract from the sprite's current position makes it move smoothly and nicely in each frame.

---
Tags: sfml, coordinates
---


# Question
Title: Getting text dimensions with TextGenerator.GetPreferredHeight/Width not working
I am using Unity 2021.3.3f1 and trying to make a pop up with a sprite as a background, where the size of this sprite adjusts to the size necessary to fit the text.

From what I understand, `UnityEngine.UI.TextGenerator` should be able to give me the necessary dimensions of the sprite, given an input string and some `TextGenerationSettings`.

Here is the code I am using.

```
public class PopUp : MonoBehaviour
{
    UnityEngine.UI.Text text;
    TextGenerationSettings textGenSetting;
    TextGenerator generator

    void Start()
    {
        generator = new TextGenerator();
        textGenSetting.generationExtents = new Vector2(20f, 20f);
    }

    void Update()
    {
        RecalculateText();
    }

    private void RecalculateText()
    {
        textGenSetting.fontSize = text.fontSize;
        textGenSetting.alignByGeometry = text.alignByGeometry;
        textGenSetting.color = text.color;
        textGenSetting.fontStyle = text.fontStyle;
        textGenSetting.resizeTextForBestFit = text.resizeTextForBestFit;
        textGenSetting.resizeTextMaxSize = text.resizeTextMaxSize;
        textGenSetting.resizeTextMinSize = text.resizeTextMinSize;
        textGenSetting.richText = text.supportRichText;
        textGenSetting.horizontalOverflow = text.horizontalOverflow;
        textGenSetting.verticalOverflow = text.verticalOverflow;
        textGenSetting.updateBounds = true;
        textGenSetting.font = text.font;
        textGenSetting.lineSpacing = text.lineSpacing;

        var newHeight = generator.GetPreferredHeight(text.text, textGenSetting);
        var newWidth = generator.GetPreferredWidth(text.text, textGenSetting);
        var newRect = generator.rectExtents;

        //Debug Log 1
        Debug.Log(string.Format("newWidth: {0}, newHeight: {1}, numLinesGenerated: {2}", newWidth, newHeight, generator.lineCount));

        //Debug Log 2
        Debug.Log(string.Format("newRectWidth: {0}, newRectHeight: {1}, numLinesGenerated: {2}", newRect.width, newRect.height, generator.lineCount));

        //Debug Log 3
        Debug.Log(string.Format("generationExtents: width {0}, height: {1}, numLinesGenerated: {2}", textGenSetting.generationExtents.x, textGenSetting.generationExtents.y, generator.lineCount));
    }
}

```

Since I'm not sure which method/field should be giving me the correct height and width for any given text, I'm printing multiple fields/method results to the console.

However, none of those gives the desired result.

---

**Outputs of `Debug Log 1`**

The line marked `//Debug Log 1` above gives the following output when I have an empty string (""), a string with one character ("a"), a string with two characters ("aa"), and a long string (with plenty of spaces in between for potential line breaks)

```
Text is : . newWidth: 0, newHeight: 15, numLinesGenerated: 1

Text is : a. newWidth: 7, newHeight: 30, numLinesGenerated: 1

Text is : aa. newWidth: 14, newHeight: 45, numLinesGenerated: 1

Text is : Nam a tempor lorem. Ut eleifend, massa sed tincidunt blandit, risus nunc pharetra orci, at mattis turpis augue eu eros. Aliquam a faucibus dolor. Vestibulum ultrices turpis quis mi aliquam, a facilisis metus rutrum. Nulla sodales, ante vitae maximus fringilla, tellus erat ultricies felis, ac sodales felis lorem nec lorem. Fusce cursus turpis odio, vel tristique justo pulvinar sed. Nunc efficitur, ante ac mollis pretium, elit felis elementum lorem, vitae porttitor ex arcu vulputate ante. Donec elit purus, porta nec tortor vitae, semper suscipit sem. Ut ante dui, lobortis vel nulla vitae, condimentum laoreet magna. Maecenas aliquet aliquet nulla a fringilla. Proin rhoncus est eget nunc venenatis tempus. Praesent rhoncus est et velit gravida, non posuere justo scelerisque. Praesent ultrices lectus quis quam iaculis faucibus quis id sem. Quisque enim massa, molestie ac tortor sit amet, porta tristique diam. Suspendisse potenti. Fusce rutrum massa metus, eu facilisis nisi luctus vel.. newWidth: 5634, newHeight: 12675, numLinesGenerated: 1

```

**Outputs of `Debug Log 2`**

Here's the same for `//Debug Log 2`

```
Text is: . newRectWidth: 0, newRectHeight: 15, numLinesGenerated: 1

Text is: a. newRectWidth: 7, newRectHeight: 15, numLinesGenerated: 1

Text is: aa. newRectWidth: 14, newRectHeight: 15, numLinesGenerated: 1

Text is: Nam a tempor lorem. Ut eleifend, massa sed tincidunt blandit, risus nunc pharetra orci, at mattis turpis augue eu eros. Aliquam a faucibus dolor. Vestibulum ultrices turpis quis mi aliquam, a facilisis metus rutrum. Nulla sodales, ante vitae maximus fringilla, tellus erat ultricies felis, ac sodales felis lorem nec lorem. Fusce cursus turpis odio, vel tristique justo pulvinar sed. Nunc efficitur, ante ac mollis pretium, elit felis elementum lorem, vitae porttitor ex arcu vulputate ante. Donec elit purus, porta nec tortor vitae, semper suscipit sem. Ut ante dui, lobortis vel nulla vitae, condimentum laoreet magna. Maecenas aliquet aliquet nulla a fringilla. Proin rhoncus est eget nunc venenatis tempus. Praesent rhoncus est et velit gravida, non posuere justo scelerisque. Praesent ultrices lectus quis quam iaculis faucibus quis id sem. Quisque enim massa, molestie ac tortor sit amet, porta tristique diam. Suspendisse potenti. Fusce rutrum massa metus, eu facilisis nisi luctus vel.. newRectWidth: 5634, newRectHeight: 15, numLinesGenerated: 1

```

**Outputs of `Debug Log 3`**

And here for `Debug Log 3`

```
Text is: . generationExtents: width 20, height: 20, numLinesGenerated: 1

Text is: a. generationExtents: width 20, height: 20, numLinesGenerated: 1

Text is: aa. generationExtents: width 20, height: 20, numLinesGenerated: 1

Text is: Nam a tempor lorem. Ut eleifend, massa sed tincidunt blandit, risus nunc pharetra orci, at mattis turpis augue eu eros. Aliquam a faucibus dolor. Vestibulum ultrices turpis quis mi aliquam, a facilisis metus rutrum. Nulla sodales, ante vitae maximus fringilla, tellus erat ultricies felis, ac sodales felis lorem nec lorem. Fusce cursus turpis odio, vel tristique justo pulvinar sed. Nunc efficitur, ante ac mollis pretium, elit felis elementum lorem, vitae porttitor ex arcu vulputate ante. Donec elit purus, porta nec tortor vitae, semper suscipit sem. Ut ante dui, lobortis vel nulla vitae, condimentum laoreet magna. Maecenas aliquet aliquet nulla a fringilla. Proin rhoncus est eget nunc venenatis tempus. Praesent rhoncus est et velit gravida, non posuere justo scelerisque. Praesent ultrices lectus quis quam iaculis faucibus quis id sem. Quisque enim massa, molestie ac tortor sit amet, porta tristique diam. Suspendisse potenti. Fusce rutrum massa metus, eu facilisis nisi luctus vel.. generationExtents: width 20, height: 20, numLinesGenerated: 1

```

---

**Conclusion**

**Debug Log 1**

`generator.GetPreferredWidth` adds 7 to the preferred width for each character (and 4 for each space) and `generator.GetPreferredHeight` adds 15 to the preferred height for **each character (no idea why)** and **neither `GetPreferredWidth` nor `GetPreferredHeight` calculate line Breaks in any sensible way**

**Debug Log 2**

`generator.rectExtents.width` gets incremente by 7 for each character (and 4 for each space), **but `generator.rectExtents.height` is not incremented at all** (so again, no line breaks or valid height readings)

**Debug Log 3**

This (probably expected) always outputs 20,20 (i.e., whatever `textGenSetting.generationExtents` is set to). I tried this anyway since I thought maybe `generator.Populate()` would update this value of the `textGenSetting` struct.

**Question: Am I missing something? Or is this in some way expected behaviour? How can I get this to work, or, alternatively, use some other way to auto-layout text and get the extents of said text so that I can adjust my sprites to fit this text?**

Here are my text settings, for complete information.

# Answer
Welp, turns out after writing this post, even though I had done quite some research before, I finally found an answer. Changing my RecalculateText method to the following worked, allthough I haven't investigated where I went wrong with my previous approaches.

```
private void RecalculateText(string sText)
    {
        TextGenerator textGen = new TextGenerator();
        TextGenerationSettings tgSettings = text.GetGenerationSettings(text.rectTransform.rect.size);
        var width = textGen.GetPreferredWidth(text.text, tgSettings);
        var height = textGen.GetPreferredHeight(text.text, tgSettings);
    }

```

Kudos go to pineda100 over on the unity forum, who's answer to a similar question provided the snippet above.
> 0 votes

---
Tags: unity, c#, fonts, unity-ui
---


# Question
Title: How to smoothly interpolate 2D camera with pan and zoom
I'm developing an animation application with a 2D virtual camera. The camera viewport can be positioned and scaled in the keyframes and is then interpolated to render the final animation from the viewpoint of the camera. I'm looking for the best way to interpolate the camera's parameters of x,y position, and scale so that objects in the scene are transformed by the camera change size at a constant rate and so that all objects/pixels in the scene travel in a straight line.

The transform matrix for rendering the scene from the point of view of the camera is calculated from the position and scale as follows, where DimX, DimY are the dimensions of the scene image, Pos and Scale are the position and scale of the camera (the variables that I want to interpolate).

```
  LCen := PointF(DimX*0.5, DimY*0.5);
  CamTransformInv := TMatrix.CreateTranslation(-(Pos.X + LCen.X), -(Pos.Y + LCen.Y));
  LScaleInv := 1 / Scale;
  CamTransformInv := CamTransformInv * TMatrix.CreateScaling(LScaleInv, LScaleInv);
  CamTransformInv := CamTransformInv * TMatrix.CreateTranslation(LCen.X, LCen.Y);

```

Below is an animation created by linearly interpolating the scale and position. The interpolation is as follows, where k is the interpolation ratio.

```
  CamT.Scale := LinearInterpolate(Cam1.Scale, Cam2.Scale, k);
  CamT.Pos.X := LinearInterpolate(Cam1.Pos.X, Cam2.Pos.X, k);
  CamT.Pos.Y := LinearInterpolate(Cam1.Pos.Y, Cam2.Pos.Y, k);

```

The black line extends from the center of the viewport in the start position to the center of the viewport in the end position. You can see the effect of it appearing to speed up as it zooms in and then suddenly slowing down as it repeats, which I'd like to avoid. On the plus side, all objects in the scene move in a straight line. I've made the animation loop to make the acceleration effect more obvious.

Here's what the camera viewport is doing during the interpolation. The position and scale are both changing.

So I modified my code to linearly interpolate the Ln of the scale and take Exp of the result.

```
  CamT.Scale := Exp(LinearInterpolate(Ln(Cam1.Scale), Ln(Cam2.Scale), k));
  CamT.Pos.X := LinearInterpolate(Cam1.Pos.X, Cam2.Pos.X, k);
  CamT.Pos.Y := LinearInterpolate(Cam1.Pos.Y, Cam2.Pos.Y, k);

```

This results in an exponential interpolation with the scale change slowing down as it zooms in which looks good since objects in the scene then grow at a constant rate. This makes sense because objects in the scene get multiplied by scale whereas objects get added by position, so interpolation of scale should be multiplicative. This is achieved by taking the log before interpolating. The position is still as linear as before. The problem now is that parts of the image to the sides of the line move in a curve. It doesn't look right (see the top of the tower).

Here's what the camera viewport is doing during the interpolation. Note that the top left and bottom right corners of the viewport are traveling along curves.

It occurred to me that the problem is because I'm interpolating the scale non-linearly and the position linearly. If I made the position decelerate in the same way as the scale is decelerating then it would look correct. However, I can't think how this would be computed as the position and scale are coupled. If there's no scale change then the position should change linearly, but the greater the scale change the greater the non-linearity of the position should be. The position interpolation should depend on the scale somehow.

Is there a standard way of doing this? I have tried the following thinking that it should work, but it's not right either.

```
  CamT.Scale := Exp(LinearInterpolate(Ln(Cam1.Scale), Ln(Cam2.Scale), k));
  CamT.Pos.X := LinearInterpolate(Cam1.Pos.X/Cam1.Scale, Cam2.Pos.X/Cam2.Scale, k) * CamT.Scale;
  CamT.Pos.Y := LinearInterpolate(Cam1.Pos.Y/Cam1.Scale, Cam2.Pos.Y/Cam2.Scale, k) * CamT.Scale;

```

I did find a similar question from over 10 years ago. The suggestion there was to interpolate the inverse of scale, but that doesn't seem correct mathematically and didn't work when I tried it (I got the opposite acceleration effect).

Zooming and panning a camera simultaneously causes a swooping effect

# Answer
For a smooth loop like this, we want to scale the camera viewport from 1 x at the start to \\$r\\$ x at the end of the first loop (where \\$r\\$ is the ratio between the inner image size and the outer image), then \\$r^2\\$ x at the end of the second loop, \\$r^3\\$ at the end of the third loop, etc.

A function whose value compounds by some ratio each time we move a fixed distance along its domain is an exponential function. Specifically, if \\$t = \frac {\text{time}} {\text{loop period}}\\$, then \\$\text{scale} = a \cdot r^t\\$

```
scale = initialScale * Pow(ratio, t)

```

To avoid any visible variation in our movement speed or direction, the rate of travel of the center point across the image should stay in fixed proportion to the current size of the viewport. So that means that our derivative is a multiple of the formula above, and we can integrate it to get an expression for our absolute position. (Here I'm leaving off the coefficient, since we just need proportionality)

$$\int\_0^t {r^x}dx\\ = \frac {r^t - 1} {\ln r}$$

At \\$t = 0\\$ that's 0, and at \\$t = 1\\$ it's \\$\frac {r - 1} {\ln r}\\$, so we can multiply by the reciprocal to scale it into an interpolation weight between 0 and 1:

```
positionInterpolation = (Pow(ratio, t) - 1)/(ratio - 1)

```

Now you can use this weight as the input to a lerp between your start and end positions, getting a result like this:
> 3 votes

# Answer
Here is my solution based on the answer given by DMGregory. This is Delphi Pascal. The `LinearInterpolate` function is just a lerp. Care has to be taken to avoid divide by zero.

```
      CamT.Scale := Exp(LinearInterpolate(Ln(Cam1.Scale), Ln(Cam2.Scale), k));
      if abs(Cam2.Scale - Cam1.Scale) > 0.001 then begin
        r := Cam2.Scale / Cam1.Scale
        w := (Power(r, k) - 1) / (r - 1);
        CamT.Pos.X := LinearInterpolate(Cam1.Pos.X, Cam2.Pos.X, w);
        CamT.Pos.Y := LinearInterpolate(Cam1.Pos.Y, Cam2.Pos.Y, w);
      end else begin
        CamT.Pos.X := LinearInterpolate(Cam1.Pos.X, Cam2.Pos.X, k);
        CamT.Pos.Y := LinearInterpolate(Cam1.Pos.Y, Cam2.Pos.Y, k);
      end;

```
> 1 votes

# Answer
Dunno if this is what you wanted, but this was sufficient for me:

Basically, instead of linearly interpolating the zoom, I linearly interpolated the height of the camera viewport and then backwards-calculated the zoom to get that height. Here's the code I used:

```
camera *Camera = &Renderer->OffscreenFramebuffer.Camera;
texture *Texture = GetTexture(TextureLoader, "chapter1/cutscene1/_backgrounds/FreedomTower");

const float DURATION = 5.0f;

const v2 TARGET_CAMERA_POS = V2(179.0f, 455.0f);
const float TARGET_CAMERA_VIEWPORT_HEIGHT = 50.0f; // In pixels (so fifty pixels).

static v2 CameraPositionSpeed;

static float CameraHeight;
static float CameraHeightSpeed;

static float TimeElapsed;

static bool IsInitialized = false;
if (!IsInitialized)
{
    // Put the camera at the middle of the screen.
    Camera->Position = 0.5f*WINDOW_SIZE_PIXELS;

    CameraPositionSpeed = (TARGET_CAMERA_POS - Camera->Position)/DURATION;

    CameraHeight = WINDOW_HEIGHT_PIXELS;
    CameraHeightSpeed = (TARGET_CAMERA_VIEWPORT_HEIGHT - CameraHeight)/DURATION; // The rate at which we change the camera's height.

    TimeElapsed = 0.0f;

    IsInitialized = true;
}

Camera->Position += Game->dt*CameraPositionSpeed;

CameraHeight += Game->dt*CameraHeightSpeed;
Camera->Zoom = WINDOW_HEIGHT_PIXELS/CameraHeight; // Backwards-calculate the zoom based on the desired height.

// Render texture such that the bottom left is at the origin.
rect2 TextureRect = RectFromPosSize(V2_ZERO, Texture->Size);
AddTexture(Renderer, Texture->Handle, TextureRect, Texture->TexCoords, 4);

```
> 0 votes

---
Tags: 2d, mathematics, camera, interpolation
---


# Question
Title: Zooming and panning a camera simultaneously causes a swooping effect
In a 2d game, I have a basic camera class. The guts of the class creates a transformation matrix that is later passed to the Begin() method of a SpriteBatch. The transformation is done like this:

```
        Transform = Matrix.Identity *
                    Matrix.CreateTranslation(-Position.X, -Position.Y, 0) *
                    Matrix.CreateScale(new Vector3(Scale, Scale, Scale)) *
                    Matrix.CreateTranslation(ScreenCenter.X, ScreenCenter.Y, 0);

```

I'm trying to create an effect that zooms in on a specific point on the screen. The issue is that the zoom/translation causes a strange "swooping" effect when applied. For example, when the zoom is set to 1.0 and the current position is (0, 0), and I change these to 2.0 and (100, 200) over a 1 second interval, the camera appears to take a curved path to (100, 200).

Here is my code to update the position / scale on each frame (I removed logic to determine when the transition is finished):

```
        _positionTimeElapsed += gameTime.ElapsedGameTime.TotalMilliseconds;
        _scaleTimeElapsed += gameTime.ElapsedGameTime.TotalMilliseconds;

        Position = Vector2.Lerp(
            _positionStart,
            PositionDestination.Value,
            (float)(_positionTimeElapsed / TransitionTimeMilliseconds));

        Scale = (ScaleDestination.Value - _scaleStart)
             * (float)(_scaleTimeElapsed / TransitionTimeMilliseconds)
             + _scaleStart;

```

I'm relatively confident that I'm missing something basic about Matrix math. Does anyone know how to transition both position and scale simultaneously and have the camera appear to take a linear path to the destination?

**UPDATE**

Added two videos on YouTube that show the issue and the fix in action. These videos zoom to 10x over 5 seconds to make the bug obvious.

Broken: http://www.youtube.com/watch?v=d8fJ4Zf-sqU

Fixed: http://www.youtube.com/watch?v=GpcUc25eZ8o

# Answer
> 10 votes
Your swooping effect is because there is no stationary pixel during the interpolation. In a dolly and pan, there will be a point (a line actually) that doesn't change in appearance other than mip level.

You're using a zoom/scale, and because of this you're suffering from an accelerated scale problem, if you tried going from 2.0 to 0.1, then it would become more obvious why this was a non-linear operation.

You need to consider the zoom as it's inverse, then this goes away. at half-way, your zoom is 1.5, but if you took the inverse of your zoom (1.0 -\> 0.5 instead of 1.0 to 2.0), then half-way becomes 1.3333 (1.0/0.75), which actually gives you the zoom you want at that part of your linear interpolation across space (the 0,0 to 100,200).

For Kylotan: To make a camera look like it's not swooping, you have to be able to pin a point in the screen. What you're after is a linear interpolation of the top,bottom,left,and right values of the render rectangle, well, that's not going to happen if you're interpolating the scale, because that's the "inverse" of the size of the rectangle.

What happened was, interpolating the scale cause the rectangle to shrink non linearly over time. example: assuming the rectangle was -100,100,-100,100 (that's left,right,top,bottom) translation moves it to 0,200,100,300, but shrinks (scaled 0.5) as the scene is zoomed to 50,150,150,250 that's the final destination of the interpolation... but, if you interpolate the zoom... zoom at 1.5 == 0.666 scale in render rectangle, leading to -16.666,116.666,33.333,166.666

At any point during the interpolation, the world point 200,400 should always appear in the same relative position to the render rectangle. At the start it is 200,400 but at scale 1, and at the end it is at 100,200 relative, but scaled up by 2 due to scene scaling, so it's still the same position relatively.

if you take the halfway point, it's at 150,300, but the scene is scaled by 1/.75 at this point so the relative position is once again 200,400 (150/0.75==200 & 300/0.75==400)

# Answer
> 0 votes
I used Richard Fabian's answer and reversed my interpolation function, which worked for me.

Here is the code I used, in case it's useful for other readers:

```
  interpolate(p0, p1, k) {
    return p0+(p1-p0)*k;
  }

  interpolateScale(s0, s1, k) {
    return 1/this.interpolate(1/s0, 1/s1, k);
  }

```

# Answer
> 0 votes
I was able to achieve this:

Basically, instead of linearly interpolating the zoom, I linearly interpolated the height of the camera viewport and then backwards-calculated the zoom to get that height. Here's the code I used:

```
camera *Camera = &Renderer->OffscreenFramebuffer.Camera;
texture *Texture = GetTexture(TextureLoader, "chapter1/cutscene1/_backgrounds/FreedomTower");

const float DURATION = 5.0f;

const v2 TARGET_CAMERA_POS = V2(179.0f, 455.0f);
const float TARGET_CAMERA_VIEWPORT_HEIGHT = 50.0f; // In pixels (so fifty pixels).

static v2 CameraPositionSpeed;

static float CameraHeight;
static float CameraHeightSpeed;

static float TimeElapsed;

static bool IsInitialized = false;
if (!IsInitialized)
{
    // Put the camera at the middle of the screen.
    Camera->Position = 0.5f*WINDOW_SIZE_PIXELS;

    CameraPositionSpeed = (TARGET_CAMERA_POS - Camera->Position)/DURATION;

    CameraHeight = WINDOW_HEIGHT_PIXELS;
    CameraHeightSpeed = (TARGET_CAMERA_VIEWPORT_HEIGHT - CameraHeight)/DURATION; // The rate at which we change the camera's height.

    TimeElapsed = 0.0f;

    IsInitialized = true;
}

Camera->Position += Game->dt*CameraPositionSpeed;

CameraHeight += Game->dt*CameraHeightSpeed;
Camera->Zoom = WINDOW_HEIGHT_PIXELS/CameraHeight; // Backwards-calculate the zoom based on the desired height.

// Render texture such that the bottom left is at the origin.
rect2 TextureRect = RectFromPosSize(V2_ZERO, Texture->Size);
AddTexture(Renderer, Texture->Handle, TextureRect, Texture->TexCoords, 4);

```

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


title: Create list of images for animation

text:
# Question
Title: Create list of images for animation
I'm using pygame and trying to create an animation by going through a list of variables:

```
self.image = self.walk_right[self.index]

```

I have loaded the images into variables and now I want to add them to my list. I assume there should be a way to use a for loop to do this.

I tried using a formatted string to append them to the list, however then they become strings and I get the error:

> TypeError: Source objects must be a surface

Is there a way to convert these strings back to being variables? Is there a better way to do this? Or do I need to type out the name of each frame once i've imported it from the sprite sheet?

```
        walk_right_1 = sprite_sheet.get_image(1,11,sprite_width,sprite_height,1.25,0)
        walk_right_2 = sprite_sheet.get_image(2,11,sprite_width,sprite_height,1.25,0)
        walk_right_3 = sprite_sheet.get_image(3,11,sprite_width,sprite_height,1.25,0)
        walk_right_4 = sprite_sheet.get_image(4,11,sprite_width,sprite_height,1.25,0)
        walk_right_5 = sprite_sheet.get_image(5,11,sprite_width,sprite_height,1.25,0)
        walk_right_6 = sprite_sheet.get_image(6,11,sprite_width,sprite_height,1.25,0)
        walk_right_7 = sprite_sheet.get_image(7,11,sprite_width,sprite_height,1.25,0)
        walk_right_8 = sprite_sheet.get_image(8,11,sprite_width,sprite_height,1.25,0)
        walk_right_9 = sprite_sheet.get_image(9,11,sprite_width,sprite_height,1.25,0)
        self.walk_right = []

        for num in range (1,10):
            self.walk_right.append(f'walk_right_{num}')

```

# Answer
You can simply put `sprite_sheet.get_image` into the loop:

```
self.walk_right = []

for num in range (1,10):
    walk_right_temp = sprite_sheet.get_image(num,11,sprite_width,sprite_height,1.25,0)
    self.walk_right.append(walk_right_temp)

```

Or use python's list comprehension:

```
self.walk_right = [sprite_sheet.get_image(num,11,sprite_width,sprite_height,1.25,0) for num in range (1,10)]

```

Or, It is indeed possible to find local/global/member variables by string if *really necessary*(Most of the time you don't need to do this):

```
self.__dict__["walk_right"]= []
for num in range (1,10):
    self.__dict__["walk_right"].append(locals()[f'walk_right_{num}'])

```
> 1 votes

---
Tags: animation, sprites, python, pygame
---


title: How to I modify a texture in OpenGL?

text:
# Question
Title: How to I modify a texture in OpenGL?
I am programming the editor for a RTS game and I have created the following:

I am trying to modify the terrain so that it is not completely grassy. I am intending to add functionality so that I can create paths while playing the game. I already have created a blendmap that someone here recommended for me, but that does not allow the user to edit the texture while using the app, but only after drawing an image and saving it to the game folder. I fiddled with the shaders a bit, but I was only able to add a square that is able to move, but it does not leave a path behind it. Here is an example of what I am working towards. I have not been able to find any resources that really shows what I need.

Here is a snippet of the code:

```
if(((tiledCoords.x - mouseTexCoords.x) < 4) && ((tiledCoords.x - mouseTexCoords.x) > 0))
{
if(((tiledCoords.y - mouseTexCoords.y) < 4) && ((tiledCoords.y - mouseTexCoords.y) > 0))
{
blendMapColor.g = 1;
//rTextureColor = texture(rTexture, tiledCoords) * 1;

}
}

```

With these if statements, it checks to see if the mouse is over a certain area within a few units, and if it is, it changes the terrain texture to a sand texture. However, it is unsuccessful in being able to create paths, but rather, a mere square that can move around the landscape.

Thank you all in advance!

# Answer
> 0 votes
How I see it in my head:

You have the tiles, each tile has at least one type of terrain texture at each moment (stone, grass, snow etc.) or some value that represent type of terrain on its tiles. From now you can draw each tile separately sampling terrain texture appropriate for the type of terrain in current tile.

**Blending two different type of terrain**

Let's go farther and allow one tile to have, let's say, an array of terrain types in it. For example one tile has *terrain = \[grass, stone\]*, another *terrain = \[grass\]*. Base on that you can sample and blend between all terrain texture you tile has for smooth looking.

**Cursor moving**

When you move cursor and know the chosen type of terrain (e.x grass), you detect if cursor is over a curtain tile, then changes tile terrain type to grass or, if you support blending, you can add to terrain type array of tile the grass type, so hovered tile now has \[snow, grass\]. You can decide to add or remove a curtain type of terrain from tile based on what type of terrain it surrounded (what type of terrain surrounded tiles have). It's done in game/engine code. I don't how exactly you draw terrain, but you can send all terrain types as one array to opengl buffer and access it by index in shader, index = index of your tile. Or you can draw tile one by one time setting type for each tile to shader each time it's about to draw.

**Modifying texture**

You don't need this, usually you have a concrete set of textures you use in game. And then, in fragment shader, you work with them. You can use multiple of textures and blend between them in shader. And in your game code using opengl you set exact texture you want your fragment shader to use. For now I would recommend to send all your terrain textures to shader (it actually can be a one atlas) and by type in tiles decide for texture or textures to use to get a result color(sampling).

I hope I got you thinking.

---
Tags: opengl, c++, textures, terrain
---


# Question
Title: Some objects only rendering half of the screen in snake game
I'm trying to make a basic snake game with OpenGL. I hold all the game object locations in a matrix called `MAP`. And when i render them, i operate the location info from `MAP` (that comes as x and y *\[0 \< x \< 40 and 0 \< y \< 20\]*) so that i can use it in the `glTranslatef()`.

I use the same equation for all objects. Snake's head is rendering correctly and can be move to anywhere in the screen but tails and bait are only rendering to half of the screen. Here's the code:

```
void SetLocationE()
{
    glLoadIdentity();
    glTranslatef(-11.5f, -8.125f, .0f);
}

void ScreenBuffer::RenderToScreen(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    /* DRAW */
    for (int i = 0; i < 20; i++)
    {
        for (int j = 0; j < 40; j++)
        {

            if (MAP[i][j] == 'x')
            {
                SetLocationE();
                bx = j;
                by = i;
                /* BAIT */
                bxx = bx * 23 / 40;
                byy = by * 16.25 / 40;
                glTranslatef(bxx, byy, zet);
                glBegin(GL_QUADS);
                //painting
                glColor3f(0.0f, 0.0f, 0.0f);
                //drawing  TOP RIGHT -> TOP LEFT
                //         -> BOTTOM LEFT -> BOTTOM RIGHT
                glVertex3f(0.15f, 0.15f, .0f);  //tr
                glVertex3f(-0.15f, 0.15f, .0f);  //tl
                glVertex3f(-0.15f, -0.15f, .0f);  //bl
                glVertex3f(0.15f, -0.15f, .0f);  //br
                glEnd();

            }

            else if (MAP[i][j] == '0')
            {
                SetLocationE();
                hx = j;
                hy = i;
                /* HEAD */
                hxx = hx * 23 / 40;
                hyy = hy * 16.25 / 20;
                glTranslatef(hxx, hyy, zet);
                glBegin(GL_QUADS);
                //painting
                glColor3f(0.0f, 0.3f, 0.1f);
                //drawing  TOP RIGHT -> TOP LEFT
                //         -> BOTTOM LEFT -> BOTTOM RIGHT
                glVertex3f(0.15f, 0.15f, .0f);  //tr
                glVertex3f(-0.15f, 0.15f, .0f);  //tl
                glVertex3f(-0.15f, -0.15f, .0f);  //bl
                glVertex3f(0.15f, -0.15f, .0f);  //br
                glEnd();
            }

            else if (MAP[i][j] == 'o')
            {
                SetLocationE();
                /* TAIL */
                txx = j * 23 / 40;
                tyy = i * 16.25 / 40;
                glTranslatef(txx, tyy, zet);
                glBegin(GL_QUADS);
                //painting
                glColor3f(0.0f, 0.7f, 0.2f);
                //drawing  TOP RIGHT -> TOP LEFT
                //         -> BOTTOM LEFT -> BOTTOM RIGHT
                glVertex3f(0.15f, 0.15f, .0f);  //tr
                glVertex3f(-0.15f, 0.15f, .0f);  //tl
                glVertex3f(-0.15f, -0.15f, .0f);  //bl
                glVertex3f(0.15f, -0.15f, .0f);  //br
                glEnd();

            }
        }
    }
}

```

Moving of the head is correct. When out of borders, it reappears again. Same thing is available for the tails but they reappear if they are at the horizontally half line. Tails and bait is rendering between red lines:

It was a console game at first. Now i'm trying to implement OpenGL to the old codes. I don't know what causes this. Thanks in advance.

# Answer
> 0 votes
I think you have a typo in these lines (BAIT and TAILS), it should be divided by 20 instead of 40 (HEAD divides y by 20). That explains why they are shown only on the bottom half of the screen.

```
byy = by * 16.25 / 40;    // should be 20.0 instead of 40

tyy = i * 16.25 / 40;     // should be 20.0 instead of 40

```

Also you are doing integer divisions in the same lines. Use 40.0 instead of 40 to force a float division

```
/* BAIT */
bxx = bx * 23 / 40.0;
byy = by * 16.25 / 20.0;

/* HEAD */
hxx = hx * 23 / 40.0;
hyy = hy * 16.25 / 20.0;

/* TAIL */
txx = j * 23 / 40.0;
tyy = i * 16.25 / 20.0;

```

Also you can extract the drawing of the quad to another function, because it is the same code.

```
void SetLocationE()
{
    glLoadIdentity();
    glTranslatef(-11.5f, -8.125f, .0f);
}

void ScreenBuffer::drawQuad(int column, int row, float r, float g, float b)
{
    // Draw quad
    SetLocationE();
    float x = column * 23.0 / 40.0;
    float y = row * 16.25 / 20.0;
    glTranslatef(x, y, zet);
    glBegin(GL_QUADS);
    //painting
    glColor3f(r, g, b);
    //drawing  TOP RIGHT -> TOP LEFT
    //         -> BOTTOM LEFT -> BOTTOM RIGHT
    glVertex3f(0.15f, 0.15f, .0f);  //tr
    glVertex3f(-0.15f, 0.15f, .0f);  //tl
    glVertex3f(-0.15f, -0.15f, .0f);  //bl
    glVertex3f(0.15f, -0.15f, .0f);  //br
    glEnd();
}

void ScreenBuffer::RenderToScreen(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    /* DRAW */
    for (int i = 0; i < 20; i++)  // Y [0-20]
    {
        for (int j = 0; j < 40; j++)  // X [0-40]
        {
            // select color
            if (MAP[i][j] == 'x') {
                 drawQuad(j, i, 0.0f, 0.0f, 0.0f);
            }
            else if (MAP[i][j] == '0')
            {
                drawQuad(j, i, 0.0f, 0.3f, 0.1f);
            }
            else if (MAP[i][j] == 'o')
            {
                drawQuad(j, i, 0.0f, 0.7f, 0.2f);
            }
        }
    }
}

```

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


# Question
Title: Custom world map chunks not loading correctly
```
public class ChunkReader : MonoBehaviour
{
    public int chunk_width = 128;
    public int chunk_height = 64;

    public int map_width = 2048;
    public int map_height = 1024;

    public Texture2D HeightMap;

    private int chunk_count = 0;

    //private int CurXChunk, CurYChunk; //Which chunk are we parsing?
    private void Start()
    {
        HeightMap = Resources.Load("EarthBumpMap") as Texture2D;
        //LoadChunk(0, 0);
        LoadChunks(map_width, map_height);
    }
    void LoadChunks(int map_width, int map_height)
    {
        for(int i = 0; i < map_width; i+=chunk_width)
        {
            for(int j = 0; j < map_width; j+=chunk_height)
            {
                LoadChunk(i, j);
            }
        }
    }

    void LoadChunk(int chunk_x, int chunk_y)
    {
        List<Vector3> verts = new List<Vector3>();
        List<int> tris = new List<int>();

        //Bottom left section of the map, other sections are similar
        for (int i = chunk_x; i < chunk_width; i++)
        {
            for (int j = chunk_y; j < chunk_height; j++)
            {
                //Add each new vertex in the plane
                verts.Add(new Vector3(i, HeightMap.GetPixel(i, j).grayscale * 100, j));
                //Skip if a new square on the plane hasn't been formed
                if (i == 0 || j == 0) continue;
                //Adds the index of the three vertices in order to make up each of the two tris
                tris.Add(chunk_height * i + j); //Top right
                tris.Add(chunk_height * i + j - 1); //Bottom right
                tris.Add(chunk_height * (i - 1) + j - 1); //Bottom left - First triangle
                tris.Add(chunk_height * (i - 1) + j - 1); //Bottom left
                tris.Add(chunk_height * (i - 1) + j); //Top left
                tris.Add(chunk_height * i + j); //Top right - Second triangle
            }
        }

        Vector2[] uvs = new Vector2[verts.Count];
        for (var i = 0; i < uvs.Length; i++) //Give UV coords X,Z world coords
            uvs[i] = new Vector2(verts[i].x, verts[i].z);

        GameObject plane = new GameObject("Chunk  " + chunk_count); //Create GO and add necessary components
        chunk_count++;
        plane.AddComponent<MeshFilter>();
        plane.AddComponent<MeshRenderer>();
        Mesh procMesh = new Mesh();
        procMesh.vertices = verts.ToArray(); //Assign verts, uvs, and tris to the mesh
        procMesh.uv = uvs;
        procMesh.triangles = tris.ToArray();
        procMesh.RecalculateNormals(); //Determines which way the triangles are facing
        plane.GetComponent<MeshFilter>().mesh = procMesh; //Assign Mesh object to MeshFilter
    }
    // Update is called once per frame
    void Update()
    {

    }
}

```

Basically, I'm trying to load a map into my game using Unity3D using the above code and the below-linked heightmap, but only the first chunk (at 0,0) actually loads, and the rest don't render for whatever reason. I really don't understand what I'm doing wrong. Probably super basic.

As you can see below, Chunk 0 generates fine, but all concurrent chunks generate with no functional mesh and at the exact same location.

# Answer
There are a couple of issues with your algorithm:

First, in `LoadChunks`, you use the same boundary for both of your loops (`map_width`). This wouldn't be an issue if your map were square. The line

```
for(int j = 0; j < map_width; j+=chunk_height)

```

should be

```
for(int j = 0; j < map_height; j+=chunk_height)

```

This is not the cause of having only the first chunk generate. The reason why only the first chunk generates is that there is an issue in the loops boundaries in the `LoadChunk` function.

```
for (int i = chunk_x; i < chunk_width; i++)
{
    for (int j = chunk_y; j < chunk_height; j++)
    {

```

This will work for the first chunk, but when you get to the other ones, `chunk_x` or `chunk_y` will necessarily be greater-or-equal than-to `chunk_width` or `chunk_height` because they were the upper-bound of the previous run.

Some parts of the inner loop appear to expect the indices `i` and `j` to be in the range \[0..chunk\_size), while some other parts expect them to be in the range \[0..map\_size).

To make the code a bit easier to read, I suggest you stick with the concept of \[0..chunk\_size):

```
for (int i = 0; i < chunk_width; i++)
{
    for (int j = 0; j < chunk_height; j++)
    {
        int world_index_x = chunk_x + i;
        int world_index_y = chunk_y + j;
        verts.Add(new Vector3(world_index_x, HeightMap.GetPixel(world_index_x, world_index_y).grayscale * 100, world_index_y));

```

The final code should be something like this:

```
public class ChunkReader : MonoBehaviour
{
    public int chunk_width = 128;
    public int chunk_height = 64;

    public int map_width = 2048;
    public int map_height = 1024;

    public Texture2D HeightMap;

    private int chunk_count = 0;

    //private int CurXChunk, CurYChunk; //Which chunk are we parsing?
    private void Start()
    {
        HeightMap = Resources.Load("EarthBumpMap") as Texture2D;
        //LoadChunk(0, 0);
        LoadChunks(map_width, map_height);
    }
    void LoadChunks(int map_width, int map_height)
    {
        for(int i = 0; i < map_width; i+=chunk_width)
        {
            for(int j = 0; j < map_height; j+=chunk_height)
            {
                LoadChunk(i, j);
            }
        }
    }

    void LoadChunk(int chunk_x, int chunk_y)
    {
        List<Vector3> verts = new List<Vector3>();
        List<int> tris = new List<int>();

        //Bottom left section of the map, other sections are similar
        for (int i = 0; i < chunk_width; i++)
        {
            for (int j = 0; j < chunk_height; j++)
            {
                //Add each new vertex in the plane
                int world_index_x = chunk_x + i;
                int world_index_y = chunk_y + j;
                verts.Add(new Vector3(world_index_x, HeightMap.GetPixel(world_index_x, world_index_y).grayscale * 100, world_index_y));
                //Skip if a new square on the plane hasn't been formed
                if (i == 0 || j == 0) continue;
                //Adds the index of the three vertices in order to make up each of the two tris
                tris.Add(chunk_height * i + j); //Top right
                tris.Add(chunk_height * i + j - 1); //Bottom right
                tris.Add(chunk_height * (i - 1) + j - 1); //Bottom left - First triangle
                tris.Add(chunk_height * (i - 1) + j - 1); //Bottom left
                tris.Add(chunk_height * (i - 1) + j); //Top left
                tris.Add(chunk_height * i + j); //Top right - Second triangle
            }
        }

        Vector2[] uvs = new Vector2[verts.Count];
        for (var i = 0; i < uvs.Length; i++) //Give UV coords X,Z world coords
            uvs[i] = new Vector2(verts[i].x, verts[i].z);

        GameObject plane = new GameObject("Chunk  " + chunk_count); //Create GO and add necessary components
        chunk_count++;
        plane.AddComponent<MeshFilter>();
        plane.AddComponent<MeshRenderer>();
        Mesh procMesh = new Mesh();
        procMesh.vertices = verts.ToArray(); //Assign verts, uvs, and tris to the mesh
        procMesh.uv = uvs;
        procMesh.triangles = tris.ToArray();
        procMesh.RecalculateNormals(); //Determines which way the triangles are facing
        plane.GetComponent<MeshFilter>().mesh = procMesh; //Assign Mesh object to MeshFilter
    }
    // Update is called once per frame
    void Update()
    {

    }
}

```
> 1 votes

---
Tags: unity, terrain, 3d-meshes, mesh, terrain-rendering
---


# Question
Title: How to use Transform.lossyScale in a local reference frame?
According to the Unity docs for Transform.lossyScale, this attribute is "The global scale of the object". From what I can tell, this isn't actually an estimate of the scaling aligned with the World's coordinate system, but instead it is aligned to something else - possibly the top-most ancestor of the object in the Scene hierarchy, but it's not very clear.

To see what I mean, create a Grand Parent, Parent and Child object hierarchy in a new scene, and have them all print out their `transform.lossyScale` vectors in `Update()`. Set the scaling on the Grant Parent to something like x=10, y=1, z=1. Now run the project and rotate the Grant Parent object within the scene and you'll note that none of the lossy scale vectors actually change when the Grand Parent object rotates. But rotate just the Parent and you'll see that both it and the Child lossy scale vectors **do** change. It's as if they are both expressed in the Grand Parent's local frame of reference. But why both? Why isn't the Child's lossy scale expressed in the Parent's local frame of reference instead? Perhaps it's the highest object in the hierarchy that is used as the final frame of reference?

None of this seems to suggest that the lossy scale vector is in any way aligned with the World coordinate system.

In terms of what I'm actually trying to achieve - I have a script that creates a CapsuleCollider along the local X axis of a GameObject. I want the collider to be sized such that its overall height ("height" + 2 * "radius") is determined by some parameter of the GameObject ("width"):

```
public class MyCollider : MonoBehaviour
{
    [SerializeField] private float radius = 0.5f;
    [SerializeField] private float width = 1.0f;

    private CapsuleCollider _collider;

    private void Start()
    {
        _collider = gameObject.AddComponent<CapsuleCollider>();
        _collider.radius = radius;

        //_collider.height = width + 2 * radius * transform.lossyScale.x;  // works when aligned with parent's X axis
        //_collider.height = width + 2 * radius * transform.lossyScale.z;  // works when aligned with parent's Z axis

        _collider.direction = 0;  // X-axis
    }

```

I want the final CapsuleCollider size to be determined by any scaling on the parent (and perhaps its parents, although a single level will do for now). I've managed to get to the point where my scaling works correctly when the object with this script is in the same frame of reference as the parent object (no rotation!) - see first commented line, using the x component. If I rotate the object 90 degrees to align with the parent's Z axis, I can get away with using the z component. But I can't find a general solution for an arbitrary rotation of my MyCollider object.

I've tried converting lossyScale to local coordinates with `transform.InverseTransformDirection(transform.lossyScale)` but because lossyScale isn't really in World coordinates, this doesn't work.

So how can I get an estimate or otherwise of final scaling in my object's local reference frame? Any suggestions for a fix or alternate approach?

I am aware that `Transform.lossyScale` is really only a guess at the final scaling, due to skew caused by rotation. However in my case I'm constrained to a single Parent and therefore only its rotation and the object's own rotation.

I'm also aware that the CapsuleCollider's actual radius can be different to the value specified, and that non-uniform scaling of the collider on an axis will actually do some kind of max(abs()) of the other two axes,

# Answer
I've run into similar issue and this is what I've found:

I am sure you are aware of this (since I am answering), but this thread provides code snippet for how the capsule collider size is actually computed and it indeed uses lossyScale.

So what is lossy scale actually? It's related to the physics engine used in Unity - PhysX. For rigid body simulation it uses colliders with transformation that are represented only by rotation and translation. See the following links for docs:

1. Geometry
2. PxTransform Class Reference

If the object has only uniform scale, you don't care about the missing scale, you just take the scales along the hierarchy and apply it to the radius/height. But if there is both a rotation and scale the matrices (and sizes) will never match because of the shear.

To resolve this you take the localToWorldMatrix on your transform and then pure rotation matrix (computed by quaternion multiplication - Matrix4x4.Rotate(transform.parent.localRotation * transform.localRotation)).

If you take matrices and extract the first three columns, you get the vectors representing your X,Y,Z axis in world space. The second matrix is orthonormal (the axes are unit vectors and perpendicular to each other). If you take the length of columns in localToWorldMatrix, it will tell you how the original basis (normal basis (1,0,0), (0,1,0), (0,0,1)) is scaled. If there is shear however, you need these projected onto the orthonormal basis (so that it can be used by PhysX). And that's the lossyScale - world space size of the object, if we use orthonormal basis.

Now on how to add the collider. If you add collider to an object with a mesh, it will automatically be created for you with correct scales applied. If you plan on using your own script with some values, these values should be done in the local coordinate space so you should directly use your radius/height.

But if you want to create a collider, that has height 5 meters in world space on axis X, then you would take the lossyScale (for example (2,1,3)) and set the height of capsule collider to 2.5. I can imagine this could be very useful for assigning colliders to hierarchy objects without renderable since Unity does not handle these cases.
> 1 votes

---
Tags: unity, transformation, scale, collider
---


# Question
Title: Exposing list of interfaces to inspector using Odin
Use case: scriptable objects that contain different algorithms but generate compatible data, which are used randomly in a procedural system. They implement an interface so that the system can give them inputs and get outputs without knowing the concrete type, allowing a list of type MyInterface to contain various different algorithms.

I want an exposed list in the inspector that a designer can drag configured scriptable objects into, and the system will be influenced by whichever objects are there.

It works if I have an exposed list of any scriptableObjects and manually ensure they all implement MyInterface, and loop through that list internally adding them to a`List<MyInterFace>` that the system can iterate through. However `List<MyInterface>` won't show up in the inspector.

I've been told Odin will allow me to serialize the `List<MyInterface>` and access directly in the inspector.

Is this possible? Full disclosure I don't understand serialization well and very possibly just didn't convey what I'm trying to do properly.

The following code will work but the contents of the list will not carry through to runtime, and every time I have to initialize the list in the inspector by selecting `List<MyInterface>` from a dropdown:

```
public class Odintest : MonoBehaviour
{
    [ShowInInspector] public List<IMyInterface> InterfaceList;

    [Button("AccessAlgorithms")]
    public void AccessAlgorithms()
    {
        foreach (var v in InterfaceList)
        {
            print(v.MyMethod());
        }
    }

}

public interface IMyInterface
{
    public float MyVar { get; set; }
    public float MyMethod();
}

[CreateAssetMenu]
public partial class MySrciptableObject1 : ScriptableObject, IMyInterface
{
    public float param1;
    public float MyVar { get; set; }
    public float MyMethod()
    {
        // do something
        float result1 = 1;
        return result1;
    }
}

[CreateAssetMenu]
public class MySrciptableObject2 : ScriptableObject, IMyInterface
{
    public float param2;

    public float MyVar { get; set; }
    public float MyMethod()
    {
        // do somethign else
        float result1 = 1;
        return result1;
    }
}

```

I've read through the docs on implementing the serializer but I can't work out how to apply that to an interface.

Thanks for any help

# Answer
> 0 votes
You need to do this:

```
public class Odintest : SerializedMonoBehaviour
{
    [OdinSerialize] public List<IMyInterface> InterfaceList;

    // ...
}

```

Notice `SerializedMonoBehaviour` and `OdinSerialize`.

`[ShowInInspector]` displays the field in the editor, but doesn't serialize it.

---
Tags: unity, serialization
---


# Question
Title: How to control post processing effects per-pixel with a render texture?
My game's protagonist is after a specific resource on the map, its concentration stored in a field on the CPU-side, and I would like to provide a subtle hint as to where it is so that the player can "sniff" it out.

To clarify what I mean by "field", I mean it in the physics sense—like an electromagnetic field. For each coordinate, there's a value associated with it. It would be relatively easy to make it a render pass.

Post processing would be my go-to if this were a video or animation. My method would be to use a render pass to detect the concentration at that distance (or the accumulated concentration, like a mist layer), and then use it to, say, increase color saturation or slightly shift the hue. Areas with this resource should visually scream at the player, no matter what's present there.

Unity's post processing effects are wonderful, and this might be mostly taken care of for me. I figured I could write that camera pass to a render texture, and then use the render texture's value to determine how much the saturation is changed for that pixel; but I'm not seeing any way to tie a control, on an override in a post-processing Volume Profile, to the value of a pixel in a render texture. It's probably doable, but I haven't figured it out yet.

Is there a straightforward, or at least reliable, way to do this? That is, can I tie a post processing field to the value of a render texture?

# Answer
It took a while, but I finally have something going. This is all for URP, HDRP is likely similar.

To begin, you'll need a shader (you can make it with shader graph if it helps you) which will base its operations on the actual render (call it \_MainTex as a reference, so Unity knows to use it) and a control texture, which should be a render texture. Have it do whatever you would like to \_MainTex, we can use it in a `Blit` operation in custom post-processing.

Duplicate your camera, set it to be a child (with an identity transform) of your main camera. Turn off shadows and post-processing, and give it a reasonable name. Create a render texture, and assign that render texture to the camera's Output Texture under Output. Lastly, create a render layer specifically for this effect. Set the new camera's culling mask to only render your new layer, and usually, you'll want to adjust your main camera so that it doesn't render this layer.

Everything the camera renders will go on that render texture. Make sure it's set to an appropriate bit depth and number of channels for what you're doing. We'll also need our render texture's aspect to match our display aspect, which can be wonky and unpredictable. This should technically run any time the resolution changes, but I haven't gotten around to that yet and just adjust it at game start, with this component:

```
public class AdjustResolution : MonoBehaviour
{
    void Start()
    {
        Camera camera = GetComponent<Camera>();
        RenderTexture currentRT = camera.targetTexture;
        currentRT.width = Screen.width;
        currentRT.height = Screen.height;
    }
}

```

We now have a render texture which follows the main camera and mimics its transform, which also has an adjusted width/height to match the main camera. (Technically what matters most is the aspect, but that's gotten very hard to predict these days!) It renders only the custom layer.

After building your shader and creating a material, plug the render texture into the material's control parameter. Now we need to implement some basic custom post processing.

Grab your new camera's renderer, I believe it defaults to URP-HighFidelity-Renderer. At the bottom, you will have "Add Renderer Feature". Create a renderer feature script under Create\>Rendering\>URP Renderer Feature. This is a class that bears more explanation than I can give it here, but it basically controls how the post processing feature should be done. Give it an appropriate name. For completeness, I'm going to drop the source of my current feature here, though I may not be done with it yet.

```
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class BlitRenderPassFeature : ScriptableRendererFeature
{
    class CustomRenderPass : ScriptableRenderPass
    {
        public RenderTargetIdentifier source;

        private Material material;
        private RenderTargetHandle tempRenderTargetHandler;

        public CustomRenderPass(Material material)
        {
            this.material = material;

            tempRenderTargetHandler.Init("_TemporaryColorTexture");
        }

        // This method is called before executing the render pass.
        // It can be used to configure render targets and their clear state. Also to create temporary render target textures.
        // When empty this render pass will render to the active camera render target.
        // You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
        // The render pipeline will ensure target setup and clearing happens in a performant manner.
        public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
        {
        }

        // Here you can implement the rendering logic.
        // Use <c>ScriptableRenderContext</c> to issue drawing commands or execute command buffers
        // https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.html
        // You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline.
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            CommandBuffer cmdBuffer = CommandBufferPool.Get("BlitRenderPass(Custom)");

            cmdBuffer.GetTemporaryRT(tempRenderTargetHandler.id, renderingData.cameraData.cameraTargetDescriptor);
            Blit(cmdBuffer, source, tempRenderTargetHandler.Identifier(), material);
            Blit(cmdBuffer, tempRenderTargetHandler.Identifier(), source);

            context.ExecuteCommandBuffer(cmdBuffer);
            CommandBufferPool.Release(cmdBuffer);
        }

        // Cleanup any allocated resources that were created during the execution of this render pass.
        public override void OnCameraCleanup(CommandBuffer cmd)
        {
        }
    }

    [System.Serializable]
    public class Settings {
        public Material material = null;
    }

    public Settings settings = new Settings();
    CustomRenderPass m_ScriptablePass;

    /// <inheritdoc/>
    public override void Create()
    {
        m_ScriptablePass = new CustomRenderPass(settings.material);

        // Configures where the render pass should be injected.
        m_ScriptablePass.renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
    }

    // Here you can inject one or multiple render passes in the renderer.
    // This method is called when setting up the renderer once per-camera.
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        m_ScriptablePass.source = renderer.cameraColorTarget;
        renderer.EnqueuePass(m_ScriptablePass);
    }
}

```

As you can see there's a lot going on in there, but it's relatively straightforward in its activity. By attaching a material to our render pass, we can call the `Blit` function with it to apply it to our full render. The four-parameter `Blit` call allows for a material to be passed in. Note that Unity has issues with rendering a source pass onto itself, so you'll need to create a render target handle for it, blit to that, and then blit back.

Add your post-processing feature to your renderer via the "Add Renderer Feature"; if all goes well, it should show up in the menu. Remember to attach your material, with your custom shader, to it.

Lastly, we need to ensure that our new camera is only rendering what it's supposed to. (You will likely need duplicate objects for this; I have a separate terrain, in my game, starring a bunch of bees, that simply encodes bloom data so that they can see it at a distance, even when details aren't rendering.) Set all objects that contain data for this camera to be the same layer as its culling mask, so they're only rendered to the render texture.

I generally do this in code by using a script to change the non-shared texture, and am working with a terrain; this is unlikely to be true for all users, but to provide an example, I set my terrain to use a basic URP unlit texture and did this.

```
    Material nectarMaterial = Instantiate(nectarTerrain.materialTemplate);
    Texture2D nectarTexture = new Texture2D(
        data.detailResolution,
        data.detailResolution,
        TextureFormat.R16, -1, true);

    for(int i = 0; i < nectarTexture.width; i++)
        for(int j = 0; j < nectarTexture.height; j++)
            nectarTexture.SetPixel(i, j, fertility[i, j] * Color.white);

    nectarTexture.Apply();
    Debug.Log("Default texture: " + (nectarTexture == null ? "NULL" : nectarTexture));
    nectarMaterial.SetTexture("_BaseMap", nectarTexture);

    nectarTerrain.materialTemplate = nectarMaterial;

```

Whatever you put on this is going to update the render texture, which will control the post-processing effect. We have a render texture that is adjusted to match our display, rendered exactly from the current camera; so UV0 should be the input for both textures in your shader if you want them to line up accurately.

You now have a pixel-accurate post-processing effect.
> 1 votes

---
Tags: unity, post-processing, rendertexture
---


# Question
Title: Remove 2D images from layer where overlapping layers hide them completely
I'm creating a 2d game (engine written in JavaScript) with layers system. I would like to have some post process to optimize the images and the layers.

If there is too many images in one layer it completely covers some of the images at the lower layers. So I would like to remove them form the final build, but not worry about them at creating time so to not slow down development.

I have tried with the bounding box and combining neighbours but this doesn’t t account for alpha transparency.

Can you please share some techniques how to handle this problem?

# Answer
So there is the solution I have found.

Basically I have many images one on top of another due to the ground textures in my 2d editor. And it is unnecessarily loading textures and creating objects in the game.

The solution is a post processing tool that I have created. It does the following steps so you can incorporate it in your own engine:

1. Splits the map into chunks and begin moving camera from one chunk to another.
2. Get all images in this chunk and order them by depth value in array (it can be Z value) starting from the bottom up.
3. Set all images to grayscale with a shader and set the alpha to 100% (so if there is transparency set this transparency to max).
4. Loop through the images and for each image it does this

a) Tints the image red

b) Gets snapshot of the canvas (in my case) and check for red pixels within some tolerance.

c) If there is no pixels found it destroys the image and deletes it form the database.

I know this is very slow process that I found, but it's offline and can be done nightly before builds. This cleans and removes any forgotten images that the players will never see but they sill will load in memory.

Hope this helps anyone.
> 1 votes

---
Tags: 2d, javascript, optimization
---


# Question
Title: How do I revert back to "normal" speed after a slight boost hitting a collider mid-air?
How do I revert back to "normal" speed after a slight boost from hitting a collider mid-air?

```
private void OnCollisionEnter2D(Collision2D collision)
{
    var Speed = lastVelocity.magnitude;
    var Direction = Vector3.Reflect(lastVelocity.normalized, collision.GetContact(0).normal);
    rb.velocity = Direction * Mathf.Max(Speed, 0f);

    if (collision.gameObject.CompareTag("Blocker"))
    {
        rb.AddForce(Direction * 5f, ForceMode2D.Impulse);
    }

}

```

I'm using `AddForce` & it works but the thing is, it doesn't revert back to normal speed. I was told to try `forcemode.impulse` but it didn't work.

# Answer
> 1 votes
Use a coroutine:

```
IEnumerator WaitThenChangeSpeed(float delay, float speed) {
    yield return new WaitForSeconds(delay);
    rb.velocity = rb.velocity.normalized * speed;
}

void OnCollisionEnter2D(Collision2D collision)
{
    var speed = lastVelocity.magnitude;
    var direction = Vector3.Reflect(lastVelocity, collision.GetContact(0).normal).normalized;
    rb.velocity = direction * speed;

    if (collision.gameObject.CompareTag("Blocker"))
    {
        rb.AddForce(Direction * 5f, ForceMode2D.Impulse);
        StartCoroutine(WaitThenChangeSpeed(1f, speed));
    }
}

```

Note that there's no need for `Mathf.Max` here. By construction, `Speed` can only be non-negative, because `.magnitude` never returns a negative number.

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


# Question
Title: How to pool bullets for a double barreled gun with alternating fire?
I have created the gun with two barrels, which fire in alternation.

I have implemented pooling for one barrel, But I need to pool bullets in both barrels when firing in alternation.

This is my Bullet.cs script:

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

public class Bullet : MonoBehaviour {
 private
  Fire_Bullet _gun;

 public
  void SetGun(Fire_Bullet gun) = > _gun = gun;

 private
  void OnCollisionEnter(Collision collision) {
    gameObject.SetActive(false);
    _gun.AddToPool(this);
  }
}

```

This is Fire\_bullet.cs script attached to the gun:

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

public class Fire_Bullet : MonoBehaviour
{

    public Transform barrel_L_SpawnPoint;
    public Transform barrel_R_SpawnPoint;

    [SerializeField] private Bullet bullet_prefab;
    [SerializeField] private float _delay =0.2f;
    [SerializeField]  private float _bulletSpeed = 5f;

    private float nextFire = 0f;
    private bool shootSequance = false;
    private Queue<Bullet> _pool = new Queue<Bullet>();
    private Queue<Bullet> _poolTwo = new Queue<Bullet>();

    // Start is called before the first frame update
    void Start()
    {
        if (barrel_L_SpawnPoint == null || barrel_R_SpawnPoint == null)
        {
            Debug.LogError(" Barrel Spwan point is Mossing");
        }
        if(bullet_prefab == null)
        {
            Debug.LogError("Bullet Prefabs is Missing");
        }

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            nextFire = Time.time +_delay;
            var bullet = GetBullet();
            bullet.transform.position = barrel_R_SpawnPoint.position;
            bullet.transform.rotation = barrel_R_SpawnPoint.rotation;
            bullet.transform.position = barrel_L_SpawnPoint.position;
            bullet.transform.rotation = barrel_L_SpawnPoint.rotation;
            bullet.GetComponent<Rigidbody>().AddForce(barrel_R_SpawnPoint.up * _bulletSpeed, ForceMode.Impulse);
            bullet.GetComponent<Rigidbody>().AddForce(barrel_L_SpawnPoint.up * _bulletSpeed, ForceMode.Impulse);
        }
    }

    private Bullet GetBullet()
    {
        if (_pool.Count > 0 && shootSequance == false)
        {
            var bullet = _pool.Dequeue();
            bullet.gameObject.SetActive(true);
            return bullet;
        }
        else
        {
            var bullet = Instantiate(bullet_prefab, barrel_R_SpawnPoint.position, barrel_R_SpawnPoint.rotation);
            bullet.SetGun(this);
            shootSequance = true;
            return bullet;
        }

    }

    private bool PlayerCanShoot()
    {
        return Time.time >=  nextFire;
    }

    internal void AddToPool(Bullet bullet)
    {
        _pool.Enqueue(bullet);
    }
}

```

# Answer
There is no good reason why you would use separate pools for both barrels. You can have both of them drain from the same pool.

Your current code takes one bullet from the pool. Then it sets it up with all the properties of the left barrel. But then it overwrites all those settings it just set and overwrites them with those of the right barrel. This makes no sense.

I think what you *actually* want to do is to use either the properties of the left spawn point or the properties of the right spawn point , depending on which barrel's turn it is to fire. How do you keep track of which spawn point is the next one to fire? By adding another variable. Let's call it

```
private Transform active_SpawnPoint;

```

Now in your Update method, you need to set which spawn point is the active one:

```
    if (Input.GetMouseButtonDown(0))
    {
        if (active_SpawnPoint == barrel_L_SpawnPoint) {
            active_SpawnPoint = barrel_R_SpawnPoint;
        } else {
            active_SpawnPoint = barrel_L_SpawnPoint;
        }

```

This will toggle which barrel is the active one each time the player presses the left mouse button. Then, in the following code which does the bullet spawning, you use the properties of whichever spawn point is the `active_SpawnPoint`:

```
        var bullet = GetBullet();
        bullet.transform.position = active_SpawnPoint.position;
        bullet.transform.rotation = active_SpawnPoint.rotation;
        bullet.GetComponent<Rigidbody>().AddForce(active_SpawnPoint.up * _bulletSpeed, ForceMode.Impulse);

```
> 0 votes

---
Tags: unity, c#, object-pools
---


title: How can modders decrypt a game's files?

text:
# Question
Title: How can modders decrypt a game's files?
For example, GTA V modders could decrypt RPF files, so how could they do so?

Here are the possible reasons I can think of:

* They are encrypted using weak encryption methods
* They have been decrypted by expert hackers (which means they can hack other more critical systems)
* They were insiders or were helped by insiders
* Rockstar Games officially helped modders

# Answer
> 2 votes
When you want to use encrypted asset files in a game you developed, then the game executable must be able to decrypt those files. That means that somewhere in your game exectuable you must embed both the algorithm and the decryption key to perform that decryption. When these are part of the exectuable, then a determined cracker can find them. It's not a question of "if", it's a question of "when". With a popular game like GTA V, there are lots and lots of people looking for this information in game files. So it's just a question of time until someone finds it and publishes it on the Internet.

---
Tags: modding, encryption
---