# Question
Title: How to create a camera that combines both forced movement and smooth player following
# Context

So I'm making a clone of *Crossy Roads* where the camera follows the player. It does some linear interpolation (Lerp) after moving, and the camera starts moving away from the player in the positive direction (x-axis until camera reaches to a certain range where player is not visible enough). Things I have tried is by flagging it, but I think I'm doing it wrong.

# Problem

I have done my camera movements accordingly, but I am having an issue where the conditions are not properly met. I'm get the offset camera after not moving, but it does not the Lerp, and vice-versa. I want both to happen after a certain condition after the game starts. When the player moves, the camera follows it in Lerp. However, once the player is "Idle", its still Lerping. I want the camera to continue by itself and at the same time focus at the player's object.

# Example

## Camera with Lerp, but not moving away from the player

## Camera moving away, but not following player with lerp

# Code

## `CameraController.cs`

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

/*
** Camera following player (Smoothing and angle): https://youtu.be/4HpC--2iowE
** Maximo: https://www.youtube.com/watch?v=bXNFxQpp2qk&ab_channel=iHeartGameDev
** Moving character relative to camera: https://forum.unity.com/threads/moving-character-relative-to-camera.383086/
** Camera follow v2: https://youtu.be/Jpqt2gRHXtc?list=PLq_nO-RwB516fNlRBce0GbtJSfysAjOgU
*/

public class CameraController : MonoBehaviour
{
    public GameObject player;
    public PlayerControl playerControlScript;
    private Vector3 newCameraPos;
    public bool stillIdle;

    void Start()
    {
        stillIdle = false;
        PlayerControl playerControlScript = GetComponent<PlayerControl>();
    }

    void LateUpdate()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        if (playerControlScript.GetfirstInput()) //True
        {
            stillIdle = true;
            newCameraPos = Vector3.Lerp(transform.position, playerControlScript.transform.position, Time.deltaTime);
            transform.position = new Vector3(newCameraPos.x, 1, newCameraPos.z);
        }
        if (stillIdle)
            transform.position = new Vector3(transform.position.x + 0.69f * Time.deltaTime, transform.position.y, transform.position.z); //Moving camera away effect
    }
}

```

## `PlayerControl.cs`

```
public class PlayerControl : MonoBehaviour
{
    bool firstInput;
    Vector3 startPos;
    Vector3 endPos;
    public bool GetfirstInput() //I was learning how to have a Get function while my member was private from another script file
    {
        return firstInput;
    }
    void Update()
    {
         if (Input.GetButtonDown("up") || Input.GetButtonDown("left") || Input.GetButtonDown("right") || Input.GetButtonDown("down"))
        {
            //if game starts
            {
                //Other variables being initialized here
                firstInput = true;
            }
        }

    }
}

```

# Hierarchy/Inspector

## Main Camera

## Player Object

Some help would be appreciate it. I feel I have been staring at this problem and I bet it is something minimal and small from just thinking it.

Let me know if you need clarifications. I'm happy to edit and answer them for everyone

# Answer
Maybe try Cinemachine? It's a package that pretty much gives the facilities to easily produce camera follow, camera bounds, etc.

I was thinking maybe just find out if the player is above the centre of the screen, and if so, lerp the camera towards them until they are at centre screen. Then, apply a constant movement every frame:

```
void FixedUpdate()
{
   if(<Camera camera>.WorldToScreenPoint(<Transform player>.position).y >= Screen.height/2){<CinemachineVirtualCamera cameraController>.Follow = <Transform player>;}
   else{<CinemachineVirtualCamera cameraController>.Follow = null;}
   camera.transform.Translate(<float cameraSpeed> * <Vector3 cameraDirection> * Time.deltaTime);
}

```

Make sure to insert `using Cinemachine;` at the top of your script, and replace `<anything in these brackets>` with their respective values. Hope it works, I haven't had time to test. (If it doesn't, feel free to send the error code and I will try and fix it for you)
> 0 votes

# Answer
# Create a two-part system

If I'm reading the question correctly, you have three rules:

* The camera should catch up quickly if player when the player moves ahead of it
* The camera should slowly move forward at all times
* The camera's movement should be smooth (for example, by `lerp`)

I suggest creating a two-part system, where an invisible "Camera Target" game object enforces the first two rules, and the camera is only responsible for the third.

## The Camera Target

The camera target should be a non-rendering game object which "teleports" to wherever the camera should be moving toward. It can enforce the first two rules by the following:

* Every FixedUpdate, move the target some distance forward
* When the player moves, if the target is behind them, snap it to their current position.

This separate target can be useful if you want to change the rules for camera following. For example, maybe after playtesting you decide that you only want to force the camera forward if the player gets into the top 20% of the screen, instead of just the top 50%. If you need to make changes, it will be easier to implement if the target logic is decoupled from the smoothness logic.

## The camera itself

Once you know where you *want* the camera to be, all the camera needs to do is move towards the target during FixedUpdate. I recommend using FixedUpdate rather than Update for both of these objects to make sure your camera movement is not framerate-dependent.

You also might want to consider using something besides `lerp` for your smoothness. Using `lerp` in this way can doesn't strictly guarantee that the player will always be on screen - though in practice, it basically does for most reasonable speeds.
> 0 votes

---
Tags: unity, c#, camera, isometric, lerp
---


# Question
Title: Attaching gameObjects to a moving Mesh by position retrieved from triangle index
I am trying to attach GameObjects `testAttach` to triangle indices in `trianglesToAttachTo` on a mesh, call it goMesh. I've identified the triangleIndices I want to attach to from retrieving via `RaycastHit.triangleIndex` but I seem to run into issues like: `IndexOutOfRangeException: Index was outside the bounds of the array.` I have tried removing the 3 multiplier, but that leads to positions that do not reflect the selected triangle positions.

Super quick test script:

public class AttachToFaceMeshEars : MonoBehaviour
{
    public GameObject[] testAttach;

    public int[] trianglesToAttachTo = { 1604, 1982 };

    public GameObject goMesh;

    void Update()
    {
        Test(goMesh);
    }

    void Test(GameObject g)
    {
        for (int i = 0; i < testAttach.Length; i++) AttachTo(g,g.GetComponent<MeshFilter>().mesh, trianglesToAttachTo[i], testAttach[i]);
    }

    void AttachTo(GameObject goMesh,Mesh mesh,int triangle,GameObject go)
    {
        int[] tris = mesh.triangles;
        Vector3[] vertices = mesh.vertices;
        Vector3 p0 = vertices[ 3 * tris[triangle] ];

        go.transform.position = goMesh.transform.TransformPoint(p0);
    }

}

````

# Answer
Since the `mesh.triangles` array is the one that contains three entries per triangle, the correct way to index a specific vertex would be `vertices[ tris[ 3*triangle ] ]`.
> 1 votes

---
Tags: unity, mesh
---


title: Putting two R16_UNORM in a R32_UINT

text:
# Question
Title: Putting two R16_UNORM in a R32_UINT
With my hardware limitation for CS5 I'm using R32\_UINT in my shaders to store compacted colors and normasl as 555 bits each. My packing is using uint3 and the result is of poor quality. I'm planning to store the color as 565 bits and normals as 77 bits + 2 bits, one for a sign (of normal z) and one for a mask, but in a R16\_UNORM each that gives me better quality and pack the two in my R32\_UINT.

below the packing/unpacking funcs for float3 color to 565 bits as R16\_unorm and back that works with correct quality in my other shaders. I also added the expected coding for the Normals to Nxy 77 bits

```
float C3_R16(float3 Color)
{
   uint3 uColor = uint3(min(Color,float3(1.0, 1.0, 1.0))*float3(31.0, 63.0, 31.0));
   return float(uColor.r | (uColor.g<<5) | (uColor.b<<11))/65535.0;
}

float3 R16_C3(float Pack)
{
    uint iPack = uint(Pack);
    return float3(iPack&0x1F, (iPack>>5)&0x3F, (iPack>>11)&0x1F)/float3(31,63,31);
}

float N2_R16(float3 Normal)//unchecked behavior
{
   uint2 uNormal = uint2(min(Normal.rg,float2(1.0, 1.0))*float2(127.0, 127.0));
   return float(uNormal.r | (uNormal.g<<7))/65535.0;
}

float3 R16_N3(float Pack)//unchecked
{
    uint iPack = uint(Pack*65535);
    float3 N;
    N.xy = float2(iPack&0x7F, (iPack>>7)&0x7F)/float2(127,127)*2-1;//maybe optimze with /float2(63.5,63.5)-1;
    N.z = sqrt(1-dot(N.xy,N.xy));//in view space I should not need sign
    return N;
}

```

The Normal 77 (N2\_R16) enoding is to show how I will proceed for the Nxy encoding/decoding. The two final bits are added with a test and bitshift like uint(N.z\<0)\<\<15.

Now to convert two R16 into a R32\_UINT I'm planning to use asuint function this way:

```
uint ColorOut = (asuint(C3_R16(mycolor.rgb))&0x00EFFFFF)>>7;
//uint NormalOut = (asuint(C2_R16(mynormal.rg))&0x00EFFFFF)>>7;//this may be optimized to avoid latter <<16
uint MyFinalR32_UINT = ColorOut;//| NormalOut<<16; currently only one R16 is added for the color

```

In this code I'm storing only one R16 at the moment to check how it works.

For unpaking I'm doing this:

```
  uint Data = txDiffuseInt.Load(uint3(Input.Tex.x*960, Input.Tex.y*540,0));
  float3 C = R16_C3(float(Data&0x0000FFFF));

```

According to IEEE rules the \*0x00EFFFFF mask considers that the 9 msb are the sign and 8 bit exponent and the lower 23 bit the mantissa. As the value reulting from C3\_R16 must be in the range \[0..1\] I should not need the sign and exponent. The \>\>7 is to pick the 16 MSB bit of the mantissa (again if I'm correct these are the most significant bits). This is were things go wrong I think. My colors are mostly blue with some green on unpacking. Some objects should be full red.

Is my description of float32 well-used?

# Answer
First answer

The definition of float 32 I found was not correct on 1 bit. Correct definition is Bit 32 sign Bit 31-25 exponent Bit 24-1 mantissa

Using asfloat/asuint functions you can have the float and uint version of your data like:

```
0x3f800000 =  1.000
0x3dcccccd =  0.100
0xbf800000 = -1.000

```

Regarding the exponent, as we manipulate bits it is not linear. So for instance below are some ranges of value and the corresponding exponent expressed as their value and binary:

```
63 0011 1111 1.0 - 0.5
62 0011 1110 0.4 - 0.2
61 0011 1101 0.1 - 0.04
60 0011 1100 0.03 - 0.008
59 0011 1011 0.007 - 0.002
58 0011 1010 0.001 - 0.0005
57 0011 1000 0.0004 - 0.0003

