# Question
Title: Generating the distance of an intersection through a box from the camera in Unity C#
So, I recently saw this fantastic video by Sebastian Lague about planetary generation- https://www.youtube.com/watch?v=lctXaT9pxA0&t=1100s And I decided to replicate it, however, on a flat plane, not a sphere.In the video, (at timestamp linked) he uses some mathematical expression to figure out the distance of the camera's vector through an arbitrary sphere, and uses this to shade the ocean. I can't figure out how to write a similar estimator for an arbitrary rectangular prism. Anyone have any ideas?

EDIT- I have shifted to using surface shaders, but I can't figure out how to compensate for distance in depth-

Shader "Custom/SurfaceDepthShader"
{
    Properties {
        _ColorShallow ("Color Shallow", Color) = (1,1,1,1)
        _ColorDeep ("Color Deep", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5

        _fadeDepth("Base Alpha", Range(0,1)) = 0.5

        _InvFade ("Soft Factor", Range(0.01,3.0)) = 1.0
    }
    SubShader {
        Tags { "Queue"="Transparent" "RenderType"="Transparent" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard vertex:vert alpha:fade nolightmap

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
            float4 screenPos;
            float3 worldPos;
            float eyeDepth;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _ColorShallow;
        fixed4 _ColorDeep;

        sampler2D_float _CameraDepthTexture;
        float4 _CameraDepthTexture_TexelSize;

        float _InvFade;
        float _fadeDepth;

        void vert (inout appdata_full v, out Input o)
        {
            UNITY_INITIALIZE_OUTPUT(Input, o);
            COMPUTE_EYEDEPTH(o.eyeDepth);
        }

        void surf (Input IN, inout SurfaceOutputStandard o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _ColorShallow;
            //
            //  smoothness come from slider variables

            o.Smoothness = _Glossiness;

            float rawZ = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos));
            float sceneZ = LinearEyeDepth(rawZ);
            float partZ = IN.eyeDepth;

            float dist = distance(_WorldSpaceCameraPos, IN.worldPos);

            float fade = 1.0;
            if ( rawZ > 0.0 ) // Make sure the depth texture exists
                fade = saturate(_InvFade * (sceneZ - partZ));

            o.Albedo = lerp(_ColorShallow, _ColorDeep, fade) * c;
            o.Alpha = c.a * fade * _fadeDepth;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
```
</code></pre>

# Answer
I am not completely sure I understand what you're asking, because it seems like you linked to the wrong timestamp in the video. It sounds like you're asking how to change the color based on distance from the camera. If so:

Unity has a built-in shader variable `_WorldSpaceCameraPos` which represents the world-space position of the camera.

You can track the world-space position of a pixel in a vertex/fragment shader like this:

```
struct appdata {
    float4 vertex : POSITION;
};

struct v2f {
    float4 vertex : SV_POSITION;
    float3 worldPos : TEXCOORD0;
};

v2f vert (appdata v) {
    v2f result;
    result.vertex = UnityObjectToClipPos(v.vertex);
    //Calculate the world position of this pixel:
    result.worldPos = mul(unity_ObjectToWorld, v.vertex);
    return o;
}

```

Then in your frag function you can check the distance and perform math based on that:

```
fixed4 frag(v2f i) : SV_Target {
    //calculate distance from camera to pixel
    float dist = distance(_WorldSpaceCameraPos, i.worldPos);

    //do some math using the distance to determine your final color.
    //this is a very simple example:
    float blue = (1000 - dist) / 1000; //black at 1000m, pure blue at 0m
    blue = clamp(blue, 0, 1);
    fixed4 color = fixed4(0, 0, blue, 1);
}

```

**Edit:** Okay, now having seen the correct section of the video, it seems like you're wondering how to shade the ocean based on the depth of the ocean. I don't think my above code is directly applicable.

I am a little confused about the approach he's using in the video. He says "this shader will be run for every pixel on the screen", which sounds like he's using a screen-space shader. I may be missing something, as I have not watched the entire video, but that does not seem like an optimal solution to me. If I understand correctly, he has to do a bunch of extra math to determine which pixels, out of all of the pixels on the screen, are actually part of the ocean, then shade them according to the depth buffer.

The way I would do this would be to use a material shader, not a screen-space shader. If you were making a spherical world like in the video, you would do this:

1. Add a sphere to the scene at the same position as the planet, and give it a radius that matches your desired ocean depth.
2. Author a material shader that determines color based on the depth buffer, similar to way he does in the video.
3. Create a material that uses the material shader from step 2, and assign it to the sphere you created in step 1. Now you have your ocean and don't need to perform screen-space calculations to determine which pixels onscreen should be considered "ocean" pixels.

If you're doing a flat world, just make the ocean a plane instead of a sphere, and position it to achieve your desired ocean depth.
> 0 votes

---
Tags: unity, shaders, hlsl
---


# Question
Title: LibGDX Efficient way to reduce a vector's value gradually until it reaches 0,0
I can manage to achieve this but the code seems to be much longer than it should be. `Velocity` is given an initial value, either positive or negative and then is gradually reduced until it is 0,0.

```
Vector2 velocity = new Vector2(4,-3);
private float decSpeed = .2f;

public void update(float delta) {
velocity.x = setVel(velocity.x);
velocity.y = setVel(velocity.y);
}

private float setVel(float vel) {
    if (vel > 0) {
        if (vel - decSpeed <= 0)
            vel = 0;
        else
            vel -= decSpeed;
    } else if (vel < 0)
        if (vel + decSpeed >= 0)
            vel = 0;
        else
            vel += decSpeed;
    return vel;
}

```

I simply want to decrease the vector value for both x and y by a fixed amount, but of course you have to take into account that the vector can be either positive or negative.

# Answer
If you don't need the deceleration to be the same fixed amount each frame, you can instead apply a "drag multiplier". This is used in many games as a crude approximation of air resistance, where the faster you go, the more air you have to push through per unit of time, increasing the friction at high speeds.

```
public float velocityMultiplier = 0.95f;

public void update() {
    velocity.x *= velocityMultiplier;
    velocity.y *= velocityMultiplier;
}

```

This reduces the magnitude of your velocity vector while preserving its direction.

If you want to adjust the amount of braking to match your timestep, you need to compute an updated multiplier:

(I've also included a clamp-to-zero if you fall below a minimum speed constant)

```
public void update(float delta) {

    float multiplier = Math.pow(velocityMultiplier, delta * 30.0f);

    if (velocity.x * velocity.x + velocity.y * velocity.y < MIN_SPEED * MIN_SPEED)
        multiplier = 0f;

    velocity.x *= multiplier;
    velocity.y *= multiplier;
}

```

This will make your drag occur at the same rate as it would at a fixed 30 FPS framerate with your current `velocityMuliplier` setting, but adjusted to handle shorter or longer frames too.

(The `* 30.0f` above just sets the "reference framerate" we're using to measure our `velocityMultiplier`. So with the values above, we lose 5% of our velocity per 30th of a second)
> 3 votes

# Answer
If you want deceleration to be linear, you can subtract a fixed amount from the length of the vector, or set the vector to zero if it below the step size. So you might have something like:

```
float len = velocity.length();
if (len < difference) {
    velocity.x = 0;
    velocity.y = 0;
} else {
    float scale = difference / len;
    velocity.x -= velocity.x * scale;
    velocity.y -= velocity.y * scale;
}

```

This is slower than DMGregory's answer because of the square root hidden in the `length` function, so if you don't about keeping the deceleration constant his might be a better fit.

You might choose to use the Fast Inverse Square Root to speed things up, getting something like

```
float sqlen = velocity.x * velocity.x + velocity.y * velocity.y;
if (sqlen < difference * difference) {
    velocity.x = 0;
    velocity.y = 0;
} else {
    float scale = fastInvSqrt(sqlen) * difference;
    velocity.x -= velocity.x * scale;
    velocity.y -= velocity.y * scale;
}

```
> 0 votes

---
Tags: java, libgdx, mathematics, vector, linear-algebra
---


# Question
Title: GameObject.Find() can't find object after loading the scene
I have 2 scenes in my project, MainMenu and Game.

MainMenu scene contains 2 buttons, 'Hide Black' and 'Hide White'. Game scene contains 2 panels, 'Black' and 'White'. When the user clicks any of button from main menu, I wanna hide the corresponding panel in Game scene and also load the scene. This is the script for the same.

```
using UnityEngine;
using UnityEngine.SceneManagement;

public class MainMenu : MonoBehaviour {
    public void HideBlack() {
        SceneManager.LoadScene(1);
        GameObject black = GameObject.Find("Black");
        black.SetActive(false);
    }

    public void HideWhite() {
        SceneManager.LoadScene(1);
        GameObject white = GameObject.Find("White");
        white.SetActive(false);
    }
}

```

But it turns out that GameObject.Find can't find the panels in my Game scene. I looked my forums for help but I find them confusing. What's going on here?

EDIT - This is not from my actual project. I created these scenes just to explain the problem better. I must use 2 scenes in my actual project as I have 3D objects in Game scenes.

# Answer
I just figured in out. I wanted to load the same scene but with different UI on two different options. So I needed to hide other UI elements. To solve my problem I assigned Hide.cs script to an empty game object in my Game scene.

```
using UnityEngine;

public class Hide : MonoBehaviour {
    public GameObject black, white;
    public static bool hideBlack;

    void Start() {
        if(hideBlack) {
            black.SetActive(false);
        } else {
            white.SetActive(false);
        }
    }
}

```

And this is MainMenu.cs

```
using UnityEngine;
using UnityEngine.SceneManagement;

public class MainMenu : MonoBehaviour {
    public void HideBlack() {
        Hide.hideBlack = true;
        SceneManager.LoadScene(1);
    }

    public void HideWhite() {
        Hide.hideBlack = false;
        SceneManager.LoadScene(1);
    }
}

```
> 0 votes

---
Tags: unity, unity-ui
---


title: How front-to-back blending works?

text:
# Question
Title: How front-to-back blending works?
I would like to implement dual depth peeling in my engine. I read the original paper and examined the corresponding source code. I understand the algorithm, except how the blending works, especially in the front-to-back part. I'm so confused now, I'm not sure anything about alpha blending.

So let's start with the basics. I think there are two options: either we compute the pixel's color and it's transparency and store them separately (straight), or we multiply them and then we don't use the alpha channel's value (premultiplied alpha). The second option is what we usually do when we set glBlendFunc's parameters to GL\_SRC\_ALPHA and GL\_ONE\_MINUS\_SRC\_ALPHA. When we blend two pixels, the GPU multiplies the source color with the source alpha and it multiplies the destination color with (1 - source alpha). We don't multiply the destination color with the destination alpha because basically it's already multiplied with it. So we assume the destination alpha is 1 (and also the destination alpha is not correct, because of the GL\_SRC\_ALPHA and GL\_ONE\_MINUS\_SRC\_ALPHA parameters, so we can't use it anyways). Am I right so far?

At this point the back-to-front part of the dual depth peeling makes sense to me. In dual\_peeling\_peel\_fragment.glsl we just store the color with the alpha (we can't blend it yet because we have to use max blending in this shader).

```
void main(void)
{
    ...
    gl_FragData[2] = vec4(0.0);
    ...
    if (fragDepth == nearestDepth) {
        ...
    } else {
        gl_FragData[2] += color;
    }
}

```

Then in the dual\_peeling\_blend\_fragment.glsl shader we just blend it with the background.

```
void main(void)
{
    gl_FragColor = textureRect(TempTex, gl_FragCoord.xy);
    ...
}

```

Here we use additive blending with the already mentioned parameters which makes sense to me.

But when we compute the front-to-back part in dual\_peeling\_peel\_fragment.glsl, I don't understand the code.

```
void main(void)
{
    ...
    vec4 forwardTemp = textureRect(FrontBlenderTex, gl_FragCoord.xy);
    ...
    gl_FragData[1] = forwardTemp;
    ...
    float alphaMultiplier = 1.0 - forwardTemp.w;
    ...
    vec4 color = ShadeFragment();
    ...
    if (fragDepth == nearestDepth) {
        gl_FragData[1].xyz += color.rgb * color.a * alphaMultiplier;
        gl_FragData[1].w = 1.0 - alphaMultiplier * (1.0 - color.a);
    } else {
        ...
    }
}

```

Here we compute the color value and multiply it with some alpha values and we also compute the alpha. I don't see where these equations come from. We don't modify the destination color (which is the nearer), but we multiply the source color with the source alpha and with (1 - destination alpha). And then we also compute the alpha value. So this not straight neither premultiplied. Also in the paper they use slightly different equations in page 6.

Where the paper multiplies with destination alpha the source code multiplies with (1 - destination alpha). I found a blog post where the author is also confused about that.

And then, at the end in dual\_peeling\_final\_fragment.glsl we blend together the back-to-front part with the front-to-back part.

```
void main(void)
{
    vec4 frontColor = textureRect(FrontBlenderTex, gl_FragCoord.xy);
    vec3 backColor = textureRect(BackBlenderTex, gl_FragCoord.xy).rgb;
    float alphaMultiplier = 1.0 - frontColor.w;
    gl_FragColor.rgb = frontColor + backColor * alphaMultiplier;
}

```

But I don't understand why we only multiply the back part with (1 - front part alpha). In this part we use additive blending.

# Answer
I think a figured it out. I was correct about back-to-front blending. The destination color stores the already blended layers in premultiplied format, we assume that the alpha is 1. We don't care about what is actually stored in the alpha channel and we don't use this value when we blend a new layer. We can think about this like alpha is the amount of light which is reflected from the surface, while (1 - alpha) is the amount of light which is passing through to the farther layers. So it makes sense that when we blend a new layer, we multiply the new layer with it's alpha and we multiply the farther, already blended layers with (1 - alpha).

Front-to-back blending is the same but on the opposite direction. We store the the already blended (nearer) layers in the destination and we blend the source under it. We store the blended color in premultiplied format, but we also store it's alpha value and that's what confused me. Why are we store the alpha value if the color is already multiplied with it? We don't store the alpha because of the already blended layers, but rather because we have to know this information if we want to blend a new layer under the destination. We have to multiply the source color with (1 - destination alpha) because this is the amount of light which is passing through the already blended layers (and we also have to multiply it with it's own alpha of course). And we also maintain the destination's alpha value because we just blended a new layer.

The equations in the paper and in the code are a little bit different, but both of them are correct. The code does exactly what I described above. According to the paper we don't store the real alpha value of the blended layers but rather (1 - alpha) of the blended layers. This is a little counter intuitive because we don't store the alpha value in the alpha channel however if we think about it we don't have to. Because in the equation we have to multiply the source color with (1 - destination alpha). So this is basically just a trick to compute a little less in the shader.

This book's page 185-190 helped me a lot.
> 3 votes

---
Tags: opengl, transparency, alpha-blending
---


title: Limit rotation angle

text:
# Question
Title: Limit rotation angle
I am currently trying to rotate the weapons of a spaceship towards the mouse position, but in order to avoid the collision of projectiles with the ship I want to limit the angle the weapon can turn.

I've tried doing this:

```
    Vector3 mousePos = Input.mousePosition;
    float range = 100.0f;
    float rotStep = 0.1f;

    Vector3 positionOnScreen = Camera.main.ScreenToWorldPoint(mousePos + Vector3.forward * range);

    Vector3 targetDir = positionOnScreen - transform.position;
    Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, rotStep * Time.deltaTime, 0.0f);

    Quaternion lookRot = Quaternion.LookRotation(newDir);

    float xAngle = lookRot.eulerAngles.x;
    if (xAngle > 10 && xAngle <= 180)
    {
        xAngle = 10;
    }
    else if (xAngle < 350 && xAngle > 180)
    {
        xAngle = 350;
    }

    float yAngle = lookRot.eulerAngles.y;
    if (yAngle > 10 && yAngle <= 180)
    {
        yAngle = 10;
    }
    else if (yAngle < 350 && yAngle > 180)
    {
        yAngle = 350;
    }

    float zAngle = lookRot.eulerAngles.z;
    if (zAngle > 10 && zAngle <= 180)
    {
        zAngle = 10;
    }
    else if (zAngle < 350 && zAngle > 180)
    {
        zAngle = 350;
    }

    lookRot.eulerAngles =new Vector3(xAngle, yAngle, zAngle);
    transform.rotation = lookRot;

```

The problem here is that I don't know how to limit the rotation angle since it's not the same depending on the ship rotation (for example if it's (0, 0 , 0) or (-90, -90, -90)). I've tried using transform.localRotation too, but still happens the same. Do you how could I limit the rotation regardless of the ship rotation?

# Answer
> 0 votes
I think you should use the `LocalRotation`. because from what I see you are only checking the rotation of the cannons in world space, not locally.

# Answer
> 0 votes
Here's a way to do this with local rotation, expressing our limits symmetrically about our initial orientation to avoid the problems described in this answer.

```
public float yawRange;
public float pitchRange;

// Cache our initial rotation in Start, to use it as the center of our range.
Quaternion _neutralRotation;

void Start() {
    _neutralRotation = transform.localRotation;
}

void Update() {
    // The first part proceeds as before.
    Vector3 mousePos = Input.mousePosition;
    float range = 100.0f;
    float rotStep = 0.1f;

    Vector3 positionInWorld = Camera.main.ScreenToWorldPoint(mousePos + Vector3.forward * range);

    // Then we transform into our parent's local space, to get an offset from our local position.
    Vector3 positionInParent = transform.parent.InverseTransformPoint(positionInWorld);

    Vector3 targetDir = positionInParent - transform.localPosition;

    Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, rotStep * Time.deltaTime, 0.0f);

    // We convert this into a rotation space where Euler angles (0, 0, 0) describe the orientation
    // at the center of our range, so we get symmetric behaviour in all directions from here.
    Vector3 relativeToCenter = (Quaternion.Inverse(_neutralRotation) * newDir).normalized;

    // We extract the Euler angles that describe this direction, and clamp them.
    float yaw = Mathf.Atan2(relativeToCenter.x, relativeToCenter.z) * Mathf.Rad2Deg;
    float pitch = Mathf.Asin(relativeToCenter.y) * Mathf.Rad2Deg;;

    yaw = Mathf.Clamp(yaw, -yawRange, yawRange);
    pitch = Mathf.Clamp(pitch, -pitchRange, pitchRange);

    // We apply this clamped rotation relative to our center, relative to our parent.
    transform.localRotation = _neutralRotation * Quaternion.Euler(pitch, yaw, 0);
}

```

---
Tags: unity, rotation
---


# Question
Title: Why does Avatar Mask not work as expected?
I have 2 layers: The base layer, and an upper body layer. On the upper body layer, I have an avatar mask because I only want to affect the upper body. However, this mask doesn't work as expected.

Here is what it looks like:

This is what is looks like when the upper body layer has a weight of 0:

And this is with the upper body layer with a weight of 1 and with the Avatar Mask:

As one can see, the lower body is affected. The avatar mask doesn't seem to have an effect. Is that a bug in Unity, or is there anything I could still check?

Thank you!

# Answer
The problem was that I had defined my model's rig as "Generic".

In this case, the "Humanoid" type avatar mask may not be used.

According to the docs, in this case, the "Transform" avatar mask type has to be used.

Once I used the "Transform" avatar mask type, it worked as expected.
> 0 votes

---
Tags: unity, animation-controller, avatar
---


# Question
Title: Unity depth shader not giving correct values
I did the following shader (looked up and changed for my needs):

```
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/DepthShader"
{
        SubShader
        {
            Pass
            {
                CGPROGRAM

                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"

                uniform sampler2D _CameraDepthTexture;
                uniform half4 _CameraDepthTexture_TexelSize;

                struct input
                {
                    float4 pos : POSITION;
                    half2 uv : TEXCOORD0;
                };

                struct output
                {
                    float4 pos : SV_POSITION;
                    half2 uv : TEXCOORD0;
                };

                output vert(input i)
                {
                    output o;
                    o.pos = UnityObjectToClipPos(i.pos);
                    o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, i.uv);
                    // why do we need this? cause sometimes the image I get is flipped. see: http://docs.unity3d.com/Manual/SL-PlatformDifferences.html
                    #if UNITY_UV_STARTS_AT_TOP
                    if (_CameraDepthTexture_TexelSize.y < 0)
                            o.uv.y = 1 - o.uv.y;
                    #endif

                    return o;
                }

                fixed4 frag(output o) : COLOR
                {
                    float depth = DECODE_EYEDEPTH(tex2D(_CameraDepthTexture, o.uv));
                    return depth;
                }

                ENDCG
            }
        }
}

