# Question
Title: Why would some assets require a transposed TBN matrix?
I'm writing an OpenGL/DX11 Windows/Linux "engine" and I've encountered a confusing behavior in DX, specifically. For math, I'm using GLM, which means all of my HLSL `mull()` calls relating to transformations have the matrix as the first parameter.

All that being said, here's a screenshot with the current setup, running OpenGL.

And here's nothing changed, but switching to DX11.

The terrain is still fine, but the ship's normals are obviously in disagreement. If I transpose the TBN matrix, I get correct ship lighting and incorrect terrain lighting, like this.

Of course the first thing that comes to mind is column versus row major (hence me even trying a transposed matrix in the first place). I've not had issues with matrix/vector notation since everything uses GLM CPU-side. Even if that were the issue though, it wouldn't explain why one asset requires a transposition and the other does not.

I'll provide my fragment and pixel shaders for sanity checking if anyone would like to peruse them, but I'm hoping (guessing?) this is more of an asset pipeline issue than a code issue. Regardless, I'm eager to solve it. =) Thank you in advance!

GLSL fragment code:

```
#version 460 core

layout(location = 0) in VS_OUT {
    vec4 world_pos;
    vec3 normal;
    vec3 tangent;
    vec3 bitangent;
    vec2 texcoords;
} ps_in;

struct DirectionalLight {
    vec4 direction;

    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    float shine;
    float attenuation;
};

struct PointLight {
    vec4  position;

    vec4  ambient;
    vec4  diffuse;
    vec4  specular;
    float shine;
    float attenuation;
};

struct SpotLight {
    vec4  position;
    vec4  heading;

    vec4  ambient;
    vec4  diffuse;
    vec4  specular;
    float shine;
    float attenuation;

    float inner_cone;
    float outer_cone;
};

struct Material {
    vec4  ambient;
    vec4  diffuse;
    vec4  specular;
    float shine;
};

layout(std140, binding = 1) uniform WorldMaterial {
    mat4  world_matrix;
    Material material;
};

layout(std140, binding = 2) uniform LightParams {
    DirectionalLight directional;
    PointLight point;
    SpotLight  spot;
    vec4 camera_pos;
};

layout (binding = 0) uniform sampler2D diffuse_map;
layout (binding = 1) uniform sampler2D normal_map;
layout (binding = 2) uniform sampler2D specular_map;
layout (binding = 3) uniform sampler2D emission_map;

layout(location = 0) out vec4 final_color;

vec4 phong_model(vec3 normal, vec4 light_pos, vec4 ambient, vec4 diffuse,
                vec4 specular, float attenuation) {
    vec4 surface_to_light  = normalize(light_pos - ps_in.world_pos);
    vec4 surface_to_camera = normalize(camera_pos - ps_in.world_pos);

    //ambient
    vec4 ambient_result = ambient * material.ambient;

    //diffuse
    float diffuse_coefficient = max(0.0, dot(normal.xyz, surface_to_light.xyz));
    vec4 diffuse_result = diffuse_coefficient * diffuse;

    //specular
    float shine = 0.0;
    if(diffuse_coefficient > 0.0) {
        vec3 reflected = reflect(-surface_to_light.xyz, normal);
        shine = pow(max(0.0, dot(surface_to_camera.xyz, reflected)),
                    material.shine);
    }

    vec4 specular_result = specular * material.specular * shine;

    //attenuation
    float to_light = length(light_pos - ps_in.world_pos);
    float attenuation_result = 1.0 / dot(
        vec3(0.0, attenuation, 0.0),
        vec3(1.0, to_light, pow(to_light, 2))
    );

    return ambient_result + attenuation_result *
                            (diffuse_result + specular_result);
}

vec4 directional_calc(vec3 normal) {
    // ambient
    vec4 ambient = directional.ambient * material.ambient;

    // diffuse
    vec4  direction = normalize(-directional.direction);
    float angle     = max(dot(normal, direction.xyz), 0.0);
    vec4  diffuse   = directional.diffuse * angle * material.diffuse;

    // specular
    vec3  view_dir    = normalize(camera_pos.xyz - ps_in.world_pos.xyz);
    vec3  reflect_dir = reflect(-direction.xyz, normal);
    float shine       = pow(max(dot(view_dir, reflect_dir), 0.0),
                            material.shine);
    vec4  specular    = directional.specular * material.specular * shine;

    return vec4(ambient + diffuse + specular);
}

vec4 point_calc(vec3 normal) {
    return phong_model(normal, point.position, point.ambient,
                    point.diffuse, point.specular, point.attenuation);
}

vec4 spot_calc(vec3 normal) {
    vec4 light_to_surface = normalize(ps_in.world_pos - spot.position);
    float pixel_angle = dot(light_to_surface, spot.heading);

    if(pixel_angle > spot.outer_cone) {
        vec4 light_intensity = phong_model(normal, spot.position,
                                        spot.ambient, spot.diffuse,
                                        spot.specular, spot.attenuation);

        float theta   = pixel_angle;
        float epsilon = spot.inner_cone - spot.outer_cone;
        float fade    = clamp((theta - spot.outer_cone) / epsilon, 0.0, 1.0);

        return light_intensity * fade;
    }
    else {
        return vec4(0.0);
    }
}

void main() {
    mat3 TBN = mat3(ps_in.tangent,
                    ps_in.bitangent,
                    ps_in.normal);

    vec3 normal = texture(normal_map, ps_in.texcoords).rgb;
    normal = normal * 2.0 - 1.0;
    normal = normalize(TBN * normal);

    // vec3 normal = normalize(ps_in.normal_mat * ps_in.normal);

    // combination!
    vec4 directional = directional_calc(normal);
    vec4 point = point_calc(normal);
    vec4 spot = spot_calc(normal);

    vec4 light_intensity = directional + point + spot;
    vec4 texel = texture(diffuse_map, ps_in.texcoords);

    final_color = light_intensity * texel;
}

```

HLSL pixel code:

```
struct Material {
    float4 ambient;
    float4 diffuse;
    float4 specular;
    float  shine;
};

struct DirectionalLight {
    float4 direction;

    float4 ambient;
    float4 diffuse;
    float4 specular;
    float  shine;
    float  attenuation;
};

struct PointLight {
    float4 position;

    float4 ambient;
    float4 diffuse;
    float4 specular;
    float  shine;
    float  attenuation;
};

struct SpotLight {
    float4 position;
    float4 heading;

    float4 ambient;
    float4 diffuse;
    float4 specular;
    float  shine;
    float  attenuation;

    float inner_cone;
    float outer_cone;
};

cbuffer WorldMaterial : register(b1) {
    float4x4 world_matrix;
    Material material;
}

cbuffer LightParams : register(b2) {
    DirectionalLight directional;
    PointLight       pointlight;
    SpotLight        spotlight;
    float4           camera_pos;
};

Texture2D    diffuse_map       : register(t0);
SamplerState diffuse_map_samp  : register(s0);
Texture2D    normal_map        : register(t1);
SamplerState normal_map_samp   : register(s1);
Texture2D    specular_map      : register(t2);
SamplerState specular_map_samp : register(s2);
Texture2D    emission_map      : register(t3);
SamplerState emission_map_samp : register(s3);

struct VS_OUT {
    float4 sv_pos    : SV_POSITION;
    float4 world_pos : POSITION;
    float4 normal    : NORMAL;
    float4 tangent   : TANGENT;
    float4 bitangent : BINORMAL;
    float2 texcoords : TEXCOORD;
};

float4 phong_model(float3 normal, float4 light_pos, float4 ambient, float4 diffuse,
                float4 specular, float attenuation, float4 world_pos) {
    float4 surface_to_light  = normalize(light_pos - world_pos);
    float4 surface_to_camera = normalize(camera_pos - world_pos);

    //ambient
    float4 ambient_result = ambient * material.ambient;

    //diffuse
    float diffuse_coefficient = max(0.0, dot(normal.xyz, surface_to_light.xyz));
    float4 diffuse_result = diffuse_coefficient * diffuse;

    //specular
    float shine = 0.0;
    if(diffuse_coefficient > 0.0) {
        float3 reflected = reflect(-surface_to_light.xyz, normal);
        shine = pow(max(0.0, dot(surface_to_camera.xyz, reflected)),
                    material.shine);
    }

    float4 specular_result = specular * material.specular * shine;

    //attenuation
    float to_light = length(light_pos - world_pos);
    float attenuation_result = 1.0 / dot(
        float3(0.0, attenuation, 0.0),
        float3(1.0, to_light, pow(to_light, 2))
    );

    return ambient_result + attenuation_result *
        (diffuse_result + specular_result);
}

float4 directional_calc(float3 normal, float4 world_pos) {
    // ambient
    float4 ambient = directional.ambient * material.ambient;

    // diffuse
    float4 direction = normalize(-directional.direction);
    float  angle     = max(dot(normal, direction.xyz), 0.0);
    float4 diffuse   = directional.diffuse * angle * material.diffuse;

    // specular
    float3 view_dir    = normalize(camera_pos.xyz - world_pos.xyz);
    float3 reflect_dir = reflect(-direction.xyz, normal);
    float  shine       = pow(max(dot(view_dir, reflect_dir), 0.0),
                            material.shine);
    float4 specular    = directional.specular * material.specular * shine;

    return float4(ambient + diffuse + specular);
}

float4 point_calc(float3 normal, float4 world_pos) {
    return phong_model(normal, pointlight.position, pointlight.ambient,
                    pointlight.diffuse, pointlight.specular,
                    pointlight.attenuation, world_pos);
}

float4 spot_calc(float3 normal, float4 world_pos) {
    float4 light_to_surface = normalize(world_pos - spotlight.position);
    float pixel_angle = dot(light_to_surface, spotlight.heading);

    if(pixel_angle > spotlight.outer_cone) {
        float4 light_intensity =
            phong_model(normal, spotlight.position,
                        spotlight.ambient, spotlight.diffuse,
                        spotlight.specular, spotlight.attenuation,
                        world_pos);

        float theta = pixel_angle;
        float epsilon = spotlight.inner_cone - spotlight.outer_cone;
        float fade = clamp((theta - spotlight.outer_cone) / epsilon, 0.0, 1.0);

        return light_intensity * fade;
    }
    else {
        return float4(0.0, 0.0, 0.0, 0.0);
    }
}

float4 main(VS_OUT input) : SV_TARGET
{
    float3x3 TBN = float3x3(
        input.tangent.xyz,
        input.bitangent.xyz,
        input.normal.xyz
    );

    float3 normal = normal_map.Sample(normal_map_samp, input.texcoords).rgb;
    normal = normal * 2.0 - 1.0;
    normal = normalize(mul(TBN, normal));

    float4 dir_val   = directional_calc(normal, input.world_pos);
    float4 point_val = point_calc(normal, input.world_pos);
    float4 spot_val  = spot_calc(normal, input.world_pos);

    float4 light_intensity = dir_val + point_val + spot_val;
    float4 texel = diffuse_map.Sample(diffuse_map_samp, input.texcoords);

    return light_intensity * texel;
}

```