```

If I consider using a unorm float in the range \[0-1\] and that values below 0.0003 are not useful, then I don’t need the bit sign 32 and the exponent bits 31-28 are constant. In the range we have always bit 31=0, 30=1, 29=1, 28=1. So I can decide to store only bit 27-25 for my packed data. In the range \[0.008-1\] you can even store only two bits.

Using a 16 bit format this leaves me 13 bits for the mantissa. The 32 float has 24 bits mantissa with higher bit being the most significant so we need to shift 11 bit left to store these 13 significant bits in our remaining R16 13 bits. Because the exponent bit and the mantissa part are on following bits 27-9 we end up with this single operation tha tremoves the sign and upper bit 31-28 exponent:

```
float My32Float = value;
uint Myuint32Value = asuint(My32Float);
uint MyPackedUint16Value = (Myuint32Value & 0x07FFFFFF)>>11;

```

Unpacking is like this:

```
uint MyPackData = value;//may come from texture 32_UNIT;
float MyUnpackedFloat = asfloat(0x38000000 | (MyPackData << 12));

```

The 0x38000000 mask restores the missing exponent bits that are constant in the range of values.

I have checked the presision that is good. Zero is restored as 0.0000031 so a test can be needed if zero is really wanted.

Second answer

I have below a couple of (un)packing methods that works quite fine but except the 565 packing the others have some artifacts depending on the POV (see picture). Some help wanted to solve that.

Except the 565 that stores the 3 normal components, the other methods store only Nxy and calculate back z with a sign for the Lambert and without sign for the 88 and 88as1F. In my view space the z sign appeared to be always negative on flat as well as on bumpy surfaces.

Some code to pack normal in R16 formats (select the method by moving the comment)

```
//#define SM_NPACK_565   //pack float3 as 565 bit format
//#define SM_NPACK_88    //pack float3 as xy 88 bit format
//#define SM_NPACK_871   //pack float3 as xy 87 bit format, 1 bit sign (if needed)
//#define SM_NPACK_88LEA //pack float3 as xy 88 bit format using Lambert Azimuthal Equal Area
#define SM_NPACK_88as1F_UNORM   //pack float3 as xy in single float as floor(x)+frac(y). Use the above uint32 to uint16 final packing

uint N3_R16(float3 Normal)
{
#ifdef SM_NPACK_565
    Normal = Normal*0.5+0.5;
    uint3 uColor =  uint3(Normal*float3(31,31,63));
    return uColor.r| (uColor.g<<5)| (uColor.b<<10);
#endif
#ifdef SM_NPACK_88
   uint2 uColor =  uint2(Normal.xy*127.5+127.5);
   return uColor.r| (uColor.g<<8);
#endif
#ifdef SM_NPACK_871
    uint2 uColor =  uint2((Normal.xy*0.5+0.5)*float2(255,127));
    return uColor.r| (uColor.g<<8)| ((Normal.z<0)<<15);
#endif
#ifdef SM_NPACK_88LEA
    float p = sqrt(Normal.z*8+8);
    uint2 uColor =  uint2(Normal.xy*255.0/p+127.5f);
    return uColor.r| (uColor.g<<8);
#endif
#ifdef SM_NPACK_88as1F_UNORM
    float2 Data = Normal.xy*0.5+0.5;
    float fValue = (floor(Data.x*255.0)+Data.y*0.99)/256.0;    //ensure that the final value is 255.9999 max with 255 max for x and 0.999 max for y.
    return (asuint(fValue) & 0x07FFFFFF) >> 11;
#endif
}

float3 R16_N3(uint Pack)
{
    float3 N;
#ifdef SM_NPACK_565
    N = float3( Pack & 0x001F, (Pack >> 5 )& 0x001F , (Pack >> 10 )& 0x003F )/ float3(15.5,15.5,31.5) -1;
#endif
#ifdef SM_NPACK_88
    N.xy = float2( Pack & 0x00FF, (Pack >> 8 )& 0x00FF)*INV255x2-1;
    /*if( N.x+N.y>1.95f) N.z = 1; else*/ N.z = -sqrt(1-dot(N.xy,N.xy));
#endif
#ifdef SM_NPACK_871
    N.xy = float2( Pack & 0x00FF, (Pack >> 8 )& 0x007F)/ float2(127.5,63.5) -1;
    int s = (Pack & 0x8000)!=0?-1:1;
    /*if( N.x+N.y>1.95f) N.z = 1; else*/ N.z =s*sqrt(1-dot(N.xy,N.xy));
#endif
#ifdef SM_NPACK_88LEA
    N.xy = float2( Pack & 0x00FF, (Pack >> 8 )& 0x00FF)*INV255;
    float2 fenc = N*4-2;
    float f = dot(fenc,fenc);
    N = float3( fenc*sqrt(1-f*0.25), 1-f*0.5);
#endif
#ifdef SM_NPACK_88as1F_UNORM
    float f = asfloat(0x38000000 | (Pack << 11))*256.0;
    N.x = floor(f);
    N.y = f-N.x;
    N.x *= 1.0/255.0;
    N.xy = N.xy*2-1;
    N.z = -sqrt(1-dot(N.xy,N.xy));
#endif
    return N;
}

```

The line test /*if( N.x+N.y\>1.95f) N.z = 1; else*/ is used when I have unlit object. For those I set arbitrary normals to (1,1,1). As normalized normals are never \>= 1.0 (or \<=-1) I use it to skip lighting in my shaders. Whe nthis line aer not active the objects appear full black or full white depending on the packing method.

The picture with artifacts

After some search I found that clamping the normal to (-0.99, 0.99) solved the issue for method 88LEA. There might be a precision issue with these calculations. For other methods used to store only Nxy they are still not fully correct on any POV.
> 0 votes

---
Tags: hlsl, color, storage
---


# Question
Title: What is the use of multiple vertex color sets
I noticed that Assimp supports meshes with multiple vertex color sets, but what is the use of multiple vertex color sets? I mean are multiple vertex color sets are really used in any games, and if yes, for what purpose?

# Answer
> 3 votes
Vertex colours are just arbitrary extra data you can pack into a mesh - you don't have to use them as literal colours when rendering. So frequently, these get used as control weights for a variety of effects:

* Storing low-frequency ambient occlusion or baked lighting data (which might be literal light colours, or each channel could store an exposure mask for a given light source or approximated bounce).
* Controlling which vertices in a cloth or foliage mesh are free to flutter in the wind or get pushed away from force fields, versus which ones should stay more rigidly fixed in place.
* Storing a local offset to a pivot point, or the orientation of a joint/axis, so that branches of a tree or dangling bits of a costume can be animated cheaply in a vertex shader without needing full skeletal animation for every wiggly bit.
* Controlling the frequency bands of such motion, so leaf tips can tremble while thicker branches slowly sway.
* Controlling the phase of animation, so effects can ripple from one part of the surface to another in an artist-controllable way, independent of the mesh's pose or texture unwrap. This can also be used to make different parts of the asset animate out of sync with each other, so the effect looks more organic rather than mechanical.
* Masking which parts of a mesh with overhangs should get wet when it rains.
* ...or more generally, picking out any parts of the mesh that should have some special effect applied, that doesn't need the per-pixel precision of an extra mask texture.

Natalie Burke presented a great GDC talk with lots of examples of how these types of techniques are used in Destiny, especially for things like the animations of weapons and other gear items.

You can find similar techniques in this longer presentation from Gilbert Sanders about vegetation rendering in Horizon Zero Dawn (around 10 minutes in).

Something handy about encoding this information in the vertex colours instead of using the vertices' local positions is that vertex colours are preserved unchanged, even if you combine multiple small meshes using the same material into a single batch (which usually involves 'baking out' their transformations, modifying the local space vertices that the vertex shader sees). So that's why you'll still see this used, even in cases where the vertex colour is just a predictable gradient in the mesh's local coordinate space.

---
Tags: graphic-effects, vertex, 3d-modeling, vertex-shader, vertex-attribute
---


# Question
Title: Calculate the Right and Up vectors using yaw and pitch in right-handed coordinates
I have an assignment where they ask me to calculate Vector Right and Vector Up, it's for a camera creation using C++ and DirectX. For the Vector Right, they specify I should use 90-yaw, so I got:

\\$ V\_{Right} = \\{cos(90-yaw), 0, sin(90-yaw)\\}. \\$

For Vector Up, I'm still not sure how should I calculate it using yaw and pitch. My initial thought was to set it like this:

\\$ V\_{Up} = \\{cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch)\\}. \\$

However, I think I'm confusing it with the Forward Vector. I know I can get a rotation matrix and use also cross products to obtain them, but they specify that I should use yaw and pitch and I'm kinda lost here since cannot find a clear answer with the setup I'm mentioning.

Could you help me to find the Up, Right and Direction vectors? (I suppose the direction is the Forward one.)

Any help would be useful!

# Answer
You don't specify your reference frame, but based on your $$V\_{Right} = \lbrace \cos(90−yaw),0,\sin(90−yaw) \rbrace $$ I'm guessing it's {forward, up, right} with yaw about the y-axis and pitch about the z-axis. To get the yaw rotation matrix, consider rotation in the x-z plane:

$$ Rot\_{y} (yaw) = \begin{bmatrix} \cos (yaw) & 0 & \sin (yaw) \\ 0 & 1 & 0 \\ \- \sin (yaw) & 0 & \cos (yaw) \end{bmatrix} $$

The pitch rotation matrix is in the x-y plane: $$ Rot\_{z} (pitch) = \begin{bmatrix} \cos (pitch) & - \sin (pitch) & 0 \\ \sin (pitch) & \cos (pitch) & 0 \\ 0 & 0 & 1 \\ \end{bmatrix} $$

You should apply pitch first, then yaw, so the final rotation matrix is

$$ Rot\_y (yaw) \cdot Rot\_z (pitch) $$

which you can work out for yourself. To get your forward, up, right vectors after rotation, multiply your basis vectors (e.g. forward is \[1, 0, 0\]) by the rotation matrix.

If you want to use (90 deg-yaw), remember that the cosine of an angle is the sine of its complement, or

$$ \cos (\theta) = \sin ( 90^{\circ} - \theta ) $$
> 1 votes

---
Tags: c++, directx, vector
---


# Question
Title: Is it possible to keep a prefab of a UI element with UI Toolkit?
I'm digging into Unity's new UI Toolkit, and so far I like it a lot; but there are a few things bugging me about it.

I have a dynamic list in my UI which keeps track of way point paths, and it changes its contents with play. This is mostly taken care of with a group and labels added to it in C#; but there's a specific kind of formatting I use for my labels and it's a lot of get/set calls to update it every single time.

Under ideal circumstances, I would make my ideal label in the editor, make it a prefab, and just insert that prefab; but this doesn't seem to be possible with the UI Toolkit.

If I can't make a UI prefab, how can I easily and clearly create the same style of label every single time without too many lines of code?

# Answer
Got it.

While UXML (XML in general really) does not qualify as a prefab or typical asset, a utility exists to load such a file as one.

Suppose our file is called "PathLabel", and is in a `Resources` directory. We can load that utility class like so:

```
var pathLabelPrefab = Resources.Load<VisualTreeAsset>("PathLabel").CloneTree();

