title: Cast ray to select block in voxel game

text:
# Question
Title: Cast ray to select block in voxel game
I am developing a game with a Minecraft-like terrain made out of blocks. Since basic rendering and chunk loading is done now, I want to implement block selecting.

Therefore I need to find out what block the first person camera is facing. I already heard of unprojecting the whole scene but I decided against that because it sounds hacky and isn't accurate. Maybe I could somehow cast a ray in view direction but I do not know how to check the collision with a block in my voxel data. Of course this calculations must be done on the CPU since I need the results to perform game logic operations.

So how could I find out which block is in front of the camera? If it is preferable, how could I cast a ray and check collisions?

# Answer
> 23 votes
When I had this problem while working on my Cubes, I found the paper "A Fast Voxel Traversal Algorithm for Ray Tracing" by John Amanatides and Andrew Woo, 1987 which describes an algorithm which can be applied to this task; it is accurate and needs only one loop iteration per voxel intersected.

I have written an implementation of the relevant parts of the paper's algorithm in JavaScript. My implementation adds two features: it allows specifying a limit on the distance of the raycast (useful for avoiding performance issues as well as defining a limited 'reach'), and also computes which face of each voxel the ray entered.

The input `origin` vector must be scaled such that the side length of a voxel is 1. The length of the `direction` vector is not significant but may affect the numerical accuracy of the algorithm.

The algorithm operates by using a parameterized representation of the ray, `origin + t * direction`. For each coordinate axis, we keep track of the `t` value which we would have if we took a step sufficient to cross a voxel boundary along that axis (i.e. change the integer part of the coordinate) in the variables `tMaxX`, `tMaxY`, and `tMaxZ`. Then, we take a step (using the `step` and `tDelta` variables) along whichever axis has the least `tMax` — i.e. whichever voxel-boundary is closest.

```
/**
 * Call the callback with (x,y,z,value,face) of all blocks along the line
 * segment from point 'origin' in vector direction 'direction' of length
 * 'radius'. 'radius' may be infinite.
 *
 * 'face' is the normal vector of the face of that block that was entered.
 * It should not be used after the callback returns.
 *
 * If the callback returns a true value, the traversal will be stopped.
 */
function raycast(origin, direction, radius, callback) {
  // From "A Fast Voxel Traversal Algorithm for Ray Tracing"
  // by John Amanatides and Andrew Woo, 1987
  // <http://www.cse.yorku.ca/~amana/research/grid.pdf>
  // <http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.42.3443>
  // Extensions to the described algorithm:
  //   • Imposed a distance limit.
  //   • The face passed through to reach the current cube is provided to
  //     the callback.

  // The foundation of this algorithm is a parameterized representation of
  // the provided ray,
  //                    origin + t * direction,
  // except that t is not actually stored; rather, at any given point in the
  // traversal, we keep track of the *greater* t values which we would have
  // if we took a step sufficient to cross a cube boundary along that axis
  // (i.e. change the integer part of the coordinate) in the variables
  // tMaxX, tMaxY, and tMaxZ.

  // Cube containing origin point.
  var x = Math.floor(origin[0]);
  var y = Math.floor(origin[1]);
  var z = Math.floor(origin[2]);
  // Break out direction vector.
  var dx = direction[0];
  var dy = direction[1];
  var dz = direction[2];
  // Direction to increment x,y,z when stepping.
  var stepX = signum(dx);
  var stepY = signum(dy);
  var stepZ = signum(dz);
  // See description above. The initial values depend on the fractional
  // part of the origin.
  var tMaxX = intbound(origin[0], dx);
  var tMaxY = intbound(origin[1], dy);
  var tMaxZ = intbound(origin[2], dz);
  // The change in t when taking a step (always positive).
  var tDeltaX = stepX/dx;
  var tDeltaY = stepY/dy;
  var tDeltaZ = stepZ/dz;
  // Buffer for reporting faces to the callback.
  var face = vec3.create();

  // Avoids an infinite loop.
  if (dx === 0 && dy === 0 && dz === 0)
    throw new RangeError("Raycast in zero direction!");

  // Rescale from units of 1 cube-edge to units of 'direction' so we can
  // compare with 't'.
  radius /= Math.sqrt(dx*dx+dy*dy+dz*dz);

  while (/* ray has not gone past bounds of world */
         (stepX > 0 ? x < wx : x >= 0) &&
         (stepY > 0 ? y < wy : y >= 0) &&
         (stepZ > 0 ? z < wz : z >= 0)) {

    // Invoke the callback, unless we are not *yet* within the bounds of the
    // world.
    if (!(x < 0 || y < 0 || z < 0 || x >= wx || y >= wy || z >= wz))
      if (callback(x, y, z, blocks[x*wy*wz + y*wz + z], face))
        break;

    // tMaxX stores the t-value at which we cross a cube boundary along the
    // X axis, and similarly for Y and Z. Therefore, choosing the least tMax
    // chooses the closest cube boundary. Only the first case of the four
    // has been commented in detail.
    if (tMaxX < tMaxY) {
      if (tMaxX < tMaxZ) {
        if (tMaxX > radius) break;
        // Update which cube we are now in.
        x += stepX;
        // Adjust tMaxX to the next X-oriented boundary crossing.
        tMaxX += tDeltaX;
        // Record the normal vector of the cube face we entered.
        face[0] = -stepX;
        face[1] = 0;
        face[2] = 0;
      } else {
        if (tMaxZ > radius) break;
        z += stepZ;
        tMaxZ += tDeltaZ;
        face[0] = 0;
        face[1] = 0;
        face[2] = -stepZ;
      }
    } else {
      if (tMaxY < tMaxZ) {
        if (tMaxY > radius) break;
        y += stepY;
        tMaxY += tDeltaY;
        face[0] = 0;
        face[1] = -stepY;
        face[2] = 0;
      } else {
        // Identical to the second case, repeated for simplicity in
        // the conditionals.
        if (tMaxZ > radius) break;
        z += stepZ;
        tMaxZ += tDeltaZ;
        face[0] = 0;
        face[1] = 0;
        face[2] = -stepZ;
      }
    }
  }
}

function intbound(s, ds) {
  // Find the smallest positive t such that s+t*ds is an integer.
  if (ds < 0) {
    return intbound(-s, -ds);
  } else {
    s = mod(s, 1);
    // problem is now s+t*ds = 1
    return (1-s)/ds;
  }
}

function signum(x) {
  return x > 0 ? 1 : x < 0 ? -1 : 0;
}

function mod(value, modulus) {
  return (value % modulus + modulus) % modulus;
}

```

Permanent link to this version of the source on GitHub.

# Answer
> 1 votes
Perhaps look into Bresenham's line algorithm, particularly if you're working with unit-blocks (as most minecraftish games tend to).

Basically this takes any two points, and traces an unbroken line between them. If you cast a vector from the player to their maximum picking distance, you can use this, and the players positions as points.

I have a 3D implementation in python here: bresenham3d.py.

# Answer
> 0 votes
To find the **first** block in front of the camera, create a for loop that loops from 0 to some maximum distance. Then, multiply the camera's forward vector by the counter and check if the block at that position is solid. If it is, then store the position of the block for later use and stop looping.

If you also want to be able to place blocks, face-picking is no harder. Simply loop back from the block and find the first empty block.

# Answer
> 0 votes
I made a post on Reddit with my implementation, which uses Bresenham's Line Algorithm. Here's an example of how you would use it:

```
// A plotter with 0, 0, 0 as the origin and blocks that are 1x1x1.
PlotCell3f plotter = new PlotCell3f(0, 0, 0, 1, 1, 1);
// From the center of the camera and its direction...
plotter.plot( camera.position, camera.direction, 100);
// Find the first non-air block
while ( plotter.next() ) {
   Vec3i v = plotter.get();
   Block b = map.getBlock(v);
   if (b != null && !b.isAir()) {
      plotter.end();
      // set selected block to v
   }
}

```

Here is the implementation itself:

```
public interface Plot<T>
{
    public boolean next();
    public void reset();
    public void end();
    public T get();
}

public class PlotCell3f implements Plot<Vec3i>
{

    private final Vec3f size = new Vec3f();
    private final Vec3f off = new Vec3f();
    private final Vec3f pos = new Vec3f();
    private final Vec3f dir = new Vec3f();

    private final Vec3i index = new Vec3i();

    private final Vec3f delta = new Vec3f();
    private final Vec3i sign = new Vec3i();
    private final Vec3f max = new Vec3f();

    private int limit;
    private int plotted;

    public PlotCell3f(float offx, float offy, float offz, float width, float height, float depth)
    {
        off.set( offx, offy, offz );
        size.set( width, height, depth );
    }

    public void plot(Vec3f position, Vec3f direction, int cells)
    {
        limit = cells;

        pos.set( position );
        dir.norm( direction );

        delta.set( size );
        delta.div( dir );

        sign.x = (dir.x > 0) ? 1 : (dir.x < 0 ? -1 : 0);
        sign.y = (dir.y > 0) ? 1 : (dir.y < 0 ? -1 : 0);
        sign.z = (dir.z > 0) ? 1 : (dir.z < 0 ? -1 : 0);

        reset();
    }

    @Override
    public boolean next()
    {
        if (plotted++ > 0)
        {
            float mx = sign.x * max.x;
            float my = sign.y * max.y;
            float mz = sign.z * max.z;

            if (mx < my && mx < mz)
            {
                max.x += delta.x;
                index.x += sign.x;
            }
            else if (mz < my && mz < mx)
            {
                max.z += delta.z;
                index.z += sign.z;
            }
            else
            {
                max.y += delta.y;
                index.y += sign.y;
            }
        }
        return (plotted <= limit);
    }

    @Override
    public void reset()
    {
        plotted = 0;

        index.x = (int)Math.floor((pos.x - off.x) / size.x);
        index.y = (int)Math.floor((pos.y - off.y) / size.y);
        index.z = (int)Math.floor((pos.z - off.z) / size.z);

        float ax = index.x * size.x + off.x;
        float ay = index.y * size.y + off.y;
        float az = index.z * size.z + off.z;

        max.x = (sign.x > 0) ? ax + size.x - pos.x : pos.x - ax;
        max.y = (sign.y > 0) ? ay + size.y - pos.y : pos.y - ay;
        max.z = (sign.z > 0) ? az + size.z - pos.z : pos.z - az;
        max.div( dir );
    }

    @Override
    public void end()
    {
        plotted = limit + 1;
    }

    @Override
    public Vec3i get()
    {
        return index;
    }

    public Vec3f actual() {
        return new Vec3f(index.x * size.x + off.x,
                index.y * size.y + off.y,
                index.z * size.z + off.z);
    }

    public Vec3f size() {
        return size;
    }

    public void size(float w, float h, float d) {
        size.set(w, h, d);
    }

    public Vec3f offset() {
        return off;
    }

    public void offset(float x, float y, float z) {
        off.set(x, y, z);
    }

    public Vec3f position() {
        return pos;
    }

    public Vec3f direction() {
        return dir;
    }

    public Vec3i sign() {
        return sign;
    }

    public Vec3f delta() {
        return delta;
    }

    public Vec3f max() {
        return max;
    }

    public int limit() {
        return limit;
    }

    public int plotted() {
        return plotted;
    }

}

```