# Answer
> 0 votes
Well, that was silly. =) It turned out I was normalizing normals and tangents in my GLSL shader and not in my DX shader. Naturally, that mean the normals I was calculating myself (for the terrain; the ship already had its normals baked in) were whacky and GL just happened to be instructed to be more cautious.

Easy peasy!

---
Tags: opengl, shaders, directx11, matrix, normals
---


# Question
Title: How to colour blend between two materials?
I've been trying to get a material (with an image texture) to animate towards a colour mix with transparency, but either I'm attempting something the wrong way, or unable to find the right keyword to find about similar examples.

What I'm trying to accomplish is to make a 3D character blush; I have the face area on it's own material, with textures set, but that's where my problem is. If it was animating between two colours, I would simply use Color.Lerp, but since textures are included, that makes me think I have to somehow have a colour mix option for this.

I've also tried to just use the built-in animator to see if Unity would blend between the colours of two different materials, but after all it turned out to be an instant change on the new keyframe; which leaves me to think so far my only exit could be to manually create several keyframes, and create several materials to get it close to acceptable.

Although my knowledge about it is close to zero, is this after all only possible with a custom fragment shader? I don't know if there's a suitable package, or built-in Unity feature that makes something like this possible, or if at all I'm approaching this problem the right way...

**Update:** This is the shader I'm using right now, from 魔王. It might be a little confusing since inputs are all abbreviated, so here are some example files that are being used.

# Answer
> 0 votes
What you ask is can be achieved by various ways i think

such as

**Single Material**

You can select your character's cheeks and mark them as another material in blender3d(3ds etc.). Then only thing you need to do is use the same texture material with a red color tint.

**Vertex Colors**

You can paint your character's cheeks with a white vertex color in blender3d(3ds etc.) to mask out the areas which you want to be blushed.Only thing you need to is to take the vertex color and multiply it by the blush tint you choose.(Every other vertex colors must be black in this case)

**Decals**

This may seem a pushover but it may help in some cases.Just find or create a blurred red dot image and use it as a `decal`

# Answer
> 0 votes
`color.Lerp` is useful when your materials do not have any different textures or maps. The general lerp solution is between the materials themselves. This part of code might solve your problem:

```
public Material firstMaterial; // first material with texture 1
public Material secondMaterial; // second material with texture 2
public void Update()
{
    firstMaterial.Lerp(firstMaterial, secondMaterial, Time.time);
}

```

---
Tags: unity, animation, fragment-shader
---


title: pygame only moving when moving mouse

text:
# Question
Title: pygame only moving when moving mouse
Every time I press the left or right arrow keys it moves a little however when I wiggle the mouse around while pressing the keys the player flys across the screen for no reason. I'm following freeCodeCamps video on pygame and I did everything he did but its not working. Any help is apricated thanks!

```
    import pygame

# Starts pygame
pygame.init()

# Creates screen
# Needs two sets of () for some reason
screen = pygame.display.set_mode((800, 600))

# Sets top text of window
pygame.display.set_caption("LaBruh Invaders")

# Sets window Icon
icon = pygame.image.load('labruh.png')
pygame.display.set_icon(icon)

# player starting Pic and location
playerIMG = pygame.image.load('farmerCapy.png')
playerX = 400
playerX_change = 0

playerY = 300
playerY_change = 0

# Resizes img
playerIMG = pygame.transform.scale(playerIMG, (150, 150))

def player(x, y):
    # Blit means draw on surface
    screen.blit(playerIMG, (x, y))

# Game loop (Update every frame)
running = True

while running:
    # Changes color of screen
    screen.fill((0, 0, 0))

    for event in pygame.event.get():
        # Checks if key is pressed
        if event.type == pygame.KEYDOWN:
            # If left arrow is pressed moves left
            if event.key == pygame.K_LEFT:
                playerX_change = -5
            if event.key == pygame.K_RIGHT:
                playerX_change = 5

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                playerX_change = 0

        playerX += playerX_change

        # Runs player funct which draws the player at X and Y cords
        player(playerX, playerY)

        # Makes screen quitable

        if playerX > 750:
            playerX = 0

        if playerX < -20:
            playerX = 740

        if event.type == pygame.QUIT:
            running = False

        # Updates the screen
        pygame.display.update()

```

# Answer
> 1 votes
You should discard all unexpected input. like:

```
import pygame

# Starts pygame
pygame.init()

# Creates screen
# Needs two sets of () for some reason
screen = pygame.display.set_mode((800, 600))

# Sets top text of window
pygame.display.set_caption("LaBruh Invaders")

# Sets window Icon
icon = pygame.image.load('labruh.png')
pygame.display.set_icon(icon)

# player starting Pic and location
playerIMG = pygame.image.load('farmerCapy.png')
playerX = 400
playerX_change = 0

playerY = 300
playerY_change = 0

# Resizes img
playerIMG = pygame.transform.scale(playerIMG, (150, 150))

def player(x, y):
    # Blit means draw on surface
    screen.blit(playerIMG, (x, y))

# Game loop (Update every frame)
running = True

while running:
    # Changes color of screen
    screen.fill((0, 0, 0))

    for event in pygame.event.get():
        # Checks if key is pressed
        if event.type == pygame.KEYDOWN:
            # If left arrow is pressed moves left
            if event.key == pygame.K_LEFT:
                playerX_change = -5
            if event.key == pygame.K_RIGHT:
                playerX_change = 5
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                playerX_change = 0
        elif event.type == pygame.QUIT:
            running = False
            break
        else:
            continue

        playerX += playerX_change

        # Runs player funct which draws the player at X and Y cords
        player(playerX, playerY)

        # Makes screen quitable

        if playerX > 750:
            playerX = 0

        if playerX < -20:
            playerX = 740

        # Updates the screen
        pygame.display.update()

```

---
Tags: python, pygame
---


# Question
Title: Find closest open space in grid of rectangles?
I'm making a builder game where you snap arbitrarily sized rectangles into a 2D grid. I want the player to be able to drag and drop these rectangles anywhere on the grid, but prevent collisions (i.e., they snap to the closest available space when the user lets go of the drag). I already have a decent way to determine collisions and "nearby" rectangles, but am looking for an efficient method to find the "closest available grid space" based on this information.

## Desired behavior:

In the image, the blue rectangle is the dragged thing; the green is the expected "snapping" spot. I want the "snapping" to happen in realtime and to handle 1) reasonably large numbers of nearby rectangles (at least 20-30?), 2) full intersections (one rect inside the other), 3) "concave" structures like on the top-right example.

## My current method:

1. Find all rectangles that are colliding with the active rectangle (not the issue AFAIK).
2. For each axis, generate a list of every possible displacement by summing variants of the intersection size (ex: `[-(rectSize - x), -x, 0, x, rectSize - x]`). Also take into account cases where one rectangle is fully intersected.
3. Find every combination of the displacements for the two axes (cartesian product).
4. Project the active rectangle to each possible displacement, and drop any that have collisions.
5. Calculate the distance from the center of the active rectangle to each of remaining projected rectangle's centers.
6. The snap position is the remaining projected rectangle with the shortest distance.

## The problem:

My method works, but is much more expensive than I'd like. I'm wondering if this is the best solution, but should just be optimized, or if there's a different approach that's naturally more efficient.

I've found some related questions (link, link, link), but they seem focused on solving slightly different problems. Topics like rectangle packing seem similar, but also not the same as what I'm looking for.

# Answer
I did some tests and found that this method does work.

First you need to find the nearest grid coordinates to the position of the dragged block (blue box). Then do a grid-based BFS on the target coordinates. Find a nearest feasible location(green box).

I use unity for testing, Code:

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

public class NewBehaviourScript : MonoBehaviour
{
    public GameObject block;
    private Vector2Int blockSize = Vector2Int.one;
    private Vector3 targetPos;
    private Vector3 putPos;
    private HashSet<Tuple<int, int>> map = new HashSet<Tuple<int, int>>();
    private List<Vector2Int> direction = new List<Vector2Int>{
        new Vector2Int(1,1),
        new Vector2Int(1,-1),
        new Vector2Int(-1,1),
        new Vector2Int(-1,-1),
    };
    void Start()
    {
    }
    void Update()
    {
        var pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        block.transform.position = new Vector3(pos.x, pos.y, -1);
        UpdateTargetPos(pos);
        UpdatePutPos();
        if (Input.GetMouseButtonDown(0))
        {
            PutBlock();
            RandBlock();
        }
    }
    private void UpdateTargetPos(Vector3 pos)
    {
        var leftDown = pos - new Vector3(blockSize.x / 2f, blockSize.y / 2f, 0);
        targetPos = new Vector3(Round(leftDown.x), Round(leftDown.y), 0);
        DrawBlock(targetPos, Color.blue);
    }
    private void UpdatePutPos()
    {
        var queue = new Queue<Tuple<int, int>>();
        var closeSet = new HashSet<Tuple<int, int>>();
        var start = new Tuple<int, int>((int)targetPos.x, (int)targetPos.y);
        queue.Enqueue(start);
        while (queue.Count > 0)
        {
            var nodeNow = queue.Dequeue();
            closeSet.Add(nodeNow);
            var hasBlock = false;
            RangePos(new Vector3(nodeNow.Item1, nodeNow.Item2), (key) =>
            {
                if (map.Contains(key))
                {
                    hasBlock = true;
                    return true;
                }
                return false;
            });
            if (!hasBlock)
            {
                putPos = new Vector3(nodeNow.Item1, nodeNow.Item2, 0);
                break;
            }
            foreach (var dir in direction)
            {
                var keyNext = new Tuple<int, int>(nodeNow.Item1 + dir.x, nodeNow.Item2 + dir.y);
                if (!closeSet.Contains(keyNext))
                {
                    queue.Enqueue(keyNext);
                }
            }
        }
        DrawBlock(putPos, Color.green);
    }
    private void DrawBlock(Vector3 leftDown, Color color)
    {
        float sizeX = blockSize.x;
        float sizeY = blockSize.y;
        var rightUp = leftDown + Vector3.right * sizeX + Vector3.up * sizeY;
        Debug.DrawLine(leftDown, leftDown + Vector3.up * sizeY, color);
        Debug.DrawLine(leftDown, leftDown + Vector3.right * sizeX, color);
        Debug.DrawLine(rightUp, leftDown + Vector3.up * sizeY, color);
        Debug.DrawLine(rightUp, leftDown + Vector3.right * sizeX, color);
    }
    private void PutBlock()
    {
        var newblock = GameObject.Instantiate(block);
        newblock.transform.position = putPos + new Vector3(blockSize.x / 2f, blockSize.y / 2f, 0);
        RangePos(putPos, (key) =>
        {
            map.Add(key);
            return false;
        });
    }
    private void RandBlock()
    {
        blockSize = new Vector2Int(UnityEngine.Random.Range(1, 4), UnityEngine.Random.Range(1, 4));
        block.transform.localScale = new Vector3(blockSize.x, blockSize.y, 1);
        block.GetComponent<SpriteRenderer>().color = UnityEngine.Random.ColorHSV();
    }
    private void RangePos(Vector3 leftDown, Func<Tuple<int, int>, bool> f)
    {
        var startX = (int)leftDown.x;
        var startY = (int)leftDown.y;
        for (int i = 0; i < blockSize.x; i++)
        {
            for (int j = 0; j < blockSize.y; j++)
            {
                var key = new Tuple<int, int>(startX + i, startY + j);
                if (f(key))
                {
                    return;
                }
            }
        }
    }
    private float Round(float value)
    {
        var vx = value + 0.5f;
        return (float)Math.Floor(vx);
    }
}