```

VisualAssetTree qualifies as a loadable asset, and its function, `CloneTree()`, returns a `UITemplates.TemplateContainer`. This class is a subclass of `VisualElement`, and can be added to our UI Document with a simple `add` call.

Just in case anyone else is curious. In summary, create a new document, drop it in a folder titled "Resources", load it with `Resources.Load`, and add it to your visual group in your main UI.
> 2 votes

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


title: Rotate Child GameObject Over Time

text:
# Question
Title: Rotate Child GameObject Over Time
Good Morning All,

I have a character gameobject with a few child gameobjects that lead to the sprite.

* Character

> * Character Rotator
>
> > * Sprite Holder

I have been flipping the character like this depending on if left or right is pressed and it's worked fine:

```
// Flip the player's sprite based on input and x vector
        if (myVector.x < 0 && facingRight)
        {
            facingRight = !facingRight;
            // childToRotate is Character Rotator
            hildToRotate.transform.localRotation = Quaternion.Euler(0, 180, 0);
        }

        if (myVector.x > 0 && !facingRight)
        {
            facingRight = !facingRight;
            // childToRotate is Character Rotator
            childToRotate.transform.localRotation = Quaternion.Euler(0, 0, 0);
        }

```

Now, I want to rotate the character 180 degrees over time, rather than it being an instant flip. ( Just like in Paper Mario games )

This was my attempt at creating the effect:

```
public IEnumerator RotateCharacterModel()
    {
        float startRotation = childToRotate.transform.eulerAngles.y;
        float endRotation = startRotation + 180f;
        float t = 0.0f;
        float duration = .3f;
        while (t < duration)
        {
            t += Time.deltaTime;
            float yRotation = Mathf.Lerp(startRotation, endRotation, t / duration) % 180.0f;

         // this is where I need to rotate the "Character Rotator's" local rotation but I am struggling...

        }
        _characterIsRotating = false;
    }

```

I think I'm very close, I just need assistance replacing the last comment with code that rotates the "Character Rotators" local rotation.

Any assistance with this would be immensely appreciated! Thank you for taking the time!

# Answer
Interpolating Euler angles is fraught. You'll generally get more intuitive behaviour with fewer confusing edge cases by expressing your orientations as Quaternions, and interpolating those:

```
public IEnumerator RotateCharacterModel()
{
    Quaternion startRotation = childToRotate.transform.rotation;
    // Rotate start by 180 degrees on the world y axis.
    Quaternion endRotation = Quaternion.Euler(0, 180, 0) * startRotation;

    float duration = .3f;
    // Thinking of this as a speed saves a division every step.
    float speed = 1f/duration;

    // Use a for loop instead of a while,
    // that way all your loop variable stuff stays together.
    for (float t = 0; t < 1f; t += speed * Time.deltaTime)
    {
        childToRotate.transform.rotation = Quaternion.Lerp(
                                                 startRotation,
                                                 endRotation,
                                                 t
                                           );
    }
    // Snap to the final orientation (loop can end with spare change left over)
    childToRotate.transform.rotation = endRotation;
    _characterIsRotating = false;
}

```
> 0 votes

---
Tags: unity
---


# Question
Title: How should I design my AI in 2D fighting game?
I am currently trying to make an AI for my 2D Fighting Game like Brawlhalla or Super Smash Bros. The problem is that I don't know how to go around doing it, like what algorithm should I use. The methods I have found like mini-max would take to long to make decisions and finite state machine seems a bit to simple to make it even slightly difficult. I do have time on my side if that helps.

# Answer
> 4 votes
## The specifics.

On top of the typical fighting-brawling AI (as given in other answers and comments), your AI needs to predict and achieve such a world state, in which the opponent crosses a border of a no-return zone (or other kind of environment hazard).

This task may be subdivided into the following components:

* Predicting the long-term consequences of a "punch". After all, sending an enemy flying to death involves some flying, which is not instant (unlike the punch itself).
* Finding a position for a good punch, while avoiding being punched on the way. This is rather simple, once you can predict when someone can knock a character out from given position.

Predicting future is really hard, and I see this to be the main challenge here — and thus the focus of my answer. In fact, you may consider constraining the game mechanics to make it more predictable.

## Heuristics.

If the game employs somewhat simple mechanics, then a manually coded approximation will do. Sprinkle with some extra rules regarding the character's state and abilities and then tweak the numbers until your play-testers report satisfaction.

For example, choose few random positions around the enemy, and see if tracing a line in opposite direction would cross a hazard or will end up above a chasm. If answer is positive, then see if you could navigate there. Because the enemy also moves, you'll need to update the goal regularly.

As for defense, check if the enemy can knock the character out the same way. If so, try to get into safety, either by retreating to the previously known safe place, or by locating a new one with a series of "punch-probes" (pick few random points nearby and see if they are safe). Alternatively, you could also try blocking, dodging, and employing whatever else the game offers.

(By the way, the method of probing a set of (predefined or random) points is a rather popular approach in designing game AI for complex environmental interactions. In Unreal Engine terms (which has one of the bestest Behavior Tree editors around), this is called Environmental Query, you may want to look further into it.)

## Simulation.

For more complex games (especially when talking about environment and complex characters' abilities), a proper simulation would be required. Helpfully enough, fighter-type games usually are pretty lightweight in terms of game state, which makes probing multiple simulations rather affordable.

You'll need at least two instances of your world: the "real" one, and the simulated. Every so often, the "real" world will be cloned into the simulated one to run the simulation (usually few times in a row) and see how it goes.

But this raises a question: how will the actors in the simulation predict the future of the simulation? To break the infinite recursion, the characters should not to try predicting the future, but instead try a random sequence of actions, and choose the best one. (If you are looking to learn more, the method described is known as Evolutionary Algorithm, and Genetic Algorithm is its popular variant.)

* The simulation runs few times (each time initializing from the current "real" world's state).
* Before the runs, each actor chooses a new plan: a random sequence of actions. (E.g. pressing left, then waiting half a second, then pressing jump. This can be further improved with heuristics.)
* During each run, each actor follows their plan unconditionally. Each plan is scored based on the outcome of run (e.g. ending up near a chasm will result in a penalty, while punching an enemy would result in a reward).
* In the beginning of the every next run, actors with a high(er) score will keep their plan intact, while the actors with low(er)score will re-roll a new plan.

Running this for few cycles should result in a somewhat optimal plan for each character. All what remains for each actor is to stick to the chosen plan in the "real" world.

(Also, you probably want to simulate the players' characters too, because them standing still could make the AI extremely aggressive — because the AI will incorrectly predict that the player is completely inert and defenseless.)

The simulation approach can be really good, because it requires virtually no tweaking and re-testing every time you update the game.

## Reinforced learning.

This is rather academic topic, thus I am not going into too much details, but the basic idea is equipping your AI with bunch of sensors (e.g. measuring distance under the feet, distance to the enemy, reading health, stun status, etc) and a miniature "brain" (in a form of a matrix multiplication pipeline) that will get inputs from the sensors and transform them into action preference (e.g. pressing left or right). The brain itself is produced in a "learning" process, where the AI is allowed to run free, interact with the world semi-randomly, and be judged, which will modify the brain to improve the performance.

# Answer
> 0 votes
I don't like 2d fighting games. I didn't play one in ages and I never made one. So I am probably not the most qualified person to answer. But if someone would put a gun to my head and tell me to, then I would probably start the AI based on a behavior tree.

Behavior trees are a common and well-documented pattern in game AI programming. Others have explained it much better than I could. So the rest of this answer will assume that the reader is familiar with the principles and the terminology of behavior trees.

---

Have you read up on behavior trees and are familiar with the theory? Did pick one of the many Unity addons for behavior trees or implement a basic code-only BT framework yourself (been there, done that, took about 2 hours)? Good, then let's see how we can apply the theory to a fighting game.

---

As a first "Hello World" of fighting game AI, I would start with a simple repeating sequence, like two steps forward, two steps back, jump up, punch. Now this is of course not really a challenge, but it at least gets us somewhere and proves that the system works.

The next step would be to build a behavior tree which represents the regular logic of a player in a fighting game. What is that logic?

1. Is the opponent performing an attack? Then I should probably do something so I don't get hit.
2. If not, is the opponent in a position where I can hit them with an attack? Then I should probably perform that attack.
3. If not, then I should probably get closer to the enemy so I can hit them.

In behavior tree terms, this sounds like a selector:

```
               ┌────────────┐
               │  Repeater  │
               └──────┬─────┘
                      │
 ┌────────────────────▼─────────────────────┐
 │  Selector                                │
 │  "Main"                                  │
 └────┬───────────────┬──────────────┬──────┘
      │               │              │
 ┌────▼────┐    ┌─────▼────┐   ┌─────▼──────┐
 │"Defend" │    │ "Attack" │   │ "Approach" │
 └─────────┘    └──────────┘   └────────────┘

```

The "Defend" branch would first check if the opponent is actually performing an attack right now. If it doesn't, the branch fails so we can proceed with the attack branch. If not, we would go through all the defensive options the character has available (ducking, jumping, blocking), check if they are currently possible to perform, check if they would even help in this situation, and then succeed by performing that defensive maneuver:

```
┌───────────────────────────────────────────────────────────────────────────────────────┐
│Sequence                                                                               │
│"Defend"                                                                               │
└─────┬────────────────────────────────────────────────────┬────────────────────────────┘
      │                                                    │
┌─────▼─────────────┐ ┌────────────────────────────────────▼────────────────────────────┐
│Enemy is attacking?│ │ Selector                                                        │
│                   │ │"Pick maneuver"                                                  │
└───────────────────┘ └───────────────┬──────────────────────────────────┬─────────┬────┘
                                      │                                  │         │
                      ┌───────────────▼───────────────────────────┐ ┌────▼───┐ ┌───▼────┐
                      │Sequence                                   │ │Sequence│ │Sequence│
                      │"Duck"                                     │ │"Jump"  │ │"Block" │
                      └────┬───────────────────┬───────────────┬──┘ └───┬────┘ └───┬────┘
                           │                   │               │        │          │
                      ┌────▼──────┐  ┌─────────▼─────────┐ ┌───▼──┐     ▼          ▼
                      │Can I duck?│  │Would ducking help?│ │Duck! │    ...        ...
                      └───────────┘  └───────────────────┘ └──────┘