# Answer
> 0 votes
My approach is somewhat different, yet heavily relies on answers in this thread (especially @Maxim Kamalov's comment with his gist - was great starting point, basically main logic is taken from there and improved).

The problem with existing code for me was different edge-cases (coordinate delta equal to zero ("straight lines"), hitting exactly the edge (where tMax values are equal), negative traversal, not accounting the fact that blocks in my data structure are .5f-based, not 0-based (center is in the very center of the cube), floating point precision, and a few others).

Information upon this is not so spread, so I decided to share my traversal approach. You can think of it as variation of Amanatides and Woo algorithm. Main difference is that I'm not using ray, but rather 2 points - but it shouldn't be too hard to adjust.

Note that It might (and probably will) be slower, but it is more precise than face-to-face traversal.

Also, I'm not quite fond of using local functions, but that made developing the logic for me easier.

Hope it helps to whoever it may concern :)

using System.Collections.Generic;

public static class Foo
{
    public static IEnumerable<Vector3> GetIntersectedWorldBlocksD(Vector3 pointA, Vector3 pointB)
    {
        var line = new HashSet<Vector3>
        {
            new Vector3(Mathf.Round(pointA.X), Mathf.Round(pointA.Y), Mathf.Round(pointA.Z))
        };

        var x = (float) Mathf.Round(pointA.X);
        var y = (float) Mathf.Round(pointA.Y);
        var z = (float) Mathf.Round(pointA.Z);

        var delta = pointB - pointA;
        var deltaNormal = delta.Normal;
        var dx = deltaNormal.X;
        var dy = deltaNormal.Y;
        var dz = deltaNormal.Z;

        var stepX = Signum(dx);
        var stepY = Signum(dy);
        var stepZ = Signum(dz);

        var tMaxX = Intbound(pointA.X - 0.5f, deltaNormal.x);
        var tMaxY = Intbound(pointA.Y - 0.5f, deltaNormal.y);
        var tMaxZ = Intbound(pointA.Z - 0.5f, deltaNormal.z);

        var tDeltaX = stepX / dx;
        var tDeltaY = stepY / dy;
        var tDeltaZ = stepZ / dz;

        var lineLength = delta.Length;

        bool StepX()
        {
            if (tMaxX >= lineLength) return true;
            x += stepX;
            tMaxX += tDeltaX;
            return false;
        }

        bool StepY()
        {
            if (tMaxY >= lineLength) return true;
            y += stepY;
            tMaxY += tDeltaY;
            return false;
        }

        bool StepZ()
        {
            if (tMaxZ >= lineLength) return true;
            z += stepZ;
            tMaxZ += tDeltaZ;
            return false;
        }

        var res = true;

        if (stepX != 0 && stepY != 0 && stepZ != 0)
            while (true)
            {
                var tX = tMaxX.Precision5();
                var tY = tMaxY.Precision5();
                var tZ = tMaxZ.Precision5();
                if (tX < tY)
                {
                    if (tX < tZ)
                        res = StepX();
                    else if (tZ < tX)
                        res = StepZ();
                    else
                        res = StepZ() || StepX();
                }
                else if (tY < tX)
                {
                    if (tY < tZ)
                        res = StepY();
                    else if (tZ < tY)
                        res = StepZ();
                    else
                        res = StepY() || StepZ();
                }
                else
                {
                    if (tY < tZ)
                        res = StepX() || StepY();
                    else if (tZ < tY)
                        res = StepZ();
                    else
                        res = StepX() || StepY() || StepZ();
                }

                line.Add(new Vector3(x, y, z));
                if (res) break;
            }
        else if (stepX == 0 && stepY != 0 && stepZ != 0)
            while (true)
            {
                var tY = tMaxY.Precision5();
                var tZ = tMaxZ.Precision5();
                if (tY < tZ)
                    res = StepY();
                else if (tZ < tY)
                    res = StepZ();
                else
                    res = StepY() || StepZ();
                line.Add(new Vector3(x, y, z));
                if (res) break;
            }
        else if (stepX != 0 && stepY == 0 && stepZ != 0)
            while (true)
            {
                var tX = tMaxX.Precision5();
                var tZ = tMaxZ.Precision5();
                if (tX < tZ)
                    res = StepX();
                else if (tZ < tX)
                    res = StepZ();
                else
                    res = StepZ() || StepX();

                line.Add(new Vector3(x, y, z));
                if (res)
                {
                    break;
                }
            }
        else if (stepX != 0 && stepY != 0 && stepZ == 0)
            while (true)
            {
                var tY = tMaxY.Precision5();
                var tX = tMaxZ.Precision5();
                if (tY < tX)
                    res = StepY();
                else if (tX < tY)
                    res = StepX();
                else
                    res = StepY() || StepX();

                line.Add(new Vector3(x, y, z));
                if (res) break;
            }
        else if (stepX != 0 && stepY == 0 && stepZ == 0)
            while (true)
            {
                res = StepX();
                line.Add(new Vector3(x, y, z));
                if (res) break;
            }
        else if (stepX == 0 && stepY != 0 && stepZ == 0)
            while (true)
            {
                res = StepY();
                line.Add(new Vector3(x, y, z));
                if (res) break;
            }
        else if (stepX == 0 && stepY == 0 && stepZ != 0)
            while (true)
            {
                res = StepZ();
                line.Add(new Vector3(x, y, z));
                if (res) break;
            }

        return line;
    }

    private static int Signum(float x)
    {
        return x > 0 ? 1 : x < 0 ? -1 : 0;
    }

    private static float Ceil(float s)
    {
        return s == 0f ? 1f : Mathf.Ceil(s);
    }

    private static float Intbound(float s, float ds)
    {
        if (ds < 0 && Mathf.Round(s) == s) return 0;
        s = Mod(s, 1);
        return (ds > 0 ? Ceil(s) - s : s - Mathf.Floor(s)) / Mathf.Abs(ds);
    }

    private static float Mod(float value, float modulus)
    {
        return (value % modulus + modulus) % modulus;
    }

    public static float Precision5(this float val)
    {
        return  ((int)(100000 * val)) / 100000.0f;
    }
}
```
</code></pre>

# Answer
> 0 votes
I read this question a few years ago and found the other answer by Reid (2013) linking to Amanatides and Woo (1987) \[1\]. While the underlying raycasting algorithm is actually quite nice, the code of all other answers so far seem rather complicated with a lot of lines and many branches, making it hard to understand.

Here is a elegant variant of the code using vectors and operator overloading in pseudocode more fitting to our modern times:

```
def castRay(pos: V3, step: V3, isWall: (V3, Int) => Boolean): (Double, Int) =
  val sign: V3 = step.sign
  val reci: V3 = 1/step.abs

  var grid: V3 = pos.floor
  var steps: V3 = (sign+1)/2 - (pos-grid)/step
  while true:
    val axis: Int = steps.argmin
    grid[axis] += sign[axis]
    if isWall(grid, axis): return (pos + step * steps[axis], axis)
    steps[axis] += reci[axis]

```

This method works for raycasts into arbitrary dimensions (0,1,2,3,4,...). But only the 2d and 3d variants are of practical use. (Still, considering the 1d case can be a useful simplification to understand the essence of the algorithm.)

The algorithm works like this:

0. Precalculate the elementwise `sign`s of the step vector, and the elementwise absolute `reci`procal of the steps, cause we'll need them soon.
1. The starting position can be separated into the position snapped to the grid (`grid = pos.floor`), and the delta between the grid position and the actual position (`pos-grid`).
2. During the following loop, the vector `steps` will keep for each axis track of how many steps we did in that direction to cross a grid-boundary. Because we snapped to the grid in the previous step, we shall initialize the distance with the amount of steps needed to traverse that delta (`- (pos-grid)/step`).

However if we are walking into a negative direction, we need the amount of steps of the complement of the delta, which we get by adding one (`(sign+1)/2`).
3. Repeat

1. in what axis is the nearest border `steps.argmin`
    2. move into the direction of that axis on the grid (`+= sign[axis]`)
    3. if this move crossed a wall, RETURN
    4. update steps by amount of steps needed to traverse a unit distance (`+= 1/steps.abs` or equivalently `+= reci[axis]`)

---

The helper functions are as follows: `+` `-` `*` `/` `.floor` `.sign` `.abs` are the element-wise operations (the element-wise multiplication is called *hadamard product*). What do i mean with element-wise? Well they are implemented like this:

```
def a * b :=
  val c = new V3
  for i: c[i] = a[i] * b[i]
  return c

```

And `argmin` should return the index of the axis which has the minimal value. For example `argmin(V3(12, -42, 28)) = 1`, because the value `-42` at index 1 is the lowest of the vector.

Pitfalls:

* `.sign` should either return `-1` or `+1` for each element of the vector but never `0`, or the algorithm may run infinitely. For example `sign(0) = +1` is good, while `sign(0) = 0` is not ok.
* To avoid infinite loops, when the ray never hits a collision, you should add a maximum distance traveled check in the loop condition.
* Ensure that your isWall method doesn't throw IndexOutOfBounds exceptions, but simply returns a sensible value for out of bounds wall queries.

Note: With regard to the discussion in the comments about problems with negative positions. I believe I have tested this algorithm for positive and negative positions, and positive and negative steps, and it should work either way.

\[1\] "A Fast Voxel Traversal Algorithm for Ray Tracing". Amanatides and Woo, 1987

---
Tags: camera, voxels, raycasting, selection
---


# Question
Title: Should dealing damage and healing be the same function called change hp or should they be sepparated into the functions of their own?
I'm making a simple game with sliders, where there is a damage over time function, the main focus of the player is to upkeep the player health as long as possible by clicking corresponding buttons. My question is, should I create a single function called ChangeHealth which will need a float parameter to change it. Or I can make to separate functions where the hp can be altered with an only function.

# Answer
> 1 votes
You could separate them for additional clarity, but the core function of altering the health value itself I think should just be a method called 'AdjustHealth', and you can provide a positive or negative value to change; atleast that's the approach I generally take.

You can then have an independent Heal / Damage method that both call on the AdjustHealth method.

# Answer
> 2 votes
I think there is more nuance to this than just "whichever works best in code". For example, you might want to have certain events in your game fire when a character is healed or take damage, e.g. an ability might heal you for 10% of the damage you deal, so it listens to the `OnDamaged` event which is fired when you call `DealDamage(Number)` from code.

Of course you could do this with a generic `ChangeHealth(Number)` function as well by calling `OnDamaged` when the value is `< 0` and `OnHealed` when the value is `> 0`, but what if we want to fire the `OnHealed` event even if we are healed for a negative value (so effectively taking damage)? Then our logic of checking for `<0` or `>0` inside the `ChangeHealth` function would not work; it would call the wrong function when we are healed or damaged for a negative value.

In my opinion I would design two explicit functions, one `DealDamage` and one `ApplyHealing`, that way if you ever need to do explicit logic for one of the two cases there is never any ambiguity about what the caller meant to do. Of course, if changing health in your codebase is more complex than doing `health -= damage` you might want to extract the health-changing logic into its own separate **private** utility function that is only used internally by the two other functions.

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


title: How to fit game to screen size?

text:
# Question
Title: How to fit game to screen size?
I create a WebGL game. After building project I discovered that the game doesn't fit the screen size

How you can see the canvas is perfectly scaled but the game didn't

I don't know what I changed but in previous build there wasn't this problem. I tried to undo all my last changes but Unity doesn't remember the very old changes, so I don't know what I changed. But I sure that I changed was only the new created canvas and disabled button

The result which I try to achieve (image was saved from old build, so the position of buttons doesn't make any sense):

Here is my current settings:

Unity Editor settings:

HTML file

```
<!DOCTYPE html>
<html lang="en-us">
<head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Unity WebGL Player | Your Snake</title>
    <link rel="shortcut icon" href="TemplateData/favicon.ico">
    <link rel="stylesheet" href="TemplateData/style.css">