```

What i want is to get depth map with actual distances, not within 0-1 range. Main script is showing color scene but inside i'm checking what's the distance to center of screen:

```
    private Shader _shader;
    private Shader shader
    {
        get { return _shader != null ? _shader : (_shader = Shader.Find("Custom/DepthShader")); }
    }

    private Material _material;

    private Material material
    {
        get
        {
            if (_material == null)
            {
                _material = new Material(shader);
                _material.hideFlags = HideFlags.HideAndDontSave;
            }
            return _material;
        }
    }

    private void Start()
    {   GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;
    }

    private void OnRenderImage(RenderTexture src, RenderTexture dest)
    {

        RenderTexture buffer = new RenderTexture(
                               Screen.width, Screen.height,
                               0,                            // No depth/stencil buffer
                               RenderTextureFormat.ARGBFloat,   // Standard colour format
                               RenderTextureReadWrite.Linear // No sRGB conversions
                           );
        Graphics.Blit(src, buffer, material);

        // main scene
        Graphics.Blit(src, dest);
        RenderTexture.active = buffer;           // If not using a scene camera
        Texture2D outputTex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBAFloat, false);
        outputTex.ReadPixels(
                  new Rect(0, 0, Screen.width, Screen.height),
                  0, 0,
                  false
        );
        outputTex.Apply();
        Color[] depthMap = outputTex.GetPixels();

        Color color = depthMap[Screen.width * Screen.height / 2 + Screen.width / 2];
        Debug.Log("distance to center pixel is: " + color[0]);

        Object.Destroy(outputTex);

    }