```

The "Attack" branch would look basically the same. A selector going through all the attacks the AI has available, each one represented by a sequence "Am I able to use this attack?" -\> "Is the opponent in range for this attack?" -\> "Use this attack".

When no attack is performable right now, then we still have the "Approach" node. For starters, we could just walk forward. But this node could later be expanded by a more varied palette of movements, like jumping towards the enemy, or occasionally moving backwards just to throw the enemy off.

There might be one problem, though: Even though the AI will probably not yet be very strong in the strategy department, it is still blessed with superhuman reflexes. It will block everything when it has the choice and spam any attack that has a chance to connect. That might not be too fun to play against. To make the AI a bit easier to play against and also make it a bit less predictable, you could add a random chance for each "Am I able to do this?" leaf to just fail for no reason. So sometimes the AI won't block or attack even though it theoretically could. Just like a human player who doesn't always have perfect reaction either. Adjusting that random fail chance up and down would then also be a great way to adjust the difficulty.

---
Tags: unity, ai
---


title: OpenGL 4 depth of field

text:
# Question
Title: OpenGL 4 depth of field
I am implementing depth of field. My fragment shader has the following code in it:

```
#version 430

uniform sampler2D depth_tex; // texture uniform
uniform sampler2D colour_tex; // texture uniform

uniform int img_width;
uniform int img_height;
uniform float model_distance;
uniform float near;
uniform float far;

uniform int cam_factor;

vec2 img_size = vec2(img_width, img_height);

in vec2 ftexcoord;

layout(location = 0) out vec4 frag_colour;

float to_distance(float depth_colour)
{
    float dist = (2.0*near*far) / (far + near - depth_colour*(far - near));
    return dist;
}

float to_depth(float dist)
{
    float depth = (far*(dist - 2.0*near) + near*dist)/(dist*(far - near));
    return depth;
}

vec4 get_blurred_pixel(vec2 tc)
{
    float depth_colour = texture(depth_tex, tc).r;

    float distance_to_pixel = to_distance(depth_colour);

    float x = clamp(distance_to_pixel, 0.0, 2*model_distance) / (2*model_distance);

    // tent function
    if(x > 0.5)
         x = 1.0 - x;

    x = 1.0 - pow(x, 1.0/10.0);

   const float pi_times_2 = 6.28318530718; // Pi*2

    float directions = 16.0; // BLUR directions (Default 16.0 - More is better but slower)
    float quality = 10.0; // BLUR quality (Default 4.0 - More is better but slower)
    float size = 8.0; // BLUR size (radius)
        vec2 radius = vec2(size/img_size.x * cam_factor, size/img_size.y * cam_factor);

   vec4 blurred_colour = texture(colour_tex, tc);

    for( float d=0.0; d<pi_times_2; d+= pi_times_2/directions)
        for(float i=1.0/quality; i<=1.0; i+=1.0/quality)
            blurred_colour += texture( colour_tex, tc + vec2(cos(d),sin(d))*radius*x*i);

    // Output to screen
    blurred_colour /= quality * directions - 15.0;

    return blurred_colour;
}

// https://www.shadertoy.com/view/Xltfzj
// https://www.blitzcoder.org/forum/topic.php?id=124
void main()
{
    frag_colour.rgb = get_blurred_pixel(ftexcoord).rgb;
    frag_colour.a = 1.0;
}

```

The lines where I use x as a blur factor are:

```
float x = clamp(distance_to_pixel, 0.0, 2*model_distance) / (2*model_distance);

// tent function
if(x > 0.5)
     x = 1.0 - x;

x = 1.0 - pow(x, 1.0/10.0);

```

This code works for far distances, but not for close distances. I cannot figure out why it does not work for close distances. Please let me know if you need more code. Thanks for your time.

# Answer
Thanks for the guidance.

I found a solution. The solution was to scale and translate the variable before calling pow().

```
float x = clamp(distance_to_pixel, 0.0, 2*model_distance) / (2*model_distance);

// tent function
if(x > 0.5)
    x = 1.0 - x; // from 0 to 0.5

x *= 2.0; // from 0 to 1
x *= 2.0; // from 0 to 2
x -= 1.0; // from -1 to 1

x = abs(x);
x = pow(x, 10.0);

```

Here is an image showing the blurred foreground and background, and the focus on the lady character:
> 1 votes

---
Tags: opengl, c++, shaders
---


# Question
Title: Why is my Moon not orbiting Earth in my physics demo
I am in the midst of making a gravitational body demo for my physics engine. For the demo, I am trying to simulate both all the inner planets' (Mercury-Venus-Earth-Mars) orbits around the sun, as well as the orbit of the moon around the Earth. The planets are all working as expected, however the Moon does not seem to want to orbit the Earth. I am at a complete loss for why this is. I'm pretty sure it's not that the gravity is calculated incorrectly, otherwise the planets would not all correctly orbit the sun. The calculations to determine the force acting on the moon begin just below the `while(!WindowShouldClose())` loop. Below is a (rather lengthy) MCVE to see what I mean. I'm hoping that it is a conceptual issue about how I've set up my initial conditions more than a coding mistake. Please note that it requires an installation of raylib

Currently, the moon starts with the correct initial velocity relative to the sun (the combination of the Earth's velocity relative to the Sun and the moon's velocity relative to the Earth), however that velocity never significantly changes, so the moon ends up going in basically a straight line forever. The "basically" is important. The Moon *is* being affected by the Earth, just on a much much smaller scale than anticipated

To use the simulation, there are the standard WASD keys, and the mouse to look around.

```
#include "raylib.h"
#include "rlgl.h"
#include <math.h>
#include <vector>

#define real_sqrt sqrt
#define real_pow powf

// Set some physical values for the simulation
#define G 6.67408e-11 // [m^3 kg^-1 s^-2]

#define SOLARMASS 1.989e30 // [kg]
#define SOLARRADIUS 6.957e8 // [m]

#define EARTHMASS 5.97219e24 // [kg]
#define EARTHORBIT 1.496e11 // [m]
#define EARTHVELOCITY 2.978e4 // [m/s] (Relative to Sun)
#define EARTHRADIUS 6.371e6 // [m]

#define MOONMASS 7.34767309e22 // [kg]
#define MOONORBIT 3.844e8 // [m]
#define MOONVELOCITY 1.023e3 // [m/s] (Relative to Earth)
#define MOONRADIUS 1.737e6 // [m]

using namespace std;

namespace engine {
    typedef float real;

    class Vec3 {
        public:
            // Spatial coordinates
            real x;
            real y;
            real z;

        private:
            // Padding to ensure four word alignment
            real pad;

        public:
            // Default constructor creates a 0 vector
            Vec3() : x(0), y(0), z(0) {}

            // Constructor for when values are passed
            Vec3(const real x, const real y, const real z) : x(x), y(y), z(z) {}

        // Get magnitude of vector
        real magnitude() const {
            return real_sqrt(x*x + y*y + z*z);
        }

        // Sometimes it is useful and faster to just have the square of the magnitude
        real squareMagnitude() const {
            return x * x + y * y + z * z;
        }

        // Normalize a non-zero vector
        void normalize() {
            real l = magnitude();
            if (l > 0) {
                (*this) *= ((real)1)/l;
            }
        }

        // Multiplies vector by given scalar
        void operator *= (const real scalar) {
            x *= scalar;
            y *= scalar;
            z *= scalar;
        }

        // Returns vector scaled by value
        Vec3 operator * (const real value) const {
            return Vec3(x * value, y * value, z * value);
        }

        // Adds given vector
        Vec3 operator + (const Vec3& v) const {
            return Vec3(x + v.x, y + v.y, z + v.z);
        }

        void operator += (const Vec3& v) {
            x += v.x;
            y += v.y;
            z += v.z;
        }

        // Subtracts given vector
        void operator -= (const Vec3& v) {
            x -= v.x;
            y -= v.y;
            z -= v.z;
        }

        Vec3 operator - (const Vec3& v) const {
            return Vec3(x - v.x, y - v.y, z - v.z);
        }

        // Adds a given scaled vector
        void addScaledVector(const Vec3& v, real scale) {
            x += (v.x * scale);
            y += (v.y * scale);
            z += (v.z * scale);
        }

        real operator * (const Vec3& v) const {
            return x * v.x + y * v.y + z * v.z;
        }

        void operator = (const Vec3& v) {
            x = v.x;
            y = v.y;
            z = v.z;
        }

        void clear() {
            x = y = z = 0;
        }
    }; // class Vec3

    class Particle {
        protected:
            // Keep track of position and its time derivatives
            Vec3 pos;
            Vec3 vel;
            Vec3 acc;

            // Keep track of damping of linear motion
            real damping;

            /**
             * Holds the inverse of the mass of the particle. It
             * is more useful to hold the inverse mass because
             * integration is simpler, and because in real-time
             * simulation it is more useful to have objects with
             * infinite mass (immovable) than zero mass
             * (completely unstable in numerical simulation).
            */
            real inverseMass;

            Vec3 forceAccum;

        public:
            Particle() : pos(0, 0, 0), vel(0, 0, 0), acc(0, 0, 0), damping((real)1.0), inverseMass(0) {};

            Particle(const Vec3 pos,
                        const Vec3 vel,
                        const Vec3 acc,
                        const real damping,
                        const real inverseMass) : pos(pos), vel(vel), acc(acc), damping(damping), inverseMass(inverseMass) {};

            void integrate(real duration) {
                // We won't integrate particles with infinite or negative mass
                if (inverseMass <= 0.0f) return;

                assert(duration > 0.0);

                // Update linear position.
                pos.addScaledVector(vel, duration);
                pos.addScaledVector(acc, duration * duration * 0.5);

                //Vec3 resultingAcc = acc;
                //resultingAcc.addScaledVector(forceAccum, inverseMass);
                acc = forceAccum * inverseMass;

                // Impose drag.
                vel *= real_pow(damping, duration);

                // Update linear velocity from the acceleration.
                //vel.addScaledVector(resultingAcc, duration);
                vel.addScaledVector(acc, duration);

                // Clear forces
                clearAccumulator();
            } // integrate()

            // Return position of particle
            Vec3 getPosition() const {
                return pos;
            }

            void clearAccumulator() {
                forceAccum.clear();
            }

            void addForce(const Vec3& f) {
                forceAccum += f;
            }

            bool hasFiniteMass() const {
                return inverseMass > 0.0f;
            }

            real getMass() const {
                if (inverseMass == 0) {
                    return std::numeric_limits<float>::max();
                } else {
                    return ((real)1.0)/inverseMass;
                }
            }
    }; // class Particle

    class ParticleForceGenerator {
        public:
            virtual void updateForce(Particle *particle, real duration) = 0;
    };

    class ParticleForceRegistry {
        protected:
            // Keep track of force generator and the particle that called for it
            struct ParticleForceRegistration {
                Particle *particle;
                ParticleForceGenerator *fg;
            };

            // Holds list of registrations
            typedef std::vector<ParticleForceRegistration> Registry;
            Registry registrations;

        public:
            // Registers the given force generator to apply to the given particle
            void add(Particle* particle, ParticleForceGenerator* fg) {
                ParticleForceRegistration registration;
                registration.particle = particle;
                registration.fg = fg;
                registrations.push_back(registration);
            }

            // Clear all registrations from the registry
            void clear() {
                registrations.clear();
            }