```
> 3 votes

---
Tags: algorithm, geometry, optimization, collision-resolution
---


title: Godot: is_on_floor always false

text:
# Question
Title: Godot: is_on_floor always false
This is an extremely simple game (following tutorial).

My code and configuration allows the actor object to fall on a platform made of tilemaps and not fall through, but the function is\_on\_floor() always outputs false.

```
extends KinematicBody2D
class_name Actor

var velocity: = Vector2.ZERO;
export var gravity: = 3000.0;

func _physics_process(delta):
    velocity.y+=delta*gravity;

    velocity = move_and_slide(velocity);
    if is_on_floor():
        print_debug("on floor");
    else:
        print_debug("not on floor"); #only this line prints

```

What's going on? Is the is\_on\_floor() function usable or do I need to use an alternative way of floor-detection?

# Answer
> 4 votes
If you call `move_and_slide` with only one parameter, all collisions are considered walls. *This is useful in top down games.*

You need to specify an up vector which Godot will use to decide if the collision is a wall, a floor or a ceiling.

For example, like this:

```
velocity = move_and_slide(velocity, Vector2.UP)

```

---
Tags: collision-detection, godot
---


# Question
Title: Using Unity Jobs to encode file to PNG and then save it on Main Thread
I have a following code , and i can not retrive encoded Output from Job.

If I Use JOB : The result is not a valid png file. What I get is a 67,2 MB file which can not be opened with any image editor I tried. When I open it with a text editor, it seems to contain only whitespaces.

else i got normal valid png file saved on my disc .

Can we use this approach for encoding inside Unity ?

```
public class Loger : MonoBehaviour
{
    [SerializeField]
    public bool isLoging = true;

    [SerializeField]
    private RenderTexture _rt;
    private NativeArray<byte> _data;
    private AsyncGPUReadbackRequest _request;

    public bool useJob;

    private void Start()
    {
        CreateBuffer(ref _data, ref _rt);
        StartCoroutine(StartEncoding(_rt, isLoging));

    }

    System.Collections.IEnumerator StartEncoding(RenderTexture oRTs, bool active)
    {
        int i = 0;
        while (active)
        {
            _request= AsyncGPUReadback.RequestIntoNativeArray(ref _data, oRTs, 0);
        if(_request.hasError)
            {
                Debug.Log("Error in GPU request "); break;
            }

            yield return new WaitUntil(() => _request.done);

            if(useJob)
            {
                Debug.Log("creating  Job");
                EncodeJob job = new EncodeJob
                {
                    input = new NativeArray<byte>(_data, Allocator.TempJob),
                    output = new NativeArray<byte>(_data.Length, Allocator.TempJob),
                    graphicsFormat = oRTs.graphicsFormat,
                    width = oRTs.width,
                    height = oRTs.height,
                    result = new NativeArray<int>(1, Allocator.TempJob)
                };

                JobHandle jobTask = job.Schedule();
                jobTask.Complete();
                Debug.Log("result from job is " + " " + job.result[0]);
                var data = job.output;
                Debug.Log("created PNG file ");
                string pathName = "Logs/" + "FLCW" + "/" + i++ + "JOB" + ".png";
                System.IO.File.WriteAllBytes(pathName, data.ToArray());
                yield return new WaitUntil(() => _request.done);
            }

            else if(!useJob)
            {
                var fileData =ImageConversion.EncodeNativeArrayToPNG(_data, oRTs.graphicsFormat, (uint)oRTs.width, (uint)oRTs.height);
                Debug.Log("created PNG file ");
                string pathName = "Logs/" + "FLCW" + "/" + i++ + "MAIN" +".png" ;
                System.IO.File.WriteAllBytes(pathName, fileData.ToArray());
                yield return new WaitUntil(() => _request.done);
            }

            yield return new WaitUntil(() => _request.done);
        }
    }

    void CreateBuffer(ref NativeArray<byte> buffer, ref RenderTexture oRTS)
    {
        buffer = new NativeArray<byte>(oRTS.height * oRTS.width * 4, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
    }

    private void OnApplicationQuit()
    {
        _data.Dispose();
    }

    struct EncodeJob : IJob
    {
        public NativeArray<byte> input;
        public NativeArray<byte>  output;
        public GraphicsFormat graphicsFormat;
        public NativeArray<int> result;
        public int width;
        public int height;
            public void Execute()
        {
            output = ImageConversion.EncodeNativeArrayToPNG(input,graphicsFormat,(uint)width,(uint)height);
            result[0] = width + height;
        }

    }

}

```

# Answer
After testing I found a few problems.

1. The png format does not save the color information of each pixel. It is a compressed image format. The length of the btyes written to the file is obviously uncompressed.
2. According to 1, you can't know the size of the png before starting the job. The size allocated for the output can only be used as the buffer size.
3. Assignment to member variables during job execution is invalid, that's why you use NativeArray to hold the resulting value. So the assignment to output is also invalid:

```
public void Execute()
{
    output = ...
}

```

Fix:

1. Use NativeArray to pass out the length of the resulting array.
2. Use the length value to slice the output and save it to a file.

Code:

```
EncodeJob job = new EncodeJob
{
    ...
    result = new NativeArray<int>(2, Allocator.TempJob)
};

JobHandle jobTask = job.Schedule();
jobTask.Complete();

Debug.Log("result from job is " + " " + job.result[0]);
var data = new byte[job.result[1]];
NativeArray<byte>.Copy(job.output, data, job.result[1]);
Debug.Log("created PNG file ");
string pathName = "Logs/" + "FLCW" + "/" + i++ + "JOB" + ".png";
System.IO.File.WriteAllBytes(pathName, data);

```

And:

```
public void Execute()
{
    var o = ImageConversion.EncodeArrayToPNG(input.ToArray(), graphicsFormat,
    (uint)width, (uint)height);
    NativeArray<byte>.Copy(o, output, o.Length);
    result[0] = width + height;
    result[1] = o.Length;
}

```
> 3 votes

---
Tags: unity, multithreading, png, unity-job-system
---


# Question
Title: glDrawArrays draws nothing in C. Trying to draw point in openGL(in C), no error but draws nothing
```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "glut.h"

//initilization of funtion
void init(void) {
    glClearColor(0.0, 0.0, 0.0, 1.0);
}

//function to draw
void display(void) {

    //delear: 6 points array
    static const GLfloat vtx2[] = { -0.8f,0.6f,0.0f,0.7f,-0.8f,-0.6f,0.8f,0.6f,0.0f,-0.7f,0.8f,-0.6f };

    glClear(GL_COLOR_BUFFER_BIT);

    glColor3b(0.1, 0.8, 0.1);
    glPointSize(10.0);
    glVertexPointer(2, GL_FLOAT, 0, vtx2);
    glEnableClientState(GL_VERTEX_ARRAY);
    glDrawArrays(GL_POINTS, 0, 6);
    glDisableClientState(GL_VERTEX_ARRAY);

    glFlush();//execution
}

//main function
int main(int argc, char* argv[]) {
    //GLUT library initialization
    glutInit(&argc, argv);
    //setup dispalying mode
    glutInitDisplayMode(GLUT_RGBA);
    //creat window
    glutCreateWindow(argv[0]);
    //sign function to draw
    glutDisplayFunc(display);
    //Intilaization
    init();
    //main loop
    glutMainLoop();

    return EXIT_SUCCESS;
}

```

# Answer
glColor3b specifies colour as 3 signed bytes, but you are passing float values. These float values will be all rounded down to 0, which is black, the same as your clear colour.

If you want to specify colour as floats, use glColor3f.
> 1 votes

---
Tags: opengl, c
---


title: Reference as local variable in Unity c#

text:
# Question
Title: Reference as local variable in Unity c#
In the script below, "btn" is a local variable in OnEnable() method. It's said that local variable is deallocated (lost) when leaving the countaining method. Why this one (btn) is not ? Nb: when the game is running and Button is clicked (OnClick) method is called

```
using UnityEngine.ui;
List<Button> _answers;
public List<Button> Answers { get { return _answers; } }
[SerializeField] Button buttonPrefab;

private void OnEnable()
{
    CreateAnswerButtonPool();

    for (int i = 0; i < Answers.Count; i++)
    {
        Button btn = Answers[i];
        btn.onClick.AddListener(() => OnClick(btn));
    }
}