</head>
<body>
    <div
        id="unity-container"
        class="unity-desktop"
        style="
            position: absolute;
            height: 100%;
            width: 100%;
            left: 0;
            top: 0;
            transform: none;
        "
    >
        <canvas
            id="unity-canvas"
            width=1080
            height=1920
            style="
                position: absolute;
                width: 100%;
                height: 100%;
                cursor: default;
            "
        ></canvas>
        <div id="unity-loading-bar">
            <div id="unity-logo"></div>
            <div id="unity-progress-bar-empty">
                <div id="unity-progress-bar-full"></div>
            </div>
        </div>
        <div id="unity-warning"></div>
        <!--<div id="unity-footer">
            <div id="unity-webgl-logo"></div>
            <div id="unity-fullscreen-button"></div>
            <div id="unity-build-title">Your Snake</div>
        </div>-->
    </div>
    <script>
        const container = document.querySelector('#unity-container');
        const canvas = document.querySelector('#unity-canvas');
        const loadingBar = document.querySelector('#unity-loading-bar');
        const progressBarFull = document.querySelector('#unity-progress-bar-full');
        //const fullscreenButton = document.querySelector('#unity-fullscreen-button');
        const warningBanner = document.querySelector('#unity-warning');

        // Shows a temporary message banner/ribbon for a few seconds, or
        // a permanent error message on top of the canvas if type=='error'.
        // If type=='warning', a yellow highlight color is used.
        // Modify or remove this function to customize the visually presented
        // way that non-critical warnings and error messages are presented to the
        // user.
        function unityShowBanner(msg, type) {
            function updateBannerVisibility() {
                warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
            }

            const div = document.createElement('div');
            div.innerHTML = msg;
            warningBanner.appendChild(div);
            if (type === 'error') div.style = 'background: red; padding: 10px;';
            else {
                if (type === 'warning') div.style = 'background: yellow; padding: 10px;';
                setTimeout(function () {
                    warningBanner.removeChild(div);
                    updateBannerVisibility();
                }, 5000);
            }
            updateBannerVisibility();
        }

        const buildUrl = 'Build';
        const loaderUrl = buildUrl + '/Build.loader.js';
        const config = {
            dataUrl: buildUrl + '/Build.data.unityweb',
            frameworkUrl: buildUrl + '/Build.framework.js.unityweb',
            codeUrl: buildUrl + '/Build.wasm.unityweb',
            streamingAssetsUrl: 'StreamingAssets',
            companyName: 'EzioMercer',
            productName: 'Your Snake',
            productVersion: '0.1.0',
            showBanner: unityShowBanner,
        };

        // By default Unity keeps WebGL canvas render target size matched with
        // the DOM size of the canvas element (scaled by window.devicePixelRatio)
        // Set this to false if you want to decouple this synchronization from
        // happening inside the engine, and you would instead like to size up
        // the canvas DOM size and WebGL render target sizes yourself.
        // config.matchWebGLToCanvasSize = false;

        /*if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
            // Mobile device style: fill the whole browser client area with the game canvas:

            const meta = document.createElement('meta');
            meta.name = 'viewport';
            meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';
            document.getElementsByTagName('head')[0].appendChild(meta);
            container.className = 'unity-mobile';
            canvas.className = 'unity-mobile';

            // To lower canvas resolution on mobile devices to gain some
            // performance, uncomment the following line:
            // config.devicePixelRatio = 1;

            unityShowBanner('WebGL builds are not supported on mobile devices.');
        } else {
            // Desktop style: Render the game canvas in a window that can be maximized to fullscreen:

            canvas.style.width = '100%';
            canvas.style.height = '100%';
        }*/

        canvas.style.width = '100%';
        canvas.style.height = '100%';

        loadingBar.style.display = 'block';

        const script = document.createElement('script');
        script.src = loaderUrl;
        script.onload = () => {
            createUnityInstance(canvas, config, (progress) => {
                progressBarFull.style.width = 100 * progress + '%';
            }).then((unityInstance) => {
                loadingBar.style.display = 'none';
                // fullscreenButton.onclick = () => {
                //  unityInstance.SetFullscreen(1);
                // };
            }).catch((message) => {
                alert(message);
            });
        };
        document.body.appendChild(script);
    </script>
</body>
</html>

```

CSS file

```
body { padding: 0; margin: 0 }
#unity-container { position: absolute }
#unity-container.unity-desktop { left: 50%; top: 50%; transform: translate(-50%, -50%) }
#unity-container.unity-mobile { width: 100%; height: 100% }
#unity-canvas { background: #231F20 }
.unity-mobile #unity-canvas { width: 100%; height: 100% }
#unity-loading-bar { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: none }
#unity-logo { width: 154px; height: 130px; background: url('unity-logo-dark.png') no-repeat center }
#unity-progress-bar-empty { width: 141px; height: 18px; margin-top: 10px; margin-left: 6.5px; background: url('progress-bar-empty-dark.png') no-repeat center }
#unity-progress-bar-full { width: 0%; height: 18px; margin-top: 10px; background: url('progress-bar-full-dark.png') no-repeat center }
#unity-footer { position: relative }
.unity-mobile #unity-footer { display: none }
#unity-webgl-logo { float:left; width: 204px; height: 38px; background: url('webgl-logo.png') no-repeat center }
#unity-build-title { float: right; margin-right: 10px; line-height: 38px; font-family: arial; font-size: 18px }
#unity-fullscreen-button { float: right; width: 38px; height: 38px; background: url('fullscreen-button.png') no-repeat center }
#unity-warning { position: absolute; left: 50%; top: 5%; transform: translate(-50%); background: white; padding: 10px; display: none }

```

# Answer
> 0 votes
Many thanks to the DMGregory for help in this matter

The problem was that I have a script which manipulate with `camera.rect`:

```
using UnityEngine;

public class GameAspectRatio : MonoBehaviour {
    [SerializeField] private new Camera camera;
    [SerializeField] private float targetAspect;

    private void Awake() {
        // determine the game window's current aspect ratio
        float windowAspect = (float) Screen.width / (float) Screen.height;

        // current viewport height should be scaled by this amount
        float scaleHeight = windowAspect / targetAspect;
        float scaleWidth = 1.0f / scaleHeight;

        camera.rect = scaleHeight < 1.0f ?
            //adding letterboxes
            new Rect(0, (1.0f - scaleHeight) / 2.0f, 1, scaleHeight) :
            //adding pillarboxes
            new Rect((1.0f - scaleWidth) / 2.0f, 0, scaleWidth, 1);
    }
}

```

After this advice I edited my script to this:

```
using UnityEngine;

public class GameAspectRatio : MonoBehaviour {
    [SerializeField] private new Camera camera;
    [SerializeField] private float targetAspect;

    private void Awake() {
        // determine the game window's current aspect ratio
        float windowAspect = (float) Screen.width / (float) Screen.height;

        // current viewport height should be scaled by this amount
        float scaleHeight = windowAspect / targetAspect;
        float scaleWidth = 1.0f / scaleHeight;

        if (scaleHeight < 1.0f) {
            //adding letterboxes
            camera.rect = new Rect(0, (1.0f - scaleHeight) / 2.0f, 1, scaleHeight);
        }
    }
}

```

And now everything is working fine:

---
Tags: unity, html-canvas, webgl, resolution, configuration
---


# Question
Title: Simple GLSL shader results in "1: '€' : unexpected token" compilation error
I have a very simple shader here:

```
#version 460

layout (location = 0) in vec3 inPos;
layout (location = 0) out vec3 outPos;

void main() {
    gl_Position = vec4(inPos.x, inPos.y, inPos.z, 1.0);
    outPos = inPos;
}

```

and compiled the shader using the command:

```
glslangValidator -V -G -o triangle.vert.spv triangle.vert

```

and the compiler turned 3 errors:

```
error : #version: ES shaders for SPIR-V require version 310 or higher
error : Source\Shaders\triangle.vert:1: '€' : unexpected token
error : Source\Shaders\triangle.vert:1: '' : compilation terminated