            // Calls all the force generators to update the forces of their corresponding particles
            void updateForces(real duration) {
                Registry::iterator i = registrations.begin();

                for (; i != registrations.end(); i++) {
                    i->fg->updateForce(i->particle, duration);
                }
            }
    }; // class ParticleForceRegistry

    class ParticlePointGravity : public ParticleForceGenerator {
        Vec3 origin;
        real mass;

        public:
            ParticlePointGravity(const Vec3& origin, const real mass)
            : origin(origin), mass(mass)
            {
            }

            void setOrigin(const Vec3& origin) {
                this->origin = origin;
            }

            void updateForce(Particle* particle, real duration) {
                // Check if particle has a finite mass
                if (!particle->hasFiniteMass()) return;

                Vec3 force;

                // Calculate the direction of the force
                Vec3 direction = particle->getPosition() - origin;
                real distance = direction.magnitude();
                direction.normalize();

                // Calculate the magnitude of the force
                real forceMagnitude = -G * particle->getMass() * mass / (distance * distance);
                force = direction * forceMagnitude;

                // Apply the force
                particle->addForce(force);
            }
    }; // class ParticlePointGravity
}; // namespace engine

using namespace engine;

int main() {
    // Initial conditions are at the rightmost point of the orbit (looking down on the system),
    //   where the position is only in x and the velocity is only in z
    Vec3 moon_xi = Vec3(MOONORBIT + EARTHORBIT, 0, 0); // [m]
    Vec3 moon_vi = Vec3(0, 0, MOONVELOCITY + EARTHVELOCITY); // [m/s]
    Vec3 moon_ai = Vec3(0, 0, 0); // [m/s^2]

    Vec3 earth_xi = Vec3(EARTHORBIT, 0, 0); // [m]
    Vec3 earth_vi = Vec3(0, 0, EARTHVELOCITY); // [m/s]
    Vec3 earth_ai = Vec3(0, 0, 0); // [m/s^2]

    Vec3 solGravityOrigin = Vec3(0, 0, 0);
    real solMass = SOLARMASS; // [kg]

    Particle *earth = new Particle(earth_xi, earth_vi, earth_ai, 1, 1/EARTHMASS);
    Particle *moon = new Particle(moon_xi, moon_vi, moon_ai, 1, 1/MOONMASS);

    // Raylib Initialization
    //--------------------------------------------------------------------------------------
    const int screenWidth = 720;
    const int screenHeight = 450;

    InitWindow(screenWidth, screenHeight, "Djinn - Solar Orbit Demo");

    // Define the camera to look into our 3d world (position, target, up vector)
    Camera camera = { 0 };
    camera.position = (Vector3){ 15.0f, 5.0f, 0.0f };
    camera.target = (Vector3){ 15.0f, 0.0f, 0.0f };
    camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
    camera.fovy = 60.0f;
    camera.projection = CAMERA_PERSPECTIVE;

    SetCameraMode(camera, CAMERA_FIRST_PERSON); // Set a first person camera mode
    SetCameraMoveControls(KEY_W, KEY_S, KEY_D, KEY_A, KEY_SPACE, KEY_LEFT_SHIFT);

    SetTargetFPS(60);                           // Set our game to run at 60 frames-per-second
    //--------------------------------------------------------------------------------------

    // Time resolution
    real dt = 1e4; // [s]

    // Define force registry
    ParticleForceRegistry registry;

    // Define force generators to be applied to the particle
    ParticlePointGravity* solGravity = new ParticlePointGravity(solGravityOrigin, solMass); // Args: (Vec3) origin, (real) mass
    ParticlePointGravity* earthGravity = new ParticlePointGravity(earth_xi, EARTHMASS);

    // Register force generators with the particle
    registry.add(earth, solGravity);
    registry.add(moon, earthGravity);

    while(!WindowShouldClose()) {
        // Update the forces per loop
        registry.updateForces(dt);

        // Calculate the new pos, vel, and acc of the moon and earth
        earth->integrate(dt);
        moon->integrate(dt);

        // Set the earth gravity's new origin to the new position of the earth
        earthGravity->setOrigin(earth->getPosition());

        // Get positions and scale down to fit on screen
        Vec3 earth_x = earth->getPosition() * 1e-10; // Scale down to tens of meters
        Vec3 moon_x = moon->getPosition() * 1e-10; // Scale down to tens of meters

        // Convert my Vec3 object to a Raylib Vector3 object
        Vector3 *rl_earth_x = reinterpret_cast<Vector3*>(&earth_x); // Raylib vector for drawing
        Vector3 *rl_moon_x = reinterpret_cast<Vector3*>(&moon_x);

        UpdateCamera(&camera);

        BeginDrawing();
            ClearBackground(BLACK);

            BeginMode3D(camera);

                DrawGrid(1000, 1.0f);        // Draw a grid

                DrawSphere(*rl_earth_x, 0.25, BLUE); // Draw earth

                DrawSphere(*rl_moon_x, 0.1, GRAY); // Draw moon

                DrawSphere((Vector3){0, 0, 0}, 1, YELLOW); // Draw Sol

            EndMode3D();

            DrawRectangle(10, 30, 150, 75, Fade(SKYBLUE, 0.5f));
            DrawRectangleLines(10, 30, 150, 75, BLUE);

            DrawText("Earth:", 20, 40, 10, WHITE);
            DrawText(TextFormat("X: %02.02f", rl_earth_x->x), 20, 55, 10, WHITE);
            DrawText(TextFormat("Y: %02.02f", rl_earth_x->y), 20, 70, 10, WHITE);
            DrawText(TextFormat("Z: %02.02f", rl_earth_x->z), 20, 85, 10, WHITE);

            DrawText("Moon:", 80, 40, 10, WHITE);
            DrawText(TextFormat("X: %02.02f", rl_moon_x->x), 80, 55, 10, WHITE);
            DrawText(TextFormat("Y: %02.02f", rl_moon_x->y), 80, 70, 10, WHITE);
            DrawText(TextFormat("Z: %02.02f", rl_moon_x->z), 80, 85, 10, WHITE);

            DrawFPS(10, 10);

        EndDrawing();
    }

    CloseWindow();

    return 0;
}

```

NOTE: The flags to compile this code looks like : `-framework IOKit -framework Cocoa -framework OpenGL <backtick>pkg-config --libs --cflags raylib<backtick>`

# Answer
> 0 votes
The problem might be here:

```
registry.add(earth, solGravity);
registry.add(moon, earthGravity);

```

You state that the earth is affected by the sun and the moon is affected by the earth. But you forgot something crucial: The moon is also affected by the sun!

```
registry.add(earth, solGravity);
registry.add(moon, earthGravity);
registry.add(moon, solGravity);

```

In reality, every mass in the universe affects every other mass - no exceptions! So if you want to be completely physically correct, then you also need to have the earth's gravity affect the sun and the moon's gravity affect the earth *and* the sun. The latter is probably far too small to matter for your simulation. But it might matter in case of Jupiter. The influence of Jupiter on the sun is in fact large enough that the Sun and Jupiter orbit a point which is slightly outside of the sun.

And you probably want to simulate fictional solar systems with more extreme orbits and bodies. In those cases your intuition on what matters and what doesn't might be wrong. So which gravity on which body can be ignored and which can not is something I would decide automatically at runtime and not while designing the solar system.

What I would do in this case is put all the bodies into an array (or std::vector) and then just use two nested for-loops to connect every body with every other body, skipping those cases where the body A is so much lighter than body B that it *probably* doesn't matter. The exact cutoff factor would be a tradeoff between accuracy and speed you would need to decide yourself.

---
Tags: c++, physics-engine, raylib
---


title: Creating a nav mesh

text:
# Question
Title: Creating a nav mesh
I'm coding a custom engine using Python and Pygame. It's a top down 2D isometric RTS and I wan't to implement pathfinding for my units.

My research has lead me to using a Navigation mesh which seems to be the optimal solution. Currently this is what I got:

1. Create cells that covers every walkable space.
2. Use A\* pathfinding on the center of each rect
3. Use the stupid funnel algorithm to shorten the path (every vector) optimally around unwalkable objects

Questions:

1. Is this a correct interpretation?
2. I'm thinking of doing the cells as rects as all objects in my engine currently will be rectangular (contrary to triangles which are often recommended)?
3. I don't know how to size my cell rects. Is it viable to do them as large as possible until they "reach" an object? Otherwise what metric should be used?

# Answer
TLDR: Which option to use depends on the need. Grid-based maps use navmesh will have additional workload, but the effect is better in most cases.

Navmesh is essentially an optimization of a grid-based pathfinding scheme. Its main purpose is to reduce the number of nodes in the entire map to optimize performance. Most navmesh uses triangular meshes as basic data.

As for the relationship of them, I made a rough form:

|  | cells/tiles | triangle mesh |
| --- | --- | --- |
| data structure | 2d-array / cross linked list | (undirected) graph |
| shortest path search algorithm | bfs | graph search (floyd,dijkstra,...) |
| optimization | A\* and its variants | A\* and its variants |
| shorten the path | Line drawing algorithm (Bresenham's line algorithm) | funnel algorithm |

In the pathfinding algorithm, the two are basically the same thing. A 2d array can be seen as an undirected graph with a node distance of 1. When the distance between nodes in an undirected graph is 1, Dijkstra's algorithm degenerates into BFS. So tile pathfinding is a special case of graph search, some additional variants can be used, such as JPS.

A\* achieves better performance by using heuristics to guide its search. It can be seen as an extension of Dijkstra's algorithm. So of course it can be used in BFS.

Now we come back to the original question.

> 1. Create cells that covers every walkable space.
> 2. Use A\* pathfinding on the center of each rect.

From these two pieces of information, the basic solution is to divide the space into 2D regions, and then perform grid-based A\* pathfinding. I don't think it's a navmesh because it doesn't optimize for the number of nodes. You can switch to a triangle-based navmesh through some schemes, or use some rectangle-based node reduction strategies. this is an example

> 3. Use the stupid funnel algorithm to shorten the path (every vector) optimally around unwalkable objects

The funnel algorithm as far as I know is based on triangles. I don't know if there's a rectangle-based version (it's theoretically possible), but it doesn't make much sense to do so. Because grid-based paths inherently have significant precision limitations, path vector directions are always multiples of 45° or 90°. The funnel algorithm cannot eliminate this precision limitation. Maybe it can straighten your path by 10% instead of 100%.

An alternative solution is to check the visibility of the nodes between the paths (using the line drawing algorithm), and if two nodes are mutually visible, delete all nodes between them. *(I will explain this algorithm in detail in the additional information.)*

Questions:

> 1. Is this a correct interpretation?
> 2. I'm thinking of doing the cells as rects as all objects in my engine currently will be rectangular (contrary to triangles which are often recommended)?

Already answered.

> 3. I don't know how to size my cell rects. Is it viable to do them as large as possible until they "reach" an object? Otherwise what metric should be used?

In grid-based pathfinding, it depends on how precise you want it to be, the higher the precision the lower the performance. You can get the specific parameters you want by testing. Navmesh will not have this problem, because the number of nodes has been reduced.

***Additional information**: How to get a triangle based navmesh from a grid based map?

Option 1: Achieve by yourself. In general, triangles need to be generated from grid data. Generally, there will be steps such as searching for blocking polygonal edges, smoothing edges, setting boundary points, triangulation, and merging triangles. this is an example

Option 2: Add a third-party pathfinding module to your engine, such as recastnavigation. It also needs to generate the data it needs through the grid. For example, after generating triangles, convert them to `.obj` files, and then import them into recast to generate navmesh. The advantage of this is that there are out-of-the-box optimizations available, such as triangle merging, baking different meshes through agent radius, etc.

***Additional information2** If I adopt grid-based pathfinding, how can I reduce the path using the straight line drawing algorithm?

1. The basic strategy is to check if the nodes of the path obtained by pathfinding are visible between them, and if they are visible, delete all nodes between them. Two nodes are visible if the line between them does not pass through the block.
2. Bresenham's\_line\_algorithm is used to rasterize the straight line represented by the geometry into grid coordinates. In this way, we can get the coordinates that need to be detected.
3. If all the coordinates that need to be detected(The yellow grids in the picture above) are not blocking, then it can be seen that the two nodes are visible.
4. How to check the whole path? A locally optimal strategy is to start from the starting point, find the visible point **farthest** from the current point, and then set this point as the current point to repeat until the current point is the end point.

We represent this process in pseudocode:

```
path = [(1,1),(1,2),...] //original path
reducedPath = [path[0]] //path after optimization
curIndex = 0 //starting point
while(true) {
    bool isOK = false
    for(int i = len(path) - 1; i > curIndex; i--) {
        //Traverse in reverse order to find the farthest visible point
        if (isVisible(path[curIndex], path[i])) {  //Visibility detection using line drawing algorithm
            reducedPath.add(path[i])
            curIndex = i
            isOK = true
            break
        }
    }
    if !isOK {
        //No optimization available, start searching from the next node
        curIndex++
        if (curIndex == len(path)-1) { //The last point has been reached, end the iteration
            break
        }
    }
}