```

So here: Debug.Log("distance to center pixel is: " + color\[0\]); I'm trying to check correctness of my depth values by checking center pixel value. In the scene I put camera then after 25 meters small wall then again after 25 meters big wall (parallel to small one). So camera is looking at the center of small wall. I am expecting the center pixel to be the small wall so depth value should be ~25.

But what I get from Debug.Log is something around 999.8341. If camera is positioned closer i start seeing more or less reasonable values.

I decided saved those values into file as matrix and here is what it is showing around the center:

Is my approach correct or did I make some mistake?

*EDIT:* The scene image looks like this:

# Answer
> 0 votes
I don't know Unity, but the "buffer = new RenderTexture" looks like something I would want to do one time in start(), not every time the image is rendered in OnRenderImage().

---
Tags: unity, shaders, depth
---


# Question
Title: Unity - Reading Map image Pixel by Pixel produces extra pixel at the beginning of each row
I have a C# script in unity(attached to the bottom of the post) and I am itterating through a image pixel by pixel and I am confused on the results I get. There is an extra white block being processed in at the beginning of processing and results in the overall map being thrown off in generation. The image is exactly 50x50 pixels.

A better way would be to put it is as the image below(screenshot from pixel painting app so you can see the pixel grid) starting in the bottom left hand corner going from left to right then up the rows in processing. At the beginning there is an extra white pixel being read. So in the image there are 4 white pixels and then one orange. But from the Console output included below the code below adds an extra white pixel before it sees the orange.

```
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;
using System.IO;
public class LevelGenerator : MonoBehaviour
{

[TitleGroup("Base Settings")]
[Space]
[Header("Ground")]
public GameObject groundTile1;
public GameObject groundTile2;
public GameObject groundTile3;
[Space]
[Header("Parent Game Objects")]
public GameObject groundParent;
public GameObject roadsParent;
public GameObject towersParent;
public GameObject treeParent;
public GameObject groundClutterParent;
public GameObject housesParent;
public GameObject waterParent;
[Space]
[Header("Road")]
public GameObject roadTile1;
public GameObject roadTile2;
public GameObject roadTile3;
[Space]
[Header("Water")]
public GameObject waterTile;
[Space]
[Header("Trees")]
public GameObject tree1;
public GameObject tree2;
public GameObject tree3;
[Space]
[Header("Ground Clutter")]
public GameObject groundClutter1;
public GameObject groundClutter2;
[Space]
[Header("Houses")]
public GameObject house1;
public GameObject house2;
[Space]
[Header("Tower Spot Tile")]
public GameObject towerSpotTile;
[Space]
[Header("Map")]
public Texture2D map;
[Space]
[Header("Debug Log")]
[Header("Basic Details")]
public int width;
public int height;
public string logLocation;

[Header("Sizing Details")]
public GameObject baseCube;
public float baseCubeHeight;
public float baseCubeWidth;
public float baseCubeDepth;
[Button(ButtonSizes.Small)]
private void getDimensions()
{
    CalculateHeightAndWidth();
}
// Start is called before the first frame update
void Start()
{
    CalculateHeightAndWidth();
}

// Update is called once per frame
void Update()
{

}

public void CalculateHeightAndWidth()
{
    baseCubeHeight = baseCube.GetComponent<Renderer>().bounds.size.y;
    baseCubeWidth = baseCube.GetComponent<Renderer>().bounds.size.x;
    baseCubeDepth = baseCube.GetComponent<Renderer>().bounds.size.z;
    //Reset class variables to 0
    height = 0;
    width = 0;

    float curDepth;
    float curWidth;
    Color pixelColor;
    GameObject placeThis;
    string outputPath = "Assets/Logs/level_generator_log.txt";
    StreamWriter writer = new StreamWriter(outputPath, true);
    for (int hcount = 0; hcount < map.height; hcount++)
    {
        for (int wcount = 0; wcount < map.width; wcount++)
        {

            pixelColor = map.GetPixel(width, height);

            writer.WriteLine("/r/n The current pixel (W=" + wcount + " x H=" + hcount +") Color: "+ToHEX(pixelColor)+" - Block Type = "+whichBlockType(ToHEX(pixelColor)));
            //Incriment Class Width Counter
            width = wcount;

        }
        //Incriment Class Height Counter
        height = hcount;
    }

    writer.Close();
}

public string whichBlockType(string colorCode)
{
    switch (colorCode)
    {
        //Road
        case "000000": //Black
            //Debug.Log("road");
            return "road";
            //break;
        //Tower Spots
        case "DA0205": //Red
            //Debug.Log("tower spot");
            return "tower";
            //break;
        //Water
        case "023ADA": //Blue
            //Debug.Log("water");
            return "water";
        //break;
        //Ground Clutter
        case "02DA37": //Green
            return "groundClutter";
        case "4D2122": //Brown
            //Debug.Log("tree");
            return "house";
            //break;
        //Starting Portal
        case "FD8F4D": //Orange
            //Debug.Log("start-portal");
            return "start-portal";
            //break;
        //Ground
        case "FFFFFF":
            //Debug.Log("ground");
            return "ground";
        //break
        default:
            return "ERROR: UKNOWN BLOCK TYPE! ERROR 1 - LevelGenerator.cs Line 150";
    }
}

public string ToHEX(Color color)
{
    string hex = ColorUtility.ToHtmlStringRGB(color);
    return hex;
}

```

}

Log

```
 The current pixel (W=0 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=1 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=2 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=3 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=4 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=5 x H=0) Color: FD8F4D - Block Type = start-portal
 The current pixel (W=6 x H=0) Color: FD8F4D - Block Type = start-portal
 The current pixel (W=7 x H=0) Color: FD8F4D - Block Type = start-portal
 The current pixel (W=8 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=9 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=10 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=11 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=12 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=13 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=14 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=15 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=16 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=17 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=18 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=19 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=20 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=21 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=22 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=23 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=24 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=25 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=26 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=27 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=28 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=29 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=30 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=31 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=32 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=33 x H=0) Color: DA0205 - Block Type = tower
 The current pixel (W=34 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=35 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=36 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=37 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=38 x H=0) Color: DA0205 - Block Type = tower
 The current pixel (W=39 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=40 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=41 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=42 x H=0) Color: DA0205 - Block Type = tower
 The current pixel (W=43 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=44 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=45 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=46 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=47 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=48 x H=0) Color: DA0205 - Block Type = tower
 The current pixel (W=49 x H=0) Color: FFFFFF - Block Type = ground
 The current pixel (W=0 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=1 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=2 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=3 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=4 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=5 x H=1) Color: FD8F4D - Block Type = start-portal
 The current pixel (W=6 x H=1) Color: FD8F4D - Block Type = start-portal
 The current pixel (W=7 x H=1) Color: FD8F4D - Block Type = start-portal
 The current pixel (W=8 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=9 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=10 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=11 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=12 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=13 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=14 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=15 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=16 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=17 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=18 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=19 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=20 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=21 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=22 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=23 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=24 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=25 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=26 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=27 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=28 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=29 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=30 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=31 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=32 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=33 x H=1) Color: DA0205 - Block Type = tower
 The current pixel (W=34 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=35 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=36 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=37 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=38 x H=1) Color: DA0205 - Block Type = tower
 The current pixel (W=39 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=40 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=41 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=42 x H=1) Color: DA0205 - Block Type = tower
 The current pixel (W=43 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=44 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=45 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=46 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=47 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=48 x H=1) Color: DA0205 - Block Type = tower
 The current pixel (W=49 x H=1) Color: FFFFFF - Block Type = ground
 The current pixel (W=0 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=1 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=2 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=3 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=4 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=5 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=6 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=7 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=8 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=9 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=10 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=11 x H=2) Color: 02DA37 - Block Type = groundClutter
 The current pixel (W=12 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=13 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=14 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=15 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=16 x H=2) Color: DA0205 - Block Type = tower
 The current pixel (W=17 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=18 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=19 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=20 x H=2) Color: DA0205 - Block Type = tower
 The current pixel (W=21 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=22 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=23 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=24 x H=2) Color: DA0205 - Block Type = tower
 The current pixel (W=25 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=26 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=27 x H=2) Color: DA0205 - Block Type = tower
 The current pixel (W=28 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=29 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=30 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=31 x H=2) Color: DA0205 - Block Type = tower
 The current pixel (W=32 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=33 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=34 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=35 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=36 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=37 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=38 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=39 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=40 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=41 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=42 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=43 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=44 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=45 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=46 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=47 x H=2) Color: 000000 - Block Type = road
 The current pixel (W=48 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=49 x H=2) Color: FFFFFF - Block Type = ground
 The current pixel (W=0 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=1 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=2 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=3 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=4 x H=3) Color: DA0205 - Block Type = tower
 The current pixel (W=5 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=6 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=7 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=8 x H=3) Color: DA0205 - Block Type = tower
 The current pixel (W=9 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=10 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=11 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=12 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=13 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=14 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=15 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=16 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=17 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=18 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=19 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=20 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=21 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=22 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=23 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=24 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=25 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=26 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=27 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=28 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=29 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=30 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=31 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=32 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=33 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=34 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=35 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=36 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=37 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=38 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=39 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=40 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=41 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=42 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=43 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=44 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=45 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=46 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=47 x H=3) Color: 000000 - Block Type = road
 The current pixel (W=48 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=49 x H=3) Color: FFFFFF - Block Type = ground
 The current pixel (W=0 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=1 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=2 x H=4) Color: 02DA37 - Block Type = groundClutter
 The current pixel (W=3 x H=4) Color: 4D2122 - Block Type = house
 The current pixel (W=4 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=5 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=6 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=7 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=8 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=9 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=10 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=11 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=12 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=13 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=14 x H=4) Color: 02DA37 - Block Type = groundClutter
 The current pixel (W=15 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=16 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=17 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=18 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=19 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=20 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=21 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=22 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=23 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=24 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=25 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=26 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=27 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=28 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=29 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=30 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=31 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=32 x H=4) Color: 02DA37 - Block Type = groundClutter
 The current pixel (W=33 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=34 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=35 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=36 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=37 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=38 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=39 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=40 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=41 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=42 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=43 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=44 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=45 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=46 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=47 x H=4) Color: 000000 - Block Type = road
 The current pixel (W=48 x H=4) Color: FFFFFF - Block Type = ground
 The current pixel (W=49 x H=4) Color: FFFFFF - Block Type = ground

```

# Answer
Ok so I solved my problem, what a simple stupid mistake it was. I was using "width" and "height" and using them to get the current pixel. However I had the incrementing happening at the end of the loop which in turn was causing the first line of the image being reproduced and throwing everything off :/

So if you have count's off while processing pixels make sure you didn't do what I did.
> 1 votes

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


# Question
Title: UE4 Blueprint Multiplayer Spawning Issue
I'm attempting to copy/modify the MultiplayerShootout project's multiplayer functionality for my own project. I'm running into issues when Player 2 joins a running session though. Finding it very hard to debug multiplayer stuff because you have to run it in standalone and toggling breakpoints doesn't seem to be illustrating any issues.

Here's the issue: https://youtu.be/270p4YS36Pw

The first player to search for a game hosts a game, then the OnPostLogin in the GameMode fires and calls the ClientPostLogin event in the PlayerController, then the PlayerController calls the RespawnPlayer event inside the GameMode which spawns and possesses the character. The second player finds a session and joins it, but the server is not spawning a character for them on the other PlayerStart.

The logic is very much similar to the MultiplayerShootout, but I have modified it in the following ways:

The 1v1 button searches for sessions, and if it can't find any it will automatically host a session.

The ClientPostLogin event on the PlayerController and the RespawnPlayer event on the GameMode accepts a Selected Character (Actor class) variable. This is so I can get the player to select their character before they matchmake and pass it through to the PlayerController and then GameMode for spawning purposes. Would really appreciate some help on this, been stuck on it for a while.

Here's some of the blueprint scripting to make sense of it:

OnPostLogin event in the GameMode

ClientPostLogin in the PlayerController

RespawnPlayer event in the GameMode

1v1 button released event in the PlayScreen Widget

HostGame event in the GameInstance

JoinGame event in the GameInstance

Edit: I'm using UEngine version 4.24.3

# Answer
Moving the RespawnPlayerEvent into the PlayerController fixed this. I think it had to do with the inability for the second client who joins (who is not the server host) to call a function in the GameMode (which only exists on the server).

To sum it up:

* The player selects a character and stores the actor class in a variable inside the GameInstance (this is because the GameInstance does not lose information upon traveling to different maps).
* When a player joins/hosts a server the OnPostLogin event fires, passing the PlayerController and firing the ClientPostLogin event inside the PlayerController.
* The PlayerController then gets the Selected Character variable from the GameInstance and passes it on to the RespawnPlayerEvent which is also inside the PlayerController.
> 0 votes

---
Tags: multiplayer, unreal-4, blueprints, online, spawning
---


# Question
Title: File saved to IndexedDB lost unless we change scenes
Our game includes an in-game level editor. When the user saves a custom level, the level is serialized and written to a file:

```
public void SaveFile<T>(T obj, string path) {
    if (!typeof(T).IsSerializable) {
        throw new ArgumentException("Tried to save non-serializable type " + typeof(T).Name);
    }

    FileStream fs = null;
    try {
        fs = new FileStream(path, FileMode.Create);
        DataContractJsonSerializer serializer = GetSerializer();
        serializer.WriteObject(fs, obj);
    } catch (Exception ex) {
        Debug.LogException(ex);
    } finally {
        if (fs != null) fs.Close();
    }
}

```

Serialized files can be loaded like this:

```
public T LoadFile<T>(string path) {
    if (!typeof(T).IsSerializable) {
        throw new ArgumentException("Tried to deserialize non-serializable type " + typeof(T).Name);
    }

    if (!File.Exists(path)) return default(T);

    FileStream fs = null;
    T result;
    try {
        fs = new FileStream(path, FileMode.Open);
        DataContractJsonSerializer serializer = GetSerializer();
        var result = (T)serializer.ReadObject(fs);
    } catch (Exception ex) {
        Debug.LogException(ex);
        throw ex;
    } finally {
        if (fs != null) fs.Close();
    }

    return result;
}

```

When displaying a "Load" menu, we enumerate the saved files like this:

```
public List<T> LoadFiles() {
    if (!Directory.Exists(path)) {
        Debug.Log("No save files found");
        return new List<T>();
    }

    var files = Directory.EnumerateFiles(path);
    Debug.Log("Found " + files.Count() + " files");

    List<T> result = new List<T>(files.Count());
    foreach (string file in files) {
        Debug.Log(file);
        T obj = LoadFile<T>(file);
        if (obj == null) Debug.Log("File at " + file + " loaded null");
        if (obj != null) result.Add(obj);
    }
    return result;
}

```

I have omitted a lot of code for brevity, but what is shown above should cover the important parts.

In the Editor, everything works perfectly. However, in WebGL builds (where files are saved to/loaded from the browser IndexedDB), there is a strange quirk: the file doesn't remain in IndexedDB *unless the user changes to a different scene after saving.*

Scenario 1:

1. In the level Editor, Bob presses "Save"
2. The file is saved, and the browser console shows the log entry `File saved to /idbfs/abc123/CustomLevels//FileName`
3. Bob refreshes the webpage
4. Bob clicks "Load"
5. The game searches IndexedDB but does not find the file saved in step 2

Scenario 2:

1. In the level Editor, Alice presses "Save"
2. The file is saved, and the browser console shows the log entry `File saved to /idbfs/abc123/CustomLevels//FileName`
3. **Alice returns to the main menu scene**
4. Alice refreshes the webpage
5. Alice clicks "Load"
6. The game searches IndexedDB and does find the file saved in step 2

The browser console log suggests that after Bob refreshes the page in Scenario 1, the file no longer exists. If this was the only scenario that Bob had saved, we see the message "No save files found". If Bob had previously saved other scenarios and used the workaround of returning to the main menu scene, those previously saved files will appear in the console and save list, but the most recent file is missing.

Why would the save file disappear from the IndexedDB if the user leaves the webpage without changing scenes, but remain in the IndexedDB if the user returns to the main menu scene before leaving the webpage?

# Answer
D'oh! This is covered in the WebGL troubleshooting documentation (which did not come up in my web search results for 'Unity IndexedDB').

Unity does not flush changes to IndexedDB immediately when you save a file. They don't explain *when* they do a flush, but clearly a scene change is one event that triggers a flush.

To immediately flush the changes, we have to run a little bit of JavaScript. Create a new `.jslib` file in `Assets/Plugins/` and add the following code:

```
mergeInto(LibraryManager.library, {
    //flush our file changes to IndexedDB
    SyncDB: function () {
        FS.syncfs(false, function (err) {
           if (err) console.log("syncfs error: " + err);
        });
    }
});

```

Add a reference to the external JS function in our C# code:

```
    #if UNITY_WEBGL && !UNITY_EDITOR
        [DllImport("__Internal")]
        private static extern void SyncDB();
    #endif

```

Call the external function after saving:

```
    #if UNITY_WEBGL && !UNITY_EDITOR
        //flush our changes to IndexedDB
        SyncDB();
    #endif

```
> 6 votes

---
Tags: unity, webgl, browser-based-games
---


# Question
Title: Need help with using Player Prefs to save number of coins collected
I'm using unity 3D to make a game where the character collides with coins in order to collect them. When playing the game, the player should start out with zero coins and each time he collides with a coin, the amount should increase by one. On a main menu scene, the total number of coins (that have been collected across multiple games) should be displayed. The total number of coins is being displayed on the main menu but once in the gameplay scene, the total number of coins is being displayed there too (where it's supposed to start at 0 and then increase by 1 each time a coin is collected). Here is the script I use for when the player collides with a coin:

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