```

It seems that the compiler is having trouble reading the very first line of the code. I am very sure I don't include a euro sign in this, and the syntax should be correct.

How should I fix this?

# Answer
Turns out this problem was indeed caused by very first bytes of the file - BOM (https://en.wikipedia.org/wiki/Byte\_order\_mark)

I am using Jetbrains Rider, for me the fix was `File Encoding -> Remove BOM`.
> 2 votes

---
Tags: opengl, glsl
---


# Question
Title: How can I reduce the file size of my Unity build that contains lots of audio files?
I create a mobile app in **Unity** that use lots of MP3 files.

Would you please tell me if there are any simple and easy softwares or tools that can reduce the MP3 file size ?

Or does **Unity** have a way to reduce the MP3 file size ?

# Answer
> 4 votes
According to the documentation, Unity will re-encode any audio file you import into it anyway, so the compression of the source files isn't that relevant. And every time you re-encode an audio file in a different format (or the same format with different quality settings) you lose quality while not necessarily also reducing filesize. The default encoding format when you import a clip into Unity is "PCM" which doesn't compress at all. So by pre-compressing the audio files and then letting Unity convert them into PCM, you achieve nothing except making it sound worse.

So the recommended workflow for working with long audio files is:

1. Get a copy of the audio clip in the highest quality and as few encoding steps away from the master recording you can get.
2. Import it into Unity.
3. Go to the import settings of the audio clip asset.
4. Under "Compression Format" pick "Vorbis" or "MP3" (which one you can choose depends on your build target)
5. Adjust the "Quality" slider to get a good compromise between file size and quality.
6. When the input clip is in stereo, then depending on how the clip is used in your game, you might also consider to enable "force to mono" which usually cuts the filesize down to less than half of the original. Mono is usually what you want anyway for sounds which are supposed to be played positionally. It also usually works well for voiceovers as long as you don't have more than one person speaking in the same clip (when you have a conversation between multiple characters, then it's best to record their individual lines as mono clips and use positional audio to make the voice of each character come from a different direction). But I would not recommend it for non-diegetic background music that was produced in stereo, because that will probably make the experience worse and go against the artistic vision of the one who produced it.

The inspector will tell you the filesize taken by the audio clip in the finished game and you can click the "play" button on top of the histogram image below to preview the file. Note that the preview only updates when you click on "Apply".

---
Tags: unity, sound, music
---


# Question
Title: How do I keep my scene layout from getting messed up when resizing my windows?
Whenever my *scene* window gets resized the layout gets messed up. This included when I move or resize other views in my workflow in such a way that it changes the size of the scene window (see screenshots). This makes Unity nearly unusable. How do I prevent this nonsense?

Correct scene layout:

Messed up scene layout:

# Answer
I figured it out. The camera has several layers of background to it. I had to go to each one and click the "enable the constrained proportions" button.
> 0 votes

---
Tags: unity
---


# Question
Title: Blender export to unity via FBX: correct rotation
I know that the question of the right blender for unity export has been asked quite often, but it is based on the problem that the models are rotated 90 degrees.

In my case, the FBX objects are rotated 180 degrees (relative to the "up" axis) after importing them into unity. That means I see the back in Unity.

No matter how much I adjust the axis settings in the export dialog within Blender, the problem persists. I never use the "Apply Transform" option because it can cause problems with animated objects.

Can someone tell me how I can solve this?

# Answer
I use these settings in Blender and Unity, respectively:

In blender, you should change the "forward" to be whichever direction you are actually using as forward, of course.
> 0 votes

# Answer
When you go to File -\> Export -\> FBX in Blender, you then will find on the right side, a panel that contains a section called 'Transform', there will be settings such as 'Scale', 'Forward', and 'Up'.

Adjust the 'Forward' and 'Up' settings to change the natural exported rotation.

It might take a couple tries to find the correct orientation but you'll get it.
> -1 votes

---
Tags: unity, blender, fbx
---


# Question
Title: Why do my game objects become invisible as soon as I attach the material to which this shader script is applied?
I wrote a shader script that is an extension of the Sprite-Lit shader in previous Unity versions' standard assets in an attempt to feather the edges of a sprite using additive blending. Here is the script:

```
Shader "Unlit/Sprite-Lit-Add-Feathering"
{
    Properties
    {
        [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
        _Color("Tint", Color) = (1,1,1,1)
        [MaterialToggle] PixelSnap("Pixel snap", Float) = 0
        [PerRendererData] _AlphaTex("External Alpha", 2D) = "white" {}
        [PerRendererData] _AlphaTexST("External Alpha ST", 2D) = "white" {}

        // Gradient property for the feathering effect
        [PerRendererData] _Feathering("Feathering", 2D) = "white" {}
    }

    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        // Set the blend mode to "Blend One One" to enable additive blending
        Blend One One

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 3.0

            #include "UnityCG.cginc"

            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                half2 texcoord  : TEXCOORD0;
            };

            v2f vert(appdata_t IN, uniform fixed4 _Color)
            {
                v2f OUT;
                OUT.vertex = UnityObjectToClipPos(IN.vertex);
                OUT.texcoord = IN.texcoord;
                OUT.color = IN.color * _Color;
                #ifdef PIXELSNAP_ON
                OUT.vertex = UnityPixelSnap (OUT.vertex);
                #endif

                return OUT;
            }

            fixed4 frag(v2f IN, uniform sampler2D _MainTex, uniform sampler2D _Feathering) : SV_Target
            {
                // Sample the texture and multiply it by the vertex color
                fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;

                // Sample the feathering gradient to get the feathering factor
                float featheringFactor = tex2D(_Feathering, IN.texcoord).r;

                // Multiply the color by the feathering factor to achieve the feathering effect
                c *= featheringFactor;

                // Return the resulting color
                return c;
            }

            ENDCG
        }
    }
}

```

However, as soon as I attach the material to which this script is applied to to any 2d sprite game object, the game object simply becomes invisible in both scene view and game view. Why is this the case, and what should I modify in order to fix this problem?

# Answer
my guess is your vertex colors are all zero - try changing `COLOR` in your vertex structs to `COLOR0`

If that doesn't work, maybe try working off this example for basic vertex lighting visualization
> 0 votes

---
Tags: unity, shaders, fragment-shader, unity-shader-graph
---


title: Head bobbing never stops

text:
# Question
Title: Head bobbing never stops
I have this code on my player that makes the camera sway whenever I move, but the camera just never stops bobbing and swaying even when I'm standing still.

Here is the code:

```
{
    [SerializeField] private bool _enable = true;

    [SerializeField, Range(0, 0.1f)] private float _amplitude = 0.015f;
    [SerializeField, Range(0, 30)] private float _frequency = 10.0f;

    [SerializeField] private Transform _camera = null;
    [SerializeField] private Transform _cameraHolder = null;

    private float _toggleSpeed = 3.0f;
    private Vector3 _startPos;
    private Rigidbody _controller;

    private void Awake()
    {
        _controller = GetComponent<Rigidbody>();
        _startPos = _camera.localPosition;
    }

     void Update()
    {
        ResetPosition();

         if (!_enable) return;

        CheckMotion();
        _camera.LookAt(FocusTarget());
        PlayMotion(FootStepMotion());

    }

    private void PlayMotion(Vector3 motion)
    {
       _camera.localPosition += motion;
    }

    private void CheckMotion()
    {

        float speed = new Vector3(_controller.velocity.x, 0, _controller.velocity.z).magnitude;

        if (speed < _toggleSpeed) return;
    }

    private Vector3 FootStepMotion()
    {
        Vector3 pos = Vector3.zero;
        pos.y += Mathf.Sin(Time.time * _frequency) * _amplitude;
        pos.x += Mathf.Cos(Time.time * _frequency / 2)* _amplitude * 2;
        return pos;
    }

    private void ResetPosition()
    {
        if (_camera.localPosition == _startPos) return;
        _camera.localPosition = Vector3.Lerp(_camera.localPosition, _startPos, 1 * Time.deltaTime);
    }

    private Vector3 FocusTarget()
    {
        Vector3 pos = new Vector3(transform.position.x, transform.position.y + _cameraHolder.localPosition.y, transform.position.z);
        pos += _cameraHolder.forward * 15.0f;
        return pos;
    }
}

```

# Answer
> 0 votes
DMGregory at it again, killin it with another solution in the comments

> Your CheckMotion function does nothing. It looks like you're trying to use it to abort Update early, but a "return" in one method just returns from that method itself, it does not force its calling method to also return.

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


# Question
Title: Why does Unity lack many of the string manipulation functions?
I just learned that Unity lacks the `string.Where` function, the `string.Take` function, and the `string.Select` function.

This is actually quite inconvenient, as I'm trying to port over an old code base relating to string manipulation that heavily utilizes these functions, and I was wondering why/if there's any coherent rationale for the lack of these functions?

# Answer
Unity does have these methods:

```
using UnityEngine;
using System.Linq;

public class StringWhere : MonoBehaviour
{
    void Start()
    {
        string s = "Hello World";
        foreach (var letter in s.Where(c => c == 'o')) {
            Debug.Log(letter);
        }
    }
}

```

Output in console:

I tested this with 2021.3.11 (oldest Unity install I have right now), but it probably works the same with any Unity version recent enough to support C# version 3.0 (the one that introduced Linq). I am too lazy right now to research when that happened, but it was many years ago.

The reason why those methods are unavailable in your code is probably because you are missing the `using System.Linq` directive.

Another explanation could be that you are writing Burst-compiled code for the new and experimental ECS architecture. The Linq framework uses managed objects, so it doesn't work in Burst-compiled code. (but if you were using ECS, you should have probably noticed by now that pretty much nothing standard works in Burst-compiled code)
> 3 votes

---
Tags: unity
---


# Question
Title: How to create global function for all .JSLIB files?
I can't understand how to work with `.jslib` files. I don't understand the syntax of this type of file. Also I couldn't find any easy explanation of it

The problem started when I tried to make two functions global for all `.jslib` files:

```
/**
 * @param {string} str
 * @returns {string}
 */
function StrJSToStrCS (str) {
    const bufferSize = lengthBytesUTF8(str) + 1;
    const buffer = _malloc(bufferSize);
    stringToUTF8(str, buffer, bufferSize);
    return buffer;
}

/**
 * @param {string} str
 * @returns {string}
 */
function StrCSToStrJS (str) {
    return UTF8ToString(str);
}

```

What I already tried:

* To define these two functions in the same file

```
function StrJSToStrCS (str) {
    const bufferSize = lengthBytesUTF8(str) + 1;
    const buffer = _malloc(bufferSize);
    stringToUTF8(str, buffer, bufferSize);
    return buffer;
}

function StrCSToStrJS (str) {
    return UTF8ToString(str);
}

const lib = {
    Hello: function () {
        return StrJSToStrCS('HELLO WORLD!');
    },

    ConsoleLog: function (str) {
        console.log(StrCSToStrJS(str));
    }
};

mergeInto(LibraryManager.library, lib);

```
* To define these two functions in `script` tag in `.html` after reading this. If it's important the script tag I inserted at the bottom of `body` tag

```
<script>
    function StrJSToStrCS (str) {
        const bufferSize = lengthBytesUTF8(str) + 1;
        const buffer = _malloc(bufferSize);
        stringToUTF8(str, buffer, bufferSize);
        return buffer;
    }

    function StrCSToStrJS (str) {
        return UTF8ToString(str);
    }
</script>

```

```
const lib = {
    Hello: function () {
        return StrJSToStrCS('HELLO WORLD!');
    },

    ConsoleLog: function (str) {
        console.log(StrCSToStrJS(str));
    }
};

mergeInto(LibraryManager.library, lib);

