# Question
Title: How to creatively justify world limits to the player and challenge them to go there?
(This question is a bit similar to this question, but that question specifically asks how to implement a height ceiling/collision mechanically, and this is more of a design question rather than a programming one. It's also similar to this great question, but my situation is more specific to the "challenging them to get past the wall" scenario, and that question is now five years old, so hopefully this question is different enough to be allowed.)

## The situation

I've been working with my dev friend on a small 2D tiled game prototype that has X, Y, Z coordinate axes, allowing players to travel in the four cardinal directions as well as "fly" upwards and downwards along the Z-axis. (Think something akin to Dwarf Fortress, with a 2D map that incorporates terrain height and the ability for winged creatures to fly on the Z-level.) The theme of the game is "breaking boundaries," which naturally opens up the door for design questions about how to creatively implement boundaries and allow the player to bend or push past them to create fun.

Obviously, when you have a system where the player can travel freely on an XYZ axis around a world of limited size, there needs to be an eventual limit on two things:

* how high the player can fly up or down in the Z direction, and
* how far they can move in the X and Y directions.

This is both to preserve computing resources and to prevent the player from quite literally getting themselves lost in the sky or the void. As the Dwarf Fortress wiki sagely notes:

> The default settings produce levels with around 50 z-levels of land... Reducing the number of z-levels, especially cavern levels, can reduce processor demand and boost framerate.

However, in my situation I want the player to be fully able to try and travel past the game's "boundary limits," and to reward and challenge them for doing so. This matches the general theme of what I eventually want the game to be - a game of "breaking boundaries." **I want to come up with a creative way to both justify the world's boundaries mechanically, and make hitting that limit exciting and a challenge for the player to solve, even if there really is a "cap" that they can't get past in the end.**

## How other games solve this problem

Most games solve the problem of "how to stop the player from wandering too far" with **invisible walls** \- that is, placing invisible walls at the world boundaries and placing an invisible ceiling over the world at the maximum height cap, and mechanically forbidding players from going beyond those world boundaries, without much of a mechanical game explanation for it.

The "invisible wall" approach is undoubtedly the easy way to go - but hitting an invisible wall is a surefire way to annoy players and break immersion, and judging from mods existing specifically to remove them, I don't think this is the most enjoyable option. As I said, I want to make hitting the boundary *fun* and challenging for the player, instead of a "bummer" experience.

Subnautica, on the other hand, does the idea of world boundaries in a really creative way, and **that's the kind of idea I want to emulate**. Instead of outright stopping you from going beyond the world boundary of Crater's Edge, you instead get a creepy "Warning: Entering ecological dead zone" message on your PDA, followed by a close encounter with *these genuinely horrifying monsters that haunt my nightmares:*

You *can* technically defeat these monsters, but it's a crazy, terrifying challenge - and that's not the point of this encounter. The point was to make hitting the boundary *exciting* and memorable, and it obviously worked, since I've seen tons of screenshots and videos of cool encounters with the Ghost Leviathans on the world borders. That's exactly the kind of thing I want to emulate in my own game - a sense of excitement and danger from hitting boundaries, rather than boredom or bumming the player out.

## The question

**What are some other interesting, unique mechanical ways to "make boundaries fun" and use them to challenge the player?** I'm specifically looking for ideas that apply to my situation of a 2D world with XYZ axes, but any general design ideas you have for tackling the "invisible wall" problem from this angle are welcome.

# Answer
Make the game more difficult the further the player gets away from the world origin.

Player progression in form of new abilities, numerical advancements or just improvement in player skill might allow the player to venture out further. The final boundary of the game would then be the point where survival does not just become difficult but actually mathematically impossible.

*Subnautica* is actually a great example of this technique. But I am not talking about the horizontal exploration limited by the ghost leviathans the YouTubers like so much. I am talking about the downwards exploration with dive depth.

The game puts several boundaries on how *deep* the player can explore, and then breaks those boundaries. The first is how long the player can hold their breath. They have to return to the surface every few seconds, so there is a boundary on how deep they can explore. Players can extend that boundary by some tricks. Like carrying multiple oxygen tanks or using air pipes. Or they can do it by skill: Just be more daring and quicker in their exploration. But there is still a limit on how far the player can reasonably be expected to go in this phase of the game.

This boundary gets stretched when the player unlocks various numerical upgrades. Like higher oxygen capacity or faster swimming. This increases the exploration depth, but not by much, because it doesn't solve the fundamental problem that the player can't stay away from the surface as long as they want to.

The real boundary breaker is unlocking vehicles which can dive and supply the player with unlimited oxygen while doing so. But those vehicles also have a maximum dive depth (which can also be extended by progression). They serve as a base of operation for the players diving activities, so the same soft limits apply as those during the time where they had to go to the surface. Just with an additional x meters of depth provided by the vehicle. Also, vehicles *can* go deeper than their dive depth, but then they take continuous damage. So a daring player can stretch that limit a bit further, but not infinitely.

This is a technique you can use:

* Have a "safe" exploration radius around the player base
* When the player leaves the safe exploration radius, confront them with hazards or obstacles which allow them *a bit* of exploration beyond it, but still force them to return rather quickly.
* Add ways of player progression which extend the safe exploration radius by mitigating those hazards or providing tool to overcome the obstacles. This in turn makes more content available, which then allows to unlock more player progression, and so on.

What obstacles, hazards and progression upgrades could that be? Sorry, but we are not going to design your game for you. We don't know your game and we can't know what you would or would not find thematically appropriate.
> 5 votes

---
Tags: game-design, game-mechanics, world-design
---


# Question
Title: How do I draw lines to a custom inspector?
I have a custom editor to which I want to be able to draw a basic line graph. I have much of the functionality down, but I have only been able to test as much via the debug. I am yet to figure out how to draw the actual lines to the inspector.

How do I draw lines to a custom inspector?

---

I have found plenty of online resources, in regards to custom drawing to the editor. However, everything I find pertains specifically to drawing in the scene view; nothing seems to work inside of an actual inspector.

The two general methods I have found involve using `Handles.DrawLine` and the `GL` library. Neither appear to work; however, I have only been able to test functionality with blind coordinates, so far. I can not find anything in regards to actually determining the local coordinates of the area on the inspector where I wish to draw. Perhaps I need to start with an initial "origin" position, Perhaps I need to start with a local area defined by a `Rect`. I simply don't know.

---

It has also been a while since I had to use OpenGL, directly. It is entirely possible I am simply doing it wrong, to begin with. Here is my current graph method:

```
private void DrawVelocityGraph(float[] velocityValues, float minimumVelocity,
    float maximumVelocity)
{
    float velocityValue = velocityValues[0];
    float increment = 0;
    Vector3 lineStart = Vector3.zero;
    Vector3 lineEnd  = new Vector3(horizontalIncrement, velocityValue * verticalIncrement);

    GL.Begin(GL.LINES);

    for(int i = 1; i < velocityValues.Length; i++)
    {
        if(velocityValue == velocityValues[i]
            && (velocityValue == minimumVelocity || velocityValue == maximumVelocity))
        {
            Handles.color = VelocityGrapherColours.outOfRangeColour;
        }
        else
        {
            velocityValue = velocityValues[i];
            Handles.color = VelocityGrapherColours.lineColour;
        }

        lineStart = lineEnd;
        lineEnd.x += increment;
        lineEnd.y = velocityValue * verticalIncrement;

        GL.Vertex(lineStart);
        GL.Vertex(lineEnd);
    }

    GL.End();
}

```

# Answer
I ended up asking over at Unity Answers, and I was quickly given a reliable answer from *Bunny83*, including a working example of a custom inspector with custom drawing logic. Ultimately, you *can* draw lines over a custom inspector using OpenGL, I was just doing it wrong. Of particular note, the answer I received made note of additional requirements I had missed:

* I had to reserve a space to draw over, using `GUILayoutUtility.GetRect()`.
* I had to ensure I was only drawing during the `EventType.Repaint` event.
* While not a requirement, I had to assign a specific material, using `material.SetPass()`. Not doing this can have undesirable results.
* I had to use further common OpenGL logic, such as clearing a new area with `GL.Clear()`, and pushing and popping the current matrix with `GL.PushMatrix()` and `GL.PopMatrix()`.

---

```
<summary>The material to use when drawing with OpenGL.</summary>
private Material material;

void OnEnable()
{
    // Find the "Hidden/Internal-Colored" shader, and cache it for use.
    material = new Material(Shader.Find("Hidden/Internal-Colored"));
}

public override void OnInspectorGUI()
{
    // Begin to draw a horizontal layout, using the helpBox EditorStyle
    GUILayout.BeginHorizontal(EditorStyles.helpBox);

    // Reserve GUI space with a width from 10 to 10000, and a fixed height of 200, and
    // cache it as a rectangle.
    Rect layoutRectangle = GUILayoutUtility.GetRect(10,10000,200,200);

    if(Event.current.type == EventType.Repaint)
    {
        // If we are currently in the Repaint event, begin to draw a clip of the size of
        // previously reserved rectangle, and push the current matrix for drawing.
        GUI.BeginClip(layoutRectangle);
        GL.PushMatrix();

        // Clear the current render buffer, setting a new background colour, and set our
        // material for rendering.
        GL.Clear(true, false, Color.black);
        material.SetPass(0);

        // Start drawing in OpenGL Quads, to draw the background canvas. Set the
        // colour black as the current OpenGL drawing colour, and draw a quad covering
        // the dimensions of the layoutRectangle.
        GL.Begin(GL.QUADS);
        GL.Color(Color.black);
        GL.Vertex3(0, 0, 0);
        GL.Vertex3(layoutRectangle.width, 0, 0);
        GL.Vertex3(layoutRectangle.width, layoutRectangle.height, 0);
        GL.Vertex3(0, layoutRectangle.height, 0);
        GL.End();

        // Start drawing in OpenGL Lines, to draw the lines of the grid.
        GL.Begin(GL.LINES);

        // Store measurement values to determine the offset, for scrolling animation,
        // and the line count, for drawing the grid.
        int offset = (Time.frameCount * 2) % 50;
        int count = (int)(layoutRectangle.width / 10) + 20;

        for(int i = 0; i < count; i++)
        {
            // For every line being drawn in the grid, create a colour placeholder; if the
            // current index is divisible by 5, we are at a major segment line; set this
            // colour to a dark grey. If the current index is not divisible by 5, we are
            // at a minor segment line; set this colour to a lighter grey. Set the derived
            // colour as the current OpenGL drawing colour.
            Color lineColour = (i % 5 == 0
                ? new Color(0.5f, 0.5f, 0.5f) : new Color(0.2f, 0.2f, 0.2f);
            GL.Color(lineColour);

            // Derive a new x co-ordinate from the initial index, converting it straight
            // into line positions, and move it back to adjust for the animation offset.
            float x = i * 10 - offset;

            if (x >= 0 && x < layoutRectangle.width)
            {
                // If the current derived x position is within the bounds of the
                // rectangle, draw another vertical line.
                GL.Vertex3(x, 0, 0);
                GL.Vertex3(x, layoutRectangle.height, 0);
            }

            if (i < layoutRectangle.height / 10)
            {
                // Convert the current index value into a y position, and if it is within
                // the bounds of the rectangle, draw another horizontal line.
                GL.Vertex3(0, i * 10, 0);
                GL.Vertex3(layoutRectangle.width, i * 10, 0);
            }
        }

        // End lines drawing.
        GL.End();

        // Pop the current matrix for rendering, and end the drawing clip.
        GL.PopMatrix();
        GUI.EndClip();
    }

    // End our horizontal
    GUILayout.EndHorizontal();
}

```

---
> 8 votes

# Answer
Why don't you just use the Handles.DrawAAPolyLine(), to draw custom lines on the inspector panel, like:

```
public override void OnInspectorGUI()
{
    // ...
    GUI.BeginClip(rect);
    Handles.color = Color.red;
    Handles.DrawAAPolyLine(
        Texture2D.whiteTexture,
        15,
        Vector3.zero,
        new Vector3(120, 91, 0),
        new Vector3(220, 91, 0),
        new Vector3(350, 20, 0));
    GUI.EndClip();
    // ...
}

```
> 1 votes

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


title: Grid: Spreading temperature

text:
# Question
Title: Grid: Spreading temperature
I'm trying to spread temperature values evenly across the grid (Room) but somehow it has a bias to the right side of the map. My basic math skills are non existent so i could use some help with the following issue.

**Background Information**

I have a 2d array with the following data

```
public class HeatData
{
    public int x;
    public int y;
    public int radius;
    public double transferRate;
    public double dissipateRate;
    public double temperature;
}

```

I want to emit heat from certain tiles and spread them across the grid based on their set transfer / dissipation rates. Basically i'm adding temperature to a set of tiles and expect them to spread across the room. I have a method that gets all the surrounding neighbours and use that info in the following method.

```
private void TransferHeat()
{
    var newGridData = _grid.gridData;

    for (int x = 0; x < _grid.gridData.GetLength(0); x++)
    {
        for (int y = 0; y < _grid.gridData.GetLength(1); y++)
        {
            var data = _grid.GetData(new Vector2Int(x, y));

            var neighbours = _grid.GetNeighbours(data.position);

            foreach (var neighbour in neighbours)
            {
                var neighbourData = _grid.GetData(neighbour);

                var newData = HeatData.CleanCopy(data);
                var newNeighbourData = HeatData.CleanCopy(neighbourData);

                var difference = HeatValueForNeighbour(neighbourData, data);

                newData.temperature = data.temperature - difference;
                newNeighbourData.temperature = neighbourData.temperature + difference;

                newGridData[neighbour.x, neighbour.y] = newNeighbourData;
                newGridData[data.x, data.y] = newData;
            }
        }
    }

    foreach (var newData in newGridData)
    {
        _grid.SetData(newData.position, newData);
    }
}

```

```
private double HeatValueForNeighbour(HeatData neighbourData, HeatData data)
{
    var temperatureDifference = data.temperature - neighbourData.temperature;
    return temperatureDifference * data.transferRate;
}

```

The `CleanCopy` will copy the data into an new instance. I have been busting my brain for hours at this problem and i can't seem to figure out how to write it correctly. It seems like the temperature has a favour of spreading all the values to the right side of the map

# Answer
First, I'd make this `HeatData` type into a struct so you don't generate a tonne of garbage collection churn every time you do an iteration and spawn a fresh batch of them. This also means we no longer need a clean copy method - we get a copy just via assignment. `x` and `y` are implicit in their position in the grid, so we don't really need to store them.

```
public struct HeatData
{
    public int radius;
    public double transferRate;
    public double dissipateRate;
    public double temperature;
}

```

Similarly, if you want to use double buffering to separate a read-only and write-only copy of your data, keep both around: that way you don't incur allocation overhead or generate new garbage on every iteration by creating a new buffer.

```
public class grid {
    HeatData[,,] _grid;

    int _readIndex = 0;
    int _writeIndex { get { return 1 ^ _readIndex; } }

    bool IsInGridBounds(int x, int y) {
        return x >= 0 && y >= 0 && x < _grid.GetLength(1) && y < _grid.GetLength(2);
    }

    public HeatData GetData(int x, int y) {
        if (IsInGridBounds(x, y))
            return _grid[_readIndex, x, y];
        else
            return default;
    }

    public void SetData(int x, int y, HeatData data) {
        _grid[_writeIndex, x, y] = data;
    }

    public void FlipBuffers() {
        _readIndex = _writeIndex;
    }
}

```

Now we can clean up your loop a bit:

```
private void TransferHeat()
{
    for (int x = 0; x < _grid.gridData.GetLength(0); x++)
    {
        for (int y = 0; y < _grid.gridData.GetLength(1); y++)
        {
            // Implicitly copy since we made our type a struct.
            var data = _grid.GetData(x, y);

            var neighbours = _grid.GetNeighbours(data.position);

            foreach (var neighbour in neighbours)
            {
                // Also implicitly copy since we made our type a struct.
                var neighbourData = _grid.GetData(neighbour.x, neighbour.y);

                var difference = HeatValueForNeighbour(neighbourData, data);

                data.temperature = data.temperature - difference;
                // We don't update the neighbour's data here - we'll visit them
                // individually at some point in our loop.
            }

            // Write our new data to the write-only buffer.
            _grid.SetData(x, y, data);
        }
    }

    // Done writing. Make our write-only buffer the new read-only version.
    // We can do this by flipping one bit, without copying the whole array over.
    _grid.FlipBuffers();
}

```

Because we're only updating "this" node in each iteration, not the neighbouring nodes, you'd also want to update your heat transfer function to include information about both nodes' transfer rates - to ensure the transfer is symmetrical:

```
private double HeatValueForNeighbour(HeatData neighbourData, HeatData data)
{
    var temperatureDifference = data.temperature - neighbourData.temperature;
    // Depending on your conventions here, an average might be appropriate,
    // rather than a sum.
    return temperatureDifference * (data.transferRate + neighbourData.transferRate);
}

```

We do end up calling this function twice for each neighbouring pair A, B: once when A is "this" node and B is the neighbour, and a second time when B is "this" node and A is the neighbour. You can reduce this overhead by updating your `GetNeighbours` function to only enumerate "neighbours we haven't visited yet" and go back to updating both "this" node and its neighbours in the same pass. But then you need to read "this" node from the writable buffer, to ensure you carry forward data we wrote earlier in the iteration, and be sure to seed your starting node with the readable data.

Another technique you can use to mitigate the directional bias, if you don't want to use full double buffering, is to alternate your direction of iteration between subsequent frames. So in frame n you have a rightward bias, but in frame n+1 you have a leftward bias, and the two effects "mostly" cancel out, at half the memory cost.
> 2 votes

---
Tags: unity, c#, tilemap, grid
---


# Question
Title: How to write a shader that only uses a bump map without a normal map
So I understand that for best results one uses a height (or bump) map and a normal map together.

And I also understand that one can calculate a normal map from a height map using some sobel operator.

But out of curiosity I wonder how the first games that supported bump mapping did it.

I found this fragment shader code that seems to do it, but I am not sure: OpenGL Bump Map -- Texture artifacts ?

If the code above does exactly what I am looking for, can someone explain the line

`vec3 normalDirection = normalize(tangenteSpace*(texture2D( bump_tex, f_texcoord ).rgb*2.0 - 1.0));`

How can you get a normal from a bump ?
I understand what tangent space is mathematically but how does it work here ?
Is it a vec4 or a matrix ?

So basically my question is: How was bump mapping done without a normal map in the old days ?

# Answer
Bump mapping simulates surface displacement, i.e. the shader pretends that the pixel is further back along the surface normal than it actually is. It then compares the depth to the pixels next to it on the map, and so can establish a gradient, using pythagoras: if we know the difference in height, and the difference in pixels to the left/right/up/down/etc, then we can compute the slope in each direction. We can then use those slopes to calculate a new normal vector for that pixel. This involves several texture samples per pixel, in the sobel matrix you mentioned, and is indeed how it was done "back in the day".

For this reason, it is expensive, and sub-optimal, and in the case of blurred height maps, can led to artifacts like the ones you saw.

Normal mapping on the other hand, uses a normal map, pre-baked from a bump, or displacement ma, in exactly the same method as above. The difference is, that by doing it in advance, you save on at least 4-8 texture samples per pixel, in addition to not having to compute the slopes per pixel. Not having to do this FAR outweighs the cost of the matrix transformations from tangent to view space per pixel, making lighting much more efficient. This is how it is done in today's hardware, though tomorrow's graphics engine will likely use raytracing instead.
> 1 votes

# Answer
The code by Mikkelsen "Bump Mapping Unparametrized Surfaces on the GPU", suggested by Ray Hulha, is the right solution. However the listings are a bit fragmented in the paper.

Here is a complete solution for GLSL:

```
// Bump mapping
// from paper: Bump Mapping Unparametrized Surfaces on the GPU
vec3 vn = normalize( vnormal );
vec3 posDX = dFdx ( vworldpos.xyz );  // choose dFdx (#version 420) or dFdxFine (#version 450) here
vec3 posDY = dFdy ( vworldpos.xyz );
vec3 r1 = cross ( posDY, vn );
vec3 r2 = cross ( vn , posDX );
float det = dot (posDX , r1);
float Hll = texture( bumptex, tc ).x;    //-- height from bump map texture, tc=texture coordinates
float Hlr = texture( bumptex, tc + dFdx(vtexcoord.xy) ).x;
float Hul = texture( bumptex, tc + dFdy(vtexcoord.xy) ).x;
// float dBs = ddx_fine ( height );     //-- optional explicit height
// float dBt = ddy_fine ( height );

// gradient of surface texture. dBs=Hlr-Hll, dBt=Hul-Hll
vec3 surf_grad = sign(det) * ( (Hlr - Hll) * r1 + (Hul - Hll)* r2 );
float bump_amt = 0.7;       // bump_amt = adjustable bump amount
vec3 vbumpnorm = vn*(1.0-bump_amt) + bump_amt * normalize ( abs(det)*vn - surf_grad );  // bump normal

```

This code combines and simplifies the listings from the paper. I've also added the bump\_amt, which could be an adjustable uniform parameter to dial between the smooth and bump surface.

In terms of performance, this should work quite fast on modern GPUs. It also allows for procedural (dynamic) bump maps which you can't do with normal maps. If you are in a time-critical app like a game then the slowest part is the 3x texture fetches. This is exactly what normal maps improve on by baking the height texture into pre-separated surface derivatives, resulting in just one texture fetch.
> 2 votes

# Answer
I found some code that seems to solve this in three.js:

https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/bumpmap\_pars\_fragment.glsl.js

```
    vec2 dSTdx = dFdx( vUv );
    vec2 dSTdy = dFdy( vUv );
    float Hll = bumpScale * texture2D( bumpMap, vUv ).x;
    float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;
    float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;
    return vec2( dBx, dBy );

```

The code is based on this whitepaper: "Bump Mapping Unparametrized Surfaces on the GPU" by Morten S. Mikkelsen

http://jbit.net/~sparky/sfgrad\_bump/mm\_sfgrad\_bump.pdf
> 0 votes

---
Tags: glsl, normal-mapping, bump-map
---


title: Deceleration via Lerping

text:
# Question
Title: Deceleration via Lerping
I have written some code that creates a very nice uniform angular acceleration for an object moving around a circle. It effectively uses linear interpolation but ramps the interpolant such that the change is non-linear, hence the acceleration. The code is:

```
// Set the parameters to define the acceleration
float accelerationTime = 3f;
float startAngle = 0;
float endAngle = 180;
float currentAngle;
float startSpeed = 120;
float finalSpeed = 360;
float currentSpeed;
float radius = 3;

// Create the acceleration from 120 deg/s to 360 deg/s over a 180 degree angle within 3s
float t = 0;
accelFraction = 0;
Vector3 position;
while (accelFraction < 1f)
{
      t += Time.deltaTime;
      accelFraction = Mathf.Clamp(t / accelerationTime, 0, 1);
      currentSpeed = Mathf.Lerp(startSpeed, finalSpeed, accelFraction);
      float speedRatio = Mathf.Clamp(currentSpeed / finalSpeed, 0, 1);

      currentAngle = Mathf.Lerp(startAngle, endAngle, speedRatio * accelFraction);

      position = new Vector3(Mathf.Sin(currentAngle * Mathf.Deg2Rad), 0,
                             Mathf.Cos(currentAngle * Mathf.Deg2Rad)) * radius;
}

```

It allows me to accelerate from a start speed to an end speed, over a defined angular distance within a specific time. Great!

The problem is that I cannot figure out how to reverse this code to create the opposite effect, i.e. a deceleration. I have tried reversing the logic but it does not work, as counting downwards breaks the maths. Perhaps I am being obtuse but can anyone help here?

I would really like to keep my acceleration code the same; I suspect there is a simple tweak that I am missing. Any help is greatly appreciated!

# Answer
> 1 votes
I guess you *could* solve this problem mathematically. But I would solve this problem using an AnimationCurve instead. A very useful class which allows you to design things like ease-in and ease-out curves using a visual curve editor in the inspector.

My script:

```
public class Rotator : MonoBehaviour
{
    public float rotationDuration;
    public float startAngle;
    public float stopAngle;
    public AnimationCurve curve;

    private float currentRotationTime;

    void Update()
    {
        currentRotationTime += Time.deltaTime;
        var progress = curve.Evaluate(currentRotationTime / rotationDuration);
        var currentAngle = startAngle + (stopAngle - startAngle) * progress;

        transform.rotation = Quaternion.Euler(0f, 0f, currentAngle);
    }
}

```

(Instead of using that trigonometry logic of yours I am just rotating the object itself, but if you feed `currentAngle` into your code then it should work as expected)

How I drew the rotation curve in the inspector:

How it looks when I press play:

---
Tags: unity, physics, lerp
---


title: How screen scaling works in Unity?

text:
# Question
Title: How screen scaling works in Unity?
I created a very simple scene, to understand how screen scaling works in Unity. The scene has only a SpriteRenderer object and a TextMeshPro object - no Canvas or other UI elements. The TextMeshPro object is set to "Auto Size" (the SpriteRendered does not have such setting). Here is what happens when I change the screen size:

With a fixed aspect ratio, both the text and the sprite change their size, both when I change the height and when I change the width. But with a free aspect ratio, the text and the sprite change their size when I change the height, but NOT when I change the width.

This is quite confusing. What exactly would happen when I run the games on real screens - would the text and image scale appropriately? If not, what should I do in order to ensure that the text and image always scale?

NOTE: When I uncheck the "Auto Size" setting of the TextMeshPro, I get exactly the same behavior. So I am not sure why it is needed.

# Answer
> 3 votes
By default, Unity scales the camera *view* of your 3D world to **fit the height of the window**. That simple rule is the only thing happening in both of your examples:

* When you've fixed the aspect ratio of the window, changing the width of the window *also changes the height* of the window to match, and changing the height changes the scale of the game view.
* When you have a free/unconstrained aspect, changing the width of the window *does not* change the height of the window. Because the height of the window stays the same, the scale of your game view also stays the same.

Note that this is only a change in the **projection** mapping between the game world and the screen pixels. Your world itself - from the perspective of your code or any entities living in the game world - is still the same size. Mario doesn't have to work harder to jump higher when you play on a 1080p screen instead of 240p. We've just scaled the rendered output to cover more screen pixels.

That's why the text option `AutoSize` doesn't do anything when you change the window size. Its job is to fit the point size of the text to the world size of the text box. Because changing your view does not alter the underlying world, that text box still has exactly the same dimensions inside the game world, and there's no change for `AutoSize` to adapt to.

If you'd like to customize the scaling behaviour, you can do that with a script.

You can also get a variety of easy-to-use scaling modes if you use the UI system (so, a `Canvas` object with `Image` and `TextMeshProUGUI` children, not `SpriteRenderer` and `TextMeshPro`). This system is designed to support flexible layouts to adapt to different screen resolutions, with lots of configuration options to control exactly how you want your layout to adapt.

---
Tags: unity, scale, screen
---


# Question
Title: Determine when a character is stationary, and which direction they are facing
I'm currently trying to figure out two things for my character's movement and animation.

1. A better/faster way to track when movement stops than the IsSleeping method.
2. A way to track which direction my character is facing to send this information to the animator.

Here is the code I'm currently using for movement and sending information to the animator:

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

public class KittenController2 : MonoBehaviour
{
    Rigidbody2D rb;
    Animator ani;

    public float speed;
    public float jumpForce;

    private float direction = 0f;

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

    // Update is called once per frame
    void Update()
    {
        direction = Input.GetAxis("Horizontal");
        ani.SetBool("Stationary", rb.IsSleeping());

        if (direction > 0f)
        {
            rb.velocity = new Vector2(direction * speed, rb.velocity.y);
            ani.SetFloat("Move X", direction);
        }
        else if (direction < 0f)
        {
            rb.velocity = new Vector2(direction * speed, rb.velocity.y);
            ani.SetFloat("Move X", direction);
        }
        else
        {
            rb.velocity = new Vector2(0, rb.velocity.y);
        }

        if (Input.GetKeyDown(KeyCode.Space))
        {
            Jump();
        }
    }

    void FixedUpdate()
    {

    }

    void Jump()
    {
        rb.AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
        ani.SetTrigger("Jump");
    }
}

```

# Answer
Thanks for the input from everyone here. I managed to find a good solution to this that updates almost instantly.

Before any of the functions:

```
public float stationaryThreshold;
private float squaredStationaryThreshold;

```

Inside functions:

```
void Awake()
    {
        squaredStationaryThreshold = stationaryThreshold * stationaryThreshold;
    }

void Update()
    {
        ani.SetBool("Stationary", rb.velocity.sqrMagnitude <= squaredStationaryThreshold);
    }

```

This checks whether the square root of the movement velocity's magnitude is less than or equal to the square root of whatever the stationary threshold is set to.

I then have this communicating with the animator to achieve my goal, changing the animation from moving to idle as soon as the character stops moving.
> 1 votes

---
Tags: unity, c#, 2d, animation, character-controller
---


# Question
Title: Find the smallest angle to turn between two angles in range 0..1
I have a function for approaching a value to a target by a certain amount:

```
function appr(value, target, by)
  return value < target and min(target, value + target) or max(target, value - target)
end

```

I have an `angle` between `0..1` range, and a `target angle`.

How can I approach this angle to the target by smallest of the turns.

So these tests shall pass:

```
lrun('test1', function()

  lfequal(appra(0, 0.2, 0.1), 0.1)

  lfequal(appra(0, 0, 0.1), 0.0)
  lfequal(appra(0.5, 0.5, 0.1), 0.5)
  lfequal(appra(0.5, 0.55, 0.1), 0.55)

  lfequal(appra(0, 0.5, 0.1), 0.9)
  lfequal(appra(0, 0.4, 0.1), 0.9)
  lfequal(appra(0.3, 0.4, 0.1), 0.2)
  lfequal(appra(0, 0.6, 0.1), 0.9)
  lfequal(appra(0.1, 0.9, 0.1), 0.0)
end)

```

I tried this but it fails on the first test case.

```
function appra(value, target, by)
  local diff = (target - value + 0.5) % 1 - 0.5
  if math.abs(diff) < by then return target end
  return diff < -0.5 and value + by or (value - by + 1) % 1
end

```

# Answer
> 1 votes
## wrap\_value

We are going to start by defining `wrap_value`, because are going to need it:

```
function wrap_value(value, from, to)
    local range = to - from
    return value - (range * math.floor((value - from) / range));
end

```

This function takes a value and wraps it in a range. As if you had gone past one end of the range and entered by the opposite one. For example `wrap_value(14, 0, 10)` is `4`, and `wrap_value(-4, 0, 10)` is `6`.

---

This formula is very similar to the generalization of `mod` (remainder) to the real numbers:

```
value - size * math.floor(value / size)

```

There we are figuring out how many times `size` fits in `value` (`value / size`). Except we want an integer number of times (`math.floor(value / size)`), and we subtract it from `value` so that `value` is not bigger than `size`. *It also works with negatives.*

The above formula is similar to `math.fmod`, except without preserving the sign. To be more precise, it differs from `math.fmod` in that the result always have the same sign as `size`.

*By the way, if you make `size` equal to `1`, you get a formula for the fractional part (and unlike `math.modf` the result is always positive, it gives you the fractional part towards zero).*

Now, if we don't want a number between `0` and `size`, but a number in some range from `a` to `b`, we still need to know how many times `value` fits in the size of the range, so we are dividing `b - a`. And thus we are also multiplying by `b - a`. The only difference is that we need to offset the `value` when we divide it:

```
value - (b - a) * math.floor((value - a) / (b - a))

```

Note that when `a` is `0`, we have the same formula from before.

---

## angle\_diff

Now we can define a function to get the short difference between angles:

```
half_turn = 0.5;

function angle_diff(from, to)
    return wrap_value(to - from, -half_turn, half_turn)
end

```

*I believe you said the angles are in the range from `0` to `1`, meaning half turn is `0.5`. Otherwise you can put `pi` if you are using radians, or `180` if you are using degrees or whatever.*

What we are doing here is wrapping the difference of the angles (`to - from`) in the range from `-half_turn` to `half_turn`. That gives us the shortest way to turn from one to the other (it is as much half turn one way or the other).

---

## appr

And if you want to move one angle towards the other without overshooting, you would be doing this:

```
function appra(value, target, by)
    local diff = angle_diff(value, target)
    local sign = (diff > 0 and 1 or -1)
    local offset = math.min(math.abs(by), math.abs(diff)) * sign
    return value + offset
end

```

Here I have separated the sign and the magnitud (absolute value) of `diff`. And that magnitud is by how much we can vary the value without overshooting. So we use it constraint the magnitud you want to vary by, then we apply the sign so it is turning in the correct direction.

---

Except that fails your tests. You want to wrap the result:

```
full_turn = 2.0 * half_turn;

function appra(value, target, by)
    local diff = angle_diff(value, target)
    local sign = (diff > 0 and 1 or -1)
    local offset = math.min(math.abs(by), math.abs(diff)) * sign
    return wrap_value(value + offset, 0, full_turn)
end

```

---

## Those tests…

That code above… It does not pass your tests. Except I blame the tests. Here:

```
  lfequal(appra(0, 0.4, 0.1), 0.9)

```

If we are at `0` and going towards `0.4`, it should be shorter to increase (it is at a distance of `0.4`) than to decrease (it is at a distance of `0.6`). Thus, advancing `0.1` from `0` towards `0.4` should bring the value to `0.1` not `0.9`.

Similarly, here:

```
  lfequal(appra(0.3, 0.4, 0.1), 0.2)

```

If we are at `0.3` and going towards `0.4`, it should be shorter to increase (it is at a distance of `0.1`) than to decrease (it is at a distance of `0.9`). Thus, advancing `0.1` from `0.3` towards `0.4` should bring the value to `0.4` (which, by the way, is the goal) not `0.2`.

---
Tags: mathematics, lua, pico-8
---


# Question
Title: How to evaluate a binary expression tree in HLSL without recursion or a stack?
I'm currently working on a dual contouring implementation for which I want to create procedural terrain based on layers of noise. Both, the terrain generation and the mesh creation via dual contouring run on the GPU in compute shaders.

For configurating the terrain generation I previously changed the specific compute shader's source code itself to generate different layers of FBM noise and combine them with various CSG operations (e.g. union, intersection, difference) to arrive at the final terrain. But this offers very little flexibility, e.g. I cannot change the terrain generation at runtime.

So in order to get more flexibility for configuring the terrain generation, I've started implementing a graph tool (similiar to ShaderLab) using XNode:  *Red (leaf) nodes are operands, grey (internal) nodes are operators (either binary or unary) and the green (root) node is simple the output node. On the GPU side each operator (internal node) equals a function, e.g. a function that creates the output of the noise node.*

The idea is that I can visually create a binary expression tree (with additional unary operators), upload it to the GPU using a `StructuredBuffer<NoiseGraphNode>` where `NoiseGraphNode` is

```
struct NoiseGraphNode
{
    uint leftNodeIndex;
    uint rightNodeIndex;
    uint nodeType;
    uint dataIndex;         // Index used in conjunction with nodeType
                            // to access a node's data located in a
                            // nodeType-specific StructuredBuffer, e.g.
                            // the noise parameters in case of a noise node.
};

```

and have that graph evaluated by the GPU's compute shader for generating the noise that represents the final terrain. Normally such a graph would be evaluated using a recursive approach, something like:

```
evaluate(node) {
     if(node has children){
          left_val = evaluate(node->left);
          right_val = evaluate(node->right);

          // find operation symbol for node and use it as
          // val = left_val operation right_val

          return val;
     }
     else {
          return node_value;
     }
}

```

*Pseudo-code taken from https://stackoverflow.com/questions/10769174/evaluating-expression-trees.*

HLSL doesn't support recursion though! Another way would be to emulate the recursive implementation using a stack and a while loop (after all recursion is leveraging the call stack). But creating a stack structure in HLSL like so

```
struct NoiseGraphStack
{
    uint buffer[20];
    uint count;

    void Push(uint number)
    {
        buffer[count++] = number;   // Doesn't work because an array reference
                                    // cannot be used as an l-value.
    }

    float Pop()
    {
        return buffer[--count];
    }

    static NoiseGraphStack Create()
    {
        NoiseGraphStack stack;
        stack.count = 0;

        return stack;
    }
};

```

doesn't work either because it requires the while loop to be unrolled which isn't possible.

**Note:** The exact error message referred to in the code above is "array reference cannot be used as an l-value; not natively addressable, forcing loop to unroll."

So is it possible to evaluate a binary expression tree without recursion or a stack? Can I perhaps somehow preprocess the necessary steps for evaluating such a tree on the CPU (where I can use recursion just fine) first and linearize them before I send them to the GPU?

# Answer
Alright, I didn't manage to evaluate the binary expression tree without a stack entirely. I do need a stack but the stack capacity only has to be 2 elements in order to evaluate any binary expression tree (regardless how large). At least I think that's true, I didn't formally proof it...

I basically do two things:

1. Before I upload the tree to the GPU, I traverse it in preorder on the CPU using recursion.
2. I then upload the tree to the GPU in the traversed order. Now the GPU can simply iterate over each node in the uploaded node buffer and (using the stack mentioned initially) compute the final output.

Here's an example tree with some annotations and the GPU side algorithm for clarity:

The data for each node, e.g. the noise parameters of a noise node, are uploaded in separate buffers. My HLSL node struct looks like this:

```
struct NoiseGraphNode
{
    uint nodeType;
    uint dataIndex;
};

```

The `nodeType` of each node is used in conjunction with the `dataIndex` to choose the correct buffer and index into it.

Finally, my HLSL stack struct looks like this:

```
struct NoiseGraphStack
{
    float4 buffer[2];
    uint count;

    void Push(float4 value_gradient)
    {
        [branch]
        switch(count++)
        {
            case 0:
                buffer[0] = value_gradient;
                break;

            default:
                buffer[1] = value_gradient;
                break;
        }
    }

    void Push(float3 position)
    {
        Push(float4(position, 0.0f));
    }

    float4 Pop()
    {
        return buffer[--count];
    }

    static NoiseGraphStack Create()
    {
        NoiseGraphStack stack;
        stack.count = 0;

        return stack;
    }
};

```

**Note:** I'm using a switch case for pushing because that avoids the l-value issue mentioned in the original question.

One thing I noticed (through trial and error) is that I needed to tag certain branches in my code with the `[branch]` attribute in order for my code to compile. Without that attribute Unity threw the following error during compilation of the compute shader:

Plaintext for people googling the error message: `Shader error in 'VoxelVolume': Compilation failed for kernel 'GenerateVoxelVolume' [0x80004005 - unknown error] 'internal error: no storage type for block output`

**Note:** I'm still using a lot of branching to compute the output of the graph on the GPU but, as far as I understand, that shouldn't be a problem because the branching is based on data that is identical to all threads in a warp, meaning no branch divergence will occur.
> 2 votes

# Answer
When implementing something similar, only with post order traversal (evaluation of mathematical structures for ray marching), i encountered the same error with "array reference cannot be used as an l-value; not natively addressable".
Since for postorder traversal you need a stack with size about equal to the height of the tree, i could not use your solution of using a switch case for accessing, but i noticed that using not a global array as the stack but declaring the stack in a function does the trick and will not force the loop to unroll.
> 1 votes

---
Tags: unity, hlsl, tree, compute-shader, gpgpu
---


# Question
Title: Spawn crops/3D game objects randomly on a mesh/plane surface
I am stuck on a problem that might be quite simple yet it's getting on my nerves. I want to spawn crops on different plane shapes like in the attached screenshot.

So far my progress is that I am able to spawn crops with random distance with a certain number of rows and columns.

```
[ContextMenu("Generate Field")]
public void GenerateField()
    {
        GameObject wheatField = new GameObject();
        wheatField.transform.position = transform.position;
        int counter = 0;
        for(int i = 0; i < rows; i++)
        {
            for (int j = 0; j < column; j++)
            {
                xDelta = Random.Range(0.4f, 0.5f);
                yDelta = Random.Range(0.4f, 0.6f);
                float yPos = Random.Range(-0.25f, 0.25f);
                GameObject tempWheat = Instantiate(wheatPrefab, new Vector3(xDelta * i, 0, yDelta * j), Quaternion.identity
                    ,wheatField.transform);
                counter++;
            }
        }
        Debug.Log("TOTAL CROPS PLACED = " + counter);
    }

```

I want to do this in editor time, not runtime.

Below is the sample mesh I have where Orange, White, and Green are separate meshes.

# Answer
> 1 votes
You can use **rejection sampling** for this.

Iterate over the area covered by the mesh's bounding box, placing your rows of crops.

Each time you try to place a plant, using code similar to what you have now, first check to see whether it's on top of the mesh. You could do this by...

* Adding a `MeshCollider`, and calling `ClosestPoint` to snap the randomized crop position to a point on the mesh shape. If the snapped point is farther from your randomly chosen point than a threshold you set, consider this "outside" the mesh and skip to the next row/column cell.
* Iterating over the triangles of the mesh, and checking whether your (x,z) point is inside any of those triangles, using conventional point-in-triangle tests. If the point is not on any triangles, skip to the next row/column cell.

You can accelerate this check with a spatial partition if needed, but for low-poly shapes like you've shown in your example that optmization might not be necessary.

---
Tags: unity, 3d, random, spawning
---


# Question
Title: How can I check how long the player has been playing for?
How can I check how long the player has been playing for in Unity?

# Answer
> 0 votes
To know how long the game has been running in wall time as of the start of the current frame, you can use `Time.unscaledTime`. As described in the documentation, this gives:

> The timeScale-independent time for this frame (Read Only). This is the time in seconds since the start of the game.

Because this is unaffected by `timeScale`, it won't distort your real-world time measurement if you have slow-mo effects in your game, or if performance problems cause your game simulation to lag. It will also count time spent while the game is paused with `timeScale = 0`, if that's something used in your game.

To check whether 30 seconds have passed, you can write:

```
bool _thirtySecondsPassed = false;

void Update() {
    if (_thirtySecondsPassed == false && Time.unscaledTime >= 30f) {
        Debug.Log("Thirty seconds have passed.");
        _thirtySecondsPassed = true;
    }
}

```

Here the boolean member variable ensures you print the message just once, not every future frame after the initial 30 seconds are up.

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


# Question
Title: Can I always assume that fixed time step in Unity is reliable?
I was thinking about games on low end machines or phones where the CPU would be limited. If I were to move all of my game logic into `FixedUpdate()` can I assume that it will always be called with the same time delta? Or would it still be worth adding code to make it take the actual time delta into account?

# Answer
I've done some tests simulating low framerate conditions, and empirically confirmed that **the `deltaTime` value for each FixedUpdate step does indeed stay consistent.**

For example, using the default `Fixed TimeStep` of 0.02 (50 Hz) and `Maximum Allowed Timestep` of 0.3333333 (as set in `Edit -> Project Settings -> Time`)...

* At 60 fps we get 0-1 physics & FixedUpdate steps per frame
* At 30 fps we get 1-2 physics & FixedUpdate steps per frame
* At 15 fps we get 3-4 physics & FixedUpdate steps per frame
* At 3 fps we get 16-17 physics & FixedUpdate steps per frame, **and we hit the max allowed timestep**
* For any lower framerate, Unity clamps the real time elapsed to 0.33333, so we continue to get just 17 physics & FixedUpdate steps per frame

Throughout the whole spectrum, **every call to FixedUpdate gets the same `deltaTime` value of 0.02**. The variability in timing is handled solely by running more or fewer iterations, not by scaling the `deltaTime` value - exactly as we should expect for a "fixed" timestep.

As shown above, when the framerate is extremely low, Unity will limit the amount of time by which it advances the game simulation, capping at 17 FixedUpdate iterations with the default settings.

So, if you want to know that the *game time* represented by each FixedUpdate iteration remains the same, the answer is **yes** (as long as you don't assign a new value to `Time.fixedDeltaTime` directly)

If you want to know whether the *realtime* interval represented by each FixedUpdate iteration remains the same, the answer is **no** \- at extremely low framerates, Unity will cap the number of FixedUpdate steps, allowing game time to run slower than realtime. Also, as noted in a comment above, all the physics steps and FixedUpdates for a given frame occur back-to-back at the beginning of the frame's execution, not evenly distributed in realtime like a metronome.

---

In doing this test, I learned some interesting things about how Unity handles `Time.timeScale`:

* Slowing/speeding game time with `timeScale` does not modify the `deltaTime` of each call to FixedUpdate - you'll just get fewer or more steps in a given frame, again as we should expect from a fixed timestep.

If you want to increase physics time resolution when running in slowmo, modify `Time.fixedDeltaTime` when going in & out of the time warp.
* The enforcement of `Maximum Allowed Timestep` occurs *before* multiplying by timeScale. So if I use `Time.timeScale = 0.5f` to slow the game by half, the maximum `deltaTime` I'll see in Update will be 0.16666666 instead of 0.33333333
> 8 votes

# Answer
So a few years later I stumble upon this article johnaustin.io where someone has an answer to something very similar to what I was wondering about.

> # Is FixedUpdate always called every 0.02 seconds?
>
> No, FixedUpdate will run once for every 0.02 game-time seconds, but precisely when in real time this happens is unspecified and can vary drastically. See above: “A Heavy Load in FixedUpdate”.
>
> # How does the Unity timestep respond to low framerates?
>
> Depending on the source of the slowness, it will do different things. For slow \>FixedUpdates, it slows down the overall game-time (the game will run for 0.5 seconds in the span of one real time second). In some cases, the rendering rate can be drastically cut, even if the problem is your FixedUpdate speed.
>
> For slow Updates, FixedUpdates get crunched together during the “catch up” phase between the longer Updates. Otherwise, generally the the Update dynamic timestep just gets longer.

It's a really good read and worth checking out the article to get more information about the fixed update cycle.
> 0 votes

---
Tags: unity, game-loop, timestep, fixed-timestep
---


# Question
Title: OpenGL - How come drawing sprites takes so much performance
I'm wondering how drawing simple geometry with textures can eat up so much performance (below 60fps)? Even my good graphics card (GTX 960) can "only" draw up to 1000 sprites smoothly. The textures I'm using are all power of 2 textures and don't exceed a size of 512x512. I'm even filtering with `GL_NEAREST` only.
The sprites themself are random generated in size. So there are no 1000 fullscreen quads, which would be no real use case.

I'm drawing my sprites batched, meaning I have one dynamic vertex buffer and a static index buffer. I update the vertex buffer every frame with `glBufferSubData` once and then draw everything with \`\`glDrawElements\`. I have about 5 different textures which I bind once per frame resulting in 5 draw calls. For rendering I'm using only one shader which is bound once the application starts.
So I have 5 texture bindings, 5 draw calls, and one vertex buffer update per frame which is not really that much.

Here is an example with one texture:

```
val shaderProgram = ShaderProgram("assets/default.vert", "assets/default.frag")
val texture = Texture("assets/logo.png")
val sprite = BufferSprite(texture)
val batch = BufferSpriteBatch()

val projView = Matrix4f().identity().ortho2D(0f, 640f, 0f, 480f)

fun setup() {
    glEnable(GL_TEXTURE)
    //glColorMask(true, true, true, true)
    //glDepthMask(false)

    glUseProgram(shaderProgram.program)
    texture.bind()

    batch.begin()
        for(i in 1..1000)
            batch.draw(sprite)
    batch.update()
}

fun render() {
    glClear(GL_COLOR_BUFFER_BIT)

    stackPush().use { stack ->
        val mat = stack.mallocFloat(16)
        projView.get(mat)
        val loc = glGetUniformLocation(shaderProgram.program, "u_projView")
        glUniformMatrix4fv(loc, false, mat)

        batch.flush()
    }

}

```

The `batch.draw()` method puts the sprites vertex data in a cpu side buffer and `batch.update()` uploads everything to the gpu with `glBufferSubData`. And setting up the spritebatch looks as follows:

```
glBindBuffer(GL_ARRAY_BUFFER, tmpVbo)
            glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW)
            glEnableVertexAttribArray(0)
            glEnableVertexAttribArray(1)
            glEnableVertexAttribArray(2)
            glVertexAttribPointer(0, 2, GL_FLOAT, false, 24 * sizeof(Float), 0)
            glVertexAttribPointer(1, 4, GL_FLOAT, false, 24 * sizeof(Float), 2.toLong() * sizeof(Float))
            glVertexAttribPointer(2, 2, GL_FLOAT, false, 24 * sizeof(Float), 6.toLong() * sizeof(Float))

            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpEbo)
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)

```

I was profiling my program first, but updating the vertex buffers and all the geometry takes about 10% of the total time per frame. But swapping the buffers takes up the rest of the 90% frame time.

So I'm asking, how can such big AAA games render their scenes with millions of vertices, if drawing pixels is such a time consuming task? I know that their is a lot of optimizations in the code, but still.

# Answer
Your GPU can probably render even 100k sprites without issues, but you need to do it smart. Sprites and other geometry must be supplied to a GPU in batches grouped by the same texture, shader and blend mode.

Big AAA games are minimizing draw calls issued to the GPU. Draw calls are usually expensive, so many similar drawing operations are grouped together and send to GPU in batches. Each new shader, texture or blend mode change during rendering results in a separate draw call. Also Texture atlases are used to reduce draw calls (many images on a single texture).
> 17 votes

# Answer
The way you are batching your sprites might be suboptimal. If you're using `glDrawElements()` to render a batch of multiple sprites, then that can only mean you're storing 4 vertices per quad in your VBO (otherwise I fail to see how `glDrawElements()` alone could render several sprites at once. I might be wrong, in which case feel free to correct me).

The right solution also depends on your use case - it isn't necessarily the same for a particle system vs. general 2D rendering for a game.

The thing is : we don't need indices, and we don't need to store 4 vertex positions per quad either.
By using less memory, we would reduce the amount of data to update per frame, and reduce the number of memory accesses, which should be assumed to be slow.

What I would do is Instanced Rendering.
Basically, your problem can be described as rendering a single quad mesh, but 1000 times with different settings each (including transforms and necessary information for texture lookups).
Also, if you know that your quads always face the screen, you can even afford to send less information to the GPU (eg. positions as vec2, rotations as a single float, etc).

Here's a very very rough pseudocode for instanced rendering. In-depth tutorials and explanations of this technique are widely available and I highly recommend looking some up.

```

// When setting up attrib pointers.
// See https://www.khronos.org/opengl/wiki/Vertex_Specification#Instanced_arrays
glVertexAttribDivisor(attribQuadCenter, 1);
glVertexAttribDivisor(attribQuadScale, 1);
glVertexAttribDivisor(attribTextureUnit, 1);
glVertexAttribPointer(attribQuadCenter, ....);
glVertexAttribPointer(attribQuadScale, ....);
glVertexAttribIPointer(attribTextureUnit, .....);

glBufferSubData(...) // Supply all positions, scales and texture unit values.

// Rendering
for(int i=0 ; i<5 ; ++i) {
    glActiveTexture(GL_TEXTURE0 + i);
    glBindTexture(GL_TEXTURE_2D, textures[i]);
}
// Render absolutely all sprites in a single draw call.
glBindVertexArray(quad_vao);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1000);

```

Another technique you could look into is Point Sprites.
Point Sprites involve "drawing" a single vertex per sprite; each vertex then gets expanded into a screen-space quad, and you can tweak its appearance using the fragment shader, given normalized coordinates within that quad (eg. perform texture lookups).
The size of the screen-space quad can be written to in the vertex shader (where you could also divide it by z), as explained in the linked article.

A bunch of other things to try and profile :

* Try toggling the depth test. If you can afford to, enabling it should give you a boost.
* Consider culling large sprites that can't be seen by the camera. However, I suspect this is not worth doing unless you work with more that 10k sprites or so.
* Calling glBufferSubData() every frame for updating data for every sprite is likely to be slow and scale poorly; Memory transfers from the CPU to the GPU are costly, which is why we now have vertex buffers instead of the old fixed function pipeline.
If your use case lends itself to it, you might want to use a Compute Shader to update the VBO directly using the GPU (this is a bit more involved and there are great online resources that would explain this better than I could).
> 2 votes

# Answer
I suspect your problem is fill rate. In general, you can test this theory by changing your resolution... If the performance changed correspondent to your new resolution, you are fill bound. If it doesn't change (or not much, anyway), you're vertex bound.
> 0 votes

---
Tags: opengl, game-loop, vertex-buffer, draw-order, profiling
---


# Question
Title: HIGH energy consumption in Empty Scene Unity iOS
I am struggling from quite long about this issue where I am having High Energy Impact in **Unity 2019.2.16f1** on iOS platform and it doesn't matter which device I am using. It occurs on iPhone6 to iPhoneX also I tried in an empty scene and checked stats through xCode and still bar is in Very High. Can someone explain to me what is going on? because of this device gets heat up quickly.

Below are stats with empty scene.

I have tried following still Very High:

* Framerate to 30
* SetResolution to 720 x 1080
* Compressing Textures
* Multi-threaded Rendering enabled and disabled
* Auto Graphics API turned on and off in player setting

Though I am making game and I don't want to set resolution too low or to compress textures, I want as much attractive graphics as unity can offer.

Also is this estimation of GPU Utilization calculated on based on total capacity of GPU vs how much the app is taking at the moment? I am totally blocked here and I need to improve energy impact of my app.

# Answer
**I am constantly updating this answer, I will remove this message when I have stopped.**

There is no magic bullet that will make it work right out of the box. It's a series of steps required to achieve good results.

Even though Unity is game engine, it can be used for many different purposes. It's very convenient to use Unity for mobile development or other PC applications.

> Maxing out a device’s capabilities can quickly compromise your game’s performance by overtaxing the hardware, which leads to throttling, poor battery life, and inconsistent performance.

To decrease energy consumption of the application we need to make it do less, and that includes increasing it's performance as well, as we don't want to compute unnecessary things and make CPU, GPU, etc. to consume power.

There are lots of optimizations you could try to achieve a sufficient result.

If you need to get started on performance optimizations then this is a great place to start - Unite Europe 2017 - Performance optimization for beginners.

1. First that comes to mind is on demand rendering. From provided stats I can see that 55.6% comes from GPU which is mostly responsible for drawing a frame. We want to reduce number of frames drawn per second to as low as possible. Usually good mobile frameworks work on events, they redraw and animate only things that are visible and only when something is happening on the screen, if a picture is static - there is no need to redraw it thus lowering energy consumption.

Rendering.OnDemandRendering \- this feature appears to be available starting from `2019.3`.

You can also control framerate using Application.targetFrameRate.

> Additionally if the QualitySettings.vSyncCount property is set, the targetFrameRate will be ignored and instead the game will use the vSyncCount and the platform's default render rate to determine the target frame rate. For example, if the platform's default render rate is 60 frames per second and vSyncCount is set to 2, the game will target 30 frames per second.

To use it - you need to set `vSyncCount` to `Don't Sync` (?)\[which I *believe* is an enum with a value of `0`. That is why `QualitySettings.vSyncCount = 2` is mentioned in the documentation\].

**Note:** *changing target frame-rate affects input. To have frame-rate independent input - use New Input System that should be coming out of beta in `2020.1` \[from experience, it's still in preview but is already pretty stable\].*

2. Limit processing on GPU to the minimum.

* Less heavy shaders.
    * Faster renderers like Universal Render Pipeline, you can even write your own Render Pipeline to include only the things you need in rendering.
3. Limit processing on CPU to the minimum.

* Write optimized code.
    * DOTS (?)\[not sure about this one, but my intuition says it is faster == less processing == lower power consumption\].
    * Remove any packages you don't need (4) that use CPU.
4. In `Package Manager` window you can remove lot's of packages that might be used by default. There you can select `Built-in packages` and remove lots of things like `Physics` for example, if you don't use any 3D physics in your application etc.
5. If you are using `UI` in the canvas it tends to redraw often. When layout is changed it redraws a whole `Canvas`. You can make use of shaders to manipulate some visuals to remove this dependency, or draw a `Canvas` yourself. **\[I will elaborate on this later, it's a big topic and I am short on the time right now. I am not sure if this was fixed or not, so I will have to do more research and post some code examples maybe if they will be a fit.\]**
6. Overhead. The link has lots of useful information about overhead in Unity. Unity profiler in general does better job in giving information about processes that run in Unity. During comprehensive optimization I recommend using `Deep Profile` in `Profiler` window in Unity.

> In the Profiler, the Overhead is the total frame time minus the duration of everything else that is actively measured. It is usually related to the internal processing of the scene. The more complex the scene, the more Overhead it will produce. It also accounts for the vertical synchronization that can be set to a fixed duration with Application.targetFrameRate.
>
> The complexity of the scene does not refer directly to the amount of objects that compose it, but to the processing in general. If you have lots of objects, processing all of them will take more time than just a few. More importantly, the different engine sub-system tasks on those objects (in this case, tasks that are not being actively measured in the Profiler) will be added to this complexity, increasing the Overhead. Depending on the work performed, this increase could be significant or not. This means that it is not possible for us to provide statistics on the complexity of the scene since it depends on many factors.
>
> The Profiler's hierarchy is populated with the processes that are most likely to consume important resources, but lots of hidden tasks will still remain. In order to find what is adding more complexity, or processing to the scene, you could remove or change "aspects" of the scene one by one, then profile and see how that affects the Overhead.
>
> "Aspects" refers to the groups of objects that are processed by some sub-systems, that is 3D or 2D physics, navmesh, sprites, lighting, scripts and plugins, rendering, GUI, audio, video or particles, etc. The aspects could include settings used by the sub-systems. You might find one of these is considerably affecting the performance, and then you can optimize it.

---

There is a lot of information that I cannot fit in one post or even describe how it works in detail. So for further readings I have gathered some useful links:

Text:

Video:
> 3 votes

# Answer
Unity is a game engine.

By default it tries to make the most out of system resources to run games by the best possible quality. So, that is true that Unity and also other game engines have a strong impact on energy.

This said, I think if you want to optimize your game for minimal energy consumption, you need to measure it, and compare it to similar games. You can expect similar games to have comparably high energy consumption too.

Just don't worry about the energy impact in an empty scene. After you start to create your game, there is a lot you can do to optimize energy consumption. But generally, games are expected to consume more energy.
> 1 votes

# Answer
Delete all packages which you are not using, including a ton of Unity default packages. After deleted more than 10 packages, my project's energy impact decreased for around 1 / 3! I guess deleting unused assets like scripts and 3D models will also help.

It seems that even though your scene is empty, the packages and assets in your Unity project still consumes a lot of power, which is ridiculous.
> 0 votes

---
Tags: unity, ios, optimization
---


title: Can anyone explain this code? C# Unity

text:
# Question
Title: Can anyone explain this code? C# Unity
Can someone explain this code to me?

```
using UnityEngine;
using TMPro;

public class WinScreen : MonoBehaviour
{
    public TextMeshProUGUI MovesMadeCounter;
    public TextMeshProUGUI timePlayed;
    public GameObject winScreen;

    private void Update()
    {
        if (winScreen.activeInHierarchy == true)
        {
            Timer.instance.Finish();

            if (Time.time > 30f)
            {
                UserInput.instance.score += (int)(700000 / Time.time % 60);
            }

            Time.timeScale = 0f;
        }

        MovesMadeCounter.text = "Moves Made: " + MovesMade.instance.movesMade;
        timePlayed.text = "Time Played: " + Timer.instance.TimerText.text;
    }
}

```

Here is the script for the `Timer` script:

```
using UnityEngine;
using TMPro;

public class Timer : MonoBehaviour
{
    public static Timer instance;

    public TextMeshProUGUI TimerText;
    private float startTime;
    public bool finished = false;

    private void Start()
    {
        instance = this;

        startTime = Time.time;
    }

    private void Update()
    {
        if (finished == false)
        {
            float time = Time.time - startTime;

            string minutes = ((int)time / 60).ToString();
            string seconds = (time % 60).ToString("f0");

            TimerText.text = minutes + ":" + seconds;
        }
        else
        {
            Time.timeScale = 0f;
        }
    }

    public void Finish()
    {
        finished = true;
    }
}

```

This is for my solitaire game. I kinda know what the code means and does but I just want to double check.

# Answer
```
using UnityEngine;
using TMPro;

public class WinScreen : MonoBehaviour
{
    //reference to a TextMeshPro UI Text Field
    public TextMeshProUGUI MovesMadeCounter;
    //reference to a TextMeshPro UI Text Field
    public TextMeshProUGUI timePlayed;
    //reference to a GameObject on a canvas presumably showing the win screen UI.
    public GameObject winScreen;

    private void Update()
    {
        //if the winScreen is active in the scene
        if (winScreen.activeInHierarchy == true)
        {
            //Access the instance for the Timer singleton and stop the timing, again presumably.
            Timer.instance.Finish();

            //If the time since the application has started exceeds 30 seconds
            if (Time.time > 30f)
            {
                //increment the users score in the UserInput singleton by thre result of (700000 / Time since application start modulous 60)
                UserInput.instance.score += (int)(700000 / Time.time % 60);
            }

            //reduce the time scale of the game to zero, effectively hard "pausing" it
            Time.timeScale = 0f;
        }

        //update the text fields for the two referenced TextMeshPro UI Text Fields
        MovesMadeCounter.text = "Moves Made: " + MovesMade.instance.movesMade;
        timePlayed.text = "Time Played: " + Timer.instance.TimerText.text;
    }
}

```

Here is how I would interpet it, as Philipp said in his comment this kind of "how long do you want the piece of string" situation. And this is all assuming the method names mean what *i* think they mean, since I cannot see the implementation of them.
> 0 votes

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


# Question
Title: How to add random offset to sine time in Unity's Shader Graph?
I have created a shader using Unity's shaderGraph to move my clouds back and forth. I'm using Sine Time to alter the x-position of all the pixels in my sprite. Now, all the clouds are moving in sync, but I'd like to have them move a little more random.

In ShaderGraph, I'm trying to offset the sine wave by adding a random number to it, but it does not work the way I expect it to. Instead of having random movement, all the clouds change their starting position. I am probably going about it the wrong way. Any suggestions are more than welcome.

I have added my attempt in the table below.

| What | Screenshot from ShaderGraph |
| --- | --- |
| Change position using Sine Time.
All clouds moving in sync |  |
| Try to add offset with random range using the object's x-position as seed.
All clouds moving in sync, but start position is changed |  |

**Here are the clouds floating in my game**

# Answer
Add your random value to the time value (not sine time), then send that *summed* result to a sine function in its own graph node.

You can also optionally multiply that (time+random) input value by a randomized scale to make some clouds move with a different period.
> 1 votes

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


# Question
Title: In what circumstance might I need to output pixels in non-32-bit format?
Among practically existing devices people play games with - PC, mobile, PlayStation, XBox, Nintendo etc. - is there any possibility that a pixel on the screen is not 32-bit, and do I have to consider this for portability?

# Answer
Probably the most notable area where more exotic pixel colour formats might come up is when using a high dynamic range (HDR) display, with a platform that supports it.

PC, Xbox One S/X / Series S/X, and PS4 / PS5 all support HDR output.

For example, the HDR10 spec uses 10 bits per colour channel, instead of the usual 8 used for SDR output.

In some situations you might output your frame in ARGBHalf format (16 bits per colour channel, 64 bits per pixel). This is often the default HDR output format in Unity, for example.
> 0 votes

---
Tags: graphics, color, cross-platform, pixel
---


# Question
Title: Use a different target framework version in a unity c# project, other than 4.6
I'm using a dll in my project which is built against a higher target framework (4.6.1 actually)

I can't build or attach to Unity because of this. Visual Studio shows this error:

The primary reference "MQTTnet" could not be resolved because it was built against the ".NETFramework,Version=v4.6.1" framework. This is a higher version than the currently targeted framework ".NETFramework,Version=v4.6".

The only option in player settings in Unity for API compatibility level is .NET 4.6

how can I change that to 4.6.1 in order to be able to build or attach to Unity?

# Answer
> 2 votes
Add the following script anywhere in your project to automatically change the target framework of the c# project files.

```
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

public class VisualStudioProjectGenerationPostProcess : AssetPostprocessor
{
    private static void OnGeneratedCSProjectFiles()
        {
            Debug.Log("OnGeneratedCSProjectFiles");
            var dir = Directory.GetCurrentDirectory();
            var files = Directory.GetFiles(dir, "*.csproj");
            foreach (var file in files)
                ChangeTargetFrameworkInfProjectFiles(file);
        }

    static void ChangeTargetFrameworkInfProjectFiles(string file)
    {
        var text = File.ReadAllText(file);
        var find = "TargetFrameworkVersion>v4.6</TargetFrameworkVersion";
        var replace = "TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion";

        if (text.IndexOf(find) != -1)
        {
            text = Regex.Replace(text, find, replace);
            File.WriteAllText(file, text);
        }
    }

}

```

# Answer
> 2 votes
Since the documented OnGeneratedCSProjectFiles callback has been removed, the VisualStudioProjectGenerationPostProcess is no longer working.

Workaround

Move `Library/PackageCache/com.unity.ide.vscode@1.2.4` to `Packages/com.unity.ide.vscode@1.2.4`

Edit `Editor/ProjectGeneration/ProjectGeneration.cs`, search for `k_TargetFrameworkVersion`, and change to your desired version.

Remember to regularly check if `com.unity.ide.vscode` should be updated. You can watch the changes on https://github.com/needle-mirror/com.unity.ide.vscode

# Answer
> 1 votes
Found a workaround for this.

look for `TargetFrameworkVersion` in every .csproj file and change `v4.6` to `v4.6.1`

I used a sed script to automate this, and run I it every time Unity generates a project:

```
sed -i 's/TargetFrameworkVersion>v4.6<\/TargetFrameworkVersion/TargetFrameworkVersion>v4.6.1<\/TargetFrameworkVersion/g' next-step/Source/*.csproj

```

---
Tags: unity
---


title: Unity Editor wont open

text:
# Question
Title: Unity Editor wont open
When attempting to open an old project or create and open a new project unity won't open. The hub will open and when you choose a project it will close and then nothing will happen. Also when a new project it will state the unity version for the new project as unknown. I have tried uninstalling, deleting all the files under the registry editor, and also removing the files from the appdata and reinstalling and it doesn't appear to fix it. Does anyone have any suggestions on how I can fix this?

# Answer
This issue can often happen when your graphics driver not working properly. Here are some ways to fix your graphics driver.

**One:**

Because of hibernating your PC for long time sometimes the graphics driver won't work. Try to fix this by restarting or shutting down your computer.

**Two:**

Try updating your graphics driver from the the driver company’s website or from Windows Update.

**Three:**

If you are starting the Unity up for the first time, you need to log into an account first. If you don’t have one you can create one here.
> 1 votes

# Answer
I had some problems with my VPN service, you might have the same problem as well. I don't know why, but if I have my VPN turned on Unity won't open up (or will crash, or something like that). The workaround is to turn off the VPN while you are working with Unity or replace your custom client with OpenVPN that seems to work nicely with Unity.
> 1 votes

# Answer
Well I don't know much about it, but what I know ( \**In my experience\**), I'll share it.

\**The Problem happened to me because yesterday I downloaded & Installed Unity Pro 2020.xfx. from a website. (Cracked one).\**
I did it because of curiosity.
Today when i was working on a sample project, suddenly unity closed.
I tried to open it many times with no luck.
I searched for solution online, but no luck.
\**Then I did the following-

1. I deleted the Unity\_lic file from C:\ProgramData\Unity
2. I uninstalled the cracked Unity ( Going to Control Panel\>\> Uninstall a program and uninstalled the unity ( Only cracked unity will show there, simply named Unity)
3. I installed Unity Hub again. ( Remember, I didn't uninstalled the previous Unity Hub, just overwritten it by installing again. I had the Unity hub setup file downloaded, if you don't have it, simply download from unity website)
4. I opened Unity Hub, I got a window where it said I don't have a valid licence. I selected ACTIVATE NEW LICENCE(or something I don't remembered) Then Choosed Personal.
And that's it.
I changed a projects Unity Version to the Version I installed from Unity Hub( Check on Installs tab).
And when I clicked on the project,
It just opened. The problem solved in my case.\**
> 0 votes

---
Tags: unity
---


# Question
Title: How to get past Visual Studio "Setup Error" for Unity development?
When I launch Visual Studio from Unity on my laptop, I get the following error:

> **Setup Error**
>
> The setup for this installation of Visual Studio is not complete. Please run the Visual Studio Installer again to correct the issue.

As instructed, I've tried reinstalling Visual Studio multiple times, or using the "repair" option, but nothing has resolved the error.

How can I fix this?

# Answer
> 1 votes
What actually worked was something along those lines:

1. Completely uninstall visual studio.
2. Download and install "CCleaner".
3. Use CCleaner to clean your registry.
4. Reboot your PC. (This seems really important.)
5. Download and install Visual Studio Community 2019.
6. During installation, make sure you select the game development tool package (but uncheck the unity editor installation if you already have unity installed).
7. Let the download and install finish completely without any interruptions.

(Thanks to Alex Myers for their comment.)

---

If VS setup fails, these are alternatives:

* Visual Studio Code is also at least semi-officially supported with plug ins and ability to launch from the Unity editor.
* C# source files are just text files so you can use any text editor you wish to edit them. It won't be as nice an experience though.
* Jetbrains Rider is an alternative.
* MonoDevelop, it has less features but also lower requirements.

(Thanks to comments from Colin Young and trollingchar.)

# Answer
> 0 votes
In "preferences", go to editor and you can choose which visual studio you are using, that's how I fixed it.

---
Tags: unity, visual-studio
---


# Question
Title: I am getting the error message "Unexpected token: elif" in godot. Any tips?
```
func _process(delta):

var velocity = Vector2()

if Input.is_action_pressed("ui_right"):
    velocity.x += 1
if Input.is_action_pressed("ui_left"):
    velocity.x -= 1
if Input.is_action_pressed("ui_down"):
    velocity.y += 1
if Input.is_action_pressed("ui_up"):
    velocity.y -= 1
if velocity.length() > 1:
    velocity = velocity.normalized() * speed
    $AnimatedSprite.play()
else:
    $AnimatedSprite.stop()
position += velocity * delta
position.x = clamp(position.x, 0, screen_size.x)
position.y = clamp(position.y, 0, screen_size.y)
if velocity.x != 0:
    $AnimatedSprite.animation = "walk"
$AnimatedSprite.flip_v = false
$AnimatedSprite.flip_h = velocity.x < 0
    elif velocity.y != 0:
 $AnimatedSprite.animation = "up"
 $AnimatedSprite.flip_v = velocity.y > 0

```

line 20, any tips?

# Answer
> 5 votes
Indentation matters in gdscript; make sure your code is indented correctly so that the `elif` is at the same depth as the `if`.

---
Tags: godot
---


# Question
Title: How can I spin object randomly change direction every x seconds on the y axis only?
Even if I set the value 1 on the y only on the spinAxis variable and leave both x and z 0 it will spin also on the x and z.

How can I make the objectToSpin to spin only on the y axis ?

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

public class MissleLauncherRotation : MonoBehaviour
{
    public GameObject objectToSpin;
    public Vector3 spinAxis;
    public float timeToSpin = 5f;
    public float spinSpeed = 20f;
    public bool randomSpin = false;

    private void Start()
    {
        StartCoroutine("Spin");
    }

    private void Update()
    {

    }

    IEnumerator Spin()
    {
        float spinTimer;
        while (true)
        {
            if (randomSpin == true)
            {
                spinAxis = Random.onUnitSphere;
            }

            spinTimer = timeToSpin;
            while (spinTimer > 0f)
            {
                objectToSpin.transform.Rotate(spinAxis, Time.deltaTime * spinSpeed);
                spinTimer -= Time.deltaTime;
                yield return null;
            }
        }
    }
}

```

# Answer
I would move the spinning from an own coroutine to Update (because you want to do it every frame), but then put the regular change of the spin vector to an own coroutine (because *that's* what you want to do every n seconds).

```
public class MissleLauncherRotation : MonoBehaviour
{
    public GameObject objectToSpin;
    public float timeToSpin = 0.5f;
    public float spinSpeed;

    private Vector3 spinVector;

    private void Start()
    {
        StartCoroutine("ChangeSpin");
    }

    private void Update()
    {
         objectToSpin.transform.Rotate(spinVector * Time.deltaTime);
    }

    IEnumerator ChangeSpin()
    {
        while (true)
        {
           if (Random.value < 0.5f) {
               spinVector = new Vector3(0f, spinSpeed, 0f);
           } else {
               spinVector = new Vector3(0f, -spinSpeed, 0f);
           }
           yield return new WaitForSeconds(timeToSpin);
        }
    }
}

```

This code has a 50% chance every `timeToSpin` seconds to either switch direction or keep it. I assume that's what you meant with "change direction randomly every x seconds".
> 1 votes

# Answer
If you want to rotate around Y, then rotate around Y, not some axis that may or may not be aligned to Y. I don't know what exactly you mean by "randomly" but only on the Y axis. I assume you mean it sometimes speeds clockwise and sometimes counter-clockwise, randomly:

```
if (Random.value < 0.5f) {
    objectToSpin.transform.Rotate(Vector3.up, spinSpeed * Time.deltaTime);
} else {
    objectToSpin.transform.Rotate(Vector3.down, spinSpeed * Time.deltaTime);
}

```
> 0 votes

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


# Question
Title: UWidget::SynchronizeProperties() is not being called on in editor property change
I have to change the children list every time the enum variable property is changed from widget editor.

None of the functions I've tried so far seem to have worked (virtual void OnEndEditByDesigner(); virtual void PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent)).

SynchronizeProperties docs state that

> It can also be called by the editor to update modified state, so ensure all initialization to a widgets properties are performed here, or the property and visual state may become unsynced.

So I'm not entirely sure that it is the right function to use/overwrite (as it only "can" be called by the editor to update modified state, not will be called on property editor edit)

Here is some sample code to show an example of what I've been trying to do so far.

Sample code:

SampleButton.h

```
/* Includes */
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "Components/Button.h"
#include "Components/Image.h"
#include "Components/CanvasPanel.h"
#include "Components/ButtonSlot.h"
#include "Widgets/SOverlay.h"
#include "Components/Overlay.h"
#include "Components/TextBlock.h"
#include "Styling/SlateBrush.h"
#include "UUIW_MasterButton.generated.h"
//

UENUM(BlueprintType)
enum class EContentType : uint8
{
    WithIcon,
    WithText,
}
class SAMPLE_API SampleButton : public UButton
{
    GENERATED_BODY()
public:
    UPROPERTY(EditAnywhere, BlueprintSetter=SetType, meta = (MakeEditWidget = ""))
        EContentType ContentType = EContentType::WithIcon;
    UPROPERTY(meta = (EditCondition = "ContentType == EContentType::WithIcon || ContentType == EContentType::WithTextAndIcon", EditConditionHides))
        UImage* Icon;
    UPROPERTY(meta = (EditCondition = "ContentType == EContentType::WithText || ContentType == EContentType::WithTextAndIcon", EditConditionHides))
        UTextBlock* TextBlock;

protected:
    virtual TSharedRef<SWidget> RebuildWidget() override;
    UOverlay* Overlay;
    virtual void SynchronizeProperties();
}

```

SampleButton.cpp

#include "UI/SampleButton.h"

TSharedRef<SWidget> SampleButton::RebuildWidget()
{
    Overlay = NewObject<UOverlay>();

    auto ButtonRef = Super::RebuildWidget();
    AddChild(Overlay);
    Icon = NewObject<UImage>();
    Icon->SetDisplayLabel(TEXT("Icon"));
    TextBlock = NewObject<UTextBlock>();
    TextBlock->SetDisplayLabel(TEXT("Text"));
    switch (ContentType)
    {
    case EContentType::WithIcon:
        Overlay->AddChild(Icon);
        break;
    case EContentType::WithText:
        Overlay->AddChild(TextBlock);
        break;
    case EContentType::WithTextAndIcon:
        Overlay->AddChild(Icon);
        Overlay->AddChild(TextBlock);
        break;
    }

    if ( GetChildrenCount() > 0 )
    {
        Cast<UButtonSlot>(GetContentSlot())->BuildSlot(MyButton.ToSharedRef());
    }

    return ButtonRef;

}

void UUUIW_MasterButton::SynchronizeProperties()
{
    Super::SynchronizeProperties();
    Overlay->ClearChildren();
    switch (ContentType)
    {
    case EContentType::WithIcon:
        Overlay->AddChild(Icon);
        break;
    case EContentType::WithText:
        Overlay->AddChild(TextBlock);
        break;
    case EContentType::WithTextAndIcon:
        Overlay->AddChild(Icon);
        Overlay->AddChild(TextBlock);
        break;
    }
}

```

# Answer
> 0 votes
Well... PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent) worked, apparently. But it is called not on value change, but on blueprint compilation after that (which is why I thought that it didn't work before)

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


# Question
Title: Why does OnTriggerEnter2D/OnCollisionEnter2D work when there is no other collider object opposite?
my bullet:

1. There is a Box collider (checked "is Trigger")
2. It has Rigidbody2D (Gravity = 0, freeze rotation Z)

https://i.stack.imgur.com/ik1IY.jpg

I added the "OnTriggerEnter2D" function because isTrigger is checked. Bullet script:

```
private float lifeTime = 1.0f;

private void Start()
{
    Destroy(gameObject, lifeTime);
}

private void OnTriggerEnter2D(Collider2D collision)
{
    GameObject effect = Instantiate(hitEffect, transform.position, Quaternion.identity);
    Destroy(effect, 0.2f);
    Destroy(gameObject);
}

```

When I fire, the OnTriggerEnter2D function works even though there is no collider/object in the direction of the bullet. It only works a certain distance away from my main character, and it's always the same no matter which direction I shoot.

# Answer
> 0 votes
Here's how I fixed the inside of my OnTriggerEnter2D function:

```
if (collision.tag == "Enemy")
    {
        GameObject effect = Instantiate(hitEffect, transform.position, Quaternion.identity);
        Destroy(effect, 0.2f);
        Destroy(gameObject);
    }

```

The problem is fixed, but why do I have to do an "if" check? Doesn't the trigger function already check this?

If it only touches things with tags "Enemy" and colliders... I guess I'll have to add this for many different objects?

EDIT: I have a pistol collider in the position where the bullet was created, I made the pistol collider a little smaller and the problem went away. However, I adjusted this so that the colliders of the pistol and the bullet do not intersect, and it looked like that on the scene screen. Also, I couldn't quite understand the problem since the projectile was destroyed at a much greater distance from my pistol.

---
Tags: collision-detection, bullet-physics, collider
---


# Question
Title: Why the target variable can't find the object name "Base"?
"Base" is in another scene but I thought Find will find it even if it's in another scene.

```
public class DronesManager : MonoBehaviour
{
    public GameObject target;
    public float movementSpeed;
    public float launchTime;

    public Transform dronesUnchild;

    private List<GameObject> drones = new List<GameObject>();
    private static System.Random rnd = new System.Random();

    private void Awake()
    {
        target = GameObject.Find("Base");
    }

```

but target is null when running the game.

this is a screenshot of the hierarhcy the script is attached to the Missile Launcher in the SampleScene and the "Base" is in the Example\_01 scene.

# Answer
`Awake()` gets called immediately as soon as the object has spawned/loaded. It's almost like a constructor, in that it will finish before a call to `Instantiate()` returns the newly spawned object.

That means that anything else that's being spawned in the same/subsequent pass is not necessarily in existence yet.

In this case, it's likely that your first scene loads and calls `Awake()` on all its objects before the second scene has finished loading, so the object simply doesn't exist yet to be found.

By moving your search to `Start()`, you delay it until just before the first `Update()` tick, giving time for the rest of the scene(s) to finish loading so their objects are ready for you to find.
> 1 votes

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


# Question
Title: How to create/get good terrain texturing for an RTS game?
I'm writing an rts-style game, so I have an overhead camera, typically 20-50m above the terrain.

Most ground textures (grass, dirt, etc.) I find are obviously made for a much closer, probably FPS-style, perspective. Using them for an RTS game you either get lots of tiling or you scale them up and when you get close you see individual grass blades way too large to fit the rest of the scenery.

Looking at AAA RTS titles, the grass seems to be mostly a greenish noise texture with both small and large scale color variations, much like perlin noise works.

How is that done? Is it a texture or a procedural system? Are there sources for rts-style terrain textures? Do you simply high-pass filter your textures? Do you mix in a detail map with the regular texture? What's the approach?

My engine is Unity 3D, though I don't think the question is engine-specific.

# Answer
> 2 votes
Apply multiple "octaves" of textures/noise to avoid repetition.

(You can read more about a related technique as used for generating procedural terrains here: https://developer.nvidia.com/gpugems/gpugems3/part-i-geometry/chapter-1-generating-complex-procedural-terrains-using-gpu \- particularly "1.3.3 Making an Interesting Density Function" which mentions other ways to break up repetition like warping coordinates for higher octaves)

But the key takeaway is that you blend multiple copies of the (texture|noise) at different scales with varying weights.

As an example, you might pick (pseudocode)

```
color = texture_at(x, y) * .6
      + texture_at(x/5, y/5) * .2
      + texture_at(x/10, y/10) * .1
      + texture_at(x/50, y/50) * .1;

```

That way, when you're up close, the detail is clearly visible and the lower amplitude blurs of lower octaves are barely visible, whilst at longer range, the lower frequency features -that span multiple tiles- tend to dominate.

Obviously you can tweak the number of samples and relative weighting to get the effect you want.

A separate technique I've used elsewhere is to use the normal of the surface to blend between three textures \[Triplanar texturing\].

This was *quite* some time ago, so excuse the vagueness but...

When texturing a mesh-based procedural terrain, I used a custom shader which calculated the normal vector of the surface in world space and used the relative weight of the x, y and z vectors to blend between three textures specified by the user.

This allowed me to specify textures for a grass floor, a rock wall and a cave roof.

I managed to dig out this shader code but please bear in mind this is one of the first things I did in Unity, I'm no shader expert and I haven't reviewed it in detail...

```
Properties{
    //_MainTex ("Albedo (RGB)", 2D) = "white" {}
    _TopWeighting("Vertical Falloff", Range(0.1, 10)) = 5
    _UpTex("Top", 2D) = "red" {}
    _SideTex("Side", 2D) = "green" {}
    _DownTex("Bottom", 2D) = "blue" {}
}

// ....

struct Input {
    float3 worldPos : SV_POSITION;
    float3 worldNormal;
    float3 pos;
};

void vert(inout appdata_full v, out Input o) {
    UNITY_INITIALIZE_OUTPUT(Input, o);
    o.pos = mul(_Object2World, v.vertex);
}

// ....

void surf(Input IN, inout SurfaceOutputStandard o) {
    // Sample the various textures we're using

    fixed4 up = tex2D(_UpTex, fmod(IN.pos.xz * _UpTex_ST, 1));
    fixed4 sidex = tex2D(_SideTex, IN.pos.yz * _SideTex_ST);
    fixed4 sidez = tex2D(_SideTex, IN.pos.xy * _SideTex_ST);
    fixed4 down = tex2D(_DownTex, IN.pos.xz * _DownTex_ST);

    // Work out if we're doing the top or bottom
    float top = clamp(IN.worldNormal.y * 100000, 0, 1);

    // Work out how much weight should be given to the various textures
    float3 blending = abs(float3(IN.worldNormal.x / _TopWeighting,
                                 IN.worldNormal.y,
                                 IN.worldNormal.z / _TopWeighting));

    // Force weights to sum to 1.0
    blending = normalize(max(blending, 0.00001));

    // scale the various weights proportionally
    float b = (blending.x + blending.y + blending.z);
    blending /= float3(b, b, b);

    // Combine the textures with the appropriate weighting
    float4 tex = sidex * blending.x +
                 (top) * up * blending.y +
                 (1-top) * down * blending.y +
                 sidez * blending.z;
    o.Albedo = tex;

    // Metallic and smoothness aren't currently used,
    // set them to some neutral values

    o.Metallic = 0;
    o.Smoothness = .1;
    o.Alpha = 0;
}

```

You should be able to combine the two techniques fairly easily by updating the colour sampling at the top of the surface shader, hopefully giving you some more varied terrain.

---
Tags: textures, terrain
---