public class CoinScript : MonoBehaviour
{
    void OnTriggerEnter(Collider target)
    {
        CoinScoreManager.coinAmount += 1;
        Destroy(gameObject);
    }
}

```

Here is the script I use to manage the UI and coin number in the game play scene:

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

public class CoinScoreManager : MonoBehaviour
{
    public static int coinAmount;
    public Text coinText;

    void Start()
    {

        coinAmount = PlayerPrefs.GetInt("CoinAmount");
    }

    void Update()
    {
        coinText.text = coinAmount.ToString();
        PlayerPrefs.SetInt("CoinAmount", coinAmount);
    }
}

```

Here is the script I use to manage the UI and total coin number in the scene with the main menu:

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

public class MainMenuController : MonoBehaviour
{
    int coinAmount;
    public Text coinAmountText;

    void Start()
    {
        coinAmount = PlayerPrefs.GetInt("CoinAmount");
    }

    void Update()
    {
        coinAmountText.text = coinAmount.ToString();
    }

}

```

I think the problem is in the second script shown above. In the Start function I'm calling the coinAmount which is the same variable used to show the total coin number. I think that's the problem but I'm not really sure how to fix the problem as I'm still kinda of new to Unity and programming. Please let me know if there's anything else you need to know about the game in order to figure out how to fix this. Thanks for your help!

# Answer
There are quite a few things to improve, but that is expected from a new programmer. These are the tips for future:

* you should not be calling `PlayerPrefs` every single `Update` call. It just hogs performance. ...
* you should not trust static variables on counting stuff. Better approach would be to use Singleton pattern (answer of AndresBarrera), and use its methods. ...
* do not set `Text` value on every `Update`. It will dirty whole canvas and it will force recalculation and redrawing, which might get expensive when your canvas contains many elements.

Keeping those points in mind, you should make your `CoinScoreManager` a singleton. It should retrieve current coins count in `Awake` and cache it to `private` variable. Then, provide methods for getting and setting that variable value.

Read about C# events and how they work. Create `public event Action<int> CoinAmountChanged` event on `CoinScoreManager` and subscribe to it from `MainMenuController`. `CoinScoreManager` should raise this event when coin amount is set through method. This will make coin text change only when coin amount changes. This is what we ultimately want, right?

I gave you directions, where and what to look for. Try figuring it out yourself. If it is still too hard to grasp the concept, I will edit my answer providing the code.

# THE CODE

### CoinScoreManager.cs

```
public sealed class CoinScoreManager : MonoBehaviour
{
    private const string CoinAmountPrefName = "CoinAmount";