```
* To define these functions in `.jspre` file after reading this

> the .jspre files are added to the build using the --pre-js option, while the .jslib are added using the --js-library option

`.jspre` file:

```
function StrJSToStrCS (str) {
    const bufferSize = lengthBytesUTF8(str) + 1;
    const buffer = _malloc(bufferSize);
    stringToUTF8(str, buffer, bufferSize);
    return buffer;
}

function StrCSToStrJS (str) {
    return UTF8ToString(str);
}

```

`.jslib` file:

```
const lib = {
    Hello: function () {
        return StrJSToStrCS('HELLO WORLD!');
    },

    ConsoleLog: function (str) {
        console.log(StrCSToStrJS(str));
    }
};

mergeInto(LibraryManager.library, lib);

```
* To simply define these functions as methods in the same object:

```
const lib = {
    StrJSToStrCS: function(str) {
        const bufferSize = lengthBytesUTF8(str) + 1;
        const buffer = _malloc(bufferSize);
        stringToUTF8(str, buffer, bufferSize);
        return buffer;
    },

    StrCSToStrJS: function(str) {
        return UTF8ToString(str);
    },

    Hello: function() {
        return this.StrJSToStrCS('HELLO WORLD!');
    },

    ConsoleLog: function(str) {
        console.log(this.StrCSToStrJS(str));
    }
}

mergeInto(LibraryManager.library, lib);

```

But whatever I do, he writes every time in console that `StrJSToStrCS/StrCSToStrJS` is not defined

I don't understand at all why the last method doesn't work. Isn't `lib` just a simple object?

Is it possible to make these two functions global for all `.jslib` files?

# Answer
Finally I found the answer!

In `.jspre` file I had to write:

```
Module.StrJSToStrCS = function(str) {
    const bufferSize = lengthBytesUTF8(str) + 1;
    const buffer = _malloc(bufferSize);
    stringToUTF8(str, buffer, bufferSize);
    return buffer;
}

Module.StrCSToStrJS = function(str) {
    return UTF8ToString(str);
}

```

and then in `.jslib` file call these functions like this:

```
const lib = {
    Hello: function() {
        return gameInstance.Module.StrJSToStrCS('HELLO WORLD!');
    },

    ConsoleLog: function(str) {
        console.log(gameInstance.Module.StrCSToStrJS(str));
    }
}

mergeInto(LibraryManager.library, lib);

```
> 3 votes

# Answer
I found the official documentation very useful when I was working with webgl and unity and also has some examples. Interaction with browser scripting

Its a library file and has to be placed in Plugins folder.

In case this doesn't help, please post the Unity side of things also to get more understanding.
> 0 votes

---
Tags: unity, javascript, webgl
---


# Question
Title: Perlin algorithm generates weird artifacts
I'm writing a Perlin noise generator in C++ for terrain generation but the generator produces weird JPEG-like artifacts instead of proper noise.

I've tried doing it using C# in Unity and confirmed the results are the same. When I swap the generator for Unity's, it generates correctly. The FBM function is working properly with the Unity implementation. It must be the Perlin noise itself then. This is the code:

```
public class Perlin
{
    private static float Grad(int hash, float x, float y)
    {
        return ((hash & 1) == 0 ? x : -x) + ((hash & 2) == 0 ? y : -y);
    }
    private static float Fade(float v)
    {
        return v * v * v * (v * (v * 6.0f - 15.0f) + 10.0f);
    }
    public static float ImprovedPerlin(float x, float y)
    {
        int X = (int)Mathf.Floor(x) & 255;
        int Y = (int)Mathf.Floor(y) & 255;

        x -= Mathf.Floor(x);
        y -= Mathf.Floor(y);

        float U = Fade(x);
        float V = Fade(y);

        int A = (Perms[X] + Y) & 255;
        int B = (Perms[X + 1] + Y) & 255;

        return Mathf.Lerp(V,
                Mathf.Lerp(U,
                    Grad(Perms[A], x, y),
                    Grad(Perms[B], x - 1.0f, y)
                ),
                Mathf.Lerp(U,
                    Grad(Perms[A + 1], x, y - 1.0f),
                    Grad(Perms[B + 1], x - 1.0f, y - 1.0f)
                )
            );
    }

    private static int[] Perms = new int[257] {
        151, 160, 137,  91,  90,  15, 131,  13, 201,  95,  96,  53, 194, 233,   7, 225,
        140,  36, 103,  30,  69, 142,   8,  99,  37, 240,  21,  10,  23, 190,   6, 148,
        247, 120, 234,  75,   0,  26, 197,  62,  94, 252, 219, 203, 117,  35,  11,  32,
        57, 177,  33,  88, 237, 149,  56,  87, 174,  20, 125, 136, 171, 168,  68, 175,
        74, 165,  71, 134, 139,  48,  27, 166,  77, 146, 158, 231,  83, 111, 229, 122,
        60, 211, 133, 230, 220, 105,  92,  41,  55,  46, 245,  40, 244, 102, 143,  54,
        65,  25,  63, 161,   1, 216,  80,  73, 209,  76, 132, 187, 208,  89,  18, 169,
        200, 196, 135, 130, 116, 188, 159,  86, 164, 100, 109, 198, 173, 186,   3,  64,
        52, 217, 226, 250, 124, 123,   5, 202,  38, 147, 118, 126, 255,  82,  85, 212,
        207, 206,  59, 227,  47,  16,  58,  17, 182, 189,  28,  42, 223, 183, 170, 213,
        119, 248, 152,   2,  44, 154, 163,  70, 221, 153, 101, 155, 167,  43, 172,   9,
        129,  22,  39, 253,  19,  98, 108, 110,  79, 113, 224, 232, 178, 185, 112, 104,
        218, 246,  97, 228, 251,  34, 242, 193, 238, 210, 144,  12, 191, 179, 162, 241,
        81,  51, 145, 235, 249,  14, 239, 107,  49, 192, 214,  31, 181, 199, 106, 157,
        184,  84, 204, 176, 115, 121,  50,  45, 127,   4, 150, 254, 138, 236, 205,  93,
        222, 114,  67,  29,  24,  72, 243, 141, 128, 195,  78,  66, 215,  61, 156, 180,
        151
    };
}

```

# Answer
The comment provided by DMGregory solved the issue here:

> Did you mean to use U & V as the third parameter of your lerps (the blend factor), rather than as one of the endpoints of the interpolation?

The corrected blending of the ImprovedPerlin function would look like this:

```
// ...
return Mathf.Lerp(Mathf.Lerp(
                    Grad(Perms[A], x, y),
                    Grad(Perms[B], x - 1.0f, y)
                    U,
                ),
                Mathf.Lerp(
                    Grad(Perms[A + 1], x, y - 1.0f),
                    Grad(Perms[B + 1], x - 1.0f, y - 1.0f),
                    U,
                ),
                V
            );
// ...

```
> 1 votes

# Answer
The comment provided by DMGregory solved the issue here:

> Did you mean to use U & V as the third parameter of your lerps (the blend factor), rather than as one of the endpoints of the interpolation?
> 0 votes

---
Tags: unity, c#, c++, perlin-noise
---


# Question
Title: Visual Studio showing only one code suggestion?
I'm on visual studio 2022 (not visual studio code) for unity, and for some reason, visual studio will only display one suggestion, and asks me to press Alt+. to see the next one. IntelliSense is installed and I have:

* checked preferences
* Tried to resize the box with the mouse
* Browsed the internet

How do I fix this? If it's a design choice, it's a very bad one. I want to get the dropdown that shows me all of them.

# Answer
Found it after one more hour of browsing: Visual studio doesn't like it when you change Program Files (x86) directories to other drives
> 0 votes

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


# Question
Title: when do anti-piracy measures become malware?
I have been implementing anti-piracy measures in my game and I'm wondering at what point do things start getting shady?

For example, if I know with 10000% certainty that the software is pirated, I was going to do things like crash or freeze the PC of the user. Would this be legal or make my game into malware? I really don't want people running around with pirated copies of my game.

Obviously I am not planning on doing anything that violates user privacy, etc. I will just make the application fail and maybe crash the user's pc.

# Answer
> 3 votes
> I was going to do things like crash or freeze the PC of the user. Would this be legal?

No, a program that exceeds its intended purpose is unlawful, whether illegally installed or not.

You are welcome to block your own program as much as you want, but purposefully affecting any other part of the system is illegal.

Sony found this out the hard way with the BMG copy protection scandal, don't follow suit.

---
Tags: licensing, piracy
---


# Question
Title: TCP packets getting more and more delay as time goes by
I have a two processes - a client sending player input data to the server, via TCP.

Right now, it's sending 60 input updates per second. The first update arrives promptly in my test system, where both processes are in the same machine. They print "frame 1" at the same time.

Over time though, the client is at frame 120, and ostensibly sending frame 120, but the server is only just receiving frame 60. The gap goes wider and wider as time goes.

The packets themselves are quite small - 100 bytes per update. This doesn't seem like a big amount?

Is there something built into TCP that is causing this slowdown? I adapted my webserver TCP code to use for game development, and would rather not have to implement UDP..

# Answer
This is why game servers always use UDP instead of TCP for time sensitive data.

TCP is used for initial connections, game lobbies, and parameters, shared variables... Once TCP crosses a multi-homed router, timing becomes unimportant.

The negotiation, reliability, *sequencing* are all the trademarks of TCP. TCP requires acknowledgements for every packet(within a window), and anything received out of order will wait until it is in order.

Use UDP and ignore out of order sequence packet numbers. The usual solution is to include the last couple of frames deltas from and with the current frames absolute data.

Many papers have been written on the topic, that includes anti-cheating.

---

Solve the problem by adding timestamps, and ignoring or blending late frames.

The accumulation problem cannot be solved without a separate connection or 2 or 3...

---

You could look into WebRTC it is a broswer based protocol that leverages the advantages of UDP and provides a more simplistic interface. This solution assumes your client is browser based.
> 1 votes

# Answer
That sort of latency could come from Nagle's Algorithm buffering the data behind your back. Try disabling it using `TCP_NODELAY`.

See: https://en.wikipedia.org/wiki/Nagle%27s\_algorithm#Interactions\_with\_real-time\_systems
> 0 votes

---
Tags: networking
---


# Question
Title: What is the minimum number of points in a convex hull in most engines?
A convex hull shape in a 3D game engine defined by vertices needs at least 4 points in order to have volume, since that would make it a tetrahedron. However, some game engines may support fewer points, such as 3 points for a triangle, 2 points for a line, and 1 point is just a point.

This question is asking what the minimum sizes are between various game engines. If I am defining a standard for convex hulls and I want it to be portable between game engines, what is the minimum I should allow in the standard? If I have a convex hull that's just a line or a triangle, will that shape be usable in Unity, Unreal, Godot, Blender, Bullet, Jolt, PhysX, Havok, etc?

# Answer
The minimum common shape is a box (or plane, to which the following does not apply). A plane intersection is a simple transform, subtraction and sign check.

So the question becomes what is the minimum size for each of these objects, and that depends on there being common scales or axes across engines, a continuous collision algorithm, if used, and/or the number sub-steps allowed(user configurable in most cases).

None of which are true for all cases.

A perfect universal solution does not exist.

The grunt work is up to you.
> 0 votes

---
Tags: physics, standards, convex-hull, convex
---


# Question
Title: correct matrix to draw mesh as flat object
I need to draw a tilemap for a 2d game. For that I created vertices with their relative positions already hard baked. The coordinates start top-left with (0f, 0f) and z is always 0.

I rendered them to the `rendertarget` with the following view matrix (world and projection are both `Identity`):

```
Matrix view = Matrix.CreateOrthographic(this.miniMapRenderTarget.Width, this.miniMapRenderTarget.Height, 0, 1)
     * Matrix.CreateScale((float)(this.miniMapRenderTarget.Width / (this.map.Size.X * this.map.TileSize.X * 2)))
     * Matrix.CreateTranslation(-0.5f, -0.5f, 0);