```
5. Optional: delete all nodes with the same slope in advance, and only keep the inflection points, which can greatly reduce the number of nodes that need to be traversed. Such a strategy will not get the optimal path in some cases, but it can cover most cases.
> 3 votes

---
Tags: path-finding, python, pygame, navmesh
---


# Question
Title: What is the expected software maintenance pattern when switching Unity versions?
What is the typical upkeep of a project made in Unity, specifically how often/how much the code needs to be updated/changed/added when a new Unity version is released and/or when your currently used Unity version becomes deprecated?

I am not asking about a specific coding change. I am asking about the general pattern of upkeep needed whenever I need to switch Unity versions.

I want to avoid opinions. I know that it is impossible to predict the future. I am asking about objective facts about how Unity handles these updates.

# Answer
*By design* updating from one Unity version to another *should* be a flawless process. Unity is pretty well-committed to maintaining backwards compatibility. This goes so far that when they discover essential design flaws, they often develop features from scratch and offer them as an optional package instead of fixing and enhancing the old system (Unity UI -\> UIElements Package, IK System -\> Animation Rigging Package etc.). That's because it's impossible to fix problematic behavior, because some people somewhere might rely on that behavior. Sometimes Unity deprecates scripting APIs, but there is a system in place to automatically change sourcecode to use the new APIs instead, and it even works occasionally.

However, that's not how it usually turns out in practice. The problem is that many game developers do things in Unity in ways they are not really supposed to be doing. They rely on undocumented behavior or use bugs as if they were features. And because game developers are really creative people, they love to build essential game mechanics which hinge on engine details. Details which the developers at Unity consider to be obscure edge-cases no *reasonable* game would ever rely on. Too bad that we game developers aren't reasonable people building reasonable software.

And in most cases we are not even aware that we are doing this. Heck, *I* have been doing this. I thought creating a "dark-light" by setting the intensity of a point-light to a negative value via a script was a cool trick. Until it stopped working a couple years ago, because it was actually not supposed to be possible to do that.

Are *you* doing things like that? Impossible to say. We don't know your project. And even if we *would* know it, our guess which edge-cases might behave slightly different in game-breaking ways in the future is as good as yours. We can not tell you "how often/how much the code needs to be updated/changed/added when a new Unity version is released" because that's very, very project-specific. Sometimes it just works. Sometimes the whole project is broken and you have no idea why. Or anything in between. It's simply impossible to predict if and how much problems upgrading to a new Unity version will cause.

(And by the way, in my experience, most problems are not with the script code no longer working, but rather with the behavior of the standard components now being slightly different).

So what general advise can I give for updating Unity during a project?

1. While you develop your project, try to follow best practices. Use it in the way the Unity developer expect you to use it, because those are the ways they are least likely to break in future updates. Unfortunately it's not always easy to find out how they want you to use it. Especially when you learn from 3rd party YouTubers who learned their stuff from other YouTubers. I always recommend to rely on the official sources, like the Unity manual and script reference and the Unity blog for cutting-edge features. When those official sources tell you "yes, here is the API, but you should probably use *other API*", then you should heed their warning.
2. Don't update your Unity project to a new version just because the update is there. Only update when you have a reason. Read the release notes, and then decide for yourself if it contains a bugfix for a problem *your project* is experiencing or if it contains a new feature that you need in *your project* to accomplish something that would otherwise be impossible or take much longer to do.
3. Do the update on a new branch of your version control system, so you can return to the main branch if it turns out the update causes problems. Unity says it's not possible to downgrade a project once upgraded. This is true, but only for people who don't use version control. If you have your whole project under version control, it's trivial to just return it to a previous commit. Seriously, if you are not using version control in this day and age, you are not doing software development. You are just fooling around. Yes, even for solo developers.
4. Test the project thoroughly. In a perfect world you would have an automated test suit you can run to make sure your game still works the way it worked before. Unfortunately in the real world most game developers don't take the time to create automated tests. Even though they are really useful for things like engine updates. So you probably need to test the game manually from start to finish.
5. Then you can merge the branch into the trunk of your version control.
> 0 votes

---
Tags: unity, software-engineering, support
---


# Question
Title: How does Sorting Layer work *under the hood*?
I know how to use SpriteRendere's `Sorting Layer` and `Order in Layer`. But how do they actually work under the hood? How the render pipeline gets this information? Is there a "sprite sorter" to sort all the sprites before rendering every frame? Or are the mesh's Z changes? Or the sorting layer info is written to z-buffer for alpha blend?

# Answer
Answered from Unity staff:

> Before rendering, all the renderers are sorted in order before they are rendered. For renderers in the Transparent Queue, they are sorted using the Sorting Layer and Order first before the other criteria (See https://docs.unity3d.com/Manual/2DSorting.html). The sorted renderer list is then passed to the render pipeline for batching and rendering. The sorted renderer order is not written to the Z-buffer.
>
> All renderers do have a Sorting Layer and Order in Layer, even if you may not see it in their respective Inspectors (See https://docs.unity3d.com/ScriptReference/Renderer-sortingOrder.html). You could use that to order your Renderer if you are not using a SpriteRenderer.
> 1 votes

---
Tags: unity, sprites
---


# Question
Title: When are the resources used by a prefab loaded?
For example, I have a scene. The scene has a GameObject. The GameObject has reference to a prefab, like this:

```
class MyGameObject : MonoBehaviour
{
    [SerializedField] private GameObject myPrefab;
}

```

And I assign a prefab to it in the inspector.

The prefab has references to some really huge resources, e.g. a MeshFilter with a hi-res mesh.

Now my question is: when is the mesh loaded? When I load the scene? Or when I instantiate the prefab for the first time? Also, is there a "resource loading debugger" where I can find out the answers myself?

# Answer
It's loaded when you load the scene, along with everything else in that scene or referenced by something in the scene (recursively). The scene will not finish loading and execute its first frame until all these dependencies have finished loading.

If you want to defer the loading of this asset to a later time, you can use Addressables to store an address of the prefab rather than a direct reference. Then in script you can choose when to load the asset at that address, and can do so asynchronously while the scene runs.
> 0 votes

---
Tags: unity, loading, prefabs
---


# Question
Title: How use inspector to select a System.Type (not an instance) of classes inheriting from a specific class?
I have an abstract class, call it `FooClass`. And there are two classes that inherit from it, call 'em `BazClass` and `DazClass`. I want to create instances of `BazClass` and `DazClass` at runtime.

I have scriptable object which I want to store a variable referring to the **type** of either `BazClass` or `DazClass` (*Not to an instance of `BazClass` or `DazClass`*), so I know which type to instantiate at runtime.

1. Can I have a variable that takes types inherited from another class?

For example:

```
using System;
Type<:T> variableName where T is FooClass;
//stores a type that inherits from FooClass.

```
2. How can I visualise this variable in the Unity inspector?

# Answer
> 1 votes
Here's a demo of this working with a "Type Store" scriptable object storing two types: `FooDerivedA` which is a subclass of `FooBase`, and `MeshCollider` which is a subclass of `Collider` (so you can see it works with built-in types too)

First, we can define a class to store our serialized type information. `System.Type` isn't itself serializable, so we'll need to store an identifier like its assembly-qualified name, and use that to look up the correct type when deserializing:

```
using UnityEngine;

[System.Serializable]
public class InspectableType<T> : ISerializationCallbackReceiver {

    [SerializeField] string qualifiedName;

    System.Type storedType;

    #if UNITY_EDITOR
    // HACK: I wasn't able to find the base type from the SerializedProperty,
    // so I'm smuggling it in via an extra string stored only in-editor.
    [SerializeField] string baseTypeName;
    #endif

    public InspectableType(System.Type typeToStore) {
        storedType = typeToStore;
    }

    public override string ToString() {
        if (storedType == null) return string.Empty;
        return storedType.Name;
    }

    public void OnBeforeSerialize() {
        qualifiedName = storedType.AssemblyQualifiedName;

        #if UNITY_EDITOR
        baseTypeName = typeof(T).AssemblyQualifiedName;
        #endif
    }

    public void OnAfterDeserialize() {
        if (string.IsNullOrEmpty(qualifiedName) || qualifiedName == "null") {
            storedType = null;
            return;
        }
        storedType = System.Type.GetType(qualifiedName);
    }

    public static implicit operator System.Type(InspectableType<T> t) => t.storedType;

    // TODO: Validate that t is a subtype of T?
    public static implicit operator InspectableType<T>(System.Type t) => new InspectableType<T>(t);
}

```

This lets you add a field in your scriptable object something like this:

```
[SerializeField]
InspectableType<BaseTypeOrInterface> myType = typeof(DerivedType);

```

I've implemented implicit conversions to and from `System.Type` so you can mostly ignore this wrapper elsewhere.

Next, create a folder called "Editor" and add the following property drawer:

```
using UnityEngine;
using UnityEditor;
using System.Linq;