 private void CreateAnswerButtonPool()
{
    _answers = new List<Button>();

    for (int i = 0; i < 5; i++)
    {
        Button bt = Instantiate(buttonPrefab, buttonsparent.transform) as Button;
        bt.gameObject.SetActive(false);
        _answers.Add(bt);
    }
}

void OnClick(Button btn)
{
    //.....
}

```

# Answer
Because the method Instantiate has side effects, It will create a game object on your scene. You can check the hierarchy tab to find it.

So you don't actually lose the button component. The local variable holding a reference to it is indeed discarded, but that's okay, because the scene hierarchy still holds a reference to it (you can access it via `FindObjectsOfType()` or methods that traverse the scene hierarchy).

By the way, some statements in the post are not quite correct:

> It's said that local variable is deallocated (lost) when leaving the containing method.

Firstly, when does the 'deallocating' occur? It's not 'when leaving the containing method' but 'when leaving it's scope'.

And are all local variables deallocated or lost directly? It depends on the type of variable.

There are two kinds of types in C#: reference types and value types. Variables of reference types store references to their data (objects), while variables of value types directly contain their data. They are stored in Heap and Stack Memory respectively.

When a value type variable is discarded, it will be recycled directly. If a reference type variable is discarded, the data it referenced will still persist in memory. If it is not referenced by any object in the next garbage collection pass, it will be deleted.(Mark-and-sweep-algorithm) The variable holding its reference is discarded, but the actual object is still in heap memory. If other objects still hold references to it, then it won't be cleaned up.
> 2 votes

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


# Question
Title: Determine if a triangle is on the screen
I am working on a small software renderer, and I want to discard invisible triangles from the drawing process. Let's say I have a screen with resolution of 200x100 pixels. The triangle is defined with three 2-dimensional coordinates `{x, y}` in the screen space.

What is the **fastest possible way to get a yes/no answer for the question "Should my triangle be drawn?"**, I don't need to retrieve intersection coordinates, just a boolean answer.

**Note**: on the image below all four red triangles need to be drawn even though some of their vertices aren't on the screen.

# Answer
There are three kinds of positional relationship between two plane figures: disjoint, one inside the other, partial intersection. You need to check for partial intersection and one inside the other.

1. **One inside the other**. It means one's vertices are all in the other.

check\_point\_in\_triangle

check\_point\_in\_rectangle

In fact, the check can be ended if at least one point is inside the target graph, since it covers the case of partial intersection.

2. **Partial intersection**. It means that two graphs have at least two edges that intersect.

check\_two\_segments\_intersect
> 2 votes

---
Tags: rendering, algorithm, intersection, culling, software-rendering
---


title: Godot: How to set in game language?

text:
# Question
Title: Godot: How to set in game language?
My game can translate keys into 3 different languages (English, Chinese, Japanese)

I verified that each translation works using the "test" feature in project settings.

I want to add buttons in game that changes the language of the game into one of the three languages, i.e., there will be a button labelled "English", which when pressed turns all text into English etc.

I found that this can be done by modifying the "locale" value in a "Translation" class (documentation) However, when I try to use the Translation class's functions in code, it gives me a syntax error `Non-static function "get_locale" can only be called from an instance` (I am calling it from the player object, but as far as I can tell, there is no way to instantiate "Translation" since it cannot be added as a child node)

I see people changing the in game language of their games like in this video, so obviously it is possible to change the current language at run time but nobody anywhere has said how that can be done.

# Answer
The `Translation` is a `Resource`. You are supposed to have one for each language you support. So each translation is a different instance, and the `get_locale` method might help you identify which instance you got… You need an instance to begin with to call it.

You can set the different translations in project setting, in the localization tab. See Internationalizing games.

I'm going to presume you have already done that, since you claim the translation is already working. In that case. I'm guessing that what you want is to talk with `TranslationServer`, which you don't have to instantiate, and has `get_locale` and `set_locale` method.

The idea is that you would have some menu in the game where the user can pick the translation they want from a list, and depending on the option the user picked, you call `set_locale` with the appropriate parameter. For example, for English it would be:

```
TranslationServer.set_locale("en")

```

*You can see in the video you linked that they use `TranslationSever` near the end (link).*
> 3 votes

---
Tags: godot, localization
---


# Question
Title: What's the difference between Unity3D rendering pipeline and OpenGL rendering pipeline?
I wanted to write small software renderer that will follow almost the same flow as OpenGL does, but got stuck with understanding of the rendering pipeline. After reading tons of info across the Internet I came to conclusion that the rendering pipeline is part of hardware. What OpenGL does it just delivers data from the app to video memory and tells when pipeline must be executed.

But then I came across the info about rendering pipeline in Unity3D. After that I got confused. If pipeline is "fixed" by hardware then how Unity3D can have it's own rendering pipeline? Is it somehow another layer of abstraction that utilizes the same terminology at app/engine level which means preparing all the resources for hardware pipeline execution? Or the pipeline is orchestrated by OpenGL itself, but the computation is done on the GPU? Or Unity3D uses Vulkan that provides such capability which explains why it's like that? Or maybe I misunderstood the whole concept incorrectly?

# Answer
The graphics APIs specify pipelines because your input data (vertices, indices, shaderprograms, program constants, textures, output buffers) need to undergo many transforms before becoming an output image. Since there is a lot of data, it's all transformed the same way and the output of one stage is the input for the next, it's advantageous to special pipelines rather than individual operations on each primitive (vertex, triangle, pixel).

The graphics APIs such as d3d, opengl, vulkan define low level pipelines. For example, a pixel needs to undergo viewpoint clipping, scissor box clipping, fragment shading, depth test, stencil test, blending. Before it's output.

Engines such as unity specify high level pipelines and work with 3d models, lights, cameras, materials rather than vertices, indices, vertex shaders, fragment shaders and render targets. They build upon the 3d APIs.

Inevitably, many of the low level concepts leak through to the high level engine.
> 2 votes

---
Tags: unity, opengl, rendering, software-rendering
---


title: Create a transition fade out in libgdx

text:
# Question
Title: Create a transition fade out in libgdx
How can i create a fade out in libgdx? I have a class "Menu" and with a fade, i want to change class to "Game".

This is how i change class, from "Menu" to "Game":

```
if (Gdx.input.isTouched()){
                this.dispose();
                game.setScreen(new Game(game));
}

```

# Answer
There are many different ways of achieving this depending on how much control you need over what the fade looks like.

If you need very fine-grained control then an option is to render each `Screen` to a `FrameBuffer` and then write a custom fragement shader that takes both `FrameBuffer`'s as input and blends them according to some logic.

If what you want is a simple "*fade out screen one and then fade in screen two*" kind of behaviour then you can get this by creating a `Screen` that renders a square over your screen (for example using a `ShareRenderer`) and alter the opacity depending on how far along the fade you are.

The example below (which has two different screens, a red and a green) uses a `FadeScreen` class that is a `Screen` that can take another `Screen` as input and then either fade to a solid color or from a solid color. And by chaining two of these `FadeScreen`s a *fade-out-fade-in* effect can be acieved.

Essentially the `FadeScreen` class works by first calling `render` on the `Screen` you want to fade from or to, and then render a blended rect ontop using the `ShapeRenderer`:

```
private void renderFade() {
    Gdx.gl.glEnable(GL20.GL_BLEND);
    Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
    float f = Math.min(1.0f, elapsed / fade.duration);
    float opacity = fade.type == FadeType.OUT ? fade.interpolation.apply(f) : 1.0f - fade.interpolation.apply(f);

    shapeRenderer.setProjectionMatrix(camera.combined);
    shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
    shapeRenderer.setColor(fade.color.r, fade.color.g, fade.color.b, opacity);
    shapeRenderer.rect(0, 0, camera.viewportWidth, camera.viewportHeight);
    shapeRenderer.end();
    Gdx.gl.glDisable(GL20.GL_BLEND);
}

```

The opacity is calculated as an interpolation based on the elapsed time, and the amount is either increasing for a fade out or decreasing for a fade in.

Again this method doesn't blend one screen into another, but rather one screen into a color, and then that color into the next screen.

The fade is setup by creating a definition for the fade out and for the fade in, and then setting the current `Screen` to an instance of a `FadeScreen` that fades from **screenA** to another `FadeScreen` that fades into **screenB**.

```
        FadeScreen.FadeInfo fadeOut = new FadeScreen.FadeInfo(FadeScreen.FadeType.OUT, Color.WHITE, Interpolation.smoother, 2.0f);
        FadeScreen.FadeInfo fadeIn = new FadeScreen.FadeInfo(FadeScreen.FadeType.IN, Color.WHITE, Interpolation.smoother, 2.0f);

        fadeScreen = new FadeScreen(this, fadeOut, screenA, new FadeScreen(this, fadeIn, screenB, null));
        setScreen(fadeScreen);

```

Full source code for the `FadeScreen` class:

```
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.ScreenAdapter;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Interpolation;

public class FadeScreen extends ScreenAdapter {
    public enum FadeType { IN, OUT }

    public static class FadeInfo {
        public final FadeType type;
        public final Color color;
        public final Interpolation interpolation;
        public final float duration;

        public FadeInfo(FadeType type, Color color, Interpolation interpolation, float duration) {
            this.type = type;
            this.color = color;
            this.interpolation = interpolation;
            this.duration = duration;
        }
    }

    private final FadeInfo fade;
    private Screen screen;
    private Screen next;
    private final Game game;
    private final ShapeRenderer shapeRenderer;
    private final Camera camera;
    private float elapsed;

    public FadeScreen(Game game, FadeInfo fade, Screen screen, Screen next) {
        this.game = game;
        this.fade = fade;
        this.screen = screen;
        this.next = next;
        shapeRenderer = new ShapeRenderer();
        camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        camera.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight / 2.0f, 0.0f);
        camera.update();
    }

    private void renderFade() {
        Gdx.gl.glEnable(GL20.GL_BLEND);
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        float f = Math.min(1.0f, elapsed / fade.duration);
        float opacity = fade.type == FadeType.OUT ? fade.interpolation.apply(f) : 1.0f - fade.interpolation.apply(f);

        shapeRenderer.setProjectionMatrix(camera.combined);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
        shapeRenderer.setColor(fade.color.r, fade.color.g, fade.color.b, opacity);
        shapeRenderer.rect(0, 0, camera.viewportWidth, camera.viewportHeight);
        shapeRenderer.end();
        Gdx.gl.glDisable(GL20.GL_BLEND);
    }

    public void render(float delta) {
        if (screen != null) {
            elapsed += delta;
            if (elapsed >= fade.duration) {
                if (next != null) {
                    game.setScreen(next);
                    screen.dispose();
                    screen = null;
                } else
                    game.setScreen(screen);
            }
        }

        Gdx.gl.glClearColor(0, 0, 0, 0);
        if (screen != null)
            screen.render(delta);
        renderFade();
    }
}