```

I noticed that all stuff was just rendered to the top-right quadrant of the texture so I added a translation of -0.5 for x and y. This works find, so far.

The only bug still is that Y seem to be displayed inverted, so top is bottom. I tried to fix this by multiplying `Matrix.CreateScale(1, -1, 1)` to the matrix but then I do not see anything rendered to the texture. I guess I am doing something fundamentally wrong here and the matrix has to be constructed in a different way?

# Answer
As suggested by DMGregory, setting cullmode to none ensures that the inverted Y axis by scaling does not cull away objects. **Note: It would be even better to just invert the cullmode, e.g. setting it to counterclockwise when it was clockwise and vice versa.**

```
    this.graphicsDevice.RasterizerState = RasterizerState.CullNone;

    var view = Matrix.CreateOrthographic(this.miniMapRenderTarget.Width, this.miniMapRenderTarget.Height, 0, 1)
         * Matrix.CreateTranslation(-1, -1, 0)
         * Matrix.CreateScale(1, -1, 1);

```

I would have preferred a solution that does not enforce modifying the cullmode but at least it works now.
> 1 votes

---
Tags: camera, monogame, matrix, rendertexture
---


title: Tilemap missing collision options?

text:
# Question
Title: Tilemap missing collision options?
I've been having a lot of trouble getting tiles to have collision in the newest Godot 4 beta10.

I thought there was supposed to be a physics tab that would give collision options like in previous betas, but maybe that was removed?

# Answer
The way you edit tile collision shapes has changed in Godot 4.

1. First click the `TileSet` assets in the tilemap inspector, and additional editing options appear.

2. Add elements in the `Physics Layers` tab.

3. The physical layer you just added will appear in the `Paint` tab, click it.

4. Then you can edit the collision information of this physical layer, hope this helps.
> 4 votes

---
Tags: collision-detection, tilemap, godot-4
---


# Question
Title: Why does a script named "GameManager" have a ⚙ icon instead of a #⃣ icon in the project assets?
I am learning to use Unity for game development and one of the scripts in the Unity project window has a weird icon vs the other scripts. I'm not sure if it's something I should be concerned about or not. Does anyone know why this occurred?

# Answer
As another user said in the comment, this is a bug left over from an older version, and the official unity team decided not to fix it.

This is the report:

> The Icon for a MonoBehaviour script in the Project view can change if it is given particular names. Two examples are 'Folder' and 'GameManager', but there are almost certainly others.

> RESOLUTION NOTE (2019.2.X): Due to low severity, we decided not to change this behaviour.

This situation also occurs with other keywords, for example, if you name a script as `Folder`, its icon will become the icon of the folder. It has no effect on the correctness of the program. You can put your `GameManager` class under a custom namespace to solve the display problem.

And, this question shows how to find all keywords with a special icon.
> 7 votes

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


# Question
Title: Confused about how specific bools or flags are actually accessed and used by other scripts
I have a problem which I'm sure can be abstracted to some larger concept but I don't really have the knowledge to know what to google. I'll just explain what im trying to do and if you can please tell me how to do it, or what I should be doing instead.

I have a game I am adding a save system to, I haven't even got to the saving part and am faltering.

I have added a dataScript which holds all the game data. In this there are 20 flags(bools) that say whether 20 different doors are open. Every door is controlled with a single doorScript.

Now my issue is how do my individual doors access the specific bool that is relevant to them from the dataScript? Normally I would solve this by having an array of bools in the dataScript, and using a public int in the doorScript to choose the correct bool array index. This isn't really workable when the array gets large however as I have to remember which index corresponds to which bool.

I have seen dictionaries as a possible solution but I can't help but feel I'm making a more fundamental mistake and should be doing something completely different.

Thanks

# Answer
For saving the state of multiple objects like this, there's a lot of different techniques you can use depending on just how extensible you'd like this to be.

I'd of course recommend storing all of your data in JSON - but how you architect that state management is up to you. If you'd like a single class to hold a collection of all these doors' data, you can assign each door a GUID and have that be the access key for your saved data.

A simple way to do this automatically would be something like

```
// your door script
[SerializeField] string saveID;

bool isOpen;

void OnValidate
{
    if(string.IsNullOrWhitespace(saveID))
         saveID = Guid.NewGuid().ToString();
}

void SaveData()
{
     doorSaveManager.Open[saveID] = isOpen;
}

void LoadData()
{
   isOpen = doorSaveManager.Open[saveID]
}

```

You can also opt for a more robust serialized GUID

However, perhaps it may be best to think of the problem as a more holistic level-specific problem, rather than a door-specific problem. If you have a Save system that focuses on saving the state of anything in the entire level, then you can implement an interface for getting save data from any object in the level.

The following pseudo-code is just an example:

    interface ISaveable
    {
       SaveData MyData { get; }
    }

    [System.Serializable]
    abstract class SaveableState
    {
        public string Guid {get; private set; }
    }

    [System.Serializable]
    class DoorState : SaveableState
    {
        public bool IsOpen;
    }

    class Door : Monobehaviour, ISaveable
    {
       DoorSaveData doorState;

       SaveableState MyData => doorState;

       void Open()
       {
           PlayDoorAnimation(true);
           doorState.IsOpen = true;
       }

       void Close()
       {
           PlayDoorAnimation(false);
           doorState.IsOpen = false;
       }
    }

    class LevelStateSaver: MonoBehaviour
    {
        void SaveLevel()
    {

        var allSaveables = FindObjectsOfType<ISaveable>(true);
        var allSaveData = allSaveables.Select(x => x.MyData);

        LevelSave dataToSave = new LevelSave(allSaveData);

        // you may need to save each type specifically - im not that familiar with serializing inherited types into a single save file. It also depends on your Json serializer - you can use unity's JSONUtility or Newtonsoft. if you do need to do that, you can do the following:

        var doorData = allSaveData.Where(x => x is DoorState);
        var dropData = allSaveData.Where(x => x is DropState);

        LevelSave dataToSave = new LevelSave(doorData, dropData);

    }

    [System.Serializable]
    class LevelSave
    {
       List<SaveableState> states

       public LevelSave(List<SaveableState> states){
           this.states = states;
       }

       public Dictionary<string, SaveableState> GetDictionary()
       {
           return states.ToDictionary(x => x.id);
       }
    }

    // if you have to save on a per-type basis
    [System.Serializable]
    class LevelSave
    {
        LevelSaveGeneric<DoorState> doorSaves;
        LevelSaveGeneric<DropState> dropSaves;

       public LevelSave(List<DoorState> doors, List<DropState> drops){
           this.doorSaves = new(doors);
           this.dropSaves = new(drops);
       }

        [System.Serializable]
        class LevelSaveGeneric<T> where T : SaveableState
        {
            List<T> states;
            public LevelStateGeneric(List<T> states)
            {
                this.states = states;
            }
        }

    }

```

> 3 votes

---
Tags: unity, savegame, data
---


# Question
Title: How to create instance of child scriptable object base on string?
I am working on an Unity3D project and I have a base scriptable object and several child classes that inherit from this parent class.

```
public class Animal:ScriptableObject{}
public class Cat: Animal{}
public class Dog: Animal{}

```

I have a list of strings containing the name of the animals. I would like to create a correct instance base on a given string. My current workaround is using a switch statement

```
public Animal CreateAnimalFromString(string animalName)
{
   switch (animalName)
   {
     case "Cat":
         return ScriptableObject.CreateInstance<Cat>();
     case "Dog":
         return ScriptableObject.CreateInstance<Dog>();
     default:
         return ScriptableObject.CreateInstance<Animal>();
   }
}

```

This works fine if I have a small number of child classes, but is there a better way to do this?Thank you!

# Answer
> 2 votes
There is another version of ScriptableObject.CreateInstance that allows you to create instances by `Type`:

> public static ScriptableObject CreateInstance(Type type);

You can use the relevant functions of the `System.Reflection` package to find the `Type` through the type name string:

```
Type type = Type.GetType("Namespace.MyClass, MyAssembly");

```

or

```
Assembly assembly = typeof(SomeTypeInTheSameAssembly).Assembly;
Type type = assembly.GetType("Namespace.MyClass");

```

code:

```
using System;
using System.Reflection;
using UnityEngine;

namespace MyNameSpace
{
    public class Animal : ScriptableObject { }
    public class Cat : Animal { }
    public class Dog : Animal { }

    public class GameUtil
    {
        public static Animal CreateAnimalFromString(string animalName)
        {
            Assembly assembly = typeof(Animal).Assembly;
            Type type = assembly.GetType($"MyNameSpace.{animalName}");
            return ScriptableObject.CreateInstance(type) as Animal;
        }
    }
}

```

If you modify the design and don't want to rely on `ScriptableObject`(just as suggested), you can also create instances directly through reflection:

```
public static Animal CreateAnimalFromString(string animalName)
{
    Assembly assembly = typeof(Animal).Assembly;
    return assembly.CreateInstance($"MyNameSpace.{animalName}") as Animal;
}

```

In addition, the use of reflection is a low-efficiency approach. Generally speaking, it should be avoided as much as possible. A small switch structure may be more suitable for the current situation than reflection.

As for the problem of subsequent modification that you are worried about in the comments, it may be solved with some paperwork tricks. Here I recommend to you the **multi-line editing** function that most modern IDE software has.

Create:

Modify:

---
Tags: unity, scriptable-object
---


# Question
Title: How to adjust speed based on the angle of the Vector3 you are following?
I'm applying forces to a Rigidbody `rb`. The forces come from points along a spline `splineComputer`. The code says "find spline point that is currently nearest to `rb`, and apply forces to `rb` toward that spline point's forward direction".