using Type = System.Type;

[CustomPropertyDrawer(typeof(InspectableType<>), true)]
public class InspectableTypeDrawer : PropertyDrawer {
    System.Type[] _derivedTypes;
    GUIContent[] _optionLabels;
    int _selectedIndex;

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        var storedProperty = property.FindPropertyRelative("qualifiedName");
        string qualifiedName = storedProperty.stringValue;

        if (_optionLabels == null) {
            Initialize(property, storedProperty);
        } else if (_selectedIndex == _derivedTypes.Length) {
            if (qualifiedName != "null") UpdateIndex(storedProperty);
        } else {
            if (qualifiedName != _derivedTypes[_selectedIndex].AssemblyQualifiedName) UpdateIndex(storedProperty);
        }

        var propLabel = EditorGUI.BeginProperty(position, label, property);
        EditorGUI.BeginChangeCheck();

        _selectedIndex = EditorGUI.Popup(position, propLabel, _selectedIndex, _optionLabels);

        if (EditorGUI.EndChangeCheck()) {
            storedProperty.stringValue = _selectedIndex < _derivedTypes.Length ? _derivedTypes[_selectedIndex].AssemblyQualifiedName : "null";
        }
        EditorGUI.EndProperty();
    }

    static Type[] FindAllDerivedTypes(Type baseType)
    {
        return baseType.Assembly
            .GetTypes()
            .Where(t =>
                t != baseType &&
                baseType.IsAssignableFrom(t)
                ).ToArray<Type>();
    }

    void Initialize(SerializedProperty property, SerializedProperty stored) {

        var baseTypeProperty = property.FindPropertyRelative("baseTypeName");
        var baseType = Type.GetType(baseTypeProperty.stringValue);

        _derivedTypes = FindAllDerivedTypes(baseType);

        if (_derivedTypes.Length == 0) {
            _optionLabels = new[] { new GUIContent($"No types derived from {baseType.Name} found.")};
            return;
        }

        _optionLabels = new GUIContent[_derivedTypes.Length+1];
        for (int i = 0; i < _derivedTypes.Length; i++) {
            _optionLabels[i] = new GUIContent(_derivedTypes[i].Name);
        }
        _optionLabels[_derivedTypes.Length] = new GUIContent("null");

        UpdateIndex(stored);
    }

    void UpdateIndex(SerializedProperty stored) {
        string qualifiedName = stored.stringValue;

        for (int i = 0; i < _derivedTypes.Length; i++)
        {
            if (_derivedTypes[i].AssemblyQualifiedName == qualifiedName)
            {
                _selectedIndex = i;
                return;
            }
        }
        _selectedIndex = _derivedTypes.Length;
        stored.stringValue = "null";
    }
}

```

---
Tags: unity, c#, code-reflection
---


# Question
Title: Where am I able to find the things that were imported using Java on IntelliJ?
I am trying to build a Minecraft mod with Forge on IntelliJ, and I am wondering where I can find the parts that are being imported.

For example: `import net.minecraft.world.level.block.Block;`

I checked minecraft.net to see whether I can find it there, but I was unable to. This is the same for other sources, which I'd like to gather more information from, such as what they are, what they are used for, what else is included, etc. I also checked all the folders included in the setup with Forge.

As of now, I am more comfortable with Javascript/Node.JS, so I know if I were doing something similar to this in JS, it would be like searching it up on npmjs.com.

EDIT: I think I found it: I believe it was in `./build/_compileJava_2`. I guess my question still lasts for a general build with Java. How come although those sources are in other directories (such as `./build/_compileJava_2`) I only have to write `import net.minecraft.world.....` instead of something like `import "./build/_compileJava_2/net/minecraft/world/..."`?

# Answer
> 0 votes
Without knowing what build system you are using its hard to say.

There is a bunch of basic java stuff you probably need to learn about too. Maven is the main repo for java artifacts (https://search.maven.org/), similar to npm for js. However for commercial game files like the minecraft, they are not likely to be distributed this way.

The key thing for any java project is that imports are done by package name, not file location/path. The find the location in disk, you need to know how the classpath is being built. This provides an overview of what it is, but it is not normally set manually these days: https://stackoverflow.com/questions/2396493/what-is-a-classpath-and-how-do-i-set-it

Additionally, in Intellij, you should be able to click on the project tab and make sure it is set to project view. There should be an external libraries section listing all the dependencies. You can expand these to find more details, and right-click -\> open in -\> explorer to find the location in your file system.

---
Tags: java, minecraft-modding, modding
---


# Question
Title: Where should the origin be on modular level pieces?
I really like the idea of modelling pieces of a 3D environment as parts of a modular set and then sticking them together. I would make pieces of wall that were, for arguments sake, 3x3m and then stitch them together.

The thing I can't understand is what happens when you have a level where you can see both the interior and exterior of a wall. If a wall has any thickness then an external corner will be longer than an internal corner which will wreck my grid if I model the interior and exterior walls separately. If I model them together with the origin in the middle of the wall then that destroys the modular advantage by needing to maintain solid (2 sided) versions of the wall.

So my question is how can I model interior and exterior modular walls while still respecting the grid for snapping?

# Answer
Walls with zero thickness (i.e. plane) should be avoided in most instances, since they don't exist in reality, and on the flip-side the non-displayed wall sides should be culled before render.

## Onto the answer

Model each wall segment (plane) offset by a small amount (1 or .01) with respect to the interior direction, and sides (plane) covering the small distance as necessary to provide doorways, corners, and the like. The origin being the the center of the square.

The materials slots for the sides needs to be different from each other face to allow consistent materials corners and edges.

Twelve wall blocks four per direction (Flat, L, inverse L and U). To reduce draw calls this needs to be instanced or make larger blocks.

The modular components for each shape become the building blocks since every square becomes internal wall.

The only restriction is the camera grid collision can not be closer than the small amount to any wall.

This maintains grid integrity while providing visibility for both sides of a wall when needed.
> 2 votes

---
Tags: level-design, 3d-modeling
---


# Question
Title: Apply bloom effect to RenderTarget without affecting UI
I'm currently rendering my whole game to a `RenderTarget` in order to stretch the scene to any resolution. I also have a bloom effect rendered with the scene. I'm now working on the UI part of the game, the problem is, I don't want the bloom to affect the UI elements.

So in order to not have the bloom apply to the UI, I need to draw it after the `base.Draw(gameTime);` call. It works, the UI is not affected by the bloom but is also rendered outside of the render target which isn't making it responsive for every resolution.

How can I incorporate the UI inside the render target but without having it affected by the bloom component?

This is the Draw method code:

```
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.SetRenderTarget(_renderTarget);
        GraphicsDevice.Clear(Color.Black);

        Bloom.BeginDraw();

        _currentState.Draw(gameTime, _spriteBatch);
        GraphicsDevice.SetRenderTarget(null);
        _spriteBatch.Begin(blendState: BlendState.AlphaBlend);
        _spriteBatch.Draw(_renderTarget, new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height), Color.White);
        //_spriteBatch.Draw(texture, new Rectangle(50, 50, 500, 200), new Color(Color.Black, 0.7f));
        _spriteBatch.End();

        base.Draw(gameTime);

        _currentState.PostDraw(gameTime, _spriteBatch);
    }

```

# Answer
> 1 votes
I've figured it out thanks to the Monogame community discord. For anyone who will come across this issue - What I did in the end is render the "bloomed scene" to the main render target of the game (instead of the backbuffer as it was until now) and then render both the main render target and the UI elements to a new secondary render target which gets drawn to the backbuffer. So the solution was effectively using 2 render targets which have the same size and are using the same GraphicsDevice. Works like a charm.

---
Tags: c#, xna, monogame, rendertargets, bloom
---


# Question
Title: Sprite Shape & URP Custom 2D Lighting Shader
I've been losing my mind over this for a couple of days now, and can't find any concrete information about it.

I am trying to write a custom shader *(shader graph to be specific)* to light sprite shape objects. This is a relatively simple shader:

This is what the shader material looks like applied to a generic square sprite, and the sprite shape. This is using a `Light 2D` Spot light:

Clearly this shader is working fine for the generic square sprite, but not the sprite shape. I would think that maybe sprite shapes just can't be lit, and that would be the end of that. But when I apply the default `Sprite-Lit-Default` material, it seems to work just fine:

Albeit it requires some sort of "refresh" of the sprite shape, as it doesn't work when its assigned, but it will work once the sprite shape's "Stretch UV" option is toggled *(to note, it doesn't matter if "Stretch UV" is toggled on or off, toggling it is just used to refresh **something** about the sprite shape)*.

The reason I can't just use the built-in `Sprite-Lit-Default` material is because I want to include other properties/effects to the custom shader beyond just the basic lighting.

I'm sure there's a piece of information/knowledge that I lack, or something that I'm missing, but at the moment I'm all out of ideas. Even if a concrete answer of "it's not possible because XYZ" would make me happy at this point.

Some Housekeeping information:

* Unity version: 2021.3.8f1
* Sprite Shape version: 7.0.6
* Shader Graph version: 12.1.7
* Using the Renderer 2D in URP (Because 2d lighting)

Any other information I'd be more than happy to give. I'm not sure what else would be relevant.

# Answer
I know this was partially answered already, but for anyone still trying to get this to work with the Sprite Custom Lit shader, this seemed to work for me:

Create a Texture2D variable and make sure its Reference is set to "\_ShapeLightTexture0", and disable the Exposed checkbox.

This should grab a hard reference to Unity's built-in 2D lighting render target which you can use in place of the 2D Light Texture node.

Not sure why the 2D Light Texture node is bugged here either, but it's probably a simple fix for the Unity devs. I'll see about opening a ticket and getting this patched if no one has done so already.

In the meantime, I hope this works for others!
> 2 votes

# Answer
As a partial answer to this:

Only *Custom Lighting* is broken for sprite shapes. That is, setting the graph to `Sprite Lit Custom`, and using the `2D Light Texture` Node like in the above image (image 1).

Setting the shader graph to "Sprite Lit" instead, and *not* using the `2D Light Texture` Node works just fine:

This works if you don't want to apply any additional logic to the lighting of your sprite shape. In that case, this is all that you need to do. You can still build a Lit sprite shader that acts like the `Sprite-Lit-Default` shader as a base, and add any additional shader *stuff* on top. You just can't mess with the lighting information.

I still have no idea why the custom lit shader won't work, and I can't find any documentation/information pertaining to that. I will update this answer in the future if I stumble on anything like that.
> 3 votes

---
Tags: unity, 2d, sprites, lighting, unity-shader-graph
---


# Question
Title: How to avoid conditional statements inside a vertex shader?
How can I avoid the conditional statement of the following code snippet of the vertex shader? What is an improved way of writing the below?

```
uniform float some_value;
in vec4 a_position;
in vec2 a_texcoord;
out vec2 v_texcoord;