    public event Action<int> CoinAmountChanged;

    private int _coinAmount;

    public static CoinScoreManager Instance {get; private set;}

    private void Awake()
    {
        if (Instance == null)    // Checking if there's currently no active instance (singleton can only have one instance throughout lifespan of the program (game))
        {
            LoadCoinsAmount();
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Debug.LogWarning($"There's another instance of {nameof(CoinScoreManager)}. Destroying this script.);
            Destroy(this);
        }
    }

    private void OnDestroy()
    {
        CoinAmountChanged = null; // Clearing event subscribers to prevent memory leaks.
    }

    public void AddCoins(int count)
    {
        _coinAmount += count;

        CoinAmountChanged?.Invoke(_coinAmount);
        SaveCoinsAmount();
    }

    public int GetCoinsAmount()
    {
        return _coinAmount;
    }

    public void LoadCoinsAmount()
    {
        _coinAmount = PlayerPrefs.GetInt(CoinAmountPrefName, 0);
    }

    public void SaveCoinsAmount()
    {
        PlayerPrefs.SetInt(CoinAmountPrefName, _coinAmount);
    }
}

```

For this to work, you must add *CoinScoreManager* script on an active GameObject and the GameObject must not be child of any other objects.

### CoinScript.cs

```
...
OnTriggerEnter(Collider collision)
{
    CoinScoreManager.Instance.AddCoins(1); // Calling singleton's method. Will throw exception if CoinScoreManager component is not present in the scene.
    Destroy(gameObject);
}
...

```

And now, making *MainMenuController* to only change after coin amount is changed.

### MainMenuController.cs

```
public class MainMenuController : MonoBehaviour
{
    public Text coinAmountText;

    private void OnDestroy()
    {
        if (CoinScoreManager.Instance != null)
        {
            // Unsubscribing from event to prevent memory leaks
            CoinScoreManager.Instance.CoinsAmountChanged -= OnCoinsAmountChanged;
        }
    }

    private void Start()
    {
        // Subscribing to CoinsAmountChanged event
        CoinScoreManager.Instance.CoinsAmountChanged += OnCoinsAmountChanged;

        // Making text value to be updated when script first starts
        OnCoinAmountChanged(CoinScoreManager.Instance.GetCoinsAmount());
    }