This works, but what is missing is that the forces are applied at a constant speed, whereas I would like the speed to change based on the angle of the spline path.

Since `targetDirection` is constantly returning a `Vector3` forward direction of the nearest spline point, is there some way to say "based on angle of `targetDirection`, adjust `speed` to move faster or slow down? Or another approach to try?

```
public class SplineScript : MonoBehaviour
{
    SplineSample sample;
    public SplineComputer splineComputer;
    Rigidbody rb;
    Vector3 targetDirection;
    Quaternion targetRotation;
    public float speed = 60f;

    void Start()
    {
        sample = new();
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        splineComputer.Project(transform.position, ref sample);
        targetDirection = sample.forward;
        targetRotation = Quaternion.LookRotation(new Vector3(targetDirection.x, 0, targetDirection.z));
    }

    private void FixedUpdate()
    {
        rb.velocity = targetDirection.normalized * speed * Time.deltaTime;
    }
}

```

Overall purpose: Make rigidbodies who enter a River spline to naturally move with its current, even as river flows down slopes

# Answer
Your goal is to make the movement of the rigid body in the river more realistic, in that the speed will change according to the degree of curvature of the current position. This requires modeling the motion of objects in the river.

In the cross section of a river, the velocity of the water flow is not uniform, the velocity of the water in the center of the river is faster than that in the edge:

Of course, the shape of the river will change according to the environment, and the water flow will erode the river bank under the influence of gravity and geostrophic deflection, thus changing the environment. In conclusion, the cross-sectional shape of some river sections is irregular, which affects the flow velocity.

Generally, the water in the river will erode the outer river bank due to inertia, causing the outer river channel to become deeper and the water flow to speed up.

Now let's take a look at why objects moving in the river have constantly changing speeds. Firstly, the speed of the river itself is uneven. Some river sections are relatively narrow, so the water flow speed is higher. When the river turns, the object will continue to move forward due to inertia, thus leaving the area with the highest flow speed and even being washed to the river bank.

For objects floating in the river, they will enter the low-velocity area when the river turns, or hit the river bank to lose kinetic energy, both of which will slow the object down. For human-driven boats, for safety and efficiency reasons, they will apply a force to try to travel in areas of high river flow and away from the river bank.

Based on the above conclusions, I have some suggestions for coding:

1. Apply a force to a rigidbody instead of setting a velocity and limit the maximum velocity of it.
2. Or you can set the speed of the river, and get the difference between the object's speed and the river's speed, which is the direction of thrust or drag. The force is proportional to the square of the velocity.
3. The erosive effect of the water flow is ignored for convenience, i.e. all cross-sections are uniform. Get the distance from the object to the sample, and the velocity of the water flow will attenuate as the distance increases.
4. If the distance exceeds a set value (half-width of the river), apply a extra force pointing to the sample to simulate the impact of the river bank.
5. If the object is a boat, always apply a extra force pointing to the sample to simulate the driver's actions.
> 1 votes

---
Tags: unity, rigidbody
---


# Question
Title: Unity Android IAP "Purchase failed because Purchasing was not initialized correctly"
**What I have**

IAP button is working perfectly in unity editor. After purchasing, i'm getting debug message "ProcessPurchase: PASS. Product: 'full\_version'" . **But the button does nothing when I try to make a purchase on the device.**

Don't have any errors when purchasing product in editor

**What have i done so far**

Automatically initialize UnityPurchasing checkbox is switched ON

1. I've checked that the product ID, and price are the same in unity and Play console
2. My IAP product is showing active in play console
3. setup the Codeless IAP like this

**LogCat error when I press the button on the device**

```
2022-03-14 20:08:18.244 9293-9334/? E/Unity: Purchase failed because Purchasing was not initialized correctly
    UnityEngine.Purchasing.CodelessIAPStoreListener:InitiatePurchase(String)
    UnityEngine.Events.UnityAction:Invoke()
    UnityEngine.Events.UnityEvent:Invoke()
    UnityEngine.EventSystems.EventFunction`1:Invoke(T1, BaseEventData)
    UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1)
    UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchPress(PointerEventData, Boolean, Boolean)
    UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchEvents()
    UnityEngine.EventSystems.StandaloneInputModule:Process()

```

IAP script

```
using System;
using UnityEngine;
using UnityEngine.Purchasing; //библиотека с покупками, будет доступна когда активируем сервисы

public class IAP : MonoBehaviour, IStoreListener //для получения сообщений из Unity Purchasing
{

    private static IStoreController m_StoreController;          //доступ к системе Unity Purchasing
    private static IExtensionProvider m_StoreExtensionProvider; // подсистемы закупок для конкретных магазинов

    public static string fullVersion = "full_version";

    void Start()
    {
        if (m_StoreController == null) //если еще не инициализаровали систему Unity Purchasing, тогда инициализируем
        {
            InitializePurchasing();
        }

    }

    public void InitializePurchasing()
    {
        if (IsInitialized()) //если уже подключены к системе - выходим из функции
        {
            return;
        }

        var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());

        builder.AddProduct(fullVersion, ProductType.NonConsumable);

        UnityPurchasing.Initialize(this, builder);
    }

    public void Buy_full_version()
    {
        BuyProductID(fullVersion);
    }

    void BuyProductID(string productId)
    {
        if (IsInitialized()) //если покупка инициализирована
        {
            Product product = m_StoreController.products.WithID(productId); //находим продукт покупки

            if (product != null && product.availableToPurchase) //если продукт найдет и готов для продажи
            {
                Debug.Log(string.Format("Purchasing product asychronously: '{0}'", product.definition.id));
                m_StoreController.InitiatePurchase(product); //покупаем

            }
            else
            {
                Debug.Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
            }
        }
        else
        {
            Debug.Log("BuyProductID FAIL. Not initialized.");
        }
    }

    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) //контроль покупок
    {

         if (String.Equals(args.purchasedProduct.definition.id, fullVersion, StringComparison.Ordinal))
        {
            Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));

            //действия при покупке
            if (PlayerPrefs.HasKey("full_version") == false)
            {
                PlayerPrefs.SetInt("full_version", 1);

            }

        }

        else
        {
            Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id));
        }

        return PurchaseProcessingResult.Complete;
    }

    public void RestorePurchases() //Восстановление покупок (только для Apple). У гугл это автоматический процесс.
    {
        if (!IsInitialized())
        {
            Debug.Log("RestorePurchases FAIL. Not initialized.");
            return;
        }

        if (Application.platform == RuntimePlatform.IPhonePlayer ||
            Application.platform == RuntimePlatform.OSXPlayer) //если запущенно на эпл устройстве
        {
            Debug.Log("RestorePurchases started ...");

            var apple = m_StoreExtensionProvider.GetExtension<IAppleExtensions>();

            apple.RestoreTransactions((result) =>
            {
                Debug.Log("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore.");
            });
        }
        else
        {
            Debug.Log("RestorePurchases FAIL. Not supported on this platform. Current = " + Application.platform);
        }
    }

    public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    {
        Debug.Log("OnInitialized: PASS");
        m_StoreController = controller;
        m_StoreExtensionProvider = extensions;
    }

    private bool IsInitialized()
    {
        return m_StoreController != null && m_StoreExtensionProvider != null;
    }

    public void OnInitializeFailed(InitializationFailureReason error)
    {
        Debug.Log("OnInitializeFailed InitializationFailureReason:" + error);
    }

    public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
    {
        Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}", product.definition.storeSpecificId, failureReason));
    }

}

```

The problem is that I don't understand what this error means, and subsequently how to solve it. Hoping for your help

# Answer
In my case activating/initializing of IAP in `Project Settings->Services->In-app purchasing` helped me. Hope this will be helpful for you too.
> 1 votes

# Answer
Remove the event trigger added to the button component itself (PlayButtonSound();)
> 1 votes

---
Tags: unity, android, in-app-purchase
---


# Question
Title: Unity does not show me the problematic files when it shows me the build error "Error building Player because scripts had compiler errors"
I am trying to build an APK in Unity 2019.4.39. Unity says that the build failed, but it does not tell me the files that caused the failed build.

**Can anyone please tell me how to figure out which files caused the build to fail ?**

---

Here are the build errors:

```
Error building Player because scripts had compiler errors

UnityEditor.BuildPlayerWindow+BuildMethodException: Error building Player because scripts had compiler errors
  at UnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer (UnityEditor.BuildPlayerOptions options) [0x002b3] in /Users/bokken/buildslave/unity/build/Editor/Mono/BuildPlayerWindowBuildMethods.cs:194
  at UnityEditor.BuildPlayerWindow.CallBuildMethods (System.Boolean askForBuildLocation, UnityEditor.BuildOptions defaultBuildOptions) [0x00080] in /Users/bokken/buildslave/unity/build/Editor/Mono/BuildPlayerWindowBuildMethods.cs:95
 #0 GetStacktrace(int)
 #1 DebugStringToFile(DebugStringToFileData const&)
 #2 DebugLogHandler_CUSTOM_Internal_Log(LogType, LogOption, ScriptingBackendNativeStringPtrOpaque*, ScriptingBackendNativeObjectPtrOpaque*)
 #3  (Mono JIT Code) (wrapper managed-to-native) UnityEngine.DebugLogHandler:Internal_Log (UnityEngine.LogType,UnityEngine.LogOption,string,UnityEngine.Object)
 #4  (Mono JIT Code) [BuildPlayerWindow.cs:964] UnityEditor.BuildPlayerWindow:GUIBuildButtons (UnityEditor.Modules.IBuildWindowExtension,bool,bool,bool,UnityEditor.Build.BuildPlatform)

```

---

Here is an image of the error message on the console:

---

PS: I know that there is an excellent answer to fix the build error "**Error building Player because scripts had compiler errors**" at this link on StackOverFlow:

https://stackoverflow.com/questions/42588709/error-when-building-project-error-building-player-because-scripts-have-compile/42588940#42588940

However, in my case, Unity does even says which files are bad. So, I can't fix the error if I don't know which files cause errors.

# Answer
> 1 votes
I've found the solution to my own issue. Basically, the problem is that my project contains 2 versions of **DOTween**, and 2 versions of **Lean**. This causes the build errors.

But, if I only build the scene (without "Play" the scene first), then Unity won't tell me the files or packages that cause the build errors.

I have to "Play" the scene in Unity, and then it will tell me the files or packages that cause that are duplicated, and cause the build error.

---

Here are the details:

To find out what files or packages cause the build errors, I need to "Play" the scene in Unity. When the scene is played in Unity, it tells me that there are 2 conflicting versions of 2 different packages: **DOTween** and **Lean**.

The reason is that my old project already has 1 version of **DOTween** and **Lean**. When I install a new unity package (called **Game\_Menu**), it also installs a new version of DOTween and a new version of Lean without deleting or overwriting the old versions. So, there are 2 versions of DOTween, and 2 versions of Lean in my project. This causes the build error.

My solution is to manually remove 1 version of DOTween and 1 version of Lean. Then, Unity builds the APK successfully.

---

In the future, whenever I install this Unity package (called **Game\_Menu**), I will need to check to see if my project already contains **DOTween** or **Lean**. If it already does, then I don't need to install these 2 packages.

# Answer
> 1 votes
I'm not sure, but I would guess that the compiler error is caused by code that's nested between platform-specific compiler flags. Since you're building an Android APK, the first places I would look would be anywhere in your solution containing code within the compiler flags `#if UNITY_ANDROID` or `#if ENABLE_IL2CPP`.