```
> 1 votes

---
Tags: java, libgdx
---


title: Fade in with stage libgdx doesn't work

text:
# Question
Title: Fade in with stage libgdx doesn't work
i use a stage on my background but the fadein doens't work. This is my code:

```
public class Level1 implements Screen{

//Background stage
Texture BackgroundLevel1;
private Stage BackgroundL1;

NameGame game;

public Level1 (NameGame game){

    this.game = game;

    BackgroundL1 = new Stage();

    BackgroundLevel1 = new Texture("BackgroundLevel1.png");
    Image background = new Image(BackgroundLevel1);
    BackgroundL1.addActor(background);
}

@Override
public void show() {
}

@Override
public void render(float f) {
    Gdx.gl.glClearColor(0, 0, 0, 0);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
game.batch.begin();

    BackgroundL1.addAction(Actions.fadeIn(1));
    game.batch.draw(BackgroundLevel1, 0, 0, NameGame.WIDTH, NameGame.HEIGHT);

game.batch.end();
}

```

# Answer
Do not call `addAction` every time in the `render` method, doing that will cause your `Stage` to register a new `fadeIn` action for every frame.

Also, make sure that the `alpha` of your `Stage` is zero when you start, otherwise there is nothin to fade in as the `Stage` is already fully visible on the first render.

Further, a `Stage` is rendered by calling `draw` on the `Stage` not by passing the Texture to a `SpriteBatch`, and in order for `Action`s to work, you need to call `act` on the `Stage` every frame so that is knows how much to advance the action.

Something closer to this might work for you:

```
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Image;

public class SomeGameName extends Game {
    private Texture backgroundTexture;
    private Stage background;

    @Override
    public void create () {
        backgroundTexture = new Texture("badlogic.jpg");
        background = new Stage();
        Image image = new Image(backgroundTexture);
        background.addActor(image);
        background.addAction(
                // Add a sequence of actions, the first one immediately sets the alpha to zero, the second one fades in over 2.0 seconds
                Actions.sequence(
                        Actions.alpha(0.0f),
                        Actions.fadeIn(2.0f)
                )
        );
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        background.act(); // This makes the actions work
        background.draw(); // This renders the Stage
    }
}

```
> 1 votes

---
Tags: java, libgdx
---


# Question
Title: Problem with placing isometric tiles above and below each other
In unity when using the in built tale palette to place tiles into the scene, I have come across a small problem. Im using an isometric tile-map and whenever i go to place a block, I end up placing a tile right above another tile. So if i was to for example place a tile at z=0, if i wanted to place a block above that I would have to have my mouse hover over the bottom of that tile but instead my mouse detects the top region of the previous tile which places the new tile farther and not just above. Only way I know to place that block is, go to and empty space outside and from a specific point you hover ur mouse under the block then increase the z with subtract. This is horrible for building a proper map. Is there a way to restrict it so that i can only click on the bottom of the tile? (i'm attaching screenshots if it didn’t make sense)

1.Can place tile above old tile when hovering over the bottom of the first tile

2.But when hovering exactly over the first tile, it places new tile at a different level

Edit 1:

Edit 2: https://youtu.be/kKJ30A9u5ts As you can see I for example wanted to place a tile above an old tile but since its hovering overing the top of the tile, it places the tile in a weird spot and also more of what I mean https://youtu.be/VNF0kYoB4YQ I want to place a tile above the one I am hovering on at z=2

# Answer
> 1 votes
"Thank you for the video. I do understand what you're talking about. The problem is that not all blocks are standard cubes. So detection of "click on the top of a tile" is impossible. But the plane with z=0 is standard. So unity makes your clicks in this plane so you can never click on the top of a tile, but on the z=0 plane. The white box is drawn above the tile just to make it easier for you to see where it is. It is actually drawn on top of all tiles. This can be visually confusing." – Mangata

---
Tags: unity, 2d, tilemap, gui, isometric
---


# Question
Title: Unity not able to find package listed in their own tutorial
**Please note:** I uploaded a Youtube video here that may help tie all my confusion together but I also explain the highlights below which forms the basis of my question.

---

Unity here. I'm trying to follow their first basic tutorial and am at the "*Before you begin*" section where the fifth bullet down says:

> "*5. Install the 2D Tilemap Editor package for your project.*"

The link provided in that bullet takes you here. *That* page tells you to go to `Window >> Package Manager` and lookup the 2D Tilemap Editor package.

When I go to `Window >> Package Manager` I see:

If I click on the search bar in the top right corner and search for "2D" or "Tile" or "Editor" nothing shows up.

**Does anybody know how I can search for and import this 2D Tilemap Editor package?**

# Answer
> 4 votes
Can't say I didn't have the same problem! Just change the "Packages" dropdown to "Unity Registry" instead of "My Assets", as it will only search in your downloaded packages in this mode.

# Answer
> 2 votes
A little addition for future readers: if the accepted answer still doesn't solve the problem, probably this package is a preview. You can enable preview packages in the package manager.

---
Tags: unity, macos
---


# Question
Title: How to change animation coroutine when a variable changes, not every frame?
I want to be able to change the enum animation mode at runtime.

This way will start the coroutine every frame in Update, but I want to start the coroutine only if the value of the enum variable has changed.

```
public enum AnimationType { None, SingleColorMorph, MultiColorMorph, Shuffle, Shift };
    public AnimationType myAnimationType;
    LineRenderer myLineRenderer;
    public float morphTime;

    void Start()
    {
        myLineRenderer = this.GetComponent<LineRenderer>();
        switch (myAnimationType)
        {
            case AnimationType.SingleColorMorph:
                StartCoroutine(RandomSingleColorMorphing(myLineRenderer, morphTime));
                break;
            case AnimationType.MultiColorMorph:
                StartCoroutine(RandomMultiColorMorphing(myLineRenderer, morphTime));
                break;
            case AnimationType.Shuffle:
                StartCoroutine(ShuffleGradient(myLineRenderer, .5f));
                break;
            case AnimationType.Shift:
                StartCoroutine(AnimateLoop(myLineRenderer));
                break;
        }
    }