    private void OnCoinAmountChanged(int newAmount)
    {
        coinAmountText.text = newAmount.ToString();
    }
}

```
> 1 votes

# Answer
You see exactly what your code describes. You are storing in your PlayersPref your total amount of coins. You load this value when you start a game, it would be weird if you would not see the total amount. When a game starts, you don't want to load from your PlayersPref but just 0. You might want to introduce a second variable to your CoinScoreManager (currentGame) and display this value during your actual gameplay. When your game is over, you add this value to your coinAmount to update your mainmenu coin value and persist it.
> 0 votes

---
Tags: unity, c#, savegame, user-interface
---


# Question
Title: Difference between [P2P] Relay Servers and Dedicated Game Servers?
I came across this unity Unity conference video on buillding multiplayer games https://www.youtube.com/watch?v=CuQF7hXlVyk

**Form, this image we can see there are 3 P2P methods**

**and 1 Direct client server model**

**So what is the difference between P2P Client server and Dedicated game servers**

* **These are the my understandings,**
    + In P2P Client Server relay is just used to connect with players in order to over come NAT issues, In this model one of the client hosts the game
    + In direct dedicated game server game instance of game runs on server and clients connect to that game.

Enlighten me! Thanks!

# Answer
> 4 votes
In the peer-to-peer client-server model, the server software runs on the machine of a player who is also taking part in the game. The server software and the game client are usually integrated in the same executable.

In the dedicated server model, the server software is a separate application which usually has no visual output. It runs on a separate machine which is usually (but not necessarily) sitting in a datacenter.

The peer-to-peer model is cheaper and more convenient, because nobody needs to pay for separate machines to run servers. But it also has a couple disadvantages:

* The host must be a player with a public facing IP. They can not be behind a NAT router (unless they configure it to do port forwarding, but that's something you need to explain to players how to do).
* When the host quits the game, then the game is either over or you need to migrate the game to a new host. Host migration can be technically challenging and is often hard to do without pausing the game for a couple seconds (although some developers figured out pretty smart ways to do it with minimal disruption).
* Poor game experience when the host has a weak machine or a bad internet connection.
* The host has an unfair advantage, because they are playing with a network latency ("ping") of zero.
* It is difficult to prevent the host from cheating.
* The players can use network diagnosis tools to find out the IP address of the host and the host those of all players, which is problematic from a privacy perspective.

Using a relay fixes the first and last problem by having a server in a datacenter as an intermediate between players and hosts. But now you again need servers in a datacenter. Just *cheaper* servers, because they do nothing but sending data back and forth while the computationally expensive game mechanics are calculated on the machine of a player.

---
Tags: unity, c#, networking, multiplayer, unity-networking
---


# Question
Title: What are the accessibility implications of requiring a button press or time-out on a game over screen?
For simple games, is there a de-facto standard that game over screens time out after a few seconds before, or require some sort of input in order to, transition back to the main menu?

* Time-out pros:

+ Accessibility. Mobility-impaired users may have difficulty pushing the buttons so the game should advance for them.
* Time-out cons:

+ Accessibility. Vision-impaired users may have difficulty seeing any post-game information displayed within the allotted time.
    + Tweaking the time-out so it's not too long as to be annoying if the user happens to game over a lot. Also: "Don't make QA mad"
* Input pros:

+ Accessibility. Vision-impaired users may take as long as needed to see any post-game information displayed on screen.
    + Makes time-outs skippable.
* Input cons:

+ Accessibility. Motor-impaired users may have difficulty pushing buttons.

I remember reading a Microsoft article about certain best practice design decisions regarding accessibility a long time ago but can't recall the specifics.

# Answer
The accessibility issue is really only a problem when the input for leaving the game over screen is different form the input required to play the game.

For example, when the player is unable to operate more than 3 buttons comfortably, and your actual game only uses 3 buttons, then they can play it just fine. But when you then ask for a 4th button to leave the game over screen (or worse, a different input device like a mouse) then you added an unnecessary accessibility hurdle.

But as long as the input action which leaves the game over screen is the same as an input action which is critical for playing the game, then you are fine. Now any player who is able to play is able to leave the game over screen. And besides, it's more intuitive and convenient for *every* player to reuse a known input method than to introduce a new one. Another example for how thinking about accessibility improves the UX of everyone.

On the other hand, a game over screen which does have an automatic timeout can become an accessibility problem in itself. When you add some more information to the game over screen, then the player might need some time to absorb that information. The player might also want a break before starting the next round of the game, so pausing on the game over screen is a natural point for that.
> 10 votes

# Answer
As @BernhardBarker stated

> If you have difficulty pushing buttons, you may have difficulty playing most games.

I would go with the approach that matches your whole game controls. If you control your game using buttons, wait for button press. If you control game using voice commands, use voice commands for continuing. If your game has high contrast and big elements for vision-impaired players, use them on game over screen. And so on and so forth.
> 3 votes

# Answer
It depends as well on your type of the game. For some games the game over screen gives you an overview of what you achieved, your progress, maybe even an option of retry current level, going back to level selection or main menu. This still holds true for simple games.

Another factor is that your game over screen can function as a break to reset your mentality, prepare for another round or reflect on your last game.

Finally as a user, I feel annoyed when I'm forced to wait. If you have a timed game over screen, allow the user to skip/ shorten it with the same user control they are used for playing your game.
> 1 votes

---
Tags: game-design, accessibility
---


# Question
Title: Determine which button is at specific coordinates
I am implementing a weapon wheel in Unity and I have most of it all worked out, but am struggling with one issue:

My weapon wheel looks a bit like this one (example only):

And mine is for something else, not weapons.. but that doesn't matter.

There is no mouse involved.. the idea is to spin the wheel left and right until you've selected the item you want.. the selected one would be the one in the top most position (the example above is the bottom most position, it seems).. Anyway, I have it moving left and right just fine.. the problem now is trying to figure out which button (yes, they are implemented as UI buttons) is currently in the selected position.

My initial thoughts are

1. To calculate the center X, Y pair of the "selected" location and store those..
2. When user hits action button to select, then iterate through the 8 buttons I have in that weapon wheel and..
3. Calculate the current X and Y of each button in the loop
4. If the button overlaps the "selected" location, then invoke that button's click()

This is proving to be a real pain in the neck though.. for example, I have found that the button transform's positon is always 0,0 until you show the UI at least once.. so I have to use Update() instead of Start().. In addition, trying to calculate the overlap means needing to add width of button to current X and height to current Y and getting pixel width does not seem to be an easy task.

Is there some simpler way to do this? How can I have a "selected" button on my weapon wheel without too much fuss like this? And if this really is the only way, then please let me know how I can get the pixel width and height of buttons.

# Answer
> 1 votes
Okay, I went with @DMGregory's answer (see his comment above).

So I was already tracking the rotation angle of the wheel anyway.. then all I needed to do was normalize the degrees between 0 and 360 and then figure out which button is at which degree... like so:

An extension method for the normalizing of degrees first:

```
public static int NormalizeCircleDegrees(this int orientation)
{
    orientation %= 360;

    if (orientation < 0)
    {
        orientation += 360;
    }

    return orientation;
}

```

And then this method:

```
private Button GetSelectedButton()
{
    int normalizedDegrees = currentRotation.NormalizeCircleDegrees();

    switch (normalizedDegrees)
    {
        case 0: return Buttons[0];
        case 45: return Buttons[1];
        case 90: return Buttons[2];
        case 135: return Buttons[3];
        case 180: return Buttons[4];
        case 225: return Buttons[5];
        case 270: return Buttons[6];
        case 315: return Buttons[7];
        default: return Buttons[0];
    }
}

```

Just make sure the buttons are in the right order and voila! Much simpler...

---
Tags: unity, unity-ui
---


# Question
Title: Moving and shrinking circle to a circle inside of it (PUBG like zone)
I am trying to create a battle royale circle gamemode within Arma3 that would work like in PUBG.

For anyone who doesn't know how it looks like:
Red circle should smoothly shrink into the blue one (that means sides that close to each other should move very slowly by adjusting speed of the red circle center)

Global variables:

```
Center = (getMarkerPos "marker_start"); // eg. [1000, 1000]
ClosingSpeed = 0.5;
CurrentRadius = 1000;
EndingRadius = 250;
Offset = 1;

```

Code for generating new circle:

```
// Determines maximum radius of a new circle
private _maxRadius = CurrentRadius * 0.7;
// Generates radius of the new circle
private _randomRadius = [_maxRadius * 0.6, _maxRadius] call BIS_fnc_randomNum;
// Generates new circle center
private _randomCenter = [CurrentRadius * 0.1, (CurrentRadius - _randomRadius)] call BIS_fnc_randomNum;
// Randomizes position of the new circle within the old one
FinalCenter = Center getPos [_randomCenter, random 360];
EndingRadius = _randomRadius;
ClosingSpeed = ClosingSpeed / 2;
// This number should be somehow calculated to make the closing circle animation work properly
Offset = 0.75;

```

Shrinking code, executed every 100 ms:

```
// Decreases radius
CurrentRadius = CurrentRadius - ClosingSpeed;
// Gets the angle between two center points - in degrees
private _angle = ((FinalCenter select 1) - (Center select 1)) atan2 ((FinalCenter select 0) - (Center select 0));
if (CurrentRadius > EndingRadius) then {
    // This sets new position of the circle
    Center set [0, (Center select 0) + ((Offset * ClosingSpeed) * cos (_angle))];
    Center set [1, (Center select 1) + ((Offset * ClosingSpeed) * sin (_angle))];
};

```

Without the correct Offset it shrinks like this - center points (red circle center was moving at a wrong velocity):

# Answer
This could be solved using a parametric equation.

P' = P + (t * D)

Where: P is the starting position of the outer circle. P' is the current position of the circle. t is (elapsed time / time it takes to shrink the circle) D is a vector from P to the center of the inner circle. Note: do not normalize this vector.

If t \> 1, the circle has finished moving, so use that to trigger the next circle.

This will smoothly interpolate the position of the center and guarantee it ends where you want it.
> 2 votes

---
Tags: geometry, arma3
---


title: OnCollisionEnter2D not working

text:
# Question
Title: OnCollisionEnter2D not working
I am fairly new to Unity2D and am making a 2D platformer to get used to the engine. I am trying to create a platform that moves when the player jumps on it, however, on the script for the platform the OnCollisionEnter2D method is just not being called. This is the script:

```
public class ThrustPlatform : MonoBehaviour

[SerializeField] float thrustSpeed;
[SerializeField] float thrustDistance;

Animator thrustAnim;
Rigidbody2D rb;

private bool thrust = false;
private Vector2 startPos;
private Vector2 targetPos;

void Start()
{
    thrustAnim = GetComponent<Animator>();
    rb = GetComponent<Rigidbody2D>();

    startPos = transform.position;
    float targetX = startPos.x + thrustDistance;
    targetPos = new Vector2(targetX, startPos.y);
}

private void OnCollisionEnter2D(Collider2D coll)
{
    Debug.Log("COLLISION");
    thrust = true;
}

private void FixedUpdate()
{
    if(thrust)
    {
        rb.velocity = new Vector2(thrustSpeed, 0);
    }
}

```

The player and platform are on layers that can collide with each other in the collision matrix, the player still lands on the platform, and the player has a dynamic rigid body and the platform a kinematic rigid body. As far as I am aware kinematic rigid bodies detect collisions from dynamic rigid body, I have watched tutorials where this works. Even if I change the platform rigid body to dynamic there is no detection. I have also tried using continuous collision detection on both rigid bodies but still it is not calling. If I change it to a trigger and use OnTriggerEnter2D however, the Debug line appears.

This is the rigidbody for the platform.

This is the rigidbody details for the player.

I am very confused as to why this isn't working and I can't find a solution anywhere else (unless I am missing something very obvious).

# Answer
> 1 votes
Your method signature must match the one given in the documentation.

`OnCollisionEnter2D` takes a `Collision2D` argument, not a `Collider2D` argument as you've used here.

Because your signature doesn't match, Unity finds no matching `OnCollisionEnter2D(Collision2D collision)` function to call, so it doesn't call it.

---
Tags: unity, collision-detection, rigidbody, collider
---


# Question
Title: OpenGL texture2d/image sampling issue. Strange artifacts in texture
I have an issue when using textures in OpenGL, strange artifacts occur where geometry overlaps, but not always. Video Reference. I am using a `GL_TEXTURE_2D` with `GL_ARB_image_load_store` to make a custom depth test shader that stores material data for opaque and transparent geometry. The video given shows the artifacts occur where the support structure for a table is occluded behind the top of the table, but strangely, not occurring where the base of the table is occluded by the support.

```
#version 450 core

in VS_OUT {
    vec3 Position;
    vec3 Normal;
    vec2 TexCoords;

    mat3 TanBitanNorm;
} fs_in;

// Material data
uniform sampler2D uAlbedoMap;
uniform sampler2D uNormalMap;
uniform sampler2D uMetallicMap;

// Material info out
layout(rgba16f) coherent uniform image2D uAlbedoDepthOpaque;
layout(rgba16f) coherent uniform image2D uNormalMetallicOpaque;
layout(rgba16f) coherent uniform image2D uAlbedoDepthTransparent;
layout(rgba16f) coherent uniform image2D uNormalAlphaTransparent;

// Depth info in/out
layout(r8) uniform image2D uDepthBufferOpaque;
layout(r8) uniform image2D uDepthBufferTransparent;

void main() {
    vec3 n_tex = texture(uNormalMap, fs_in.TexCoords).xyz;
    n_tex = n_tex * 2.0f - 1.0f;

    ivec2 tx_loc = ivec2(gl_FragCoord.xy);
    const float opaque_depth = imageLoad(uDepthBufferOpaque, tx_loc).r; // Stored depth of opaque
    const float trans_depth = imageLoad(uDepthBufferTransparent, tx_loc).r; // Stored depth of transparent

    // Depth processing
    if (gl_FragCoord.z > opaque_depth) {
        bool tran = false;
        if (trans_depth > opaque_depth)
            tran = trans_depth > gl_FragCoord.z;
        else
            tran = true;

        // Transparent
        if (texture(uAlbedoMap, fs_in.TexCoords).a < 1.0f && tran) {
            imageStore(uDepthBufferTransparent, tx_loc,
                vec4(gl_FragCoord.z));

            imageStore(uAlbedoDepthTransparent, tx_loc,
                vec4(texture(uAlbedoMap, fs_in.TexCoords).rgb, gl_FragCoord.z));
            imageStore(uNormalAlphaTransparent, tx_loc,
                vec4(abs(length(n_tex) - 1.0f) > 0.1f ? fs_in.Normal : normalize(fs_in.TanBitanNorm * n_tex), texture(uAlbedoMap, fs_in.TexCoords).a));
        }

        // Opaque
        else {
            imageStore(uDepthBufferOpaque, tx_loc,
                vec4(gl_FragCoord.z));

            imageStore(uAlbedoDepthOpaque, tx_loc,
                vec4(texture(uAlbedoMap, fs_in.TexCoords).rgb, gl_FragCoord.z));
            imageStore(uNormalMetallicOpaque, tx_loc,
                vec4(abs(length(n_tex) - 1.0f) > 0.1f ? fs_in.Normal : normalize(fs_in.TanBitanNorm * n_tex), texture(uMetallicMap, fs_in.TexCoords).r));
        }
    }

    if (opaque_depth == 0.0f) {
        imageStore(uDepthBufferOpaque, tx_loc,
            vec4(0.125f));
    }

    else {
        imageStore(uDepthBufferOpaque, tx_loc,
            vec4(0.125f + opaque_depth));
    }
}

```

Render with overlapping geometry shows that artifacts still occur outside of reading from the texture. Also in the video, I move the camera back and forth (with orthographic projection) and the artifacts become brighter and darker. Render with overlapping geometry w/out depth processing shows that the brighter/darker values were from the depth test.

Any ideas on why this occurs, and how can I fix it?

# Answer
> 1 votes
The issue is Z-fighting.

The gpu, when choosing which pixels to write to the back buffer, write using a sort of painter's algorithm, farthest away, to closest, for each pixel. This is called depth testing.

Normally, this would be caused by two objects occupying the same depth in the depth buffer, but you are bypassing that, in an attempt to achieve transparency.

This is my advice:

1. Deploy a painter's algorithm to perform transparency rendering, instead of what you are doing. Furthest away to closest. This is done in your renderer, not the shader. basically take all your objects and put them in a collection, sorting in descending order, of distance from the camera.
2. Turn OFF depth testing - This is important.
3. Utilize built-in blending for building up your final buffer. I'm sorry, but I don't know the correct blending settings off-hand. Experiment, or look up the right bledning algorithm.
4. Get rid of imageLoad/imageStore: you don't need them, and tbh it complicates your shader code. Use the regular shader outputs and texture() calls. It might slow down your shader code, but it will be easy to understand what is going on. Optimize later.
5. Treat transparent and opaque as varying degrees of transparency, not different cases. See step 1.

---
Tags: opengl, shaders, textures
---


# Question
Title: Blueprint script executed on tick but not on construction
Below, on event tick, I am initializing a map of images *once*, which works fine (remember we are in a graph for a widget blueprint here).

*Z Cursor Images* is the map of the images. The keys in the map are an enum, and I am adding first an image for the default cursor, and then an image for when the player is targeting an object that she can pick up.

Now, when I do *the same* in the construction script (Event Construct), it does not throw an error but later I cannot access the textures from the map. `IsValid` returns false for them...

So why *is* the map filled on tick but not on Event Construct? And how do I solve this?

# Answer
In case you are running into a limitation that's specific to the Construction Script, you can also try other approaches. Either:

* doing the initialization in ***Event Begin Play*** instead of the ***Construction script***
* providing the *Z Cursor Images* variable with default values that suits your needs instead of programmatically setting them at start

Cheers!
> 1 votes

---
Tags: unreal-4, unreal, blueprints
---


# Question
Title: How do you deal with transparent fonts that you want to be white?
I am a complete beginner, but I thought I would try to learn how to create a basic game during quarantine. So, I apologize if this question is trivial.

However, I stumbled into a problem with fonts. I'm thinking about using the free font "Pixelmania" to show a score at the top of the screen. But the font is transparent!

How do I change the inner part of the font to be completely white? Is it necessary to manually edit the font file or is there an easier method?

# Answer
> 3 votes
Here's another technique you can use.

Select your font asset in the Inspector and set the Font Size to the size you want, and Character to the full set of characters you want to use. For this font, "ASCII upper case" would probably suffice. This generates a fixed font texture with exactly those characters present, at your chosen size, instead of dynamically building an atlas from the characters you use at runtime. Click Apply.

Next click the gear at the top of the Inspector and choose "Create Editable Copy" - this will clone the font, its material, and its font texture to separate files you can edit individually.

Select the new font texture and change its format from the default "Alpha 8" (which means Unity ignores the colour of the font image and uses just its transparency mask) to either "Automatic" (compressed, and good enough for this effect), or "RGBA 32 bit" (uncompressed).

Now open the font texture in your painting tool of choice, and flood-fill all the transparent regions with white.

Save, and now you're ready to use your edited font in UI text (not Text Mesh Pro):

The advantage of this method is you can do literally anything you want to that font texture - paint every letter a different colour, replace each letter with photos of dogs, encode information for shader effects in the R G B A channels separately, etc.

The downside is that it's now a raster effect authored at some fixed resolution. So if you want to use this font at multiple different sizes in different parts of your game, or on different devices/resolutions, you either have to make multiple font textures, or cope with quality loss when the text is displayed at a different resolution than it was authored for.

The Text Mesh Pro solution Philipp offers handles crisp text across a wide range of resolutions very efficiently, but it is a bit more restricted in what you can do to the image data for each letter, since it treats fonts more like vector data (technically signed distance fields, which is a rasterization of a vector-like source that has only "inside" and "outside", no variations within that interior)

# Answer
> 2 votes
I am afraid this won't be possible with that font. TrueType-Fonts only have solid areas and transparent areas. They don't have a way to define which parts of each letter are "inside" and thus should be shown in a different color if on a transparent background. This font is really just outline and shadow but no letter.

But instead of this font, you could use a font which is just the solid part, and then add the outline and shadow effect at runtime. You can easily do that by creating a text as a Text Mesh Pro Text instead of a standard Text. TMP can do both outlines and shadows (called "Underlay") with any font you feed it. Plus lots and lots of other cool text effects.

From the TMP website:

---
Tags: unity, fonts, spritefont
---


# Question
Title: Why is there grey haze that appears when game is simulated in viewport, and how do I fix it?
For some reason when the game runs in the regular viewport (not it's own) a grey haze slowly appears. This never used to happen. The level architecture (code) changed recently and then this started happening. However, none of the assets or visual build configurations were changed. This problem does not occur when the game is running in a separate viewport, but the fact is it wasn't an issue in the default viewport before. Does anyone know what is causing this and how to fix/prevent it?

# Answer
> 1 votes
From the information you provided, this could be an issue with a semi-transparent UI element scaling weirdly.

You can check if there's a faulty widget using the Widget Reflector: **Window \> Developer Tools \> Widget Reflector** (that's the last one in the list).

From there, activate the "Pick Painted Widgets" and hover your cursor over the "hazy" area, and it will tell you if there's any UI Widget there. (press Esc when you're hovering the element, so you can then look in the hierarchy tree of the Widget Reflector without changing the selection)

Cheers!

---
Tags: lighting, unreal, viewport
---


# Question
Title: How to get image component from blueprint in c++
I have a dialog screenwith character icon and I need to be able to set up this image in code. But I don't know how to access this Image component (I put material instances in it).

**.h**

```
UPROPERTY(EditAnywhere) TSubclassOf<UUserWidget> widgetDialogBottom;
UUserWidget* widgetDialogBottomInstance;

```

**.cpp**

```
widgetDialogBottomInstance = CreateWidget<UUserWidget>(GetWorld(), widgetDialogBottom);
widgetDialogBottomInstance->Image("mi_dialog_2"); // Need something like this
widgetDialogBottomInstance->AddToViewport();

```

I made a class DialogBottomWidget:

**.h**

```
UCLASS()
class HOME_API UDialogBottomWidget : public UUserWidget
{
        GENERATED_BODY()