---
Tags: unity, build
---


# Question
Title: Interpolating server updates with client prediction: how to actually find time variable
I'm working on a 3D web game with client-side prediction, etc. I have implemented interpolation for my entities, but it seems a bit laggy sometimes even on localhost. First I will describe the algorithm, and then I will describe the problem.

Interpolation algorithm:

1. SERVER sends to all players (at 20 ticks per sec):

1.1) positions and rotations of all players

1.2) server time at the moment of sending this data (for example `serverTime == Date.now()` (it is calculated a little differently, but the value is roughly the same as `Date.now()`; the error is 20 ms), that calculates every server tick)
2. CLIENT receives all data and:
3. Saves received `serverTime` to global variable named `localServerTime`
4. Pushes player's positions and rotations to their buffers (f.e. player1 has `buffer1: { time: number, position: Vector3, rotation: Vector2 }[]`, so we push received(from server) player1 position and rotation to the buffer1: `buffer1.push({ time: localServerTime, position: receivesPlayer1Pos, rotaiton: receivedPlayer1Rotation })`
5. CLIENT executes local game loop and changes `localServerTime`: `localServerTime += deltaMs`
6. CLIENT interpolates all other players positions and rotations like this:
7. We will interpolate players with offset == 100: `INTERPOLATION_OFFSET_MS = 100`, so find current lerp time: `currentLerpTime = localServerTime - INTERPOLATION_OFFSET_MS`
8. For all other players:
9. I will consider `player1`: get `player1`'s buffer: `buffer1` and get state interpolate FROM(`stateInterpolateFrom`) and state interpolate TO(`stateInterpolateTo`) ( we will find this two states by `currentLerpTime`, so `stateInterpolateFrom.time < currentLerpTime` and `stateInterpolateTo.time >= currentLerpTime`).
10. Then we will find alpha(number, that is in range 0-1): `alpha = (currentLerpTime - stateInterpolateFrom.time) / (stateInterpolateTo.time - stateInterpolateFrom.time)`.
11. Finally, i will interpolate position and rotation: `player1.position = lerp(stateInterpolateFrom.position, stateInterpolateTo.position, alpha)`, same for rotation

---

My problem here is the following: sometimes I have small lags that arise for some reason. I read that I need to synchronize time; I read a bunch of articles about entity interpolation, and the general principle is described there, but I did not find an algorithm about time synchronization anywhere, so I am asking for help.

I realized that the matter is in the `localServerTime`, I calculate it incorrectly, but I don’t understand what exactly needs to be done, how to calculate it. If anyone has any relevant articles to put things in place, I would be very happy if you share them.

P.S. On the client I have variable `syncedServerTimeMs`, when player connecting to the server, server send data: `{ serverTime: number, serverTick: number}` and client calculates `syncedServerTimeMs`, so I can exactly say the serverTime when I need on it. In the client loop I update `syncedServerTimeMs`: `syncedServerTimeMs += deltaMs`, maybe I must use this variable somehow?

# Answer
To get a more accurate server time, you need to know a few basic facts:

1. You cannot rely on the client and server system time being the same.
2. You cannot rely on time increments(such as `deltaMs`), some program time consumption or floating-point precision issues can cause delta time to accumulate errors on a long-time running.
3. The difference in system time (CPU time) can be relied upon. On any device `t1-t0` are accurate.
4. There is a delay in the communication between the client and the server, and it is affected by various reasons (network delay, protocol parsing, thread communication...) This delay is unstable.You cannot assume the delay is non-existent or stable.

So the solution I suggest is that the client actively asks the server time regularly, calculates the delay through the time of the packet return, and saves the calculated server time and the client time when saving. When the server time needs to be used, the **current server time** is calculated by the `current client time`, the `saved server time`, and the `client time when the server time is saved`.

Pseudocode:

```
savedServerTime = 0//saved server time
savedClientTime = 0//client time when the server time is saved

void ServerTimeRequest(){
    SendToServer({ClientTime:Time.now()})
}

void ServerTimeResponse(data){
    rtt = Time.now() - data.ClientTime
    savedServerTime = data.ServerTime + rtt/2
    savedClientTime = Time.now()
}

int GetServerTime(){
    return savedServerTime + (Time.now() - savedClientTime)
}

```

Related:

Network client-server message exchange and clock synchronization help

Simple Network Time Protocol (SNTP)
> 1 votes

# Answer
@Mangata, I didn’t care about time synchronization at all, I needed to know what time to use in interpolation, I would handle the synchronization myself. But I appreciate what you wrote, thanks.

I had to write this in the answers, not in the comments, because comment is limited by the number of characters.

in your case the error is +- rtt/2, because time to reach the server and time to reach the client maybe different. F.e. lets imagine time to reach the server(TTRS) = 5 ms, however time to reach client(TTRC) = 150 ms, then all calculations will be wrong.

I use JavaScript on client and Node.js on server. so we can something like this:

```
CLIENT:  SendToServer(SyncTimeKey)
SERVER: SendToClient({ serverTime: serverTime, dateNow: Date.now() })
CLIENT:
void ServerTimeResponse(data){
    savedDateNow = Date.now()
    savedServerTime = data.serverTime + savedDateNow - data.dateNow
}
GetServerTime function is the same as yours.

```

In this case all will be ok, but as i mentioned, question was about other problem)
> 0 votes

---
Tags: client-server, interpolation, synchronization
---


# Question
Title: why does my button lose the changed cursor and mouseover behaviour as soon as I attach a class to my file?
Using adobe animate cc - exporting to HTML5 and coding in JS (or at least trying to)

If I just hit cntrl+enter in adobe animate the button works as expected. If I run the app from a web server using the index.html file the button is there, and the down registers when you click it, but the cursor doesnt change and there is no roll over change in colour..... is there a mouseEnable or something I need to use from the class.js file?- there is no code in there at the mo, just an empty constructor

```
class Game
{
    constructor(root, lib)
    {
        this.root = root;
        this.stage = this.root.stage;
        this.lib = lib;
        this.init();
    }

    init()
    {

    }
}
```

Thanks all for your awesome efforts and have a great day

# Answer
I don't really know why - maybe you can spot the code issue but I backtracked to an earlier version and this one works:

```
class Game{
    constructor(exportRoot, stage){
        this.root = exportRoot;
        this.stage = stage;
        this.init();
    }

    init(){

        this.root.play_btn.on('click', function(){
            this.root.tester.gotoAndStop(2);
        });
    }
}
```

It moves the targeted MC timeline and has the expected button behaviour - so happy days I guess! If you know why please still let me know!
> 0 votes

---
Tags: javascript, html5, html-canvas
---


title: Move From 0 to "Max Amount" Over Time

text:
# Question
Title: Move From 0 to "Max Amount" Over Time
I need to create Coroutine that moves from 0 to "maxAmount" over "duration".

Can someone please assist me with the proper way to create this loop?

Here is my attempt at it:

```
var t = 0

While(currentAmount < maxAmount)
{
          currentAmount = Mathf.Lerp(minAmount, maxAmount, t/5f);
          t += .05f * Time.deltaTime;
          yield return null;
}

```

This moves the amount from 0 to MaxAmount, however, it doesn't seem to take the correct amount of time. (in this case 5 seconds)

# Answer
Managed to figure it out.

What I did was:

```
float t = 0;

while (currentAmount < maxAmount)
                {
                    currentAmount = Mathf.Lerp(minAmount, maxAmount, t);
                    t += Time.deltaTime/5f;
                    yield return null;
                }

```

Hopefully this helps someone in the future!
> 0 votes

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


title: How to turn off shaders?

text:
# Question
Title: How to turn off shaders?
Whenever I import something in Godot it looks like it's covered in some mushy slimy glittery stuff, I don't like it.... Garbaj on youtube showed that it's possible to turn shaders off and just render the pure texture with no external lighting, like in blender... but it was far from a tutorial and I have no idea how to do it.

# Answer
> 0 votes
> Whenever I import something in Godot it looks like it's covered in some mushy slimy glittery stuff

If I recall correctly, the way Godot 3.x did roughness scaling was wrong. If possible, edit the materials increasing roughness to compensate.

However, more importantly, the default environment gives an ugly look (e.g. a pure white material looks blue). So you will want to tweak it. In particular:

* Change the `tonemap_mode` (you don't want Linear). Optionally increase the `tonemap_white` value.
* Reduce `ambient_light_sky_contribution`. Optionally change the ambient light color.
* For the sun light add a directional light to your scene (give it a large max distance. *Rotate the directional light to align it with the sun in the sky.*

Note that this approach lets you tweak the procedural sky freely, which you might want to do for depicting different times of day. *Or you may want to replace the procedural sky with something else.*

*Speaking of time of day, you can add a `WorldEnviroment` to your scene, set its `environment`, and animate it with an `AnimationPlayer`. In which case you probably want to animate the directional light in conjunction.*

---

> Garbaj on youtube showed that it's possible to turn shaders off and just render the pure texture with no external lighting

If you want a material to not interact with lights you can mark it "`unshaded`" (you find it under "Flags" in the inspector of a `SpatialMaterial`).

---
Tags: lighting, godot
---


# Question
Title: How do I align segments of rope to connect adjacent segments?
I have made a 2D rope in Godot using this thread here.

The problem I am facing now is that the rope is not rotating towards player. I have tried `look_At` but it only works when I shoot on the right side.

Here is how it's looking now:

I want the rope segments to match together like this. This is when I shoot straight up:

# Answer
> 0 votes
I see my prior answer didn't rotate the rope pieces.

We had `rope_direction`, we can get an angle from it:

```
var rope_angle := rope_direction.angle()

```

And give that rotation to the pieces:

```
rope.global_position = rope_piece_position
rope.global_rotation = rope_angle

```

Actually I think you need to offset the angle. An angle of zero is to the right (on the x axis), but without rotation it works upwards. That is an offset of a quarter turn. So, try this:

```
rope.global_rotation = rope_angle - 0.25 * Tau

```

---
Tags: rotation, godot, rope-physics
---