    private void Update()
    {
        switch (myAnimationType)
        {
            case AnimationType.SingleColorMorph:
                StartCoroutine(RandomSingleColorMorphing(myLineRenderer, morphTime));
                break;
            case AnimationType.MultiColorMorph:
                StartCoroutine(RandomMultiColorMorphing(myLineRenderer, morphTime));
                break;
            case AnimationType.Shuffle:
                StartCoroutine(ShuffleGradient(myLineRenderer, .5f));
                break;
            case AnimationType.Shift:
                StartCoroutine(AnimateLoop(myLineRenderer));
                break;
        }
    }

```

The full script :

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

[RequireComponent(typeof(LineRenderer))]
public class LineRendererColors : MonoBehaviour
{
    public enum AnimationType { None, SingleColorMorph, MultiColorMorph, Shuffle, Shift };
    public AnimationType myAnimationType;
    LineRenderer myLineRenderer;
    public float morphTime;
    void Start()
    {
        myLineRenderer = this.GetComponent<LineRenderer>();
        switch (myAnimationType)
        {
            case AnimationType.SingleColorMorph:
                StartCoroutine(RandomSingleColorMorphing(myLineRenderer, morphTime));
                break;
            case AnimationType.MultiColorMorph:
                StartCoroutine(RandomMultiColorMorphing(myLineRenderer, morphTime));
                break;
            case AnimationType.Shuffle:
                StartCoroutine(ShuffleGradient(myLineRenderer, .5f));
                break;
            case AnimationType.Shift:
                StartCoroutine(AnimateLoop(myLineRenderer));
                break;
        }
    }

    void SetSingleColor(LineRenderer lineRendererToChange, Color newColor)
    {
        lineRendererToChange.startColor = newColor;
        lineRendererToChange.endColor = newColor;
    }

    void SetSingleColor2(LineRenderer lineRendererToChange, Color newColor)
    {
        Gradient tempGradient = new Gradient();

        GradientColorKey[] tempColorKeys = new GradientColorKey[2];
        tempColorKeys[0] = new GradientColorKey(newColor, 0);
        tempColorKeys[1] = new GradientColorKey(newColor, 1);

        tempGradient.colorKeys = tempColorKeys;

        lineRendererToChange.colorGradient = tempGradient;
    }

    void SetSingleColor3(LineRenderer lineRendererToChange, Color newColor)
    {
        Gradient tempGradient = lineRendererToChange.colorGradient;

        GradientColorKey[] tempColorKeys = tempGradient.colorKeys;
        for (int i = 0; i < tempColorKeys.Length; i++)
        {
            tempColorKeys[i].color = newColor;
        }

        tempGradient.colorKeys = tempColorKeys;

        lineRendererToChange.colorGradient = tempGradient;
    }

    IEnumerator ShuffleGradient(LineRenderer targetLineRenderer, float waitTime)
    {
        while (true)
        {
            ShuffleGradient(targetLineRenderer);
            yield return new WaitForSeconds(waitTime);
        }
    }

    void ShuffleGradient(LineRenderer targetLineRenderer)
    {
        GradientColorKey[] newColorKeys = targetLineRenderer.colorGradient.colorKeys;
        for (int i = 0; i < newColorKeys.Length; i++)
        {
            Color tempColor = newColorKeys[i].color;
            int randomIndex = Random.Range(0, newColorKeys.Length - 1);
            newColorKeys[i].color = newColorKeys[randomIndex].color;
            newColorKeys[randomIndex].color = tempColor;
        }
        Gradient tempGradient = targetLineRenderer.colorGradient;
        tempGradient.colorKeys = newColorKeys;
        targetLineRenderer.colorGradient = tempGradient;
    }

    IEnumerator RandomMultiColorMorphing(LineRenderer lineRendererToChange, float timeToMorph)
    {
        float time = 0;

        while (true)
        {
            GradientColorKey[] initialColorKeys = lineRendererToChange.colorGradient.colorKeys;
            GradientColorKey[] newColorKeys = GenerateRandomColorKeys(initialColorKeys);
            time = 0;
            while (time < timeToMorph)
            {
                time += Time.deltaTime;
                float progress = time / timeToMorph;
                GradientColorKey[] currentColorKeys = GradientColorKeyLerp(initialColorKeys, newColorKeys, progress);
                Gradient tempGradient = lineRendererToChange.colorGradient;
                tempGradient.colorKeys = currentColorKeys;
                lineRendererToChange.colorGradient = tempGradient;
                yield return null;
            }
            yield return null;
        }
    }

    GradientColorKey[] GradientColorKeyLerp(GradientColorKey[] initialColorKeys, GradientColorKey[] endColorKeys, float progress)
    {
        GradientColorKey[] newColorKeys = new GradientColorKey[initialColorKeys.Length];
        for (int i = 0; i < newColorKeys.Length; i++)
        {
            newColorKeys[i].color = Color.Lerp(initialColorKeys[i].color, endColorKeys[i].color, progress);
            newColorKeys[i].time = initialColorKeys[i].time;
        }
        return newColorKeys;
    }

    //assigns new color to each colorkey and uses Time from incomingColorKeys
    GradientColorKey[] GenerateRandomColorKeys(GradientColorKey[] incomingColorKeys)
    {
        GradientColorKey[] newColorKeys = new GradientColorKey[incomingColorKeys.Length];
        for (int i = 0; i < newColorKeys.Length; i++)
        {
            newColorKeys[i].color = RandomColor();
            newColorKeys[i].time = incomingColorKeys[i].time;
        }
        return newColorKeys;
    }

    //asumes Single color, 2 colorkeys
    IEnumerator RandomSingleColorMorphing(LineRenderer lineRendererToChange, float timeToMorph)
    {
        float time = 0;
        Color initialColor = lineRendererToChange.colorGradient.colorKeys[0].color;
        //this reduces colorkey amount to 2 just in case.
        SetSingleColor2(lineRendererToChange, initialColor);

        while (true)
        {
            initialColor = lineRendererToChange.colorGradient.colorKeys[0].color;
            Color targetColor = RandomColor();
            time = 0;
            while (time < timeToMorph)
            {
                time += Time.deltaTime;
                float progress = time / timeToMorph;
                Color currentColor = Color.Lerp(initialColor, targetColor, progress);
                SetSingleColor(lineRendererToChange, currentColor);
                yield return null;
            }
            yield return null;
        }
    }

    //Basically Color.Lerp?
    Color ColorLerpMath(Color firstColor, Color secondColor, float progress)
    {
        Vector3 firstRGB = new Vector3(firstColor.r, firstColor.g, firstColor.b);
        Vector3 secondRGB = new Vector3(secondColor.r, secondColor.g, secondColor.b);
        Vector3 difference = secondRGB - firstRGB;
        Vector3 lerpedRGB = firstRGB + (progress * difference);
        return new Color(lerpedRGB.x, lerpedRGB.y, lerpedRGB.z);
    }

    Color RandomColor()
    {
        return new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));
    }

    //returns the gradient with a copy of the first key for intersection purposes.
    Gradient AddInitialCopy(Gradient incomingGradient)
    {
        List<GradientColorKey> newColorKeys = new List<GradientColorKey>(incomingGradient.colorKeys);
        Color interSectionColor = newColorKeys[0].color;
        newColorKeys.Insert(0, new GradientColorKey(interSectionColor, 0));
        Gradient newInitGradient = new Gradient();
        newInitGradient.colorKeys = newColorKeys.ToArray();
        return newInitGradient;
    }

    //remove first and last keys since they dont shift.
    List<GradientColorKey> RemoveFirstAndLast(Gradient incomingGradient)
    {
        List<GradientColorKey> currentColorKeys = new List<GradientColorKey>(incomingGradient.colorKeys);
        currentColorKeys.RemoveAt(currentColorKeys.Count - 1);
        currentColorKeys.RemoveAt(0);
        return currentColorKeys;
    }

    Color GetIntersectionColor(List<GradientColorKey> incomingKeys, int lowestIndex, int highestIndex)
    {
        Color firstColor = incomingKeys[lowestIndex].color;
        Color lastColor = incomingKeys[highestIndex].color;
        float distance = 1 - (incomingKeys[highestIndex].time - incomingKeys[lowestIndex].time);
        float colorLerpAmount = (1f - incomingKeys[highestIndex].time) / distance; ;
        Color newIntersectionColor = Color.Lerp(lastColor, firstColor, colorLerpAmount);
        return newIntersectionColor;
    }

    //accepts max 7 colors, 1st and last should be at 0 and 1
    IEnumerator AnimateLoop(LineRenderer lineRendererToChange, float movementPerTick = .001f)
    {
        lineRendererToChange.colorGradient = AddInitialCopy(lineRendererToChange.colorGradient);

        while (true)
        {
            List<GradientColorKey> currentColorKeys = RemoveFirstAndLast(lineRendererToChange.colorGradient);
            float highestTime = 0;
            float lowestTime = 1;
            int highestIndex = currentColorKeys.Count - 1;
            int lowestIndex = 0;
            //Move all inner ones.
            for (int i = 0; i < currentColorKeys.Count; i++)
            {
                GradientColorKey tempColorKey = currentColorKeys[i];
                float newTime = tempColorKey.time + movementPerTick;

                if (newTime > 1)
                {
                    newTime = newTime - 1;
                }
                tempColorKey.time = newTime;
                currentColorKeys[i] = tempColorKey;
                if (newTime < lowestTime)
                {
                    lowestTime = newTime;
                    lowestIndex = i;
                }
                if (newTime > highestTime)
                {
                    highestTime = newTime;
                    highestIndex = i;
                }
            }
            Color newIntersectionColor = GetIntersectionColor(currentColorKeys, lowestIndex, highestIndex);
            currentColorKeys.Insert(0, new GradientColorKey(newIntersectionColor, 0));
            currentColorKeys.Add(new GradientColorKey(newIntersectionColor, 1));
            Gradient tempGradient = lineRendererToChange.colorGradient;
            tempGradient.colorKeys = currentColorKeys.ToArray();
            lineRendererToChange.colorGradient = tempGradient;
            yield return null;
        }
    }

    void AssignGradient(LineRenderer targetLineRenderer, Gradient newGradient)
    {
        targetLineRenderer.colorGradient = newGradient;
    }

    void DrawTestLine()
    {
        Vector3 firstPos = new Vector3(-5, 0, 0);
        Vector3 secondPos = new Vector3(5, 0, 0);
        int resolution = 100;
        myLineRenderer.positionCount = resolution;
        myLineRenderer.SetPositions(MakeLine(firstPos, secondPos, 100));
    }

    //makes a line from point A to point B with resolution of size points
    Vector3[] MakeLine(Vector3 initPos, Vector3 endPos, int points)
    {
        Vector3 difference = endPos - initPos;
        Vector3[] newLine = new Vector3[points];
        Vector3 differencePerPoint = difference / (float)(points - 1);
        for (int i = 0; i < points; i++)
        {
            newLine[i] = initPos + (differencePerPoint * i);
        }
        return newLine;
    }
}

```

# Answer
> 1 votes
It looks like you might want to do something like this:

```
// Make your animation type a property, with a setter method that
// switches the animation automatically when its value changes.
[SerializeField]
AnimationType _animationType;
public AnimationType {
    get { return _animationType; }
    set { if(value != _animationType) StartAnimation(value); }
}

public float morphTime;

LineRenderer _lineRenderer;

// Keep a handle to the old animation, so we can stop it.
Coroutine _animationInProgress;

// The setter method won't be called by the Inspector, so in-editor
// we need to watch for changes ourselves. I've wrapped this in
// pre-processor directives to strip it out of game builds, so you
// pay no runtime overhead for this editor convenience.
#if UNITY_EDITOR
AnimationType _cachedAnimationType;
void OnValidate() {
    if (_animationType != _cachedAnimationType) {
        if (_animationInProgress == null)
            _cachedationAnimType = _animationType;
        else
            StartAnimation(_animationType);
    }
}
#endif

void StartAnimation(AnimationType animType) {
    _animationType = animType;
    #if UNITY_EDITOR
    _cachedAnimationType = animType;
    #endif

    if (_animationInProgress != null)
        StopCoroutine(_animationInProgress);

    _animationInProgress = StartCoroutine(SelectAnimation(animType));
}

IEnumerator SelectAnimation(AnimationType animType) {
    switch (animType) {
        case AnimationType.SingleColorMorph:
            return RandomSingleColorMorphing(_lineRenderer, morphTime);
        case AnimationType.MultiColorMorph:
            return RandomMultiColorMorphing(_lineRenderer, morphTime);
        case AnimationType.Shuffle:
            return ShuffleGradient(_lineRenderer, .5f);
        case AnimationType.Shift:
            return AnimateLoop(_lineRenderer);
        default:
            return null;
    }
}

void Start() {
    _lineRenderer = GetComponent<LineRenderer>();
    StartAnimation(_animationType);
}

// No Update() method needed.

```

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


# Question
Title: How to run a long task without freezing my game?
I have a component that is in charge of generating a level at runtime, and this is an operation that takes quite some time. As a consequence, I experience a hang when this operation is executed (when the scene is loaded).

This problem can be summarized to the fact that SceneManager.LoadSceneAsync in fact is **not** async at all in its second phase, when it initializes all the objects.

There are three approaches I have searched for and thought about:

**Slicing the operation as explained on this video:**

This is non-trivial, I would have to rewrite chunks of code for the sake of avoiding a few seconds hiccup at scene load. Furthermore, the person explaining in the video says that they changed Unity source code which I don't have access to.

**Running the operation in a background thread:**

This is definitely interesting, it would require minimal changes. The only problem is that at some point I have to create Unity objects (`GameObject`, `Mesh` etc) and this is not possible when outside Unity thread.

I was thinking more or less of this code to be run on the background thread:

```
class Builder
{
    public void Build()
    {
        // 1. do something long

        // 2. create Unity object with result from #1
        // something like that
        // await RunInUnitySynchronizationContext(() => new GameObject(...))

        // 3. do extra stuff on the result of #2
    }
}

```

The thing is I have no idea at all on how that second step should be written, if possible at all.

**Use a non-animated *Loading* screen and wait for it to finish:**

This is the simplest and effectively does away with the problem by 'just' hiding it.

**Question:**

What's an effective approach to solve this problem?

# Answer
> 1 votes
I don't know your level generation code, but you can just call the necessary things from the main thread again with the below code. Would be the cleanest, if you run all the performance heavy things in the background thread and once that's finished, you go back to the main thread and finish everything up there. But again, I don't know your code and whether that's possible.

You have to add this script to a gameobject in your scene. Put it onto your gameobject that has all the manager scripts attached or put it on your camera.

```
/*
Copyright 2015 Pim de Witte All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

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

/// Author: Pim de Witte (pimdewitte.com) and contributors
///
/// A thread-safe class which holds a queue with actions to execute on the next Update() method. It can be used to make calls to the main thread for
/// things such as UI Manipulation in Unity. It was developed for use in combination with the Firebase Unity plugin, which uses separate threads for event handling
///
public class UnityMainThreadDispatcher : MonoBehaviour {

    private static readonly Queue _executionQueue = new Queue();

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

    ///
    /// Locks the queue and adds the IEnumerator to the queue
    ///
    /// IEnumerator function that will be executed from the main thread.
    public void Enqueue(IEnumerator action) {
        lock (_executionQueue) {
            _executionQueue.Enqueue (() => {
                StartCoroutine (action);
            });
        }
    }

        ///
        /// Locks the queue and adds the Action to the queue
    ///
    /// function that will be executed from the main thread.
    public void Enqueue(Action action)
    {
        Enqueue(ActionWrapper(action));
    }
    IEnumerator ActionWrapper(Action a)
    {
        a();
        yield return null;
    }

    private static UnityMainThreadDispatcher _instance = null;

    public static bool Exists() {
        return _instance != null;
    }

    public static UnityMainThreadDispatcher Instance() {
        if (!Exists ()) {
            throw new Exception ("UnityMainThreadDispatcher could not find the UnityMainThreadDispatcher object. Please ensure you have added the MainThreadExecutor Prefab to your scene.");
        }
        return _instance;
    }

    void Awake() {
        if (_instance == null) {
            _instance = this;
            DontDestroyOnLoad(this.gameObject);
        }
    }

    void OnDestroy() {
            _instance = null;
    }

}
```

You call it like this:

```
UnityMainThreadDispatcher.Instance ().Enqueue (MethodNameWithoutParameters);
UnityMainThreadDispatcher.Instance ().Enqueue (() => MethodNameWithParameters(param1));

```

Your code will be run in the next update loop.

# Answer
> 3 votes
There are 2 simple solutions:

1. If only #1 in your code example takes a long time and it can be run without any GameObjects, you use the new job system and run it in the background, and then you'll only need to wait for it to complete before executing the presumably shorter #2 and #3. If the logic could be broken into several jobs or built as a parallel job, you'll also get the benefit of parallelization.
2. A lesser alternative would be moving the logic into a Coroutine, and sprinkle *yield return* statements throughout your code, so it won't block. This doesn't move the logic into a background thread, but at least it won't block.

# Answer
> 0 votes
A more accessible but less performant alternative to the job system is to use async/await, where you can run code in C#'s thread pool with `Task.Run()`.

I am using a hybrid approach of running multithreaded code by `await`ing a function that contains a call to `Task.Run()`. Since the execution returns to the main Unity thread after the `await`, I can then call Unity's APIs from there without running into exceptions.

To avoid freezing the game at that point however, I don't see an alternative to using a coroutine. At least until Unity adopts a more asynchronous approach, which I believe it is quite late on!

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


# Question
Title: How to convert ZXY euler rotation to XYZ?
I want to know the values of `x`, `y`, `z` satisfying the following.

```
float ax = 30;
float ay = 40;
float az = 50;

var rotation1 = Quaternion.Euler(ax, ay, az).eulerAngles;
var quaternion = Quaternion.identity;
quaternion = Quaternion.AngleAxis(x, Vector3.right) * quaternion;
quaternion = Quaternion.AngleAxis(y, Vector3.up) * quaternion;
quaternion = Quaternion.AngleAxis(z, Vector3.forward) * quaternion;
var rotation2 = quaternion.eulerAngles;

Assert.AreApproximatelyEqual(rotation1, rotation2);

```

`ax`, `ay`, `az` can be arbitrary value. Unity's operation between quaternion and euler angle (Vector3) seems to rotate by Z axis first, so I think x, y, z won't be equal to ax, ay, az.

How can I derive `x`, `y`, `z`?

# Answer
I managed to write the code I need with the reference.

```
public static Vector3 ToXyz(Quaternion q) {
  var angles = new Vector3();

  // roll / x
  double sinr_cosp = 2 * (q.w * q.x + q.y * q.z);
  double cosr_cosp = 1 - 2 * (q.x * q.x + q.y * q.y);
  angles.x = (float)Math.Atan2(sinr_cosp, cosr_cosp);

  // pitch / y
  float sinp = 2 * (q.w * q.y - q.z * q.x);
  if (Math.Abs(sinp) >= 1) {
    angles.y = (float)((sinp < 0 ? -1 : 1) * Math.PI / 2);
  } else {
    angles.y = (float)Math.Asin(sinp);
  }

  // yaw / z
  double siny_cosp = 2 * (q.w * q.z + q.x * q.y);
  double cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z);
  angles.z = (float)Math.Atan2(siny_cosp, cosy_cosp);

  return angles * 180 / (float)Math.PI;
}

```
> 1 votes

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


# Question
Title: How do I duplicate a Box2d simulation, mid-simulation?
I want to serialize the state mid-game, send it over the network to an identical computer (same CPU, same OS, same binary), load it there, and have the two games run in tandem doing the exact same simulation, without one of them drifting off and going haywire.

In short: I want pop-in, pop-out networking support on my HIGHLY physics-intensive game, where sending object coordinates every few seconds is impossible, due to having thousands of objects, and many clients.

I tried this with Box2D, and saving an object's location/velocity/etc wasn't enough... there's internal state that's not accessible through any public methods.

My current workaround is to force EVERY client to save its entire worldstate and reload it from scratch, whenever a new player connects... but this is obviously bad practice, because it hangs the game for everyone whenever someone new connects. However, it works, with zero desynchronization.

So, anyone know of any other techniques that can help me? Or should I just kiss my project goodbye?

# Answer
You could try https://rapier.rs/ instead of box2d, it has the ability to take a snapshot of the world and send it as a hash string over network to produce the same physics results on both clients
> 0 votes

# Answer
I've faced the same problem (synchronizing box2d worlds for browser clients with world on node.js server) and my resolution: synchronozing box2d worlds on the fly - impossible. So I've cut off all physics from clients, and now they are receving discrete timestamped positions of objects (and some events) from server (which is running box2d) and interpolating between them. Box2d uses values generated on previous steps to calculate nex step, so you need go deep under the hood to make box2d network-compatible.
> 1 votes

# Answer
Run your simulation on the Server, send Clients timestamped object state updates (delta-compressed) at a fixed rate, send other game event messages as they occur, and let Clients deal with interpolating/extrapolating between network state updates. You don't need to send updates for all objects in the game, to all clients. Simulate the player camera frustums (3D) or view rect (2D) on the Server, and choose your preferred spatial partitioning algorithm to determine which objects a given client can see, only send updates for what a client can see. This will put more load on the server cpu, but will reduce network band on the server to something reasonable.
> 0 votes

---
Tags: box2d, networking, synchronization, serialization, game-state
---


# Question
Title: How to check if finger is touching the screen using the Unity input system?
I have a While loop that runs when the mouse is pressed and it look like this:

```
while (mouseClick.ReadValue<float>() != 0)
{
   //Do something
}

```

This works but I want this to work on mobile instead so I am trying to change this to when a finger is touching the screen. I tried this code:

```
    while (touchControls.Touch.TouchPosition.ReadValue<Vector2>() != Vector2.zero)
    {
        //Do something
    }

```

That loop starts to run when a finger presses the screen, but it never stops. And touchControls.Touch.ReadValue() != 0 didn't work either. So how can I make it work like I want?

Thanks.

# Answer
> 1 votes
One way is to access the `InputSystem` more directly.

You might be looking for TouchPhase or use the `Finger` combined with the EnhancedTouch.

```
using UnityEngine;
using UnityEngine.InputSystem.EnhancedTouch;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;

public class TouchDemo : MonoBehaviour
{
    private void OnEnable()
    {
        EnhancedTouchSupport.Enable();
    }

    private void OnDisable()
    {
        EnhancedTouchSupport.Disable();
    }

    private void Update()
    {
        foreach (var touch in Touch.activeTouches)
        {
            // Only respond to first finger
            if (touch.finger.index == 0 && touch.isInProgress)
            {
                // TODO
            }
        }
    }
}

```

**Edit:** See the Touch struct for more information about the various states of a Touch.

---
Tags: unity, touch
---


# Question
Title: Applying upgrades to pickups that do different things
In my game, the player has pickups that they can activate that each do different things. Some examples include:

* Restore your health
* Gives you a one time speed boost
* Give you a bubble that bounces you off the ground
* Move all the coins within range closer to you
* Boost you to a certain velocity for x seconds then returns you to your previous speed
* Turn off collision with enemies

These are all in their own ScriptableObjects that derive from a base Pickup ScriptableObject that has Activate, Tick, and Deactivate functions that are overridden per Pickup. These work fine (but not without their troubles), but the problem I am coming to have is implementing an upgrade system with them.

The player has and saves a list of Upgrade ScriptableObjects that detail what Pickup it is targeting, and what aspects about the Pickup it is modifying, along with the value that the upgrade gives. Things like "Magnet, Duration, 3 seconds" or "Chainsaw, Damage, 15".

The solution I came up with was to have Pickup variables that are runtime only, like duration, range, speed, horizontalRange, verticalRange, etc. and another Pickup function to be overridden, "Setup", which goes through all the Upgrades that the player has, finds which ones that target that Pickup, and then manually updates that runtime variable based on the different levels that the upgrade is at before any more processing is done. A special thing to note is that an upgrade can affect multiple aspects per level, such as level 1 upgrading duration, level 2 upgrading range, and level 3 upgrading both.

This comes with the problem that some Pickups use vastly different variables, such as a health restore not caring about a range, duration, or anything else besides "how much health do I restore". "Magnet" and "Jump Boots" both care about a duration, but not a range, while I might in the future make an upgrade that cares about damage, range, and speed... So I would be retyping the same code for 20+ Pickups with slight modifications, like one going through all range upgrades, one going through all duration upgrade, etc.

Relevant Scripts:

Pickup.cs

```
public abstract class Pickup : ScriptableObject
{
    public Sprite sprite; //what sprite it shows up as in the UI
    public GameObject prefab;
    public float defaultDuration;

    public enum PickupType
    {
        Passive,
        Active
    }
    public PickupType type;

    [SerializeField] protected PlayerManager player;
    [SerializeField] public float duration { get; protected set; }
    [SerializeField] public float range { get; protected set; }

    public virtual void Setup() { }

    public virtual bool Activate(PlayerManager playerManager)
    {
        player = playerManager;
        return true;
    }

    public virtual void Tick()
    {

    }

    public virtual void Deactivate()
    {

    }

}

```

MagnetPickup.cs

```
public class MagnetPickup : Pickup
{
    public StatModifier bouncinessModifier;
    public StatModifier fallDamageModifier;

    float defaultRange = 4f;

    public override void Setup()
    {
        duration = defaultDuration;
        List<StatUpgrade> targettedUpgrades = PlayerData.instance.GetAllUpgradesForPickup(this);
        foreach (StatUpgrade targettedUpgrade in targettedUpgrades)
        {
            foreach (UpgradeLevel level in targettedUpgrade.levels)
            {
                foreach (UpgradeStatModifier modifier in level.modifiers)
                {
                    if (modifier.statType == UpgradeStatModifier.StatType.Duration)
                    {
                        duration += modifier.value;
                    }
                }
            }
        }

        range = defaultRange;
        targettedUpgrades = PlayerData.instance.GetAllUpgradesForPickup(this);
        foreach (StatUpgrade targettedUpgrade in targettedUpgrades)
        {
            foreach (UpgradeLevel level in targettedUpgrade.levels)
            {
                foreach (UpgradeStatModifier modifier in level.modifiers)
                {
                    if (modifier.statType == UpgradeStatModifier.StatType.Range)
                    {
                        range += modifier.value;
                    }
                }
            }
        }
    }

```

I think I could get away with merging the loops in the MagnetPickup Setup so that it goes through Duration and Range, like

```
    public override void Setup()
    {
        duration = defaultDuration;
        range = defaultRange;
        List<StatUpgrade> targettedUpgrades = PlayerData.instance.GetAllUpgradesForPickup(this);
        foreach (StatUpgrade targettedUpgrade in targettedUpgrades)
        {
            foreach (UpgradeLevel level in targettedUpgrade.levels)
            {
                foreach (UpgradeStatModifier modifier in level.modifiers)
                {
                    if (modifier.statType == UpgradeStatModifier.StatType.Duration)
                    {
                        duration += modifier.value;
                    }
                    if (modifier.statType == UpgradeStatModifier.StatType.Range)
                    {
                        range += modifier.value;
                    }
                }
            }
        }
    }

```

but again, I would be writing nearly this same setup for 20+ Pickups that all use slightly different things. Thanks for taking the time and reading this, and I appreciate the help!

# Answer
> 1 votes
Here's a strategy you could try:

```
using StatType = UpgradeStatModifier.StatType;

public abstract class Pickup : ScriptableObject
{
    // Give a method to fetch a reference to a stat variable by its type:
    public abstract ref float GetStatFloat(StatType stat);

    // No longer needs to be overridden per type.
    public void Setup() {
        // Instead of assigning defaults here, just instantiate "this" mutable
        // powerup instance from a pre-authored asset containing those defaults.

        var upgrades = PlayerData.instance.GetUpgradesFor(this);
        foreach (var upgrade in upgrades) {
            foreach (var level in upgrade.levels) {
                foreach (var modifier in level.modifiers) {
                    // Same code for every float modifier!
                    GetStatFloat(modifier.statType) += modifier.value;
                }
            }
        }
    }
}

public class BoostPickup : Pickup
{
    public float duration;

    public override ref float GetStatFloat(StatType stat) {
        switch(stat) {
            case StatType.Duration: return ref duration;
            default: throw new System.ArgumentException(
              $"'{this.GetType().Name}' does not expose a float stat '{stat}'"
            );
        }
    }
}

```

You'd still have to implement the `GetStatFloat` function for each pickup type, which is not ideal, but it's reasonably small. In exchange, your upgrade logic can be completely agnostic about what concrete pickup type or attributes it's working on, so you only have to write that stuff once.

# Answer
> 0 votes
**Edit**: I think I misunderstood your intention. I'll leave my answer here in case it leads somewhere, but I do not consider it a direct answer to your problem. Sorry.

---

I may have an idea for a different approach.

1. The `Player` holds a list of `Pickup` items.
2. Each `Pickup` has a list of upgrades, `IUpgrade`. See the Magnet example below.
3. The current upgrade level of each `Pickup` is saved.
4. Each upgrade implements an `Apply(Player p)` method, that modifies a single property on the `Player`, e.g. `UpgradeDamage`.

Of course if you have hundreds of items, with hundreds of upgrade levels, this approach is probably slow to execute. Also, I did not take care of any serialization.

### Player

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

public class Player : MonoBehaviour
{
    public int damage;
    public float duration;