void main (){
    if (position.x > some_value){
      a_texcoord = a_texcoord.st * vec2(1.0, -1.0);
      gl_Position = projectionMatrix * modelViewMatrix * vec4(a_position.x, -a_position.y, a_position.z, 1.0);
    }
    else{
       a_texcoord = a_texcoord;
       gl_Position = projectionMatrix * modelViewMatrix * vec4(a_position, 1.0);
    }
}

```

# Answer
> 1 votes
It looks like your two branches only differ by a sign flip, so you can use the step function to compute the sign you want to use, then multiply by this sign unconditionally.

```
// -1.0 if x > some_value, +1.0 otherwise
float flip = -1.0f + 2.0f * step(position.x, some_value);

a_texcoord *= vec2(1.0f, flip);

gl_Position = projectionMatrix
            * modelViewMatrix
            * vec4( a_position.x,
                    flip * a_position.y,
                    a_position.z,
                    1.0
            );

```

Though be sure to profile this versus the original code. This is verging on a micro-optimization, and depending on the graphics card and how clever the shader compiler is, might not get you much performance benefit.

It does come at a cost of legibility though: I'll confess, I can *never* remember which way the arguments go in a `step`, and whether equality gives a 0 or a 1 — even now I'm *still* anxious I got it wrong above. That's a problem the clear and simple branch doesn't have.

---
Tags: vertex-shader
---


# Question
Title: How increase hp enemy when he was instantiate
help, I can not understand. In my clicker game, when I click on an enemy, he dies. There is also a score counter here.Another code creates new monsters and immediately I try to increase their hp when the counter is 5. But it does not change the health of the created mobs through "

```
public class OnEnemyClick : MonoBehaviour
    [SerializeField] public float _fullHp = 5 ;

    void Update()
    {
         HealthBar();
    }
    void OnMouseDown()
    {
        _fullHp -= 5;
    }
    public void HealthBar()
    {
        if (_fullHp <= 0)
        {
            GameManager._updateScoreValue += 1;
            Destroy(gameObject);
        }
    }
}

// GameManager.cs
public static int _updateScoreValue = 0;
int _arrayEnemiesIndex = (Random.Range(0, _arrayEnemies.Length));
Instantiate(_arrayEnemies[_arrayEnemiesIndex], GenerateSpawnPosition(), _arrayEnemies[_arrayEnemiesIndex].transform.rotation);
if(_updateScoreValue==5)
{
    onEnemyClick._fullHp += 20
}

```

# Answer
> 0 votes
So there are two ways how to fix your problem.

The first is fixing it in the GameManager to set the hp correctly in the spawned enemy. This is a bit of guessing since we do not have the full GameManager. It is similar to your last question.

```
GameObject spawnedEnemy = Instantiate(_arrayEnemies[_arrayEnemiesIndex], GenerateSpawnPosition(), _arrayEnemies[_arrayEnemiesIndex].transform.rotation);
...
spawnedEnemy.GetComponent<OnEnemyClick>._fullHp += 20;

```

The second way is to have the GameManager hold the totalHp of the mop and the OnEnemyClick is grabbing that one at the start.

```
public class OnEnemyClick: MonoBehaviour {

   [SerializeField] public float _fullHp = 0;
   void Start() {
      _fullHp += GameManager.totalHp;
   }
   ...
}

GameManager.cs
public float totalHp = 5;
...
if(_updateScoreValue == 5) {
   totalHp += 20;
}

```

I personally prefer the second way, that way it is easier to make changes in one place. It would allow you to hold in one place hp if you decide that different enemies get different amount of hp for example.

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


# Question
Title: For fully 3D isometric games, is it better to turn the camera 45°? Or have the environment be rotated 45°?
For fully 3D isometric games, is it better to turn the camera 45°? Or have the environment be rotated 45°? I'm asking because, after trying to tilt the camera 45°, the movement code had to be a bit more complex to account for the angle. I'm not sure if it will cause more issues down the line with NPC movement, etc. So perhaps it's better to just turn everything else other than the player 45°.

# Answer
> 2 votes
I made two isometric games in two different programming languages before, and I usually find it way easier to handle the game mechanics (including things like NPC movement) as if the game was completely orthogonal until it gets to visualizing it. In your terms, that would mean that the camera is at an angle and the environment is axis-aligned. That makes a ton of things a lot easier to handle. An entity moving forward, for example, simply increases its x coordinate by its velocity, instead of increasing both its x coordinate and its y coordinate by its `velocity * Math.sin(Math.PI / 4)`. Or do I need to use the cosine for y? Or perhaps -cosine?

You said that making the world axis-aligned but tilting the camera makes "the movement code a bit more complex". I don't really see why that would be the case. But there are lots of ways to do movement in an isometric game. It is very well possible that your particular solution is indeed more fit for a rotated world. For example, when you move the player with the thumb stick, then you need to rotate the input vector by the camera rotation to make the input aligned with the view. But that doesn't mean it's the *only* possible solution for your game. So if you told us more about your movement problems in a new question, we might be able to help you with finding a better solution.

# Answer
> 1 votes
The short answer is that it really shouldn't matter, use whatever you find most convenient.

The longer answer is that converting between the two is fairly simple trigonometry, so pick a coordinate system and orientation that make the game code cleanest.

Personally, I'd keep the world axis-aligned and have a "focus point" or "look at point" also in axis-aligned space.

Then just position your camera at `focus + (+x, +y, +z)` and point the camera at `focus`.

\[Obviously you can use ± `x` and `z` to control which corner you're looking from\]

But even if you chose to have the world rotated 45 degrees, the world will have it's own transform (matrix) and you could multiple any axis-aligned position by that matrix to transform it from "axis space" to "skewed world space", so again... Not onerous.

---
Tags: isometric
---


title: Randomly distribute damage among allies

text:
# Question
Title: Randomly distribute damage among allies
Let's say I have regiments of varying sizes, 500, 1000, 4000 troops.

I want to distribute 1000 troops worth of losses to them so that in aggregate they lose 1000 troops. I want to do it as a performant 1-shot calculation and not a sim.

What's the best way to do this?

# Answer
I would take one regiment, work out the losses for that randomly. I think this is a binomial distribution, but calculating a random binomial variable doesn't have a "one shot" closed form, You can get close enough by finding the expected mean and standard deviation and using the erf() function to find a random variable on the normal distribution (This might be less accurate with kill rates close to 0 or 1). Take that number off both the size of that regiment and the total damage left to allocate.

For a binomial distribution, the mean is \\$np\\$ where \\$n\\$ is the number of units and \\$p\\$ is the probability of being killed, the standard deviation is \\$\sqrt{np(p-1)}\\$. If you can generate a random Gaussian variable r with a mean of 0 and standard deviation of 1, mean+r\*sdev should give you what you want.

Now recalculate the remaining proportion of losses, and do the next regiment in the same way. Repeat for all regiments except the last one.

For the last regiment, just take the remaining damage.

It might be a little counter-intuitive, but if your distributions are close to correct and you catch edge cases (such as checking that remaining kill rate always stays between 0 and 1 inclusive), the order that you do this in doesn't mathematically matter - there won't be any bias (although I would go from smallest to largest to best avoid the edge cases).

For your example, you want to take 1000/5500 (proportion 0.1818...), so the mean is 90.909..., the standard deviation is approximately 8.62439. Say you determine that the first regiment takes 85 damage (slightly below average). You now have 915 damage to distribute between the other two regiments, 915/5000 = 0.183. Say the second regiment takes 187 damage (slightly above average). The remaining regiment takes the remaining 728 damage.

Having done all of that, it would be much easier and still reasonably quick to do a simulation (just take damage one at a time and recalculate proportions as you go) unless the regiments get really large.

For bias towards small or large regiments, just tweak the probabilities, but I'm not going to go into that since I see you removed that part of the question.
> 1 votes

---
Tags: javascript, algorithm
---


# Question
Title: Enemy AI line of sight through Raycast won't behave as expected
I have an issue with my character controller. I'm using a raycast from the enemy AI as a line of sight in order to start following the player. My issue is that with my current character controller collider offset the raycast won't work. When I zero out the character controlle'rs center all is well but, I don't want that since my character is hovering of sorts so if I zero it out it stands bellow it. Can I get some recommendations of what to do in order to fix that?

This is my `CheckLineOfSight` function:

```
    private bool CheckLineOfSight(DummyChar player)
    {
        Vector3 Direction = (player.transform.position - transform.position).normalized;
        float DotProduct = Vector3.Dot(transform.forward, Direction);

        if (DotProduct >= Mathf.Cos(FieldOfView))
        {
            Debug.Log("Can start checking for player Ray " + Direction);
            RaycastHit Hit;
            if (Physics.Raycast(transform.position, Direction, out Hit, Collider.radius, LineOfSightLayers))
            {
                Debug.Log("hited " + Hit.collider.name);
                if (player!= null)
                {
                    Debug.Log("Found target");
                    OnGainSight?.Invoke(player);
                    return true;
                }
            }
        }
        return false;
    }

```

As I mentioned, by using a dummy character with the character controller in default values, the enemy does see the player as it reaches its line of sight and does go towards him, but with my actual player that has its character controller center offset it does not see it.

Edit : here is the inspector view of the controller and player transform

Although i just realized i might be able to truly zero things out by placing the mesh into a child instead of the root

# Answer
So it seems i fixed things by adding a center point in my character.

```
Vector3 Direction = (player.hitCenter.position - transform.position).normalized;

float DotProduct = Vector3.Dot(transform.forward, Direction);

```

By adding a reference point for the ray to fall it s now registering it properly, it seems that the ray was shooting down at the feet and since there is nothing there it could not find the target
> 0 votes

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


title: GameObject mesh.vertices array is empty

text:
# Question
Title: GameObject mesh.vertices array is empty
I've an Icosphere GameObject:

I want to iterate over each of the faces and change the material based on their distance from the center, however I don't seem to be able to retrieve the list of vertices for the object:

```
void Start()
{
    // Works
    _planetRenderer = GetComponent<Renderer>();
    _planetRenderer.sharedMaterial = Materials.First(m => m.name == "Sand");

    // Can't retrieve vertices
    MeshFilter gameObjMeshFilter = GetComponent<MeshFilter>();

    Debug.Log($"Center: {transform.position}");
    Debug.Log($"Mesh Count: {gameObjMeshFilter.mesh.vertices.Length}");
}

```

The vertexCount is returned as 43530, but vertices is an empty array:

# Answer
> 0 votes
Using OnBecameVisible seems to retrieve the values, I'm not sure if that's what I want in this case though?

```
void OnBecameVisible()
{
    MeshFilter gameObjMeshFilter = GetComponent<MeshFilter>();

    Debug.Log($"Center: {transform.position}");
    Debug.Log($"Mesh Count: {gameObjMeshFilter.mesh.vertices.Length}");
}

```

---
Tags: unity, c#, geometry, 3d-meshes, vertex
---