    public:
        void SetImage(UTexture2D* InTexture);

    private:
        UPROPERTY(meta = (BindWidget)) UImage* CharacterPreview;
};

```

**.cpp**

```
#include "DialogBottomWidget.h"

void UDialogBottomWidget::SetImage(UTexture2D* InTexture)
{
    CharacterPreview->SetBrushFromTexture(InTexture);
}

```

.. and then I made a blueprint based on that class. What should I do now?

I can get reference to image `MaterialInstanceConstant'/Game/Materials/Faces/mi_dialog_2.mi_dialog_2'`, but how to put it to image component of the blueprint?

# Answer
> 1 votes
The variable ***widgetDialogBottomInstance*** should be of type ***UDialogBottomWidget*** rather than the generic ***UUserWidget***. By having the proper type for both the variable and the *CreateWidget* function template parameter, you'll be able access the *SetImage* function you wrote:

```
UDialogBottomWidget* widgetDialogBottomInstance;
...
widgetDialogBottomInstance = CreateWidget<UDialogBottomWidget>(GetWorld(), widgetDialogBottom);
widgetDialogBottomInstance->SetImage(...); // You can call SetImage here

```

Cheers!

---
Tags: c++, unreal-4, unreal
---


# Question
Title: How do I create cinematic (trailer like) shots of my game?
---

**Background**

We are in the midst of developing a trailer for our game.

It is a 3rd person adventure platformer. As such, the camera is an over the shoulder position, which is great for gameplay, but not so much for creating cinematic shots of our game.

---

**Problem**

I need to create cinematic shots of my game. This means I need to use separate camera angles to record gameplay.

As far as I am aware, I can only record the active viewport with Unreal, which leaves me stumped as to how I am supposed to play the game and record a moving camera at the same time.

---

**What I have tried**

I have attempted to use the `level sequencer recorder` to track the actors required, then playing the game and recording all my actions into the sequence created. From here, I can use a cinematic camera in a viewport and play the sequencer in the level (whilst recording), or directly rendering out the sequence.

Issue with this: The output of the sequence when rendered out is never the same as what is recorded. This issue seems to vary between machines we do it on. For instance, at my work PC, the sequence that gets played had the player mesh rotated to a completely wrong angle.

A colleague has also tried this same method, but for him some of the animations for the main character simply do not play.

---

**Question**

How do I create cinematic footage of my game akin to my proposal?

Is the level sequencer recorder the correct approach to be taking?

How have you done this in the past for your game etc.?

# Answer
If you're having issues with the Sequence Recorder, the **Replay System** might be an interesting alternative for you: https://docs.unrealengine.com/en-US/Engine/Replay/index.html

By combining that with a camera sequence, you should be able to put together a proper gameplay trailer.

If that doesn't work for you, you could also try the new Take Recorder, which seems to be the way to go now (as mentioned in the Sequence Recorder page). Here's a guide: https://docs.unrealengine.com/en-US/Engine/Sequencer/Workflow/TakeRecorder/UsingTR/index.html

Hopefully it will give you better results. Cheers!
> 1 votes

---
Tags: animation, rendering, camera, movement, unreal-4
---


# Question
Title: Change the colour of all particles on screen
I'm trying to make it so when the user clicks a button, the colour of all particles on screen change to a certain colour. Is there a way to change the colour of all particles on screen coming from the same particle emitter at runtime? I know there is the main module's startColor property, but that only changes the particle colour for new particles, not ones currently on screen. Currently I've tried messing around with the colorOverLifetime module, but I just get these weird blend between the original colour and the new one.

# Answer
> 1 votes
Thanks to DMGregory, I learned the answer was to just set the starting color to white, while setting the color over lifetime module's color to whatever color desired.

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


# Question
Title: Instantiate random different gameObjects in specific spaces?
I need to instantiate different gameObjects of different shapes and sizes on top of the left third and the right third of a table, and all this objects need to be random every time the scene loads. I have a library of around 80 GO but the most I'll instantiate, for now, is 30. All the instantiated GO have to be different, that means no duplicates.

I thought that maybe I could create 30 empty gameObjects on the table, where I want to instantiate them in random, but I'm not sure if this is the most intelligent way to do it. Is there any other way?

Also, since I have a library of GO so large, would it be possible to load the folder in the script instead of defining a list and populating it in the editor?

I'm a bit new at coding for Unity, but I'm an experienced programmer.

# Answer
> 0 votes
There are multiple ways of doing the instantiation itself:

* You could place the 30 empty gameobject as you wish in the level and then **spawn objects as children of those empty gameobjects**. Signature: `public static Object Instantiate(Object original, Transform parent);`
* You can place the 30 empty gameobjects, and **just use their transform** when spawning your objects (this way doesn't require any kind of hierarchy). Signature: `public static Object Instantiate(Object original, Vector3 position, Quaternion rotation);`
* (You could also programmatically compute the transform of each object, that's a valid option as well)

When it comes to **scanning a given path to find all assets**, take a look at the **`AssetDatabase.FindAssets`** helper: https://docs.unity3d.com/ScriptReference/AssetDatabase.FindAssets.html (You can even filter with specifics asset labels!)

To avoid copying the output list of FindAssets to shuffle it, you can **generate a list of randomized indexes using Linq**, and then simplify iterate on this index list:

```
    Random rnd = new Random();
    List<int> indexes = Enumerable.Range(0, 30).OrderBy((item)=> rnd.Next()).ToList();

```

Cheers!

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