    public List<Pickup> items = new List<Pickup>();

    private void Start()
    {
        // Add a new Pickup item for demonstration purposes
        var magnet = ScriptableObject.CreateInstance<Magnet>();
        magnet.upgradeLevel = 3;
        items.Add(magnet);

        // Apply all items
        foreach (var item in items)
        {
            item.ApplyUpgrades(this);
        }
    }
}

```

### abstract Pickup class

```
using System;
using UnityEngine;

public abstract class Pickup : ScriptableObject
{
    public int upgradeLevel = 1;

    protected abstract IUpgrade[][] upgrades { get; }

    public void ApplyUpgrades(Player player)
    {
        for (var i = 0; i < Math.Min(upgradeLevel, upgrades.Length); i++)
        {
            var levelUpgrades = upgrades[i];

            foreach (var upgrade in levelUpgrades)
            {
                upgrade.Apply(player);
            }
        }
    }
}

```

### Magnet

```
public class Magnet : Pickup
{
    private static IUpgrade[][] _upgrades =
    {
        // Level 1
        new IUpgrade[]
        {
            new UpgradeDamage(5)
        },

        // Level 2
        new IUpgrade[]
        {
            new UpgradeDuration(3f)
        },

        // Level 3
        new IUpgrade[]
        {
            new UpgradeDamage(7),
            new UpgradeDuration(5f)
        }
    };

    protected override IUpgrade[][] upgrades => _upgrades;
}

```

### IUpgrade interface

```
public interface IUpgrade
{
    public void Apply(Player p);
}

```

### UpgradeDamage

```
public class UpgradeDamage : IUpgrade
{
    private int amount;

    public UpgradeDamage(int amount)
    {
        this.amount = amount;
    }

    public void Apply(Player p)
    {
        p.damage += amount;
    }
}

```

### UpgradeDuration

```
public class UpgradeDuration : IUpgrade
{
    private float amount;

    public UpgradeDuration(float amount)
    {
        this.amount = amount;
    }

    public void Apply(Player p)
    {
        p.duration += amount;
    }
}

```

I might have misunderstood how you want items to upgrade the player, but I think the same pattern could be applied, even if you only want to perform, say, *Upgrade Level 3* for instance. Then instead of iterating each upgrade, you would just apply the upgrades at the desired level/index.

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


# Question
Title: Configurable Joint rotation doesn't seem to respect mass difference
# The Problem

I've run into a physics issue in my Unity project, and have put together a simple example scene to illustrate it. Hopefully someone will be able to tell me if I'm doing something wrong.

In my real game, I have a physics-based character with a limb that can rotate along it's length (think holding your arm out straight and twisting it). The limb and body are both rigid bodies and are connected by a Configurable Joint. My problem is that when the joint twists the limb, it also twists the body. That's not entirely surprising, Newton's 3rd law and all. But, I should be able to fix this by changing the masses of the connected objects, right? If I make the limb much less massive than the body, the limb should move much more relative to the body, right? Well, apparently that's only partially right, at least according to Unity.

# Simple Test/Reproduction

Here's my simple test scene, it involves only two cubes:

(Left cube "Big Cube" selected)

(Right cube "Little Cube" selected, showing joint anchor position)

These cubes are identical except:

* Transform position and scale
* Little Cube has a mass of 5.
* Big Cube has a mass of 100 (and is scaled 2x for clarity).
* Little Cube has a Configurable Joint on it, connected to Big Cube.

Now, watch what happens when I move the cubes toward or away from each other using the joint:

Big Cube barely moves, while Little Cube is moving all over the place. That's exactly what I would expect.

Now, let's try the same thing, but with rotation instead of position/translation:

Huh? The two cubes are moving in equal and opposite amounts. I would expect Big Cube to barely rotate at all, and Little Cube to rotate a lot, just like with the previous test.

***WHY?***

And how do I fix it so that the joint doesn't rotate the body (or at least doesn't rotate it much)?

# Answer
Well, turns out the answer was pretty simple:

***Colliders***

Colliders are present by default on the Cube primitive, but I'd been deleting them because I don't need/want collision detection. Since I'm pretty new to Unity, I didn't realize that Colliders influence the Rigidbody physics system in ways *other* than just detecting collisions. In particular:

> If you don't set the center of mass from a script it will be calculated automatically from all colliders attached to the rigidbody.

> ...positioned at this body's center of mass...
>
> Inertia tensor is a rotational analog of mass: the larger the inertia component about a particular axis is, the more torque that is required to achieve the same angular acceleration about that axis.
>
> ...
>
> If you don't set the inertia tensor from a script, it is calculated automatically from all colliders attached to the Rigidbody.

This tells me that the same amount of torque will be required to rotate any given rigidbody unless `inertiaTensor` is set, either manually, or through the use of Colliders.

Adding Colliders to the boxes causes the to behave as expected.
> 1 votes

---
Tags: unity, physics, physics-engine, joints
---


title: Inconsistent behaviour from MonoObjects

text:
# Question
Title: Inconsistent behaviour from MonoObjects
I have embedded mono inside a c++ game engine to be used with my component system. Currently, I store the MonoObjects (instances of the components) using entt like this:

```
struct ScriptsComponent
{
    // Components (scripts) that exist in the C# runtime (ie. user generated components)
    std::unordered_map<std::string, MonoObject*> externalScripts; // Name of type, ptr to object in C# runtime

    // Components that exist both in the C# runtime, and C++ runtime (ie. Engine intrinsic components)
    std::unordered_map<std::string, MonoObject*> internalScripts; // Name of type, ptr to object in C# runtime
};

```

Using that, I can for example get field values from components, by passing in MonoObjects that I retrieve from entt with the `ScriptsComponent`, and using functions like:

```
template <typename T>
static T GetComponentValue(MonoObject* componentObject, const std::string& fieldName, MonoDomain* domain)
{
    MonoClass* klass = mono_object_get_class(componentObject);
    const char* name = mono_class_get_name(klass);

    MonoClassField* field = mono_class_get_field_from_name(klass, fieldName.c_str());

    MonoObject* fieldObj = mono_field_get_value_object(domain, field, componentObject);

    return  *(T*)mono_object_unbox(fieldObj);
}

```

Or setting values:

```
static void SetFieldValue(const char* fieldName, MonoObject* object, void* value)
{
    MonoClass* klass = mono_object_get_class(object);
    if (klass) {
        MonoClassField* field = mono_class_get_field_from_name(klass, fieldName);
        mono_field_set_value(object, field, value);
    }

}

```

This all works fine, and I can correctly pass data between the managed side and unmanaged side. However, after running the program for a while (a minute or so), the MonoObjects 'break'. Either I can't get the `MonoClassField*` anymore, or the vtable field of the MonoObject is nullptr. I thought that maybe the object were being garbage collected, so I tried adding `mono_gchandle_new(object, false)`, after creating the object, but that did not work. Any ideas as to why I cant access the object fields anymore?

# Answer
> 0 votes
It seems as though the objects were being garbage collected of some sort, so pinning the object by using `mono_gchandle_new(object, true);` appears to have fixed the problem.

---
Tags: c++, mono
---